diff --git a/pkg/policy/status2.go b/pkg/policy/status2.go index 6be44fcf58..41b4c0a90a 100644 --- a/pkg/policy/status2.go +++ b/pkg/policy/status2.go @@ -15,17 +15,6 @@ import ( v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" ) -func NewStatusSync(client *versioned.Clientset, stopCh <-chan struct{}, pMetaStore *policystore.PolicyStore) *StatSync { - return &StatSync{ - cache: &statusCache{ - mu: sync.RWMutex{}, - data: make(map[string]v1.PolicyStatus), - }, - stop: stopCh, - client: client, - } -} - type statusCache struct { mu sync.RWMutex data map[string]v1.PolicyStatus @@ -38,6 +27,18 @@ type StatSync struct { policyStore *policystore.PolicyStore } +func NewStatusSync(client *versioned.Clientset, stopCh <-chan struct{}, pMetaStore *policystore.PolicyStore) *StatSync { + return &StatSync{ + cache: &statusCache{ + mu: sync.RWMutex{}, + data: make(map[string]v1.PolicyStatus), + }, + stop: stopCh, + client: client, + policyStore: pMetaStore, + } +} + func (s *StatSync) Start() { // update policy status every 10 seconds - waits for previous updateStatus to complete wait.Until(s.updateStats, 1*time.Second, s.stop) @@ -59,8 +60,14 @@ func (s *StatSync) updateStats() { func (s *StatSync) UpdateStatusWithMutateStats(response response.EngineResponse) { s.cache.mu.Lock() - policyStatus := s.cache.data[response.PolicyResponse.Policy] - s.policyStore.ListAll() + var policyStatus v1.PolicyStatus + policyStatus, exist := s.cache.data[response.PolicyResponse.Policy] + if !exist { + policy, _ := s.policyStore.Get(response.PolicyResponse.Policy) + if policy != nil { + policyStatus = policy.Status + } + } var nameToRule = make(map[string]v1.RuleStats, 0) for _, rule := range policyStatus.Rules { @@ -105,6 +112,112 @@ func (s *StatSync) UpdateStatusWithMutateStats(response response.EngineResponse) s.cache.mu.Unlock() } +func (s *StatSync) UpdateStatusWithValidateStats(response response.EngineResponse) { + s.cache.mu.Lock() + var policyStatus v1.PolicyStatus + policyStatus, exist := s.cache.data[response.PolicyResponse.Policy] + if !exist { + policy, _ := s.policyStore.Get(response.PolicyResponse.Policy) + if policy != nil { + policyStatus = policy.Status + } + } + + var nameToRule = make(map[string]v1.RuleStats, 0) + for _, rule := range policyStatus.Rules { + nameToRule[rule.Name] = rule + } + + var policyAverageExecutionTime time.Duration + for _, rule := range response.PolicyResponse.Rules { + ruleStat := nameToRule[rule.Name] + ruleStat.Name = rule.Name + + averageOver := int64(ruleStat.AppliedCount + ruleStat.ViolationCount) + newAverageExecutionTime := updateAverageTime( + rule.ProcessingTime, + ruleStat.ExecutionTime, + averageOver) + policyAverageExecutionTime += newAverageExecutionTime + ruleStat.ExecutionTime = newAverageExecutionTime.String() + + if rule.Success { + policyStatus.RulesAppliedCount++ + policyStatus.ResourcesBlockedCount++ + ruleStat.AppliedCount++ + ruleStat.ResourcesBlockedCount++ + } else { + policyStatus.ViolationCount++ + ruleStat.ViolationCount++ + } + + nameToRule[rule.Name] = ruleStat + } + + var ruleStats = make([]v1.RuleStats, 0, len(nameToRule)) + for _, ruleStat := range nameToRule { + ruleStats = append(ruleStats, ruleStat) + } + + policyStatus.AvgExecutionTime = policyAverageExecutionTime.String() + policyStatus.Rules = ruleStats + + s.cache.data[response.PolicyResponse.Policy] = policyStatus + s.cache.mu.Unlock() +} + +func (s *StatSync) UpdateStatusWithGenerateStats(response response.EngineResponse) { + s.cache.mu.Lock() + var policyStatus v1.PolicyStatus + policyStatus, exist := s.cache.data[response.PolicyResponse.Policy] + if !exist { + policy, _ := s.policyStore.Get(response.PolicyResponse.Policy) + if policy != nil { + policyStatus = policy.Status + } + } + + var nameToRule = make(map[string]v1.RuleStats, 0) + for _, rule := range policyStatus.Rules { + nameToRule[rule.Name] = rule + } + + var policyAverageExecutionTime time.Duration + for _, rule := range response.PolicyResponse.Rules { + ruleStat := nameToRule[rule.Name] + ruleStat.Name = rule.Name + + averageOver := int64(ruleStat.AppliedCount + ruleStat.ViolationCount) + newAverageExecutionTime := updateAverageTime( + rule.ProcessingTime, + ruleStat.ExecutionTime, + averageOver) + policyAverageExecutionTime += newAverageExecutionTime + ruleStat.ExecutionTime = newAverageExecutionTime.String() + + if rule.Success { + policyStatus.RulesAppliedCount++ + ruleStat.AppliedCount++ + } else { + policyStatus.ViolationCount++ + ruleStat.ViolationCount++ + } + + nameToRule[rule.Name] = ruleStat + } + + var ruleStats = make([]v1.RuleStats, 0, len(nameToRule)) + for _, ruleStat := range nameToRule { + ruleStats = append(ruleStats, ruleStat) + } + + policyStatus.AvgExecutionTime = policyAverageExecutionTime.String() + policyStatus.Rules = ruleStats + + s.cache.data[response.PolicyResponse.Policy] = policyStatus + s.cache.mu.Unlock() +} + func updateAverageTime(newTime time.Duration, oldAverageTimeString string, averageOver int64) time.Duration { if averageOver == 0 { return newTime diff --git a/pkg/policystore/policystore.go b/pkg/policystore/policystore.go index 3d23b106e4..f8a8e30874 100644 --- a/pkg/policystore/policystore.go +++ b/pkg/policystore/policystore.go @@ -96,6 +96,10 @@ func (ps *PolicyStore) ListAll() ([]kyverno.ClusterPolicy, error) { return policies, nil } +func (ps *PolicyStore) Get(policyName string) (*kyverno.ClusterPolicy, error) { + return ps.pLister.Get(policyName) +} + //UnRegister Remove policy information func (ps *PolicyStore) UnRegister(policy kyverno.ClusterPolicy) error { ps.mu.Lock()