1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

527 redesigned implementation so that package variables are not used across packages

This commit is contained in:
shravan 2020-03-04 15:45:20 +05:30
parent 38b92a0d34
commit 6206852262
11 changed files with 128 additions and 192 deletions

View file

@ -5,8 +5,6 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/nirmata/kyverno/pkg/policyStatus"
"github.com/golang/glog" "github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1" kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
dclient "github.com/nirmata/kyverno/pkg/dclient" dclient "github.com/nirmata/kyverno/pkg/dclient"
@ -127,7 +125,7 @@ func (c *Controller) applyGeneratePolicy(policyContext engine.PolicyContext, gr
} }
if gr.Status.State == "" { if gr.Status.State == "" {
c.policyStatus.Listener <- &generateSyncStats{ c.policyStatus.Listener <- generateSyncStats{
policyName: policy.Name, policyName: policy.Name,
ruleNameToProcessingTime: ruleNameToProcessingTime, ruleNameToProcessingTime: ruleNameToProcessingTime,
} }
@ -141,15 +139,11 @@ type generateSyncStats struct {
ruleNameToProcessingTime map[string]time.Duration ruleNameToProcessingTime map[string]time.Duration
} }
func (vc *generateSyncStats) UpdateStatus(s *policyStatus.Sync) { func (vc generateSyncStats) PolicyName() string {
s.Cache.Mutex.Lock() return vc.policyName
status, exist := s.Cache.Data[vc.policyName] }
if !exist {
policy, _ := s.PolicyStore.Get(vc.policyName) func (vc generateSyncStats) UpdateStatus(status kyverno.PolicyStatus) kyverno.PolicyStatus {
if policy != nil {
status = policy.Status
}
}
for i := range status.Rules { for i := range status.Rules {
if executionTime, exist := vc.ruleNameToProcessingTime[status.Rules[i].Name]; exist { if executionTime, exist := vc.ruleNameToProcessingTime[status.Rules[i].Name]; exist {
@ -164,8 +158,7 @@ func (vc *generateSyncStats) UpdateStatus(s *policyStatus.Sync) {
} }
} }
s.Cache.Data[vc.policyName] = status return status
s.Cache.Mutex.Unlock()
} }
func updateGenerateExecutionTime(newTime time.Duration, oldAverageTimeString string, averageOver int64) time.Duration { func updateGenerateExecutionTime(newTime time.Duration, oldAverageTimeString string, averageOver int64) time.Duration {

View file

@ -4,54 +4,49 @@ import (
"encoding/json" "encoding/json"
"reflect" "reflect"
"testing" "testing"
"time"
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
"github.com/nirmata/kyverno/pkg/policyStatus"
) )
type dummyStore struct {
}
func (d *dummyStore) Get(policyName string) (*v1.ClusterPolicy, error) {
return &v1.ClusterPolicy{}, nil
}
func Test_Stats(t *testing.T) { func Test_Stats(t *testing.T) {
testCase := struct { testCase := struct {
generatedCountStats []v1.GenerateRequest generatedSyncStats []generateSyncStats
expectedOutput []byte expectedOutput []byte
existingStatus map[string]v1.PolicyStatus
}{ }{
expectedOutput: []byte(`{"policy1":{"averageExecutionTime":"","resourcesGeneratedCount":1},"policy2":{"averageExecutionTime":"","resourcesGeneratedCount":1}}`), expectedOutput: []byte(`{"policy1":{"averageExecutionTime":"","resourcesGeneratedCount":2,"ruleStatus":[{"ruleName":"rule1","averageExecutionTime":"23ns","resourcesGeneratedCount":1},{"ruleName":"rule2","averageExecutionTime":"44ns","resourcesGeneratedCount":1},{"ruleName":"rule3"}]}}`),
generatedCountStats: []v1.GenerateRequest{ generatedSyncStats: []generateSyncStats{
{ {
Spec: v1.GenerateRequestSpec{ policyName: "policy1",
Policy: "policy1", ruleNameToProcessingTime: map[string]time.Duration{
}, "rule1": time.Nanosecond * 23,
Status: v1.GenerateRequestStatus{ "rule2": time.Nanosecond * 44,
GeneratedResources: make([]v1.ResourceSpec, 1),
}, },
}, },
{ },
Spec: v1.GenerateRequestSpec{ existingStatus: map[string]v1.PolicyStatus{
Policy: "policy2", "policy1": {
}, Rules: []v1.RuleStats{
Status: v1.GenerateRequestStatus{ {
GeneratedResources: make([]v1.ResourceSpec, 1), Name: "rule1",
},
{
Name: "rule2",
},
{
Name: "rule3",
},
}, },
}, },
}, },
} }
s := policyStatus.NewSync(nil, &dummyStore{}) for _, generateSyncStat := range testCase.generatedSyncStats {
testCase.existingStatus[generateSyncStat.PolicyName()] = generateSyncStat.UpdateStatus(testCase.existingStatus[generateSyncStat.PolicyName()])
for _, generateCountStat := range testCase.generatedCountStats {
receiver := &generateSyncStats{
generateRequest: generateCountStat,
}
receiver.UpdateStatus(s)
} }
output, _ := json.Marshal(s.Cache.Data) output, _ := json.Marshal(testCase.existingStatus)
if !reflect.DeepEqual(output, testCase.expectedOutput) { if !reflect.DeepEqual(output, testCase.expectedOutput) {
t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output)) t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output))
} }

View file

@ -14,7 +14,8 @@ import (
) )
type statusUpdater interface { type statusUpdater interface {
UpdateStatus(s *Sync) PolicyName() string
UpdateStatus(status v1.PolicyStatus) v1.PolicyStatus
} }
type policyStore interface { type policyStore interface {
@ -22,25 +23,25 @@ type policyStore interface {
} }
type Sync struct { type Sync struct {
Cache *cache cache *cache
Listener chan statusUpdater Listener chan statusUpdater
client *versioned.Clientset client *versioned.Clientset
PolicyStore policyStore policyStore policyStore
} }
type cache struct { type cache struct {
Mutex sync.RWMutex mutex sync.RWMutex
Data map[string]v1.PolicyStatus data map[string]v1.PolicyStatus
} }
func NewSync(c *versioned.Clientset, p policyStore) *Sync { func NewSync(c *versioned.Clientset, p policyStore) *Sync {
return &Sync{ return &Sync{
Cache: &cache{ cache: &cache{
Mutex: sync.RWMutex{}, mutex: sync.RWMutex{},
Data: make(map[string]v1.PolicyStatus), data: make(map[string]v1.PolicyStatus),
}, },
client: c, client: c,
PolicyStore: p, policyStore: p,
Listener: make(chan statusUpdater, 20), Listener: make(chan statusUpdater, 20),
} }
} }
@ -58,7 +59,19 @@ func (s *Sync) updateStatusCache(stopCh <-chan struct{}) {
for { for {
select { select {
case statusUpdater := <-s.Listener: case statusUpdater := <-s.Listener:
statusUpdater.UpdateStatus(s) s.cache.mutex.Lock()
status, exist := s.cache.data[statusUpdater.PolicyName()]
if !exist {
policy, _ := s.policyStore.Get(statusUpdater.PolicyName())
if policy != nil {
status = policy.Status
}
}
s.cache.data[statusUpdater.PolicyName()] = statusUpdater.UpdateStatus(status)
s.cache.mutex.Unlock()
case <-stopCh: case <-stopCh:
return return
} }
@ -66,24 +79,24 @@ func (s *Sync) updateStatusCache(stopCh <-chan struct{}) {
} }
func (s *Sync) updatePolicyStatus() { func (s *Sync) updatePolicyStatus() {
s.Cache.Mutex.Lock() s.cache.mutex.Lock()
var nameToStatus = make(map[string]v1.PolicyStatus, len(s.Cache.Data)) var nameToStatus = make(map[string]v1.PolicyStatus, len(s.cache.data))
for k, v := range s.Cache.Data { for k, v := range s.cache.data {
nameToStatus[k] = v nameToStatus[k] = v
} }
s.Cache.Mutex.Unlock() s.cache.mutex.Unlock()
for policyName, status := range nameToStatus { for policyName, status := range nameToStatus {
policy, err := s.PolicyStore.Get(policyName) policy, err := s.policyStore.Get(policyName)
if err != nil { if err != nil {
continue continue
} }
policy.Status = status policy.Status = status
_, err = s.client.KyvernoV1().ClusterPolicies().UpdateStatus(policy) _, err = s.client.KyvernoV1().ClusterPolicies().UpdateStatus(policy)
if err != nil { if err != nil {
s.Cache.Mutex.Lock() s.cache.mutex.Lock()
delete(s.Cache.Data, policyName) delete(s.cache.data, policyName)
s.Cache.Mutex.Unlock() s.cache.mutex.Unlock()
glog.V(4).Info(err) glog.V(4).Info(err)
} }
} }

View file

@ -100,7 +100,7 @@ func (cpv *clusterPV) createPV(newPv *kyverno.ClusterPolicyViolation) error {
} }
if newPv.Annotations["fromSync"] != "true" { if newPv.Annotations["fromSync"] != "true" {
cpv.policyStatus.Listener <- updatePolicyStatusWithViolationCount(newPv.Spec.Policy, newPv.Spec.ViolatedRules) cpv.policyStatus.Listener <- violationCount{policyName: newPv.Spec.Policy, violatedRules: newPv.Spec.ViolatedRules}
} }
glog.Infof("policy violation created for resource %v", newPv.Spec.ResourceSpec) glog.Infof("policy violation created for resource %v", newPv.Spec.ResourceSpec)
@ -126,7 +126,7 @@ func (cpv *clusterPV) updatePV(newPv, oldPv *kyverno.ClusterPolicyViolation) err
glog.Infof("cluster policy violation updated for resource %v", newPv.Spec.ResourceSpec) glog.Infof("cluster policy violation updated for resource %v", newPv.Spec.ResourceSpec)
if newPv.Annotations["fromSync"] != "true" { if newPv.Annotations["fromSync"] != "true" {
cpv.policyStatus.Listener <- updatePolicyStatusWithViolationCount(newPv.Spec.Policy, newPv.Spec.ViolatedRules) cpv.policyStatus.Listener <- violationCount{policyName: newPv.Spec.Policy, violatedRules: newPv.Spec.ViolatedRules}
} }
return nil return nil
} }

View file

@ -4,8 +4,6 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/nirmata/kyverno/pkg/policyStatus"
backoff "github.com/cenkalti/backoff" backoff "github.com/cenkalti/backoff"
"github.com/golang/glog" "github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1" kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
@ -79,22 +77,11 @@ type violationCount struct {
violatedRules []v1.ViolatedRule violatedRules []v1.ViolatedRule
} }
func updatePolicyStatusWithViolationCount(policyName string, violatedRules []kyverno.ViolatedRule) *violationCount { func (vc violationCount) PolicyName() string {
return &violationCount{ return vc.policyName
policyName: policyName,
violatedRules: violatedRules,
}
} }
func (vc *violationCount) UpdateStatus(s *policyStatus.Sync) { func (vc violationCount) UpdateStatus(status kyverno.PolicyStatus) kyverno.PolicyStatus {
s.Cache.Mutex.Lock()
status, exist := s.Cache.Data[vc.policyName]
if !exist {
policy, _ := s.PolicyStore.Get(vc.policyName)
if policy != nil {
status = policy.Status
}
}
var ruleNameToViolations = make(map[string]int) var ruleNameToViolations = make(map[string]int)
for _, rule := range vc.violatedRules { for _, rule := range vc.violatedRules {
@ -106,6 +93,5 @@ func (vc *violationCount) UpdateStatus(s *policyStatus.Sync) {
status.Rules[i].ViolationCount += ruleNameToViolations[status.Rules[i].Name] status.Rules[i].ViolationCount += ruleNameToViolations[status.Rules[i].Name]
} }
s.Cache.Data[vc.policyName] = status return status
s.Cache.Mutex.Unlock()
} }

View file

@ -99,7 +99,7 @@ func (nspv *namespacedPV) createPV(newPv *kyverno.PolicyViolation) error {
} }
if newPv.Annotations["fromSync"] != "true" { if newPv.Annotations["fromSync"] != "true" {
nspv.policyStatus.Listener <- updatePolicyStatusWithViolationCount(newPv.Spec.Policy, newPv.Spec.ViolatedRules) nspv.policyStatus.Listener <- violationCount{policyName: newPv.Spec.Policy, violatedRules: newPv.Spec.ViolatedRules}
} }
glog.Infof("policy violation created for resource %v", newPv.Spec.ResourceSpec) glog.Infof("policy violation created for resource %v", newPv.Spec.ResourceSpec)
return nil return nil
@ -122,7 +122,7 @@ func (nspv *namespacedPV) updatePV(newPv, oldPv *kyverno.PolicyViolation) error
} }
if newPv.Annotations["fromSync"] != "true" { if newPv.Annotations["fromSync"] != "true" {
nspv.policyStatus.Listener <- updatePolicyStatusWithViolationCount(newPv.Spec.Policy, newPv.Spec.ViolatedRules) nspv.policyStatus.Listener <- violationCount{policyName: newPv.Spec.Policy, violatedRules: newPv.Spec.ViolatedRules}
} }
glog.Infof("namespaced policy violation updated for resource %v", newPv.Spec.ResourceSpec) glog.Infof("namespaced policy violation updated for resource %v", newPv.Spec.ResourceSpec)
return nil return nil

