diff --git a/api/kyverno/v2/updaterequest_types.go b/api/kyverno/v2/updaterequest_types.go
index b62a4140d3..c3e57f8b7d 100644
--- a/api/kyverno/v2/updaterequest_types.go
+++ b/api/kyverno/v2/updaterequest_types.go
@@ -144,6 +144,11 @@ type RequestInfo struct {
// UserInfo is the userInfo carried in the admission request.
// +optional
AdmissionUserInfo authenticationv1.UserInfo `json:"userInfo"`
+
+ // DryRun indicates that modifications will definitely not be persisted for this request.
+ // Defaults to false.
+ // +optional
+ DryRun bool `json:"synchronize,omitempty"`
}
// AdmissionRequestInfoObject stores the admission request and operation details
diff --git a/charts/kyverno/charts/crds/templates/kyverno.io/kyverno.io_updaterequests.yaml b/charts/kyverno/charts/crds/templates/kyverno.io/kyverno.io_updaterequests.yaml
index 8c53322e15..8d5a2db8d2 100644
--- a/charts/kyverno/charts/crds/templates/kyverno.io/kyverno.io_updaterequests.yaml
+++ b/charts/kyverno/charts/crds/templates/kyverno.io/kyverno.io_updaterequests.yaml
@@ -660,6 +660,11 @@ spec:
type: string
nullable: true
type: array
+ synchronize:
+ description: |-
+ DryRun indicates that modifications will definitely not be persisted for this request.
+ Defaults to false.
+ type: boolean
userInfo:
description: UserInfo is the userInfo carried in the admission
request.
diff --git a/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_userinfoes.yaml b/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_userinfoes.yaml
index 7820dd44f8..180086a308 100644
--- a/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_userinfoes.yaml
+++ b/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_userinfoes.yaml
@@ -49,6 +49,11 @@ spec:
type: string
nullable: true
type: array
+ synchronize:
+ description: |-
+ DryRun indicates that modifications will definitely not be persisted for this request.
+ Defaults to false.
+ type: boolean
userInfo:
description: UserInfo is the userInfo carried in the admission request.
properties:
diff --git a/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_userinfoes.yaml b/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_userinfoes.yaml
index 7820dd44f8..180086a308 100644
--- a/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_userinfoes.yaml
+++ b/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_userinfoes.yaml
@@ -49,6 +49,11 @@ spec:
type: string
nullable: true
type: array
+ synchronize:
+ description: |-
+ DryRun indicates that modifications will definitely not be persisted for this request.
+ Defaults to false.
+ type: boolean
userInfo:
description: UserInfo is the userInfo carried in the admission request.
properties:
diff --git a/config/crds/kyverno/kyverno.io_updaterequests.yaml b/config/crds/kyverno/kyverno.io_updaterequests.yaml
index cf2f91d042..f12e5483db 100644
--- a/config/crds/kyverno/kyverno.io_updaterequests.yaml
+++ b/config/crds/kyverno/kyverno.io_updaterequests.yaml
@@ -654,6 +654,11 @@ spec:
type: string
nullable: true
type: array
+ synchronize:
+ description: |-
+ DryRun indicates that modifications will definitely not be persisted for this request.
+ Defaults to false.
+ type: boolean
userInfo:
description: UserInfo is the userInfo carried in the admission
request.
diff --git a/config/install-latest-testing.yaml b/config/install-latest-testing.yaml
index ebb9095376..aec1d2970a 100644
--- a/config/install-latest-testing.yaml
+++ b/config/install-latest-testing.yaml
@@ -48304,6 +48304,11 @@ spec:
type: string
nullable: true
type: array
+ synchronize:
+ description: |-
+ DryRun indicates that modifications will definitely not be persisted for this request.
+ Defaults to false.
+ type: boolean
userInfo:
description: UserInfo is the userInfo carried in the admission
request.
diff --git a/docs/user/crd/index.html b/docs/user/crd/index.html
index 70c10c58d8..a9861ab01c 100644
--- a/docs/user/crd/index.html
+++ b/docs/user/crd/index.html
@@ -6946,6 +6946,19 @@ Kubernetes authentication/v1.UserInfo
UserInfo is the userInfo carried in the admission request.
+
+
+synchronize
+
+bool
+
+ |
+
+(Optional)
+ DryRun indicates that modifications will definitely not be persisted for this request.
+Defaults to false.
+ |
+
diff --git a/docs/user/crd/kyverno.v2.html b/docs/user/crd/kyverno.v2.html
index 10e3e7c453..dc86a36855 100644
--- a/docs/user/crd/kyverno.v2.html
+++ b/docs/user/crd/kyverno.v2.html
@@ -2419,6 +2419,34 @@ Applicable only to policies that have validate.podSecurity subrule.
+
+
+
+ synchronize
+
+
+
+
+
+
+ bool
+
+
+ |
+
+
+
+ DryRun indicates that modifications will definitely not be persisted for this request.
+Defaults to false.
+
+
+
+
+
+ |
+
+
+
diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go
index 0dec3ebc49..a7471b9084 100644
--- a/pkg/engine/engine.go
+++ b/pkg/engine/engine.go
@@ -100,7 +100,7 @@ func (e *engine) Validate(
response = response.WithPolicyResponse(policyResponse)
}
response = response.WithStats(engineapi.NewExecutionStats(startTime, time.Now()))
- e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
+ e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), policyContext.AdmissionInfo(), response)
return response
}
@@ -118,7 +118,7 @@ func (e *engine) Mutate(
WithPolicyResponse(policyResponse)
}
response = response.WithStats(engineapi.NewExecutionStats(startTime, time.Now()))
- e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
+ e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), policyContext.AdmissionInfo(), response)
return response
}
@@ -134,7 +134,7 @@ func (e *engine) Generate(
response = response.WithPolicyResponse(policyResponse)
}
response = response.WithStats(engineapi.NewExecutionStats(startTime, time.Now()))
- e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
+ e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), policyContext.AdmissionInfo(), response)
return response
}
@@ -153,7 +153,7 @@ func (e *engine) VerifyAndPatchImages(
WithPatchedResource(patchedResource), innerIvm
}
response = response.WithStats(engineapi.NewExecutionStats(startTime, time.Now()))
- e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
+ e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), policyContext.AdmissionInfo(), response)
return response, ivm
}
@@ -169,7 +169,7 @@ func (e *engine) ApplyBackgroundChecks(
response = response.WithPolicyResponse(policyResponse)
}
response = response.WithStats(engineapi.NewExecutionStats(startTime, time.Now()))
- e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
+ e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), policyContext.AdmissionInfo(), response)
return response
}
diff --git a/pkg/engine/metrics.go b/pkg/engine/metrics.go
index 5357f91cf5..b2573e0706 100644
--- a/pkg/engine/metrics.go
+++ b/pkg/engine/metrics.go
@@ -2,10 +2,12 @@ package engine
import (
"context"
+ "strconv"
"strings"
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
+ kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/metrics"
"go.opentelemetry.io/otel/attribute"
@@ -17,6 +19,7 @@ func (e *engine) reportMetrics(
logger logr.Logger,
operation kyvernov1.AdmissionOperation,
admissionOperation bool,
+ admissionInfo kyvernov2.RequestInfo,
response engineapi.EngineResponse,
) {
if e.resultCounter == nil && e.durationHistogram == nil {
@@ -71,6 +74,7 @@ func (e *engine) reportMetrics(
attribute.String("rule_result", string(ruleResult)),
attribute.String("rule_type", string(ruleType)),
attribute.String("rule_execution_cause", string(executionCause)),
+ attribute.String("dry_run", strconv.FormatBool(admissionInfo.DryRun)),
}
e.resultCounter.Add(ctx, 1, metric.WithAttributes(commonLabels...))
}
@@ -88,6 +92,7 @@ func (e *engine) reportMetrics(
attribute.String("rule_result", string(ruleResult)),
attribute.String("rule_type", string(ruleType)),
attribute.String("rule_execution_cause", string(executionCause)),
+ attribute.String("dry_run", strconv.FormatBool(admissionInfo.DryRun)),
}
e.durationHistogram.Record(ctx, rule.Stats().ProcessingTime().Seconds(), metric.WithAttributes(commonLabels...))
}
diff --git a/pkg/webhooks/utils/policy_context_builder.go b/pkg/webhooks/utils/policy_context_builder.go
index d3d16b85d7..977a7b2c04 100644
--- a/pkg/webhooks/utils/policy_context_builder.go
+++ b/pkg/webhooks/utils/policy_context_builder.go
@@ -34,5 +34,9 @@ func (b *policyContextBuilder) Build(request admissionv1.AdmissionRequest, roles
Roles: roles,
ClusterRoles: clusterRoles,
}
+
+ if request.DryRun != nil {
+ userRequestInfo.DryRun = *request.DryRun
+ }
return engine.NewPolicyContextFromAdmissionRequest(b.jp, request, userRequestInfo, gvk, b.configuration)
}