1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 10:28:36 +00:00

update status v1

This commit is contained in:
shivkumar dudhani 2019-08-20 15:13:52 -07:00
parent bcad9ada2d
commit 3f876e6f46
3 changed files with 72 additions and 25 deletions

View file

@ -1,6 +1,8 @@
package v1alpha1
import (
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@ -89,7 +91,15 @@ type CloneFrom struct {
//PolicyStatus provides status for violations
type PolicyStatus struct {
Violations int `json:"violations"`
ViolationCount int `json:"violationCount"`
// Count of rules that were applied
RulesAppliedCount int `json:"rulesAppliedCount"`
// Count of resources for whom update/create api requests were blocked as the resoruce did not satisfy the policy rules
ResourcesBlockedCount int `json:"resourcesBlockedCount"`
// average time required to process the policy Mutation rules on a resource
AvgExecutionTimeMutation time.Duration `json:"averageMutationExecutionTime"`
// average time required to process the policy Validation rules on a resource
AvgExecutionTimeValidation time.Duration `json:"averageValidationExecutionTime"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View file

@ -119,7 +119,7 @@ func NewPolicyController(kyvernoClient *kyvernoclient.Clientset, client *client.
pc.rm = NewResourceManager(30)
// aggregator
pc.statusAggregator = NewPolicyStatAggregator(kyvernoClient, pInformer.Lister())
pc.statusAggregator = NewPolicyStatAggregator(kyvernoClient, pInformer)
return &pc, nil
}

View file

@ -1,6 +1,7 @@
package policy
import (
"fmt"
"reflect"
"sync"
"time"
@ -8,48 +9,55 @@ import (
"github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha1"
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/tools/cache"
)
type PolicyStatus struct {
// average time required to process the policy rules on a resource
avgExecutionTime time.Duration
// Count of rules that were applied succesfully
rulesAppliedCount int
// Count of resources for whom update/create api requests were blocked as the resoruce did not satisfy the policy rules
resourcesBlockedCount int
// Count of the resource for whom the mutation rules were applied succesfully
resourcesMutatedCount int
}
// type PolicyStatus struct {
// // average time required to process the policy rules on a resource
// avgExecutionTime time.Duration
// // Count of rules that were applied succesfully
// rulesAppliedCount int
// // Count of resources for whom update/create api requests were blocked as the resoruce did not satisfy the policy rules
// resourcesBlockedCount int
// // Count of the resource for whom the mutation rules were applied succesfully
// resourcesMutatedCount int
// }
//PolicyStatusAggregator stores information abt aggregation
type PolicyStatusAggregator struct {
// time since we start aggregating the stats
startTime time.Time
// channel to recieve stats
ch chan PolicyStat
// update polict status
// update policy status
psControl PStatusControlInterface
// pLister can list/get policy from the shared informer's store
pLister kyvernolister.PolicyLister
// pListerSynced returns true if the Policy store has been synced at least once
pListerSynced cache.InformerSynced
// UpdateViolationCount and SendStat can update same policy status
// we need to sync the updates using policyName
policyUpdateData sync.Map
}
//NewPolicyStatAggregator returns a new policy status
func NewPolicyStatAggregator(client *kyvernoclient.Clientset, pLister kyvernolister.PolicyLister) *PolicyStatusAggregator {
func NewPolicyStatAggregator(client *kyvernoclient.Clientset, pInformer kyvernoinformer.PolicyInformer) *PolicyStatusAggregator {
psa := PolicyStatusAggregator{
startTime: time.Now(),
ch: make(chan PolicyStat),
}
psa.pLister = pLister
psa.pLister = pInformer.Lister()
psa.pListerSynced = pInformer.Informer().HasSynced
psa.psControl = PSControl{Client: client}
//TODO: add WaitGroup
return &psa
}
//Run begins aggregator
func (psa *PolicyStatusAggregator) Run(workers int, stopCh <-chan struct{}) {
defer utilruntime.HandleCrash()
glog.V(4).Info("Started aggregator for policy status stats")
@ -69,7 +77,7 @@ func (psa *PolicyStatusAggregator) aggregate() {
for r := range psa.ch {
glog.V(4).Infof("recieved policy stats %v", r)
if err := psa.updateStats(r); err != nil {
glog.Info("Failed to update stats for policy %s: %v", r.PolicyName, err)
glog.Infof("Failed to update stats for policy %s: %v", r.PolicyName, err)
}
}
@ -77,32 +85,59 @@ func (psa *PolicyStatusAggregator) aggregate() {
func (psa *PolicyStatusAggregator) updateStats(stats PolicyStat) error {
func() {
glog.V(4).Infof("lock updates for policy name %s", stats.PolicyName)
glog.V(4).Infof("lock updates for policy %s", stats.PolicyName)
// Lock the update for policy
psa.policyUpdateData.Store(stats.PolicyName, struct{}{})
}()
defer func() {
glog.V(4).Infof("Unlock updates for policy name %s", stats.PolicyName)
glog.V(4).Infof("Unlock updates for policy %s", stats.PolicyName)
psa.policyUpdateData.Delete(stats.PolicyName)
}()
// //wait for cache sync
// if !cache.WaitForCacheSync(nil, psa.pListerSynced) {
// glog.Infof("unable to sync cache for policy informer")
// return nil
// }
// get policy
policy, err := psa.pLister.Get(stats.PolicyName)
if err != nil {
glog.V(4).Infof("failed to get policy %s. Unable to update violation count: %v", stats.PolicyName, err)
return err
}
newpolicy := policy
fmt.Println(newpolicy.ResourceVersion)
newpolicy.Status = kyverno.PolicyStatus{}
glog.V(4).Infof("updating stats for policy %s", policy.Name)
// update the statistics
// policy.Status
return nil
// rules applied count
newpolicy.Status.RulesAppliedCount = newpolicy.Status.RulesAppliedCount + stats.RulesAppliedCount
// resource blocked count
if stats.ResourceBlocked {
policy.Status.ResourcesBlockedCount++
}
var zeroDuration time.Duration
if newpolicy.Status.AvgExecutionTimeMutation != zeroDuration {
// avg execution time for mutation rules
newpolicy.Status.AvgExecutionTimeMutation = (newpolicy.Status.AvgExecutionTimeMutation + stats.MutationExecutionTime) / 2
} else {
newpolicy.Status.AvgExecutionTimeMutation = stats.MutationExecutionTime
}
if policy.Status.AvgExecutionTimeValidation != zeroDuration {
// avg execution time for validation rules
newpolicy.Status.AvgExecutionTimeValidation = (newpolicy.Status.AvgExecutionTimeValidation + stats.ValidationExecutionTime) / 2
} else {
newpolicy.Status.AvgExecutionTimeValidation = stats.ValidationExecutionTime
}
return psa.psControl.UpdatePolicyStatus(newpolicy)
}
//PolicyStatusInterface provides methods to modify policyStatus
type PolicyStatusInterface interface {
SendStat(stat PolicyStat)
UpdateViolationCount(policyName string, pvList []*kyverno.PolicyViolation) error
}
//PolicyStat stored stats for policy
type PolicyStat struct {
PolicyName string
MutationExecutionTime time.Duration
@ -121,12 +156,12 @@ func (psa *PolicyStatusAggregator) SendStat(stat PolicyStat) {
//UpdateViolationCount updates the active violation count
func (psa *PolicyStatusAggregator) UpdateViolationCount(policyName string, pvList []*kyverno.PolicyViolation) error {
func() {
glog.V(4).Infof("lock updates for policy name %s", policyName)
glog.V(4).Infof("lock updates for policy %s", policyName)
// Lock the update for policy
psa.policyUpdateData.Store(policyName, struct{}{})
}()
defer func() {
glog.V(4).Infof("Unlock updates for policy name %s", policyName)
glog.V(4).Infof("Unlock updates for policy %s", policyName)
psa.policyUpdateData.Delete(policyName)
}()
// get policy
@ -139,6 +174,7 @@ func (psa *PolicyStatusAggregator) UpdateViolationCount(policyName string, pvLis
newStatus := calculateStatus(pvList)
if reflect.DeepEqual(newStatus, policy.Status) {
// no update to status
glog.V(4).Infof("no changes in policy violation count for policy %s", policy.Name)
return nil
}
// update status
@ -151,7 +187,7 @@ func (psa *PolicyStatusAggregator) UpdateViolationCount(policyName string, pvLis
func calculateStatus(pvList []*kyverno.PolicyViolation) kyverno.PolicyStatus {
violationCount := len(pvList)
status := kyverno.PolicyStatus{
Violations: violationCount,
ViolationCount: violationCount,
}
return status
}
@ -166,6 +202,7 @@ type PStatusControlInterface interface {
UpdatePolicyStatus(newPolicy *kyverno.Policy) error
}
//PSControl allows update for policy status
type PSControl struct {
Client kyvernoclient.Interface
}