View file

@ -5,26 +5,9 @@ import (
"reflect" "reflect"
"testing" "testing"
"github.com/nirmata/kyverno/pkg/policyStatus"
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
) )
type dummyStore struct {
}
func (d *dummyStore) Get(policyName string) (*v1.ClusterPolicy, error) {
return &v1.ClusterPolicy{
Status: v1.PolicyStatus{
Rules: []v1.RuleStats{
{
Name: "rule4",
},
},
},
}, nil
}
func Test_Stats(t *testing.T) { func Test_Stats(t *testing.T) {
testCase := struct { testCase := struct {
violationCountStats []struct { violationCountStats []struct {
@ -32,7 +15,24 @@ func Test_Stats(t *testing.T) {
violatedRules []v1.ViolatedRule violatedRules []v1.ViolatedRule
} }
expectedOutput []byte expectedOutput []byte
existingCache map[string]v1.PolicyStatus
}{ }{
existingCache: map[string]v1.PolicyStatus{
"policy1": {
Rules: []v1.RuleStats{
{
Name: "rule4",
},
},
},
"policy2": {
Rules: []v1.RuleStats{
{
Name: "rule4",
},
},
},
},
expectedOutput: []byte(`{"policy1":{"averageExecutionTime":"","violationCount":1,"ruleStatus":[{"ruleName":"rule4","violationCount":1}]},"policy2":{"averageExecutionTime":"","violationCount":1,"ruleStatus":[{"ruleName":"rule4","violationCount":1}]}}`), expectedOutput: []byte(`{"policy1":{"averageExecutionTime":"","violationCount":1,"ruleStatus":[{"ruleName":"rule4","violationCount":1}]},"policy2":{"averageExecutionTime":"","violationCount":1,"ruleStatus":[{"ruleName":"rule4","violationCount":1}]}}`),
violationCountStats: []struct { violationCountStats: []struct {
policyName string policyName string
@ -57,17 +57,17 @@ func Test_Stats(t *testing.T) {
}, },
} }
s := policyStatus.NewSync(nil, &dummyStore{}) policyNameToStatus := testCase.existingCache
for _, violationCountStat := range testCase.violationCountStats { for _, violationCountStat := range testCase.violationCountStats {
receiver := &violationCount{ receiver := &violationCount{
policyName: violationCountStat.policyName, policyName: violationCountStat.policyName,
violatedRules: violationCountStat.violatedRules, violatedRules: violationCountStat.violatedRules,
} }
receiver.UpdateStatus(s) policyNameToStatus[receiver.PolicyName()] = receiver.UpdateStatus(policyNameToStatus[receiver.PolicyName()])
} }
output, _ := json.Marshal(s.Cache.Data) output, _ := json.Marshal(policyNameToStatus)
if !reflect.DeepEqual(output, testCase.expectedOutput) { if !reflect.DeepEqual(output, testCase.expectedOutput) {
t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output)) t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output))
} }

