mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-14 19:58:45 +00:00
refactor: kyverno_policy_results metric management (#6781)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
2f1ac317f4
commit
b2340785fc
18 changed files with 132 additions and 150 deletions
|
@ -229,6 +229,7 @@ func main() {
|
||||||
)
|
)
|
||||||
engine := engine.NewEngine(
|
engine := engine.NewEngine(
|
||||||
configuration,
|
configuration,
|
||||||
|
metricsConfig.Config(),
|
||||||
dClient,
|
dClient,
|
||||||
rclient,
|
rclient,
|
||||||
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
||||||
|
|
|
@ -478,6 +478,7 @@ OuterLoop:
|
||||||
}
|
}
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
cfg,
|
cfg,
|
||||||
|
config.NewDefaultMetricsConfiguration(),
|
||||||
c.Client,
|
c.Client,
|
||||||
registryclient.NewOrDie(),
|
registryclient.NewOrDie(),
|
||||||
store.ContextLoaderFactory(nil),
|
store.ContextLoaderFactory(nil),
|
||||||
|
@ -1073,6 +1074,7 @@ func initializeMockController(objects []runtime.Object) (*generate.GenerateContr
|
||||||
client.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
|
client.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
|
||||||
c := generate.NewGenerateControllerWithOnlyClient(client, engine.NewEngine(
|
c := generate.NewGenerateControllerWithOnlyClient(client, engine.NewEngine(
|
||||||
config.NewDefaultConfiguration(false),
|
config.NewDefaultConfiguration(false),
|
||||||
|
config.NewDefaultMetricsConfiguration(),
|
||||||
client,
|
client,
|
||||||
nil,
|
nil,
|
||||||
store.ContextLoaderFactory(nil),
|
store.ContextLoaderFactory(nil),
|
||||||
|
|
|
@ -386,6 +386,7 @@ func main() {
|
||||||
}
|
}
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
configuration,
|
configuration,
|
||||||
|
metricsConfig.Config(),
|
||||||
dClient,
|
dClient,
|
||||||
rclient,
|
rclient,
|
||||||
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
||||||
|
|
|
@ -323,6 +323,7 @@ func main() {
|
||||||
}
|
}
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
configuration,
|
configuration,
|
||||||
|
metricsConfig.Config(),
|
||||||
dClient,
|
dClient,
|
||||||
rclient,
|
rclient,
|
||||||
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
||||||
|
|
|
@ -16,35 +16,52 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/engine/internal"
|
"github.com/kyverno/kyverno/pkg/engine/internal"
|
||||||
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||||
"github.com/kyverno/kyverno/pkg/logging"
|
"github.com/kyverno/kyverno/pkg/logging"
|
||||||
|
"github.com/kyverno/kyverno/pkg/metrics"
|
||||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||||
"github.com/kyverno/kyverno/pkg/tracing"
|
"github.com/kyverno/kyverno/pkg/tracing"
|
||||||
|
"go.opentelemetry.io/otel/metric/global"
|
||||||
|
"go.opentelemetry.io/otel/metric/instrument"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
|
|
||||||
type engine struct {
|
type engine struct {
|
||||||
configuration config.Configuration
|
configuration config.Configuration
|
||||||
client dclient.Interface
|
metricsConfiguration config.MetricsConfiguration
|
||||||
rclient registryclient.Client
|
client dclient.Interface
|
||||||
contextLoader engineapi.ContextLoaderFactory
|
rclient registryclient.Client
|
||||||
exceptionSelector engineapi.PolicyExceptionSelector
|
contextLoader engineapi.ContextLoaderFactory
|
||||||
|
exceptionSelector engineapi.PolicyExceptionSelector
|
||||||
|
// metrics
|
||||||
|
resultCounter instrument.Int64Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
type handlerFactory = func() (handlers.Handler, error)
|
type handlerFactory = func() (handlers.Handler, error)
|
||||||
|
|
||||||
func NewEngine(
|
func NewEngine(
|
||||||
configuration config.Configuration,
|
configuration config.Configuration,
|
||||||
|
metricsConfiguration config.MetricsConfiguration,
|
||||||
client dclient.Interface,
|
client dclient.Interface,
|
||||||
rclient registryclient.Client,
|
rclient registryclient.Client,
|
||||||
contextLoader engineapi.ContextLoaderFactory,
|
contextLoader engineapi.ContextLoaderFactory,
|
||||||
exceptionSelector engineapi.PolicyExceptionSelector,
|
exceptionSelector engineapi.PolicyExceptionSelector,
|
||||||
) engineapi.Engine {
|
) engineapi.Engine {
|
||||||
|
meter := global.MeterProvider().Meter(metrics.MeterName)
|
||||||
|
resultCounter, err := meter.Int64Counter(
|
||||||
|
"kyverno_policy_results",
|
||||||
|
instrument.WithDescription("can be used to track the results associated with the policies applied in the user’s cluster, at the level from rule to policy to admission requests"),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
logging.Error(err, "failed to register metric kyverno_policy_results")
|
||||||
|
}
|
||||||
return &engine{
|
return &engine{
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
client: client,
|
metricsConfiguration: metricsConfiguration,
|
||||||
rclient: rclient,
|
client: client,
|
||||||
contextLoader: contextLoader,
|
rclient: rclient,
|
||||||
exceptionSelector: exceptionSelector,
|
contextLoader: contextLoader,
|
||||||
|
exceptionSelector: exceptionSelector,
|
||||||
|
resultCounter: resultCounter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +75,9 @@ func (e *engine) Validate(
|
||||||
policyResponse := e.validate(ctx, logger, policyContext)
|
policyResponse := e.validate(ctx, logger, policyContext)
|
||||||
response = response.WithPolicyResponse(policyResponse)
|
response = response.WithPolicyResponse(policyResponse)
|
||||||
}
|
}
|
||||||
return response.Done(time.Now())
|
response = response.Done(time.Now())
|
||||||
|
e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
|
||||||
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) Mutate(
|
func (e *engine) Mutate(
|
||||||
|
@ -73,7 +92,9 @@ func (e *engine) Mutate(
|
||||||
WithPolicyResponse(policyResponse).
|
WithPolicyResponse(policyResponse).
|
||||||
WithPatchedResource(patchedResource)
|
WithPatchedResource(patchedResource)
|
||||||
}
|
}
|
||||||
return response.Done(time.Now())
|
response = response.Done(time.Now())
|
||||||
|
e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
|
||||||
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) Generate(
|
func (e *engine) Generate(
|
||||||
|
@ -86,7 +107,9 @@ func (e *engine) Generate(
|
||||||
policyResponse := e.generateResponse(ctx, logger, policyContext)
|
policyResponse := e.generateResponse(ctx, logger, policyContext)
|
||||||
response = response.WithPolicyResponse(policyResponse)
|
response = response.WithPolicyResponse(policyResponse)
|
||||||
}
|
}
|
||||||
return response.Done(time.Now())
|
response = response.Done(time.Now())
|
||||||
|
e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
|
||||||
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) VerifyAndPatchImages(
|
func (e *engine) VerifyAndPatchImages(
|
||||||
|
@ -100,7 +123,9 @@ func (e *engine) VerifyAndPatchImages(
|
||||||
policyResponse, innerIvm := e.verifyAndPatchImages(ctx, logger, policyContext)
|
policyResponse, innerIvm := e.verifyAndPatchImages(ctx, logger, policyContext)
|
||||||
response, ivm = response.WithPolicyResponse(policyResponse), innerIvm
|
response, ivm = response.WithPolicyResponse(policyResponse), innerIvm
|
||||||
}
|
}
|
||||||
return response.Done(time.Now()), ivm
|
response = response.Done(time.Now())
|
||||||
|
e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
|
||||||
|
return response, ivm
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) ApplyBackgroundChecks(
|
func (e *engine) ApplyBackgroundChecks(
|
||||||
|
@ -113,7 +138,9 @@ func (e *engine) ApplyBackgroundChecks(
|
||||||
policyResponse := e.applyBackgroundChecks(ctx, logger, policyContext)
|
policyResponse := e.applyBackgroundChecks(ctx, logger, policyContext)
|
||||||
response = response.WithPolicyResponse(policyResponse)
|
response = response.WithPolicyResponse(policyResponse)
|
||||||
}
|
}
|
||||||
return response.Done(time.Now())
|
response = response.Done(time.Now())
|
||||||
|
e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
|
||||||
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) ContextLoader(
|
func (e *engine) ContextLoader(
|
||||||
|
|
|
@ -161,7 +161,10 @@ var signaturePayloads = [][]byte{
|
||||||
[]byte(`{"critical":{"identity":{"docker-reference":"ghcr.io/kyverno/test-verify-image"},"image":{"docker-manifest-digest":"sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105"},"type":"cosign container image signature"},"optional":null}`),
|
[]byte(`{"critical":{"identity":{"docker-reference":"ghcr.io/kyverno/test-verify-image"},"image":{"docker-manifest-digest":"sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105"},"type":"cosign container image signature"},"optional":null}`),
|
||||||
}
|
}
|
||||||
|
|
||||||
var cfg = config.NewDefaultConfiguration(false)
|
var (
|
||||||
|
cfg = config.NewDefaultConfiguration(false)
|
||||||
|
metricsCfg = config.NewDefaultMetricsConfiguration()
|
||||||
|
)
|
||||||
|
|
||||||
func testVerifyAndPatchImages(
|
func testVerifyAndPatchImages(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
@ -172,6 +175,7 @@ func testVerifyAndPatchImages(
|
||||||
) (engineapi.EngineResponse, engineapi.ImageVerificationMetadata) {
|
) (engineapi.EngineResponse, engineapi.ImageVerificationMetadata) {
|
||||||
e := NewEngine(
|
e := NewEngine(
|
||||||
cfg,
|
cfg,
|
||||||
|
metricsCfg,
|
||||||
nil,
|
nil,
|
||||||
rclient,
|
rclient,
|
||||||
engineapi.DefaultContextLoaderFactory(cmResolver),
|
engineapi.DefaultContextLoaderFactory(cmResolver),
|
||||||
|
|
74
pkg/engine/metrics.go
Normal file
74
pkg/engine/metrics.go
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package engine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-logr/logr"
|
||||||
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
|
"github.com/kyverno/kyverno/pkg/metrics"
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (e *engine) reportMetrics(
|
||||||
|
ctx context.Context,
|
||||||
|
logger logr.Logger,
|
||||||
|
operation kyvernov1.AdmissionOperation,
|
||||||
|
admissionOperation bool,
|
||||||
|
response engineapi.EngineResponse,
|
||||||
|
) {
|
||||||
|
if e.resultCounter != nil {
|
||||||
|
policy := response.Policy
|
||||||
|
if name, namespace, policyType, backgroundMode, validationMode, err := metrics.GetPolicyInfos(policy); err != nil {
|
||||||
|
logger.Error(err, "failed to get policy infos for metrics reporting")
|
||||||
|
} else {
|
||||||
|
if policyType == metrics.Cluster {
|
||||||
|
namespace = "-"
|
||||||
|
}
|
||||||
|
if e.metricsConfiguration.CheckNamespace(namespace) {
|
||||||
|
resourceSpec := response.Resource
|
||||||
|
resourceKind := resourceSpec.GetKind()
|
||||||
|
resourceNamespace := resourceSpec.GetNamespace()
|
||||||
|
for _, rule := range response.PolicyResponse.Rules {
|
||||||
|
ruleName := rule.Name
|
||||||
|
ruleType := metrics.ParseRuleTypeFromEngineRuleResponse(rule)
|
||||||
|
var ruleResult metrics.RuleResult
|
||||||
|
switch rule.Status {
|
||||||
|
case engineapi.RuleStatusPass:
|
||||||
|
ruleResult = metrics.Pass
|
||||||
|
case engineapi.RuleStatusFail:
|
||||||
|
ruleResult = metrics.Fail
|
||||||
|
case engineapi.RuleStatusWarn:
|
||||||
|
ruleResult = metrics.Warn
|
||||||
|
case engineapi.RuleStatusError:
|
||||||
|
ruleResult = metrics.Error
|
||||||
|
case engineapi.RuleStatusSkip:
|
||||||
|
ruleResult = metrics.Skip
|
||||||
|
default:
|
||||||
|
ruleResult = metrics.Fail
|
||||||
|
}
|
||||||
|
executionCause := metrics.AdmissionRequest
|
||||||
|
if !admissionOperation {
|
||||||
|
executionCause = metrics.BackgroundScan
|
||||||
|
}
|
||||||
|
commonLabels := []attribute.KeyValue{
|
||||||
|
attribute.String("policy_validation_mode", string(validationMode)),
|
||||||
|
attribute.String("policy_type", string(policyType)),
|
||||||
|
attribute.String("policy_background_mode", string(backgroundMode)),
|
||||||
|
attribute.String("policy_namespace", namespace),
|
||||||
|
attribute.String("policy_name", name),
|
||||||
|
attribute.String("resource_kind", resourceKind),
|
||||||
|
attribute.String("resource_namespace", resourceNamespace),
|
||||||
|
attribute.String("resource_request_operation", strings.ToLower(string(operation))),
|
||||||
|
attribute.String("rule_name", ruleName),
|
||||||
|
attribute.String("rule_result", string(ruleResult)),
|
||||||
|
attribute.String("rule_type", string(ruleType)),
|
||||||
|
attribute.String("rule_execution_cause", string(executionCause)),
|
||||||
|
}
|
||||||
|
e.resultCounter.Add(ctx, 1, commonLabels...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
client "github.com/kyverno/kyverno/pkg/clients/dclient"
|
client "github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
|
"github.com/kyverno/kyverno/pkg/config"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||||
enginetest "github.com/kyverno/kyverno/pkg/engine/test"
|
enginetest "github.com/kyverno/kyverno/pkg/engine/test"
|
||||||
|
@ -32,6 +33,7 @@ func testMutate(
|
||||||
}
|
}
|
||||||
e := NewEngine(
|
e := NewEngine(
|
||||||
cfg,
|
cfg,
|
||||||
|
config.NewDefaultMetricsConfiguration(),
|
||||||
client,
|
client,
|
||||||
rclient,
|
rclient,
|
||||||
contextLoader,
|
contextLoader,
|
||||||
|
|
|
@ -31,6 +31,7 @@ func testValidate(
|
||||||
}
|
}
|
||||||
e := NewEngine(
|
e := NewEngine(
|
||||||
cfg,
|
cfg,
|
||||||
|
config.NewDefaultMetricsConfiguration(),
|
||||||
nil,
|
nil,
|
||||||
rclient,
|
rclient,
|
||||||
contextLoader,
|
contextLoader,
|
||||||
|
|
|
@ -30,7 +30,6 @@ const (
|
||||||
type MetricsConfig struct {
|
type MetricsConfig struct {
|
||||||
// instruments
|
// instruments
|
||||||
policyChangesMetric instrument.Int64Counter
|
policyChangesMetric instrument.Int64Counter
|
||||||
policyResultsMetric instrument.Int64Counter
|
|
||||||
policyExecutionDurationMetric instrument.Float64Histogram
|
policyExecutionDurationMetric instrument.Float64Histogram
|
||||||
clientQueriesMetric instrument.Int64Counter
|
clientQueriesMetric instrument.Int64Counter
|
||||||
|
|
||||||
|
@ -41,7 +40,6 @@ type MetricsConfig struct {
|
||||||
|
|
||||||
type MetricsConfigManager interface {
|
type MetricsConfigManager interface {
|
||||||
Config() kconfig.MetricsConfiguration
|
Config() kconfig.MetricsConfiguration
|
||||||
RecordPolicyResults(ctx context.Context, policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation, ruleName string, ruleResult RuleResult, ruleType RuleType, ruleExecutionCause RuleExecutionCause)
|
|
||||||
RecordPolicyChanges(ctx context.Context, policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, policyChangeType string)
|
RecordPolicyChanges(ctx context.Context, policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, policyChangeType string)
|
||||||
RecordPolicyExecutionDuration(ctx context.Context, policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, ruleName string, ruleResult RuleResult, ruleType RuleType, ruleExecutionCause RuleExecutionCause, ruleExecutionLatency float64)
|
RecordPolicyExecutionDuration(ctx context.Context, policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, ruleName string, ruleResult RuleResult, ruleType RuleType, ruleExecutionCause RuleExecutionCause, ruleExecutionLatency float64)
|
||||||
RecordClientQueries(ctx context.Context, clientQueryOperation ClientQueryOperation, clientType ClientType, resourceKind string, resourceNamespace string)
|
RecordClientQueries(ctx context.Context, clientQueryOperation ClientQueryOperation, clientType ClientType, resourceKind string, resourceNamespace string)
|
||||||
|
@ -54,11 +52,6 @@ func (m *MetricsConfig) Config() kconfig.MetricsConfiguration {
|
||||||
func (m *MetricsConfig) initializeMetrics(meterProvider metric.MeterProvider) error {
|
func (m *MetricsConfig) initializeMetrics(meterProvider metric.MeterProvider) error {
|
||||||
var err error
|
var err error
|
||||||
meter := meterProvider.Meter(MeterName)
|
meter := meterProvider.Meter(MeterName)
|
||||||
m.policyResultsMetric, err = meter.Int64Counter("kyverno_policy_results", instrument.WithDescription("can be used to track the results associated with the policies applied in the user’s cluster, at the level from rule to policy to admission requests"))
|
|
||||||
if err != nil {
|
|
||||||
m.Log.Error(err, "Failed to create instrument, kyverno_policy_results")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.policyChangesMetric, err = meter.Int64Counter("kyverno_policy_changes", instrument.WithDescription("can be used to track all the changes associated with the Kyverno policies present on the cluster such as creation, updates and deletions"))
|
m.policyChangesMetric, err = meter.Int64Counter("kyverno_policy_changes", instrument.WithDescription("can be used to track all the changes associated with the Kyverno policies present on the cluster such as creation, updates and deletions"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.Log.Error(err, "Failed to create instrument, kyverno_policy_changes")
|
m.Log.Error(err, "Failed to create instrument, kyverno_policy_changes")
|
||||||
|
@ -169,27 +162,6 @@ func NewPrometheusConfig(
|
||||||
return provider, metricsServerMux, nil
|
return provider, metricsServerMux, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MetricsConfig) RecordPolicyResults(ctx context.Context, policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string,
|
|
||||||
resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation, ruleName string, ruleResult RuleResult, ruleType RuleType,
|
|
||||||
ruleExecutionCause RuleExecutionCause,
|
|
||||||
) {
|
|
||||||
commonLabels := []attribute.KeyValue{
|
|
||||||
attribute.String("policy_validation_mode", string(policyValidationMode)),
|
|
||||||
attribute.String("policy_type", string(policyType)),
|
|
||||||
attribute.String("policy_background_mode", string(policyBackgroundMode)),
|
|
||||||
attribute.String("policy_namespace", policyNamespace),
|
|
||||||
attribute.String("policy_name", policyName),
|
|
||||||
attribute.String("resource_kind", resourceKind),
|
|
||||||
attribute.String("resource_namespace", resourceNamespace),
|
|
||||||
attribute.String("resource_request_operation", string(resourceRequestOperation)),
|
|
||||||
attribute.String("rule_name", ruleName),
|
|
||||||
attribute.String("rule_result", string(ruleResult)),
|
|
||||||
attribute.String("rule_type", string(ruleType)),
|
|
||||||
attribute.String("rule_execution_cause", string(ruleExecutionCause)),
|
|
||||||
}
|
|
||||||
m.policyResultsMetric.Add(ctx, 1, commonLabels...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MetricsConfig) RecordPolicyChanges(ctx context.Context, policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, policyChangeType string) {
|
func (m *MetricsConfig) RecordPolicyChanges(ctx context.Context, policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, policyChangeType string) {
|
||||||
commonLabels := []attribute.KeyValue{
|
commonLabels := []attribute.KeyValue{
|
||||||
attribute.String("policy_validation_mode", string(policyValidationMode)),
|
attribute.String("policy_validation_mode", string(policyValidationMode)),
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
package policyresults
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
|
||||||
"github.com/kyverno/kyverno/pkg/metrics"
|
|
||||||
)
|
|
||||||
|
|
||||||
func registerPolicyResultsMetric(
|
|
||||||
ctx context.Context,
|
|
||||||
m metrics.MetricsConfigManager,
|
|
||||||
policyValidationMode metrics.PolicyValidationMode,
|
|
||||||
policyType metrics.PolicyType,
|
|
||||||
policyBackgroundMode metrics.PolicyBackgroundMode,
|
|
||||||
policyNamespace, policyName string,
|
|
||||||
resourceKind, resourceNamespace string,
|
|
||||||
resourceRequestOperation metrics.ResourceRequestOperation,
|
|
||||||
ruleName string,
|
|
||||||
ruleResult metrics.RuleResult,
|
|
||||||
ruleType metrics.RuleType,
|
|
||||||
ruleExecutionCause metrics.RuleExecutionCause,
|
|
||||||
) {
|
|
||||||
if policyType == metrics.Cluster {
|
|
||||||
policyNamespace = "-"
|
|
||||||
}
|
|
||||||
if m.Config().CheckNamespace(policyNamespace) {
|
|
||||||
m.RecordPolicyResults(ctx, policyValidationMode, policyType, policyBackgroundMode, policyNamespace, policyName, resourceKind, resourceNamespace, resourceRequestOperation, ruleName, ruleResult, ruleType, ruleExecutionCause)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// policy - policy related data
|
|
||||||
// engineResponse - resource and rule related data
|
|
||||||
func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse, executionCause metrics.RuleExecutionCause, resourceRequestOperation metrics.ResourceRequestOperation) error {
|
|
||||||
name, namespace, policyType, backgroundMode, validationMode, err := metrics.GetPolicyInfos(policy)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
resourceSpec := engineResponse.Resource
|
|
||||||
resourceKind := resourceSpec.GetKind()
|
|
||||||
resourceNamespace := resourceSpec.GetNamespace()
|
|
||||||
ruleResponses := engineResponse.PolicyResponse.Rules
|
|
||||||
for _, rule := range ruleResponses {
|
|
||||||
ruleName := rule.Name
|
|
||||||
ruleType := metrics.ParseRuleTypeFromEngineRuleResponse(rule)
|
|
||||||
var ruleResult metrics.RuleResult
|
|
||||||
switch rule.Status {
|
|
||||||
case engineapi.RuleStatusPass:
|
|
||||||
ruleResult = metrics.Pass
|
|
||||||
case engineapi.RuleStatusFail:
|
|
||||||
ruleResult = metrics.Fail
|
|
||||||
case engineapi.RuleStatusWarn:
|
|
||||||
ruleResult = metrics.Warn
|
|
||||||
case engineapi.RuleStatusError:
|
|
||||||
ruleResult = metrics.Error
|
|
||||||
case engineapi.RuleStatusSkip:
|
|
||||||
ruleResult = metrics.Skip
|
|
||||||
default:
|
|
||||||
ruleResult = metrics.Fail
|
|
||||||
}
|
|
||||||
registerPolicyResultsMetric(
|
|
||||||
ctx,
|
|
||||||
m,
|
|
||||||
validationMode,
|
|
||||||
policyType,
|
|
||||||
backgroundMode,
|
|
||||||
namespace, name,
|
|
||||||
resourceKind, resourceNamespace,
|
|
||||||
resourceRequestOperation,
|
|
||||||
ruleName,
|
|
||||||
ruleResult,
|
|
||||||
ruleType,
|
|
||||||
executionCause,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -54,6 +54,7 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
|
||||||
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration),
|
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration),
|
||||||
engine: engine.NewEngine(
|
engine: engine.NewEngine(
|
||||||
configuration,
|
configuration,
|
||||||
|
config.NewDefaultMetricsConfiguration(),
|
||||||
dclient,
|
dclient,
|
||||||
rclient,
|
rclient,
|
||||||
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
||||||
|
|
|
@ -124,7 +124,6 @@ func (h *generationHandler) handleTrigger(
|
||||||
h.applyGeneration(ctx, request, policy, appliedRules, policyContext)
|
h.applyGeneration(ctx, request, policy, appliedRules, policyContext)
|
||||||
h.syncTriggerAction(ctx, request, policy, failedRules, policyContext)
|
h.syncTriggerAction(ctx, request, policy, failedRules, policyContext)
|
||||||
|
|
||||||
go webhookutils.RegisterPolicyResultsMetricGeneration(ctx, h.log, h.metrics, string(request.Operation), policy, engineResponse)
|
|
||||||
go webhookutils.RegisterPolicyExecutionDurationMetricGenerate(ctx, h.log, h.metrics, string(request.Operation), policy, engineResponse)
|
go webhookutils.RegisterPolicyExecutionDurationMetricGenerate(ctx, h.log, h.metrics, string(request.Operation), policy, engineResponse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,8 +122,6 @@ func (v *mutationHandler) applyMutations(
|
||||||
engineResponses = append(engineResponses, *engineResponse)
|
engineResponses = append(engineResponses, *engineResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// registering the kyverno_policy_results_total metric concurrently
|
|
||||||
go webhookutils.RegisterPolicyResultsMetricMutation(context.TODO(), v.log, v.metrics, string(request.Operation), policy, *engineResponse)
|
|
||||||
// registering the kyverno_policy_execution_duration_seconds metric concurrently
|
// registering the kyverno_policy_execution_duration_seconds metric concurrently
|
||||||
go webhookutils.RegisterPolicyExecutionDurationMetricMutate(context.TODO(), v.log, v.metrics, string(request.Operation), policy, *engineResponse)
|
go webhookutils.RegisterPolicyExecutionDurationMetricMutate(context.TODO(), v.log, v.metrics, string(request.Operation), policy, *engineResponse)
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,6 @@ func (h *resourceHandlers) handleMutateExisting(ctx context.Context, logger logr
|
||||||
engineResponses = append(engineResponses, &engineResponse)
|
engineResponses = append(engineResponses, &engineResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// registering the kyverno_policy_results_total metric concurrently
|
|
||||||
go webhookutils.RegisterPolicyResultsMetricMutation(context.TODO(), logger, h.metricsConfig, string(request.Operation), policy, engineResponse)
|
|
||||||
// registering the kyverno_policy_execution_duration_seconds metric concurrently
|
// registering the kyverno_policy_execution_duration_seconds metric concurrently
|
||||||
go webhookutils.RegisterPolicyExecutionDurationMetricMutate(context.TODO(), logger, h.metricsConfig, string(request.Operation), policy, engineResponse)
|
go webhookutils.RegisterPolicyExecutionDurationMetricMutate(context.TODO(), logger, h.metricsConfig, string(request.Operation), policy, engineResponse)
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,6 @@ func (v *validationHandler) HandleValidation(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go webhookutils.RegisterPolicyResultsMetricValidation(ctx, logger, v.metrics, string(request.Operation), policyContext.Policy(), engineResponse)
|
|
||||||
go webhookutils.RegisterPolicyExecutionDurationMetricValidate(ctx, logger, v.metrics, string(request.Operation), policyContext.Policy(), engineResponse)
|
go webhookutils.RegisterPolicyExecutionDurationMetricValidate(ctx, logger, v.metrics, string(request.Operation), policyContext.Policy(), engineResponse)
|
||||||
|
|
||||||
engineResponses = append(engineResponses, engineResponse)
|
engineResponses = append(engineResponses, engineResponse)
|
||||||
|
@ -165,7 +164,6 @@ func (v *validationHandler) buildAuditResponses(
|
||||||
policyContext := policyContext.WithPolicy(policy).WithNamespaceLabels(namespaceLabels)
|
policyContext := policyContext.WithPolicy(policy).WithNamespaceLabels(namespaceLabels)
|
||||||
response := v.engine.Validate(ctx, policyContext)
|
response := v.engine.Validate(ctx, policyContext)
|
||||||
responses = append(responses, response)
|
responses = append(responses, response)
|
||||||
go webhookutils.RegisterPolicyResultsMetricValidation(ctx, v.log, v.metrics, string(request.Operation), policyContext.Policy(), response)
|
|
||||||
go webhookutils.RegisterPolicyExecutionDurationMetricValidate(ctx, v.log, v.metrics, string(request.Operation), policyContext.Policy(), response)
|
go webhookutils.RegisterPolicyExecutionDurationMetricValidate(ctx, v.log, v.metrics, string(request.Operation), policyContext.Policy(), response)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -1051,6 +1051,7 @@ func TestValidate_failure_action_overrides(t *testing.T) {
|
||||||
|
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
config.NewDefaultConfiguration(false),
|
config.NewDefaultConfiguration(false),
|
||||||
|
config.NewDefaultMetricsConfiguration(),
|
||||||
nil,
|
nil,
|
||||||
registryclient.NewOrDie(),
|
registryclient.NewOrDie(),
|
||||||
engineapi.DefaultContextLoaderFactory(nil),
|
engineapi.DefaultContextLoaderFactory(nil),
|
||||||
|
@ -1130,6 +1131,7 @@ func Test_RuleSelector(t *testing.T) {
|
||||||
|
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
config.NewDefaultConfiguration(false),
|
config.NewDefaultConfiguration(false),
|
||||||
|
config.NewDefaultMetricsConfiguration(),
|
||||||
nil,
|
nil,
|
||||||
registryclient.NewOrDie(),
|
registryclient.NewOrDie(),
|
||||||
engineapi.DefaultContextLoaderFactory(nil),
|
engineapi.DefaultContextLoaderFactory(nil),
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/metrics"
|
"github.com/kyverno/kyverno/pkg/metrics"
|
||||||
policyExecutionDuration "github.com/kyverno/kyverno/pkg/metrics/policyexecutionduration"
|
policyExecutionDuration "github.com/kyverno/kyverno/pkg/metrics/policyexecutionduration"
|
||||||
policyResults "github.com/kyverno/kyverno/pkg/metrics/policyresults"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type reporterFunc func(metrics.ResourceRequestOperation) error
|
type reporterFunc func(metrics.ResourceRequestOperation) error
|
||||||
|
@ -24,26 +23,6 @@ func registerMetric(logger logr.Logger, m string, requestOperation string, r rep
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// POLICY RESULTS
|
|
||||||
|
|
||||||
func RegisterPolicyResultsMetricMutation(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
|
|
||||||
registerMetric(logger, "kyverno_policy_results_total", requestOperation, func(op metrics.ResourceRequestOperation) error {
|
|
||||||
return policyResults.ProcessEngineResponse(ctx, metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterPolicyResultsMetricValidation(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
|
|
||||||
registerMetric(logger, "kyverno_policy_results_total", requestOperation, func(op metrics.ResourceRequestOperation) error {
|
|
||||||
return policyResults.ProcessEngineResponse(ctx, metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterPolicyResultsMetricGeneration(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
|
|
||||||
registerMetric(logger, "kyverno_policy_results_total", requestOperation, func(op metrics.ResourceRequestOperation) error {
|
|
||||||
return policyResults.ProcessEngineResponse(ctx, metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// POLICY EXECUTION
|
// POLICY EXECUTION
|
||||||
|
|
||||||
func RegisterPolicyExecutionDurationMetricMutate(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
|
func RegisterPolicyExecutionDurationMetricMutate(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue