diff --git a/pkg/api/kyverno/v1alpha1/types.go b/pkg/api/kyverno/v1alpha1/types.go index 44769bd446..29fb9506a4 100644 --- a/pkg/api/kyverno/v1alpha1/types.go +++ b/pkg/api/kyverno/v1alpha1/types.go @@ -95,9 +95,11 @@ type PolicyStatus struct { // 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 string `json:"averageMutationExecutionTime"` + AvgExecutionTimeMutation string `json:"averageMutationRulesExecutionTime"` // average time required to process the policy Validation rules on a resource - AvgExecutionTimeValidation string `json:"averageValidationExecutionTime"` + AvgExecutionTimeValidation string `json:"averageValidationRulesExecutionTime"` + // average time required to process the policy Validation rules on a resource + AvgExecutionTimeGeneration string `json:"averageGenerationRulesExecutionTime"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/engine/generation.go b/pkg/engine/generation.go index 9b46aa755f..5012121d37 100644 --- a/pkg/engine/generation.go +++ b/pkg/engine/generation.go @@ -18,14 +18,13 @@ import ( ) //Generate apply generation rules on a resource -func Generate(client *client.Client, policy kyverno.Policy, ns unstructured.Unstructured) EngineResponse { - var response EngineResponse +func Generate(client *client.Client, policy kyverno.Policy, ns unstructured.Unstructured) (response EngineResponse) { startTime := time.Now() glog.V(4).Infof("started applying generation rules of policy %q (%v)", policy.Name, startTime) defer func() { response.ExecutionTime = time.Since(startTime) glog.V(4).Infof("Finished applying generation rules policy %q (%v)", policy.Name, response.ExecutionTime) - glog.V(4).Infof("Mutation Rules appplied succesfully count %q for policy %q", response.RulesAppliedCount, policy.Name) + glog.V(4).Infof("Generation Rules appplied count %q for policy %q", response.RulesAppliedCount, policy.Name) }() incrementAppliedRuleCount := func() { // rules applied succesfully count diff --git a/pkg/namespace/controller.go b/pkg/namespace/controller.go index 78e6340a3f..38547fdb15 100644 --- a/pkg/namespace/controller.go +++ b/pkg/namespace/controller.go @@ -8,6 +8,7 @@ import ( "github.com/golang/glog" client "github.com/nirmata/kyverno/pkg/dclient" "github.com/nirmata/kyverno/pkg/event" + "github.com/nirmata/kyverno/pkg/policy" "k8s.io/apimachinery/pkg/api/errors" kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned" @@ -44,7 +45,8 @@ type NamespaceController struct { pvListerSynced cache.InformerSynced // pvLister can list/get policy violation from the shared informer's store pvLister kyvernolister.PolicyViolationLister - + // API to send policy stats for aggregation + policyStatus policy.PolicyStatusInterface // eventGen provides interface to generate evenets eventGen event.Interface // Namespaces that need to be synced @@ -59,6 +61,7 @@ func NewNamespaceController(kyvernoClient *kyvernoclient.Clientset, nsInformer v1Informer.NamespaceInformer, pInformer kyvernoinformer.PolicyInformer, pvInformer kyvernoinformer.PolicyViolationInformer, + policyStatus policy.PolicyStatusInterface, eventGen event.Interface) *NamespaceController { //TODO: do we need to event recorder for this controller? // create the controller @@ -83,6 +86,7 @@ func NewNamespaceController(kyvernoClient *kyvernoclient.Clientset, nsc.pLister = pInformer.Lister() nsc.pvListerSynced = pInformer.Informer().HasSynced nsc.pvLister = pvInformer.Lister() + nsc.policyStatus = policyStatus // resource manager // rebuild after 300 seconds/ 5 mins diff --git a/pkg/namespace/generation.go b/pkg/namespace/generation.go index ca715e20ce..d36bc7e24a 100644 --- a/pkg/namespace/generation.go +++ b/pkg/namespace/generation.go @@ -6,6 +6,7 @@ import ( client "github.com/nirmata/kyverno/pkg/dclient" "github.com/nirmata/kyverno/pkg/engine" + "github.com/nirmata/kyverno/pkg/policy" "github.com/golang/glog" @@ -13,7 +14,9 @@ import ( kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1" "github.com/nirmata/kyverno/pkg/info" + policyctr "github.com/nirmata/kyverno/pkg/policy" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" @@ -108,7 +111,7 @@ func (nsc *NamespaceController) processNamespace(namespace corev1.Namespace) []i glog.V(4).Infof("policy %s with resource version %s already processed on resource %s/%s/%s with resource version %s", policy.Name, policy.ResourceVersion, ns.GetKind(), ns.GetNamespace(), ns.GetName(), ns.GetResourceVersion()) continue } - policyInfo := applyPolicy(nsc.client, ns, *policy) + policyInfo := applyPolicy(nsc.client, ns, *policy, nsc.policyStatus) policyInfos = append(policyInfos, policyInfo) // post-processing, register the resource as processed nsc.rm.RegisterResource(policy.GetName(), policy.GetResourceVersion(), ns.GetKind(), ns.GetNamespace(), ns.GetName(), ns.GetResourceVersion()) @@ -141,7 +144,20 @@ func listpolicies(ns unstructured.Unstructured, pLister kyvernolister.PolicyList return filteredpolicies } -func applyPolicy(client *client.Client, resource unstructured.Unstructured, policy kyverno.Policy) info.PolicyInfo { +func applyPolicy(client *client.Client, resource unstructured.Unstructured, policy kyverno.Policy, policyStatus policy.PolicyStatusInterface) info.PolicyInfo { + var ps policyctr.PolicyStat + gatherStat := func(policyName string, er engine.EngineResponse) { + // ps := policyctr.PolicyStat{} + ps.PolicyName = policyName + ps.Stats.GenerationExecutionTime = er.ExecutionTime + ps.Stats.RulesAppliedCount = er.RulesAppliedCount + } + // send stats for aggregation + sendStat := func(blocked bool) { + //SEND + policyStatus.SendStat(ps) + } + startTime := time.Now() glog.V(4).Infof("Started apply policy %s on resource %s/%s/%s (%v)", policy.Name, resource.GetKind(), resource.GetNamespace(), resource.GetName(), startTime) defer func() { @@ -150,6 +166,10 @@ func applyPolicy(client *client.Client, resource unstructured.Unstructured, poli policyInfo := info.NewPolicyInfo(policy.Name, resource.GetKind(), resource.GetName(), resource.GetNamespace(), policy.Spec.ValidationFailureAction) engineResponse := engine.Generate(client, policy, resource) policyInfo.AddRuleInfos(engineResponse.RuleInfos) + // gather stats + gatherStat(policy.Name, engineResponse) + //send stats + sendStat(false) return policyInfo } diff --git a/pkg/policy/controller.go b/pkg/policy/controller.go index fccbed13c5..40a80cefee 100644 --- a/pkg/policy/controller.go +++ b/pkg/policy/controller.go @@ -447,6 +447,7 @@ func (pc *PolicyController) calculateStatus(policyName string, pvList []*kyverno status.ResourcesBlockedCount = stats.ResourceBlocked status.AvgExecutionTimeMutation = stats.MutationExecutionTime.String() status.AvgExecutionTimeValidation = stats.ValidationExecutionTime.String() + status.AvgExecutionTimeGeneration = stats.GenerationExecutionTime.String() } return status } diff --git a/pkg/policy/status.go b/pkg/policy/status.go index 60a6a6dbf0..133300320b 100644 --- a/pkg/policy/status.go +++ b/pkg/policy/status.go @@ -56,9 +56,6 @@ func (psa *PolicyStatusAggregator) process() { // mutation & validation rules seperately for r := range psa.ch { glog.V(4).Infof("recieved policy stats %v", r) - // if err := psa.updateStats(r); err != nil { - // glog.Infof("Failed to update stats for policy %s: %v", r.PolicyName, err) - // } psa.aggregate(r) } } @@ -96,6 +93,12 @@ func (psa *PolicyStatusAggregator) aggregate(ps PolicyStat) { } else { info.ValidationExecutionTime = ps.Stats.ValidationExecutionTime } + if info.GenerationExecutionTime != zeroDuration { + info.GenerationExecutionTime = (info.GenerationExecutionTime + ps.Stats.GenerationExecutionTime) / 2 + glog.V(4).Infof("updated avg generation time %v", info.GenerationExecutionTime) + } else { + info.GenerationExecutionTime = ps.Stats.GenerationExecutionTime + } // update psa.policyData[ps.PolicyName] = info glog.V(4).Infof("updated stats for policy %s", ps.PolicyName) @@ -144,6 +147,7 @@ type PolicyStat struct { type PolicyStatInfo struct { MutationExecutionTime time.Duration ValidationExecutionTime time.Duration + GenerationExecutionTime time.Duration RulesAppliedCount int ResourceBlocked int }