View file

@ -5,8 +5,6 @@ import (
"sort" "sort"
"time" "time"
"github.com/nirmata/kyverno/pkg/policyStatus"
"github.com/golang/glog" "github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1" kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
@ -68,7 +66,9 @@ func (ws *WebhookServer) HandleGenerate(request *v1beta1.AdmissionRequest, polic
if len(engineResponse.PolicyResponse.Rules) > 0 { if len(engineResponse.PolicyResponse.Rules) > 0 {
// some generate rules do apply to the resource // some generate rules do apply to the resource
engineResponses = append(engineResponses, engineResponse) engineResponses = append(engineResponses, engineResponse)
ws.status.Listener <- updateStatusWithGenerateStats(engineResponse) ws.status.Listener <- generateStats{
resp: engineResponse,
}
} }
} }
// Adds Generate Request to a channel(queue size 1000) to generators // Adds Generate Request to a channel(queue size 1000) to generators
@ -115,26 +115,13 @@ type generateStats struct {
resp response.EngineResponse resp response.EngineResponse
} }
func updateStatusWithGenerateStats(resp response.EngineResponse) *generateStats { func (gs generateStats) PolicyName() string {
return &generateStats{ return gs.resp.PolicyResponse.Policy
resp: resp,
}
} }
func (gs *generateStats) UpdateStatus(s *policyStatus.Sync) { func (gs generateStats) UpdateStatus(status kyverno.PolicyStatus) kyverno.PolicyStatus {
if reflect.DeepEqual(response.EngineResponse{}, gs.resp) { if reflect.DeepEqual(response.EngineResponse{}, gs.resp) {
return return status
}
s.Cache.Mutex.Lock()
status, exist := s.Cache.Data[gs.resp.PolicyResponse.Policy]
if !exist {
if s.PolicyStore != nil {
policy, _ := s.PolicyStore.Get(gs.resp.PolicyResponse.Policy)
if policy != nil {
status = policy.Status
}
}
} }
var nameToRule = make(map[string]v1.RuleStats) var nameToRule = make(map[string]v1.RuleStats)
@ -180,8 +167,7 @@ func (gs *generateStats) UpdateStatus(s *policyStatus.Sync) {
status.AvgExecutionTime = policyAverageExecutionTime.String() status.AvgExecutionTime = policyAverageExecutionTime.String()
status.Rules = ruleStats status.Rules = ruleStats
s.Cache.Data[gs.resp.PolicyResponse.Policy] = status return status
s.Cache.Mutex.Unlock()
} }
func updateAverageTime(newTime time.Duration, oldAverageTimeString string, averageOver int64) time.Duration { func updateAverageTime(newTime time.Duration, oldAverageTimeString string, averageOver int64) time.Duration {

View file

@ -5,8 +5,6 @@ import (
"sort" "sort"
"time" "time"
"github.com/nirmata/kyverno/pkg/policyStatus"
"github.com/golang/glog" "github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1" kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
@ -63,7 +61,9 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resou
policyContext.Policy = policy policyContext.Policy = policy
engineResponse := engine.Mutate(policyContext) engineResponse := engine.Mutate(policyContext)
engineResponses = append(engineResponses, engineResponse) engineResponses = append(engineResponses, engineResponse)
ws.status.Listener <- updateStatusWithMutateStats(engineResponse) ws.status.Listener <- mutateStats{
resp: engineResponse,
}
if !engineResponse.IsSuccesful() { if !engineResponse.IsSuccesful() {
glog.V(4).Infof("Failed to apply policy %s on resource %s/%s\n", policy.Name, resource.GetNamespace(), resource.GetName()) glog.V(4).Infof("Failed to apply policy %s on resource %s/%s\n", policy.Name, resource.GetNamespace(), resource.GetName())
continue continue
@ -122,27 +122,13 @@ type mutateStats struct {
resp response.EngineResponse resp response.EngineResponse
} }
func updateStatusWithMutateStats(resp response.EngineResponse) *mutateStats { func (ms mutateStats) PolicyName() string {
return &mutateStats{ return ms.resp.PolicyResponse.Policy
resp: resp,
}
} }
func (ms *mutateStats) UpdateStatus(s *policyStatus.Sync) { func (ms mutateStats) UpdateStatus(status kyverno.PolicyStatus) kyverno.PolicyStatus {
if reflect.DeepEqual(response.EngineResponse{}, ms.resp) { if reflect.DeepEqual(response.EngineResponse{}, ms.resp) {
return return status
}
s.Cache.Mutex.Lock()
status, exist := s.Cache.Data[ms.resp.PolicyResponse.Policy]
if !exist {
if s.PolicyStore != nil {
policy, _ := s.PolicyStore.Get(ms.resp.PolicyResponse.Policy)
if policy != nil {
status = policy.Status
}
}
} }
var nameToRule = make(map[string]v1.RuleStats) var nameToRule = make(map[string]v1.RuleStats)
@ -190,6 +176,5 @@ func (ms *mutateStats) UpdateStatus(s *policyStatus.Sync) {
status.AvgExecutionTime = policyAverageExecutionTime.String() status.AvgExecutionTime = policyAverageExecutionTime.String()
status.Rules = ruleStats status.Rules = ruleStats
s.Cache.Data[ms.resp.PolicyResponse.Policy] = status return status
s.Cache.Mutex.Unlock()
} }

View file

@ -8,16 +8,8 @@ import (
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
"github.com/nirmata/kyverno/pkg/engine/response" "github.com/nirmata/kyverno/pkg/engine/response"
"github.com/nirmata/kyverno/pkg/policyStatus"
) )
type dummyStore struct {
}
func (d *dummyStore) Get(policyName string) (*v1.ClusterPolicy, error) {
return &v1.ClusterPolicy{}, nil
}
func Test_GenerateStats(t *testing.T) { func Test_GenerateStats(t *testing.T) {
testCase := struct { testCase := struct {
generateStats []response.EngineResponse generateStats []response.EngineResponse
@ -70,16 +62,16 @@ func Test_GenerateStats(t *testing.T) {
}, },
} }
s := policyStatus.NewSync(nil, &dummyStore{}) policyNameToStatus := map[string]v1.PolicyStatus{}
for _, generateStat := range testCase.generateStats { for _, generateStat := range testCase.generateStats {
receiver := &generateStats{ receiver := generateStats{
resp: generateStat, resp: generateStat,
} }
receiver.UpdateStatus(s) policyNameToStatus[receiver.PolicyName()] = receiver.UpdateStatus(policyNameToStatus[receiver.PolicyName()])
} }
output, _ := json.Marshal(s.Cache.Data) output, _ := json.Marshal(policyNameToStatus)
if !reflect.DeepEqual(output, testCase.expectedOutput) { if !reflect.DeepEqual(output, testCase.expectedOutput) {
t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output)) t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output))
} }
@ -137,15 +129,15 @@ func Test_MutateStats(t *testing.T) {
}, },
} }
s := policyStatus.NewSync(nil, &dummyStore{}) policyNameToStatus := map[string]v1.PolicyStatus{}
for _, mutateStat := range testCase.mutateStats { for _, mutateStat := range testCase.mutateStats {
receiver := &mutateStats{ receiver := mutateStats{
resp: mutateStat, resp: mutateStat,
} }
receiver.UpdateStatus(s) policyNameToStatus[receiver.PolicyName()] = receiver.UpdateStatus(policyNameToStatus[receiver.PolicyName()])
} }
output, _ := json.Marshal(s.Cache.Data) output, _ := json.Marshal(policyNameToStatus)
if !reflect.DeepEqual(output, testCase.expectedOutput) { if !reflect.DeepEqual(output, testCase.expectedOutput) {
t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output)) t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output))
} }
@ -204,15 +196,15 @@ func Test_ValidateStats(t *testing.T) {
}, },
} }
s := policyStatus.NewSync(nil, &dummyStore{}) policyNameToStatus := map[string]v1.PolicyStatus{}
for _, validateStat := range testCase.validateStats { for _, validateStat := range testCase.validateStats {
receiver := &validateStats{ receiver := validateStats{
resp: validateStat, resp: validateStat,
} }
receiver.UpdateStatus(s) policyNameToStatus[receiver.PolicyName()] = receiver.UpdateStatus(policyNameToStatus[receiver.PolicyName()])
} }
output, _ := json.Marshal(s.Cache.Data) output, _ := json.Marshal(policyNameToStatus)
if !reflect.DeepEqual(output, testCase.expectedOutput) { if !reflect.DeepEqual(output, testCase.expectedOutput) {
t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output)) t.Errorf("\n\nTestcase has failed\nExpected:\n%v\nGot:\n%v\n\n", string(testCase.expectedOutput), string(output))
} }

