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:
parent
bb80e1b641
commit
fea074f493
5 changed files with 250 additions and 8 deletions
|
@ -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)
|
||||
|
|
21
pkg/metrics/policyruleinfo/parsers.go
Normal file
21
pkg/metrics/policyruleinfo/parsers.go
Normal 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)
|
||||
}
|
133
pkg/metrics/policyruleinfo/policyRuleInfo.go
Normal file
133
pkg/metrics/policyruleinfo/policyRuleInfo.go
Normal 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)
|
||||
}
|
||||
|
||||
}
|
14
pkg/metrics/policyruleinfo/types.go
Normal file
14
pkg/metrics/policyruleinfo/types.go
Normal 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
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue