1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-30 19:35:06 +00:00

feat: added kyverno_policy_rule_info_total metric

Signed-off-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com>
This commit is contained in:
Yashvardhan Kukreja 2021-05-15 18:10:11 +05:30
parent bb80e1b641
commit fea074f493
No known key found for this signature in database
GPG key ID: 6963E9412A4E5ED6
5 changed files with 250 additions and 8 deletions

View file

@ -11,7 +11,7 @@ type PromConfig struct {
type PromMetrics struct {
PolicyRuleResults *prom.GaugeVec
PolicyRuleCount *prom.GaugeVec
PolicyRuleInfo *prom.GaugeVec
PolicyChanges *prom.GaugeVec
PolicyRuleExecutionLatency *prom.GaugeVec
AdmissionReviewLatency *prom.GaugeVec
@ -36,15 +36,15 @@ func NewPromConfig() *PromConfig {
policyRuleResultsLabels,
)
policyRuleCountLabels := []string{
policyRuleInfoLabels := []string{
"policy_validation_mode", "policy_type", "policy_background_mode", "policy_namespace", "policy_name", "rule_name", "rule_type",
}
policyRuleCountMetric := prom.NewGaugeVec(
policyRuleInfoMetric := prom.NewGaugeVec(
prom.GaugeOpts{
Name: "kyverno_policy_rule_count",
Help: "can be used to track the number of rules or/and policies present in the cluster. 0 means the rule doesn't exist and has been deleted, 1 means the rule is currently existent in the cluster.",
Name: "kyverno_policy_rule_info_total",
Help: "can be used to track the info of the rules or/and policies present in the cluster. 0 means the rule doesn't exist and has been deleted, 1 means the rule is currently existent in the cluster.",
},
policyRuleCountLabels,
policyRuleInfoLabels,
)
policyChangesLabels := []string{
@ -87,14 +87,14 @@ func NewPromConfig() *PromConfig {
pc.Metrics = &PromMetrics{
PolicyRuleResults: policyRuleResultsMetric,
PolicyRuleCount: policyRuleCountMetric,
PolicyRuleInfo: policyRuleInfoMetric,
PolicyChanges: policyChangesMetric,
PolicyRuleExecutionLatency: policyRuleExecutionLatencyMetric,
AdmissionReviewLatency: admissionReviewLatencyMetric,
}
pc.MetricsRegistry.MustRegister(pc.Metrics.PolicyRuleResults)
pc.MetricsRegistry.MustRegister(pc.Metrics.PolicyRuleCount)
pc.MetricsRegistry.MustRegister(pc.Metrics.PolicyRuleInfo)
pc.MetricsRegistry.MustRegister(pc.Metrics.PolicyChanges)
pc.MetricsRegistry.MustRegister(pc.Metrics.PolicyRuleExecutionLatency)
pc.MetricsRegistry.MustRegister(pc.Metrics.AdmissionReviewLatency)

View file

@ -0,0 +1,21 @@
package policyruleinfo
import (
"fmt"
"github.com/kyverno/kyverno/pkg/metrics"
)
func ParsePolicyRuleInfoMetricChangeType(change string) (PolicyRuleInfoMetricChangeType, error) {
if change == "created" {
return PolicyRuleCreated, nil
}
if change == "deleted" {
return PolicyRuleDeleted, nil
}
return "", fmt.Errorf("wrong policy rule count metric change type found %s. Allowed: '%s', '%s'", change, "created", "deleted")
}
func ParsePromMetrics(pm metrics.PromMetrics) PromMetrics {
return PromMetrics(pm)
}

View file

@ -0,0 +1,133 @@
package policyruleinfo
import (
"fmt"
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/metrics"
prom "github.com/prometheus/client_golang/prometheus"
)
func (pm PromMetrics) registerPolicyRuleInfoMetric(
policyValidationMode metrics.PolicyValidationMode,
policyType metrics.PolicyType,
policyBackgroundMode metrics.PolicyBackgroundMode,
policyNamespace, policyName, ruleName string,
ruleType metrics.RuleType,
metricChangeType PolicyRuleInfoMetricChangeType,
) error {
var metricValue float64
switch metricChangeType {
case PolicyRuleCreated:
metricValue = float64(1)
case PolicyRuleDeleted:
metricValue = float64(0)
default:
return fmt.Errorf("unknown metric change type found: %s", metricChangeType)
}
if policyType == metrics.Cluster {
policyNamespace = "-"
}
pm.PolicyRuleInfo.With(prom.Labels{
"policy_validation_mode": string(policyValidationMode),
"policy_type": string(policyType),
"policy_background_mode": string(policyBackgroundMode),
"policy_namespace": policyNamespace,
"policy_name": policyName,
"rule_name": ruleName,
"rule_type": string(ruleType),
}).Set(metricValue)
return nil
}
func (pm PromMetrics) AddPolicy(policy interface{}) error {
switch inputPolicy := policy.(type) {
case *kyverno.ClusterPolicy:
policyValidationMode, err := metrics.ParsePolicyValidationMode(inputPolicy.Spec.ValidationFailureAction)
if err != nil {
return err
}
policyBackgroundMode := metrics.ParsePolicyBackgroundMode(*inputPolicy.Spec.Background)
policyType := metrics.Cluster
policyNamespace := "" // doesn't matter for cluster policy
policyName := inputPolicy.ObjectMeta.Name
// registering the metrics on a per-rule basis
for _, rule := range inputPolicy.Spec.Rules {
ruleName := rule.Name
ruleType := metrics.ParseRuleType(rule)
if err = pm.registerPolicyRuleInfoMetric(policyValidationMode, policyType, policyBackgroundMode, policyNamespace, policyName, ruleName, ruleType, PolicyRuleCreated); err != nil {
return err
}
}
return nil
case *kyverno.Policy:
policyValidationMode, err := metrics.ParsePolicyValidationMode(inputPolicy.Spec.ValidationFailureAction)
if err != nil {
return err
}
policyBackgroundMode := metrics.ParsePolicyBackgroundMode(*inputPolicy.Spec.Background)
policyType := metrics.Namespaced
policyNamespace := inputPolicy.ObjectMeta.Namespace
policyName := inputPolicy.ObjectMeta.Name
// registering the metrics on a per-rule basis
for _, rule := range inputPolicy.Spec.Rules {
ruleName := rule.Name
ruleType := metrics.ParseRuleType(rule)
if err = pm.registerPolicyRuleInfoMetric(policyValidationMode, policyType, policyBackgroundMode, policyNamespace, policyName, ruleName, ruleType, PolicyRuleCreated); err != nil {
return err
}
}
return nil
default:
return fmt.Errorf("wrong input type provided %T. Only kyverno.Policy and kyverno.ClusterPolicy allowed", inputPolicy)
}
}
func (pm PromMetrics) RemovePolicy(policy interface{}) error {
switch inputPolicy := policy.(type) {
case *kyverno.ClusterPolicy:
for _, rule := range inputPolicy.Spec.Rules {
policyValidationMode, err := metrics.ParsePolicyValidationMode(inputPolicy.Spec.ValidationFailureAction)
if err != nil {
return err
}
policyBackgroundMode := metrics.ParsePolicyBackgroundMode(*inputPolicy.Spec.Background)
policyType := metrics.Cluster
policyNamespace := "" // doesn't matter for cluster policy
policyName := inputPolicy.ObjectMeta.Name
ruleName := rule.Name
ruleType := metrics.ParseRuleType(rule)
if err = pm.registerPolicyRuleInfoMetric(policyValidationMode, policyType, policyBackgroundMode, policyNamespace, policyName, ruleName, ruleType, PolicyRuleDeleted); err != nil {
return err
}
}
return nil
case *kyverno.Policy:
for _, rule := range inputPolicy.Spec.Rules {
policyValidationMode, err := metrics.ParsePolicyValidationMode(inputPolicy.Spec.ValidationFailureAction)
if err != nil {
return err
}
policyBackgroundMode := metrics.ParsePolicyBackgroundMode(*inputPolicy.Spec.Background)
policyType := metrics.Namespaced
policyNamespace := inputPolicy.ObjectMeta.Namespace
policyName := inputPolicy.ObjectMeta.Name
ruleName := rule.Name
ruleType := metrics.ParseRuleType(rule)
if err = pm.registerPolicyRuleInfoMetric(policyValidationMode, policyType, policyBackgroundMode, policyNamespace, policyName, ruleName, ruleType, PolicyRuleDeleted); err != nil {
return err
}
}
return nil
default:
return fmt.Errorf("wrong input type provided %T. Only kyverno.Policy and kyverno.ClusterPolicy allowed", inputPolicy)
}
}

View file

@ -0,0 +1,14 @@
package policyruleinfo
import (
"github.com/kyverno/kyverno/pkg/metrics"
)
type PolicyRuleInfoMetricChangeType string
const (
PolicyRuleCreated PolicyRuleInfoMetricChangeType = "created"
PolicyRuleDeleted PolicyRuleInfoMetricChangeType = "deleted"
)
type PromMetrics metrics.PromMetrics

View file

@ -20,6 +20,7 @@ import (
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/kyverno/common"
"github.com/kyverno/kyverno/pkg/metrics"
policyRuleInfoMetric "github.com/kyverno/kyverno/pkg/metrics/policyruleinfo"
pm "github.com/kyverno/kyverno/pkg/policymutation"
"github.com/kyverno/kyverno/pkg/policyreport"
"github.com/kyverno/kyverno/pkg/resourcecache"
@ -196,12 +197,42 @@ func (pc *PolicyController) canBackgroundProcess(p *kyverno.ClusterPolicy) bool
return true
}
func (pc *PolicyController) registerPolicyRuleInfoMetricAddPolicy(logger logr.Logger, p *kyverno.ClusterPolicy) {
err := policyRuleInfoMetric.ParsePromMetrics(*pc.promConfig.Metrics).AddPolicy(p)
if err != nil {
logger.Error(err, "error occurred while registering kyverno_policy_rule_info_total metrics for the above policy's creation", "name", p.Name)
}
}
func (pc *PolicyController) registerPolicyRuleInfoMetricUpdatePolicy(logger logr.Logger, oldP, curP *kyverno.ClusterPolicy) {
// removing the old rules associated metrics
err := policyRuleInfoMetric.ParsePromMetrics(*pc.promConfig.Metrics).RemovePolicy(oldP)
if err != nil {
logger.Error(err, "error occurred while registering kyverno_policy_rule_info_total metrics for the above policy's updation", "name", oldP.Name)
}
// adding the new rules associated metrics
err = policyRuleInfoMetric.ParsePromMetrics(*pc.promConfig.Metrics).AddPolicy(curP)
if err != nil {
logger.Error(err, "error occurred while registering kyverno_policy_rule_info_total metrics for the above policy's updation", "name", oldP.Name)
}
}
func (pc *PolicyController) registerPolicyRuleInfoMetricDeletePolicy(logger logr.Logger, p *kyverno.ClusterPolicy) {
err := policyRuleInfoMetric.ParsePromMetrics(*pc.promConfig.Metrics).RemovePolicy(p)
if err != nil {
logger.Error(err, "error occurred while registering kyverno_policy_rule_info_total metrics for the above policy's deletion", "name", p.Name)
}
}
func (pc *PolicyController) addPolicy(obj interface{}) {
logger := pc.log
p := obj.(*kyverno.ClusterPolicy)
logger.Info("policy created", "uid", p.UID, "kind", "ClusterPolicy", "name", p.Name)
// register kyverno_policy_rule_info_total metric concurrently
go pc.registerPolicyRuleInfoMetricAddPolicy(logger, p)
if p.Spec.Background == nil || p.Spec.ValidationFailureAction == "" || missingAutoGenRules(p, logger) {
pol, _ := common.MutatePolicy(p, logger)
pol.SetGroupVersionKind(schema.GroupVersionKind{Group: "kyverno.io", Version: "v1", Kind: "ClusterPolicy"})
@ -224,6 +255,9 @@ func (pc *PolicyController) updatePolicy(old, cur interface{}) {
oldP := old.(*kyverno.ClusterPolicy)
curP := cur.(*kyverno.ClusterPolicy)
// register kyverno_policy_rule_info_total metric concurrently
go pc.registerPolicyRuleInfoMetricUpdatePolicy(logger, oldP, curP)
if curP.Spec.Background == nil || curP.Spec.ValidationFailureAction == "" || missingAutoGenRules(curP, logger) {
pol, _ := common.MutatePolicy(curP, logger)
pol.SetGroupVersionKind(schema.GroupVersionKind{Group: "kyverno.io", Version: "v1", Kind: "ClusterPolicy"})
@ -265,6 +299,9 @@ func (pc *PolicyController) deletePolicy(obj interface{}) {
}
}
// register kyverno_policy_rule_info_total metric concurrently
go pc.registerPolicyRuleInfoMetricDeletePolicy(logger, p)
logger.Info("policy deleted", "uid", p.UID, "kind", "ClusterPolicy", "name", p.Name)
// we process policies that are not set of background processing
@ -273,10 +310,40 @@ func (pc *PolicyController) deletePolicy(obj interface{}) {
pc.enqueueRCRDeletedPolicy(p.Name)
}
func (pc *PolicyController) registerPolicyRuleInfoMetricAddNsPolicy(logger logr.Logger, p *kyverno.Policy) {
err := policyRuleInfoMetric.ParsePromMetrics(*pc.promConfig.Metrics).AddPolicy(p)
if err != nil {
logger.Error(err, "error occurred while registering kyverno_policy_rule_info_total metrics for the above policy's creation", "name", p.Name)
}
}
func (pc *PolicyController) registerPolicyRuleInfoMetricUpdateNsPolicy(logger logr.Logger, oldP, curP *kyverno.Policy) {
// removing the old rules associated metrics
err := policyRuleInfoMetric.ParsePromMetrics(*pc.promConfig.Metrics).RemovePolicy(oldP)
if err != nil {
logger.Error(err, "error occurred while registering kyverno_policy_rule_info_total metrics for the above policy's updation", "name", oldP.Name)
}
// adding the new rules associated metrics
err = policyRuleInfoMetric.ParsePromMetrics(*pc.promConfig.Metrics).AddPolicy(curP)
if err != nil {
logger.Error(err, "error occurred while registering kyverno_policy_rule_info_total metrics for the above policy's updation", "name", oldP.Name)
}
}
func (pc *PolicyController) registerPolicyRuleInfoMetricDeleteNsPolicy(logger logr.Logger, p *kyverno.Policy) {
err := policyRuleInfoMetric.ParsePromMetrics(*pc.promConfig.Metrics).RemovePolicy(p)
if err != nil {
logger.Error(err, "error occurred while registering kyverno_policy_rule_info_total metrics for the above policy's deletion", "name", p.Name)
}
}
func (pc *PolicyController) addNsPolicy(obj interface{}) {
logger := pc.log
p := obj.(*kyverno.Policy)
// register kyverno_policy_rule_info_total metric concurrently
go pc.registerPolicyRuleInfoMetricAddNsPolicy(logger, p)
logger.Info("policy created", "uid", p.UID, "kind", "Policy", "name", p.Name, "namespaces", p.Namespace)
pol := ConvertPolicyToClusterPolicy(p)
@ -299,6 +366,10 @@ func (pc *PolicyController) updateNsPolicy(old, cur interface{}) {
logger := pc.log
oldP := old.(*kyverno.Policy)
curP := cur.(*kyverno.Policy)
// register kyverno_policy_rule_info_total metric concurrently
go pc.registerPolicyRuleInfoMetricUpdateNsPolicy(logger, oldP, curP)
ncurP := ConvertPolicyToClusterPolicy(curP)
if ncurP.Spec.Background == nil || ncurP.Spec.ValidationFailureAction == "" || missingAutoGenRules(ncurP, logger) {
@ -341,6 +412,9 @@ func (pc *PolicyController) deleteNsPolicy(obj interface{}) {
}
}
// register kyverno_policy_rule_info_total metric concurrently
go pc.registerPolicyRuleInfoMetricDeleteNsPolicy(logger, p)
logger.Info("policy deleted event", "uid", p.UID, "kind", "Policy", "policy_name", p.Name, "namespaces", p.Namespace)
pol := ConvertPolicyToClusterPolicy(p)