View file

@ -5,8 +5,6 @@ import (
"sort" "sort"
"time" "time"
"github.com/nirmata/kyverno/pkg/policyStatus"
"github.com/golang/glog" "github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1" kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
@ -73,7 +71,9 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, pol
continue continue
} }
engineResponses = append(engineResponses, engineResponse) engineResponses = append(engineResponses, engineResponse)
ws.status.Listener <- updateStatusWithValidateStats(engineResponse) ws.status.Listener <- validateStats{
resp: engineResponse,
}
if !engineResponse.IsSuccesful() { if !engineResponse.IsSuccesful() {
glog.V(4).Infof("Failed to apply policy %s on resource %s/%s\n", policy.Name, newR.GetNamespace(), newR.GetName()) glog.V(4).Infof("Failed to apply policy %s on resource %s/%s\n", policy.Name, newR.GetNamespace(), newR.GetName())
continue continue
@ -117,26 +117,13 @@ type validateStats struct {
resp response.EngineResponse resp response.EngineResponse
} }
func updateStatusWithValidateStats(resp response.EngineResponse) *validateStats { func (vs validateStats) PolicyName() string {
return &validateStats{ return vs.resp.PolicyResponse.Policy
resp: resp,
}
} }
func (vs *validateStats) UpdateStatus(s *policyStatus.Sync) { func (vs validateStats) UpdateStatus(status kyverno.PolicyStatus) kyverno.PolicyStatus {
if reflect.DeepEqual(response.EngineResponse{}, vs.resp) { if reflect.DeepEqual(response.EngineResponse{}, vs.resp) {
return return status
}
s.Cache.Mutex.Lock()
status, exist := s.Cache.Data[vs.resp.PolicyResponse.Policy]
if !exist {
if s.PolicyStore != nil {
policy, _ := s.PolicyStore.Get(vs.resp.PolicyResponse.Policy)
if policy != nil {
status = policy.Status
}
}
} }
var nameToRule = make(map[string]v1.RuleStats) var nameToRule = make(map[string]v1.RuleStats)
@ -186,6 +173,5 @@ func (vs *validateStats) UpdateStatus(s *policyStatus.Sync) {
status.AvgExecutionTime = policyAverageExecutionTime.String() status.AvgExecutionTime = policyAverageExecutionTime.String()
status.Rules = ruleStats status.Rules = ruleStats
s.Cache.Data[vs.resp.PolicyResponse.Policy] = status return status
s.Cache.Mutex.Unlock()
} }