1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00

feat:Webhook config per policy (#9483)

* add spec.webhookConfigurations

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* update crd

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* configure webhook

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* register webhook handler

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* skip storing finegrained policies in cache

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* update resource validate handler

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* updates

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* enable mutate resource handler for fine-grained policies

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* fix: tests

Signed-off-by: ShutingZhao <shuting@nirmata.com>

---------

Signed-off-by: ShutingZhao <shuting@nirmata.com>
This commit is contained in:
shuting 2024-01-27 21:00:22 +08:00 committed by GitHub
parent f4aba55e0a
commit 7170cbb0c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 1371 additions and 126 deletions

View file

@ -7,6 +7,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/variables/regex"
"github.com/sigstore/k8s-manifest-sigstore/pkg/k8smanifest"
admissionv1 "k8s.io/api/admission/v1"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
"k8s.io/api/admissionregistration/v1alpha1"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@ -49,6 +50,13 @@ const (
Descending ForeachOrder = "Descending"
)
// WebhookConfiguration specifies the configuration for Kubernetes admission webhookconfiguration.
type WebhookConfiguration struct {
// MatchCondition configures admission webhook matchConditions.
// +optional
MatchConditions []admissionregistrationv1.MatchCondition `json:"matchConditions,omitempty" yaml:"matchConditions,omitempty"`
}
// AnyAllConditions consists of conditions wrapped denoting a logical criteria to be fulfilled.
// AnyConditions get fulfilled when at least one of its sub-conditions passes.
// AllConditions get fulfilled only when all of its sub-conditions pass.

View file

@ -5,6 +5,7 @@ import (
"fmt"
"github.com/kyverno/kyverno/pkg/toggle"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field"
@ -121,6 +122,15 @@ type Spec struct {
// Defaults to "false" if not specified.
// +optional
UseServerSideApply bool `json:"useServerSideApply,omitempty" yaml:"useServerSideApply,omitempty"`
// WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
// Requires Kubernetes 1.27 or later.
// +optional
WebhookConfiguration *WebhookConfiguration `json:"webhookConfiguration,omitempty" yaml:"webhookConfiguration,omitempty"`
}
func (s *Spec) CustomWebhookConfiguration() bool {
return s.WebhookConfiguration != nil
}
func (s *Spec) SetRules(rules []Rule) {
@ -257,6 +267,14 @@ func (s *Spec) GetFailurePolicy(ctx context.Context) FailurePolicyType {
return *s.FailurePolicy
}
// GetMatchConditions returns matchConditions in webhookConfiguration
func (s *Spec) GetMatchConditions() []admissionregistrationv1.MatchCondition {
if s.WebhookConfiguration != nil {
return s.WebhookConfiguration.MatchConditions
}
return nil
}
// GetFailurePolicy returns the failure policy to be applied
func (s *Spec) GetApplyRules() ApplyRulesType {
if s.ApplyRules == nil {

View file

@ -23,6 +23,7 @@ package v1
import (
k8smanifest "github.com/sigstore/k8s-manifest-sigstore/pkg/k8smanifest"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
v1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
rbacv1 "k8s.io/api/rbac/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@ -1408,6 +1409,11 @@ func (in *Spec) DeepCopyInto(out *Spec) {
*out = new(bool)
**out = **in
}
if in.WebhookConfiguration != nil {
in, out := &in.WebhookConfiguration, &out.WebhookConfiguration
*out = new(WebhookConfiguration)
(*in).DeepCopyInto(*out)
}
return
}
@ -1632,3 +1638,24 @@ func (in *Variable) DeepCopy() *Variable {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WebhookConfiguration) DeepCopyInto(out *WebhookConfiguration) {
*out = *in
if in.MatchConditions != nil {
in, out := &in.MatchConditions, &out.MatchConditions
*out = make([]admissionregistrationv1.MatchCondition, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfiguration.
func (in *WebhookConfiguration) DeepCopy() *WebhookConfiguration {
if in == nil {
return nil
}
out := new(WebhookConfiguration)
in.DeepCopyInto(out)
return out
}

View file

@ -2,10 +2,18 @@ package v2beta1
import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
)
// WebhookConfiguration specifies the configuration for Kubernetes admission webhookconfiguration.
type WebhookConfiguration struct {
// MatchCondition configures admission webhook matchConditions.
// +optional
MatchConditions []admissionregistrationv1.MatchCondition `json:"matchConditions,omitempty" yaml:"matchConditions,omitempty"`
}
// Validation defines checks to be performed on matching resources.
type Validation struct {
// Message specifies a custom message to be displayed on failure.

View file

@ -82,6 +82,15 @@ type Spec struct {
// Defaults to "false" if not specified.
// +optional
UseServerSideApply bool `json:"useServerSideApply,omitempty" yaml:"useServerSideApply,omitempty"`
// WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
// Requires Kubernetes 1.27 or later.
// +optional
WebhookConfiguration *WebhookConfiguration `json:"webhookConfiguration,omitempty" yaml:"webhookConfiguration,omitempty"`
}
func (s *Spec) CustomWebhookConfiguration() bool {
return s.WebhookConfiguration != nil
}
func (s *Spec) SetRules(rules []Rule) {

View file

@ -810,6 +810,11 @@ func (in *Spec) DeepCopyInto(out *Spec) {
*out = new(bool)
**out = **in
}
if in.WebhookConfiguration != nil {
in, out := &in.WebhookConfiguration, &out.WebhookConfiguration
*out = new(WebhookConfiguration)
(*in).DeepCopyInto(*out)
}
return
}
@ -875,3 +880,24 @@ func (in *Validation) DeepCopy() *Validation {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WebhookConfiguration) DeepCopyInto(out *WebhookConfiguration) {
*out = *in
if in.MatchConditions != nil {
in, out := &in.MatchConditions, &out.MatchConditions
*out = make([]admissionregistrationv1.MatchCondition, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfiguration.
func (in *WebhookConfiguration) DeepCopy() *WebhookConfiguration {
if in == nil {
return nil
}
out := new(WebhookConfiguration)
in.DeepCopyInto(out)
return out
}

View file

@ -14420,6 +14420,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -23196,6 +23242,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -32272,6 +32364,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -41050,6 +41188,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,

View file

@ -4469,6 +4469,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -13245,6 +13291,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,

View file

@ -4470,6 +4470,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -13248,6 +13294,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,

View file

@ -4469,6 +4469,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -13245,6 +13291,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,

View file

@ -4470,6 +4470,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -13248,6 +13294,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,

View file

@ -14639,6 +14639,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -23415,6 +23461,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -32493,6 +32585,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,
@ -41271,6 +41409,52 @@ spec:
type: array
type: object
type: array
webhookConfiguration:
description: WebhookConfiguration specifies the custom configuration
for Kubernetes admission webhookconfiguration. Requires Kubernetes
1.27 or later.
properties:
matchConditions:
description: MatchCondition configures admission webhook matchConditions.
items:
description: MatchCondition represents a condition which must
by fulfilled for a request to be sent to a webhook.
properties:
expression:
description: "Expression represents the expression which
will be evaluated by CEL. Must evaluate to bool. CEL expressions
have access to the contents of the AdmissionRequest and
Authorizer, organized into CEL variables: \n 'object'
- The object from the incoming request. The value is null
for DELETE requests. 'oldObject' - The existing object.
The value is null for CREATE requests. 'request' - Attributes
of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
'authorizer' - A CEL Authorizer. May be used to perform
authorization checks for the principal (user or service
account) of the request. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
'authorizer.requestResource' - A CEL ResourceCheck constructed
from the 'authorizer' and configured with the request
resource. Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
\n Required."
type: string
name:
description: "Name is an identifier for this match condition,
used for strategic merging of MatchConditions, as well
as providing an identifier for logging purposes. A good
name should be descriptive of the associated expression.
Name must be a qualified name consisting of alphanumeric
characters, '-', '_' or '.', and must start and end with
an alphanumeric character (e.g. 'MyName', or 'my.name',
\ or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')
with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
\n Required."
type: string
required:
- expression
- name
type: object
type: array
type: object
webhookTimeoutSeconds:
description: WebhookTimeoutSeconds specifies the maximum time in seconds
allowed to apply this policy. After the configured time expires,

View file

@ -293,6 +293,21 @@ If is set to &ldquo;true&rdquo; create &amp; update for generate rules will use
Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>webhookConfiguration</code><br/>
<em>
<a href="#kyverno.io/v1.WebhookConfiguration">
WebhookConfiguration
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
Requires Kubernetes 1.27 or later.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -556,6 +571,21 @@ If is set to &ldquo;true&rdquo; create &amp; update for generate rules will use
Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>webhookConfiguration</code><br/>
<em>
<a href="#kyverno.io/v1.WebhookConfiguration">
WebhookConfiguration
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
Requires Kubernetes 1.27 or later.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -3910,6 +3940,21 @@ If is set to &ldquo;true&rdquo; create &amp; update for generate rules will use
Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>webhookConfiguration</code><br/>
<em>
<a href="#kyverno.io/v1.WebhookConfiguration">
WebhookConfiguration
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
Requires Kubernetes 1.27 or later.</p>
</td>
</tr>
</tbody>
</table>
<hr />
@ -4441,6 +4486,40 @@ expression evaluates to nil</p>
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v1.WebhookConfiguration">WebhookConfiguration
</h3>
<p>
(<em>Appears on:</em>
<a href="#kyverno.io/v1.Spec">Spec</a>)
</p>
<p>
<p>WebhookConfiguration specifies the configuration for Kubernetes admission webhookconfiguration.</p>
</p>
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>matchConditions</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#matchcondition-v1-admissionregistration">
[]Kubernetes admissionregistration/v1.MatchCondition
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>MatchCondition configures admission webhook matchConditions.</p>
</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="kyverno.io/v1alpha2">kyverno.io/v1alpha2</h2>
<p>
<p>Package v1alpha2 contains API Schema definitions for the policy v1alpha2 API group</p>
@ -8288,6 +8367,21 @@ If is set to &ldquo;true&rdquo; create &amp; update for generate rules will use
Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>webhookConfiguration</code><br/>
<em>
<a href="#kyverno.io/v2beta1.WebhookConfiguration">
WebhookConfiguration
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
Requires Kubernetes 1.27 or later.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -8550,6 +8644,21 @@ If is set to &ldquo;true&rdquo; create &amp; update for generate rules will use
Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>webhookConfiguration</code><br/>
<em>
<a href="#kyverno.io/v2beta1.WebhookConfiguration">
WebhookConfiguration
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
Requires Kubernetes 1.27 or later.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -9932,6 +10041,21 @@ If is set to &ldquo;true&rdquo; create &amp; update for generate rules will use
Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>webhookConfiguration</code><br/>
<em>
<a href="#kyverno.io/v2beta1.WebhookConfiguration">
WebhookConfiguration
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
Requires Kubernetes 1.27 or later.</p>
</td>
</tr>
</tbody>
</table>
<hr />
@ -10067,6 +10191,40 @@ CEL
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v2beta1.WebhookConfiguration">WebhookConfiguration
</h3>
<p>
(<em>Appears on:</em>
<a href="#kyverno.io/v2beta1.Spec">Spec</a>)
</p>
<p>
<p>WebhookConfiguration specifies the configuration for Kubernetes admission webhookconfiguration.</p>
</p>
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>matchConditions</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#matchcondition-v1-admissionregistration">
[]Kubernetes admissionregistration/v1.MatchCondition
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>MatchCondition configures admission webhook matchConditions.</p>
</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="reports.kyverno.io/v1">reports.kyverno.io/v1</h2>
<p>
</p>

View file

@ -38,6 +38,7 @@ type SpecApplyConfiguration struct {
GenerateExistingOnPolicyUpdate *bool `json:"generateExistingOnPolicyUpdate,omitempty"`
GenerateExisting *bool `json:"generateExisting,omitempty"`
UseServerSideApply *bool `json:"useServerSideApply,omitempty"`
WebhookConfiguration *WebhookConfigurationApplyConfiguration `json:"webhookConfiguration,omitempty"`
}
// SpecApplyConfiguration constructs an declarative configuration of the Spec type for use with
@ -159,3 +160,11 @@ func (b *SpecApplyConfiguration) WithUseServerSideApply(value bool) *SpecApplyCo
b.UseServerSideApply = &value
return b
}
// WithWebhookConfiguration sets the WebhookConfiguration field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the WebhookConfiguration field is set to the value of the last call.
func (b *SpecApplyConfiguration) WithWebhookConfiguration(value *WebhookConfigurationApplyConfiguration) *SpecApplyConfiguration {
b.WebhookConfiguration = value
return b
}

View file

@ -0,0 +1,45 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by applyconfiguration-gen. DO NOT EDIT.
package v1
import (
v1 "k8s.io/api/admissionregistration/v1"
)
// WebhookConfigurationApplyConfiguration represents an declarative configuration of the WebhookConfiguration type for use
// with apply.
type WebhookConfigurationApplyConfiguration struct {
MatchConditions []v1.MatchCondition `json:"matchConditions,omitempty"`
}
// WebhookConfigurationApplyConfiguration constructs an declarative configuration of the WebhookConfiguration type for use with
// apply.
func WebhookConfiguration() *WebhookConfigurationApplyConfiguration {
return &WebhookConfigurationApplyConfiguration{}
}
// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the MatchConditions field.
func (b *WebhookConfigurationApplyConfiguration) WithMatchConditions(values ...v1.MatchCondition) *WebhookConfigurationApplyConfiguration {
for i := range values {
b.MatchConditions = append(b.MatchConditions, values[i])
}
return b
}

View file

@ -39,6 +39,7 @@ type SpecApplyConfiguration struct {
GenerateExistingOnPolicyUpdate *bool `json:"generateExistingOnPolicyUpdate,omitempty"`
GenerateExisting *bool `json:"generateExisting,omitempty"`
UseServerSideApply *bool `json:"useServerSideApply,omitempty"`
WebhookConfiguration *WebhookConfigurationApplyConfiguration `json:"webhookConfiguration,omitempty"`
}
// SpecApplyConfiguration constructs an declarative configuration of the Spec type for use with
@ -160,3 +161,11 @@ func (b *SpecApplyConfiguration) WithUseServerSideApply(value bool) *SpecApplyCo
b.UseServerSideApply = &value
return b
}
// WithWebhookConfiguration sets the WebhookConfiguration field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the WebhookConfiguration field is set to the value of the last call.
func (b *SpecApplyConfiguration) WithWebhookConfiguration(value *WebhookConfigurationApplyConfiguration) *SpecApplyConfiguration {
b.WebhookConfiguration = value
return b
}

View file

@ -0,0 +1,45 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by applyconfiguration-gen. DO NOT EDIT.
package v2beta1
import (
v1 "k8s.io/api/admissionregistration/v1"
)
// WebhookConfigurationApplyConfiguration represents an declarative configuration of the WebhookConfiguration type for use
// with apply.
type WebhookConfigurationApplyConfiguration struct {
MatchConditions []v1.MatchCondition `json:"matchConditions,omitempty"`
}
// WebhookConfigurationApplyConfiguration constructs an declarative configuration of the WebhookConfiguration type for use with
// apply.
func WebhookConfiguration() *WebhookConfigurationApplyConfiguration {
return &WebhookConfigurationApplyConfiguration{}
}
// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the MatchConditions field.
func (b *WebhookConfigurationApplyConfiguration) WithMatchConditions(values ...v1.MatchCondition) *WebhookConfigurationApplyConfiguration {
for i := range values {
b.MatchConditions = append(b.MatchConditions, values[i])
}
return b
}

View file

@ -143,6 +143,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &kyvernov1.ValidationFailureActionOverrideApplyConfiguration{}
case v1.SchemeGroupVersion.WithKind("Variable"):
return &kyvernov1.VariableApplyConfiguration{}
case v1.SchemeGroupVersion.WithKind("WebhookConfiguration"):
return &kyvernov1.WebhookConfigurationApplyConfiguration{}
// Group=kyverno.io, Version=v1alpha2
case v1alpha2.SchemeGroupVersion.WithKind("AdmissionReport"):
@ -257,6 +259,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &kyvernov2beta1.SpecApplyConfiguration{}
case v2beta1.SchemeGroupVersion.WithKind("Validation"):
return &kyvernov2beta1.ValidationApplyConfiguration{}
case v2beta1.SchemeGroupVersion.WithKind("WebhookConfiguration"):
return &kyvernov2beta1.WebhookConfigurationApplyConfiguration{}
// Group=reports.kyverno.io, Version=v1
case reportsv1.SchemeGroupVersion.WithKind("AdmissionReport"):

View file

@ -74,6 +74,8 @@ const (
ReadinessServicePath = "/health/readiness"
// MetricsPath is the path for exposing metrics
MetricsPath = "/metrics"
// FineGrainedWebhookPath is the sub-path for fine-grained webhook configurationss
FineGrainedWebhookPath = "/finegrained"
)
// keys in config map

View file

@ -103,7 +103,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
}
return err
}
if policy.AdmissionProcessingEnabled() {
if policy.AdmissionProcessingEnabled() && !policy.GetSpec().CustomWebhookConfiguration() {
return c.cache.Set(key, policy, c.client.Discovery())
} else {
c.cache.Unset(key)

View file

@ -634,74 +634,85 @@ func (c *controller) buildResourceMutatingWebhookConfiguration(ctx context.Conte
Webhooks: []admissionregistrationv1.MutatingWebhook{},
}
if c.watchdogCheck() {
ignore := newWebhook(c.defaultTimeout, ignore)
fail := newWebhook(c.defaultTimeout, fail)
policies, err := c.getAllPolicies()
if err != nil {
return nil, err
}
c.recordPolicyState(config.MutatingWebhookConfigurationName, policies...)
for _, p := range policies {
if p.AdmissionProcessingEnabled() {
spec := p.GetSpec()
if spec.HasMutateStandard() || spec.HasVerifyImages() {
if spec.GetFailurePolicy(ctx) == kyvernov1.Ignore {
c.mergeWebhook(ignore, p, false)
} else {
c.mergeWebhook(fail, p, false)
}
}
}
}
webhookCfg := config.WebhookConfig{}
webhookCfgs := cfg.GetWebhooks()
if len(webhookCfgs) > 0 {
webhookCfg = webhookCfgs[0]
}
if !ignore.isEmpty() {
timeout := capTimeout(ignore.maxWebhookTimeout)
result.Webhooks = append(
result.Webhooks,
admissionregistrationv1.MutatingWebhook{
Name: config.MutatingWebhookName + "-ignore",
ClientConfig: c.clientConfig(caBundle, config.MutatingWebhookServicePath+"/ignore"),
Rules: ignore.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update),
FailurePolicy: &ignore.failurePolicy,
SideEffects: &noneOnDryRun,
AdmissionReviewVersions: []string{"v1"},
NamespaceSelector: webhookCfg.NamespaceSelector,
ObjectSelector: webhookCfg.ObjectSelector,
TimeoutSeconds: &timeout,
ReinvocationPolicy: &ifNeeded,
MatchConditions: cfg.GetMatchConditions(),
},
)
ignoreWebhook := newWebhook(c.defaultTimeout, ignore, cfg.GetMatchConditions())
failWebhook := newWebhook(c.defaultTimeout, fail, cfg.GetMatchConditions())
policies, err := c.getAllPolicies()
if err != nil {
return nil, err
}
if !fail.isEmpty() {
timeout := capTimeout(fail.maxWebhookTimeout)
result.Webhooks = append(
result.Webhooks,
admissionregistrationv1.MutatingWebhook{
Name: config.MutatingWebhookName + "-fail",
ClientConfig: c.clientConfig(caBundle, config.MutatingWebhookServicePath+"/fail"),
Rules: fail.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update),
FailurePolicy: &fail.failurePolicy,
SideEffects: &noneOnDryRun,
AdmissionReviewVersions: []string{"v1"},
NamespaceSelector: webhookCfg.NamespaceSelector,
ObjectSelector: webhookCfg.ObjectSelector,
TimeoutSeconds: &timeout,
ReinvocationPolicy: &ifNeeded,
MatchConditions: cfg.GetMatchConditions(),
},
)
var fineGrainedIgnoreList, fineGrainedFailList []*webhook
c.recordPolicyState(config.MutatingWebhookConfigurationName, policies...)
for _, p := range policies {
if p.AdmissionProcessingEnabled() {
spec := p.GetSpec()
if spec.HasMutateStandard() || spec.HasVerifyImages() {
if spec.CustomWebhookConfiguration() {
fineGrainedIgnore := newWebhookPerPolicy(c.defaultTimeout, ignore, cfg.GetMatchConditions(), p)
fineGrainedFail := newWebhookPerPolicy(c.defaultTimeout, fail, cfg.GetMatchConditions(), p)
if spec.GetFailurePolicy(ctx) == kyvernov1.Ignore {
c.mergeWebhook(fineGrainedIgnore, p, false)
fineGrainedIgnoreList = append(fineGrainedIgnoreList, fineGrainedIgnore)
} else {
c.mergeWebhook(fineGrainedFail, p, false)
fineGrainedFailList = append(fineGrainedFailList, fineGrainedFail)
}
continue
}
if spec.GetFailurePolicy(ctx) == kyvernov1.Ignore {
c.mergeWebhook(ignoreWebhook, p, false)
} else {
c.mergeWebhook(failWebhook, p, false)
}
}
}
}
webhooks := []*webhook{ignoreWebhook, failWebhook}
webhooks = append(webhooks, fineGrainedIgnoreList...)
webhooks = append(webhooks, fineGrainedFailList...)
result.Webhooks = c.buildResourceMutatingWebhookRules(caBundle, webhookCfg, &noneOnDryRun, webhooks)
} else {
c.recordPolicyState(config.MutatingWebhookConfigurationName)
}
return &result, nil
}
func (c *controller) buildResourceMutatingWebhookRules(caBundle []byte, webhookCfg config.WebhookConfig, sideEffects *admissionregistrationv1.SideEffectClass, webhooks []*webhook) []admissionregistrationv1.MutatingWebhook {
var mutatingWebhooks []admissionregistrationv1.MutatingWebhook
for _, webhook := range webhooks {
if webhook.isEmpty() {
continue
}
failurePolicy := webhook.failurePolicy
timeout := capTimeout(webhook.maxWebhookTimeout)
name, path := webhookNameAndPath(*webhook, config.MutatingWebhookName, config.MutatingWebhookServicePath)
mutatingWebhooks = append(
mutatingWebhooks,
admissionregistrationv1.MutatingWebhook{
Name: name,
ClientConfig: c.clientConfig(caBundle, path),
Rules: webhook.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update),
FailurePolicy: &failurePolicy,
SideEffects: sideEffects,
AdmissionReviewVersions: []string{"v1"},
NamespaceSelector: webhookCfg.NamespaceSelector,
ObjectSelector: webhookCfg.ObjectSelector,
TimeoutSeconds: &timeout,
ReinvocationPolicy: &ifNeeded,
MatchConditions: webhook.matchConditions,
},
)
}
return mutatingWebhooks
}
func (c *controller) buildDefaultResourceValidatingWebhookConfiguration(_ context.Context, cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.ValidatingWebhookConfiguration, error) {
sideEffects := &none
if c.admissionReports {
@ -760,76 +771,90 @@ func (c *controller) buildResourceValidatingWebhookConfiguration(ctx context.Con
Webhooks: []admissionregistrationv1.ValidatingWebhook{},
}
if c.watchdogCheck() {
ignore := newWebhook(c.defaultTimeout, ignore)
fail := newWebhook(c.defaultTimeout, fail)
policies, err := c.getAllPolicies()
if err != nil {
return nil, err
}
c.recordPolicyState(config.ValidatingWebhookConfigurationName, policies...)
for _, p := range policies {
if p.AdmissionProcessingEnabled() {
spec := p.GetSpec()
if spec.HasValidate() || spec.HasGenerate() || spec.HasMutateExisting() || spec.HasVerifyImageChecks() || spec.HasVerifyManifests() {
if spec.GetFailurePolicy(ctx) == kyvernov1.Ignore {
c.mergeWebhook(ignore, p, true)
} else {
c.mergeWebhook(fail, p, true)
}
}
}
}
webhookCfg := config.WebhookConfig{}
webhookCfgs := cfg.GetWebhooks()
if len(webhookCfgs) > 0 {
webhookCfg = webhookCfgs[0]
}
ignoreWebhook := newWebhook(c.defaultTimeout, ignore, cfg.GetMatchConditions())
failWebhook := newWebhook(c.defaultTimeout, fail, cfg.GetMatchConditions())
policies, err := c.getAllPolicies()
if err != nil {
return nil, err
}
var fineGrainedIgnoreList, fineGrainedFailList []*webhook
c.recordPolicyState(config.ValidatingWebhookConfigurationName, policies...)
for _, p := range policies {
if p.AdmissionProcessingEnabled() {
spec := p.GetSpec()
if spec.HasValidate() || spec.HasGenerate() || spec.HasMutateExisting() || spec.HasVerifyImageChecks() || spec.HasVerifyManifests() {
if spec.CustomWebhookConfiguration() {
fineGrainedIgnore := newWebhookPerPolicy(c.defaultTimeout, ignore, cfg.GetMatchConditions(), p)
fineGrainedFail := newWebhookPerPolicy(c.defaultTimeout, fail, cfg.GetMatchConditions(), p)
if spec.GetFailurePolicy(ctx) == kyvernov1.Ignore {
c.mergeWebhook(fineGrainedIgnore, p, true)
fineGrainedIgnoreList = append(fineGrainedIgnoreList, fineGrainedIgnore)
} else {
c.mergeWebhook(fineGrainedFail, p, true)
fineGrainedFailList = append(fineGrainedFailList, fineGrainedFail)
}
continue
}
if spec.GetFailurePolicy(ctx) == kyvernov1.Ignore {
c.mergeWebhook(ignoreWebhook, p, true)
} else {
c.mergeWebhook(failWebhook, p, true)
}
}
}
}
sideEffects := &none
if c.admissionReports {
sideEffects = &noneOnDryRun
}
if !ignore.isEmpty() {
timeout := capTimeout(ignore.maxWebhookTimeout)
result.Webhooks = append(
result.Webhooks,
admissionregistrationv1.ValidatingWebhook{
Name: config.ValidatingWebhookName + "-ignore",
ClientConfig: c.clientConfig(caBundle, config.ValidatingWebhookServicePath+"/ignore"),
Rules: ignore.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update, admissionregistrationv1.Delete, admissionregistrationv1.Connect),
FailurePolicy: &ignore.failurePolicy,
SideEffects: sideEffects,
AdmissionReviewVersions: []string{"v1"},
NamespaceSelector: webhookCfg.NamespaceSelector,
ObjectSelector: webhookCfg.ObjectSelector,
TimeoutSeconds: &timeout,
MatchConditions: cfg.GetMatchConditions(),
},
)
}
if !fail.isEmpty() {
timeout := capTimeout(fail.maxWebhookTimeout)
result.Webhooks = append(
result.Webhooks,
admissionregistrationv1.ValidatingWebhook{
Name: config.ValidatingWebhookName + "-fail",
ClientConfig: c.clientConfig(caBundle, config.ValidatingWebhookServicePath+"/fail"),
Rules: fail.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update, admissionregistrationv1.Delete, admissionregistrationv1.Connect),
FailurePolicy: &fail.failurePolicy,
SideEffects: sideEffects,
AdmissionReviewVersions: []string{"v1"},
NamespaceSelector: webhookCfg.NamespaceSelector,
ObjectSelector: webhookCfg.ObjectSelector,
TimeoutSeconds: &timeout,
MatchConditions: cfg.GetMatchConditions(),
},
)
}
webhooks := []*webhook{ignoreWebhook, failWebhook}
webhooks = append(webhooks, fineGrainedIgnoreList...)
webhooks = append(webhooks, fineGrainedFailList...)
result.Webhooks = c.buildResourceValidatingWebhookRules(caBundle, webhookCfg, sideEffects, webhooks)
} else {
c.recordPolicyState(config.MutatingWebhookConfigurationName)
}
return &result, nil
}
func (c *controller) buildResourceValidatingWebhookRules(caBundle []byte, webhookCfg config.WebhookConfig, sideEffects *admissionregistrationv1.SideEffectClass, webhooks []*webhook) []admissionregistrationv1.ValidatingWebhook {
var validatingWebhooks []admissionregistrationv1.ValidatingWebhook
for _, webhook := range webhooks {
if webhook.isEmpty() {
continue
}
timeout := capTimeout(webhook.maxWebhookTimeout)
name, path := webhookNameAndPath(*webhook, config.ValidatingWebhookName, config.ValidatingWebhookServicePath)
failurePolicy := webhook.failurePolicy
validatingWebhooks = append(
validatingWebhooks,
admissionregistrationv1.ValidatingWebhook{
Name: name,
ClientConfig: c.clientConfig(caBundle, path),
Rules: webhook.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update, admissionregistrationv1.Delete, admissionregistrationv1.Connect),
FailurePolicy: &failurePolicy,
SideEffects: sideEffects,
AdmissionReviewVersions: []string{"v1"},
NamespaceSelector: webhookCfg.NamespaceSelector,
ObjectSelector: webhookCfg.ObjectSelector,
TimeoutSeconds: &timeout,
MatchConditions: webhook.matchConditions,
},
)
}
return validatingWebhooks
}
func (c *controller) getAllPolicies() ([]kyvernov1.PolicyInterface, error) {
var policies []kyvernov1.PolicyInterface
if cpols, err := c.cpolLister.List(labels.Everything()); err != nil {

View file

@ -7,20 +7,27 @@ import (
"github.com/kyverno/kyverno/api/kyverno"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/config"
"golang.org/x/exp/maps"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
objectmeta "k8s.io/client-go/tools/cache"
"k8s.io/utils/ptr"
)
// webhook is the instance that aggregates the GVK of existing policies
// based on group, kind, scopeType, failurePolicy and webhookTimeout
// a fine-grained webhook is created per policy with a unique path
type webhook struct {
// policyMeta is set for fine-grained webhooks
policyMeta objectmeta.ObjectName
maxWebhookTimeout int32
failurePolicy admissionregistrationv1.FailurePolicyType
rules map[groupVersionScope]sets.Set[string]
matchConditions []admissionregistrationv1.MatchCondition
}
// groupVersionScope contains the GV and scopeType of a resource
@ -34,14 +41,27 @@ func (gvs groupVersionScope) String() string {
return gvs.GroupVersion.String() + "/" + string(gvs.scopeType)
}
func newWebhook(timeout int32, failurePolicy admissionregistrationv1.FailurePolicyType) *webhook {
func newWebhook(timeout int32, failurePolicy admissionregistrationv1.FailurePolicyType, matchConditions []admissionregistrationv1.MatchCondition) *webhook {
return &webhook{
maxWebhookTimeout: timeout,
failurePolicy: failurePolicy,
rules: map[groupVersionScope]sets.Set[string]{},
matchConditions: matchConditions,
}
}
func newWebhookPerPolicy(timeout int32, failurePolicy admissionregistrationv1.FailurePolicyType, matchConditions []admissionregistrationv1.MatchCondition, policy kyvernov1.PolicyInterface) *webhook {
webhook := newWebhook(timeout, failurePolicy, matchConditions)
webhook.policyMeta = objectmeta.ObjectName{
Namespace: policy.GetNamespace(),
Name: policy.GetName(),
}
if policy.GetSpec().CustomWebhookConfiguration() {
webhook.matchConditions = policy.GetSpec().GetMatchConditions()
}
return webhook
}
func (wh *webhook) buildRulesWithOperations(ops ...admissionregistrationv1.OperationType) []admissionregistrationv1.RuleWithOperations {
var rules []admissionregistrationv1.RuleWithOperations
@ -122,6 +142,14 @@ func (wh *webhook) isEmpty() bool {
return len(wh.rules) == 0
}
func (wh *webhook) key(separator string) string {
p := wh.policyMeta
if p.Namespace != "" {
return p.Namespace + separator + p.Name
}
return p.Name
}
func objectMeta(name string, annotations map[string]string, labels map[string]string, owner ...metav1.OwnerReference) metav1.ObjectMeta {
desiredLabels := make(map[string]string)
defaultLabels := map[string]string{
@ -167,3 +195,18 @@ func capTimeout(maxWebhookTimeout int32) int32 {
}
return maxWebhookTimeout
}
func webhookNameAndPath(wh webhook, baseName, basePath string) (name string, path string) {
if wh.failurePolicy == ignore {
name = baseName + "-ignore"
path = basePath + "/ignore"
} else {
name = baseName + "-fail"
path = basePath + "/fail"
}
if wh.policyMeta.Name != "" {
name = name + "-finegrained-" + wh.key("-")
path = path + config.FineGrainedWebhookPath + "/" + wh.key("/")
}
return name, path
}

View file

@ -12,9 +12,9 @@ import (
)
func Test_webhook_isEmpty(t *testing.T) {
empty := newWebhook(DefaultWebhookTimeout, admissionregistrationv1.Ignore)
empty := newWebhook(DefaultWebhookTimeout, admissionregistrationv1.Ignore, []admissionregistrationv1.MatchCondition{})
assert.Equal(t, empty.isEmpty(), true)
notEmpty := newWebhook(DefaultWebhookTimeout, admissionregistrationv1.Ignore)
notEmpty := newWebhook(DefaultWebhookTimeout, admissionregistrationv1.Ignore, []admissionregistrationv1.MatchCondition{})
notEmpty.set(GroupVersionResourceScope{
GroupVersionResource: schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"},
Scope: admissionregistrationv1.NamespacedScope,

View file

@ -123,6 +123,10 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
spec := policy.GetSpec()
background := spec.BackgroundProcessingEnabled()
mutateExistingOnPolicyUpdate := spec.GetMutateExistingOnPolicyUpdate()
if policy.GetSpec().CustomWebhookConfiguration() &&
!kubeutils.HigherThanKubernetesVersion(client.GetKubeClient().Discovery(), logging.GlobalLogger(), 1, 27, 0) {
return warnings, fmt.Errorf("custom webhook configurations are only supported in kubernetes version 1.27.0 and above")
}
warnings = append(warnings, checkValidationFailureAction(spec)...)
var errs field.ErrorList

View file

@ -8,6 +8,7 @@ import (
"time"
"github.com/go-logr/logr"
"github.com/julienschmidt/httprouter"
admissionv1 "k8s.io/api/admission/v1"
)
@ -47,8 +48,11 @@ func (inner AdmissionHandler) withAdmission(logger logr.Logger) HttpHandler {
"uid", admissionReview.Request.UID,
"user", admissionReview.Request.UserInfo,
)
params := httprouter.ParamsFromContext(request.Context())
admissionRequest := AdmissionRequest{
AdmissionRequest: *admissionReview.Request,
URLParams: params.ByName("policy"),
}
admissionResponse := inner(request.Context(), logger, admissionRequest, startTime)
admissionReview.Response = &admissionResponse

View file

@ -23,6 +23,8 @@ type AdmissionRequest struct {
// GroupVersionKind is the top level GVK.
GroupVersionKind schema.GroupVersionKind
URLParams string
}
type AdmissionResponse = admissionv1.AdmissionResponse

View file

@ -3,6 +3,8 @@ package resource
import (
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/go-logr/logr"
@ -101,16 +103,13 @@ func NewHandlers(
func (h *resourceHandlers) Validate(ctx context.Context, logger logr.Logger, request handlers.AdmissionRequest, failurePolicy string, startTime time.Time) handlers.AdmissionResponse {
kind := request.Kind.Kind
logger = logger.WithValues("kind", kind)
logger = logger.WithValues("kind", kind).WithValues("URLParams", request.URLParams)
logger.V(4).Info("received an admission request in validating webhook")
// timestamp at which this admission request got triggered
gvr := schema.GroupVersionResource(request.Resource)
policies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.ValidateEnforce, gvr, request.SubResource, request.Namespace)...)
mutatePolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.Mutate, gvr, request.SubResource, request.Namespace)...)
generatePolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.Generate, gvr, request.SubResource, request.Namespace)...)
imageVerifyValidatePolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.VerifyImagesValidate, gvr, request.SubResource, request.Namespace)...)
policies = append(policies, imageVerifyValidatePolicies...)
policies, mutatePolicies, generatePolicies, _, err := h.retrieveAndCategorizePolicies(ctx, logger, request, failurePolicy, false)
if err != nil {
return errorResponse(logger, request.UID, err, "failed to fetch policy with key")
}
if len(policies) == 0 && len(mutatePolicies) == 0 && len(generatePolicies) == 0 {
logger.V(4).Info("no policies matched admission request")
@ -143,11 +142,13 @@ func (h *resourceHandlers) Validate(ctx context.Context, logger logr.Logger, req
func (h *resourceHandlers) Mutate(ctx context.Context, logger logr.Logger, request handlers.AdmissionRequest, failurePolicy string, startTime time.Time) handlers.AdmissionResponse {
kind := request.Kind.Kind
logger = logger.WithValues("kind", kind)
logger = logger.WithValues("kind", kind).WithValues("URLParams", request.URLParams)
logger.V(4).Info("received an admission request in mutating webhook")
gvr := schema.GroupVersionResource(request.Resource)
mutatePolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.Mutate, gvr, request.SubResource, request.Namespace)...)
verifyImagesPolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.VerifyImagesMutate, gvr, request.SubResource, request.Namespace)...)
_, mutatePolicies, _, verifyImagesPolicies, err := h.retrieveAndCategorizePolicies(ctx, logger, request, failurePolicy, true)
if err != nil {
return errorResponse(logger, request.UID, err, "failed to fetch policy with key")
}
if len(mutatePolicies) == 0 && len(verifyImagesPolicies) == 0 {
logger.V(4).Info("no policies matched mutate admission request")
return admissionutils.ResponseSuccess(request.UID)
@ -184,6 +185,66 @@ func (h *resourceHandlers) Mutate(ctx context.Context, logger logr.Logger, reque
return admissionutils.MutationResponse(request.UID, patch, warnings...)
}
func (h *resourceHandlers) retrieveAndCategorizePolicies(
ctx context.Context, logger logr.Logger, request handlers.AdmissionRequest, failurePolicy string, mutation bool) (
[]kyvernov1.PolicyInterface, []kyvernov1.PolicyInterface, []kyvernov1.PolicyInterface, []kyvernov1.PolicyInterface, error,
) {
var policies, mutatePolicies, generatePolicies, imageVerifyValidatePolicies []kyvernov1.PolicyInterface
if request.URLParams == "" {
gvr := schema.GroupVersionResource(request.Resource)
policies = filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.ValidateEnforce, gvr, request.SubResource, request.Namespace)...)
mutatePolicies = filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.Mutate, gvr, request.SubResource, request.Namespace)...)
generatePolicies = filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.Generate, gvr, request.SubResource, request.Namespace)...)
if mutation {
imageVerifyValidatePolicies = filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.VerifyImagesMutate, gvr, request.SubResource, request.Namespace)...)
} else {
imageVerifyValidatePolicies = filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.VerifyImagesValidate, gvr, request.SubResource, request.Namespace)...)
policies = append(policies, imageVerifyValidatePolicies...)
}
} else {
meta := strings.Split(request.URLParams, "/")
polName := meta[1]
polNamespace := ""
if len(meta) >= 3 {
polNamespace = meta[1]
polName = meta[2]
}
var policy kyvernov1.PolicyInterface
var err error
if polNamespace == "" {
policy, err = h.cpolLister.Get(polName)
} else {
policy, err = h.polLister.Policies(polNamespace).Get(polName)
}
if err != nil {
return nil, nil, nil, nil, fmt.Errorf("key %s/%s: %v", polNamespace, polName, err)
}
filteredPolicies := filterPolicies(ctx, failurePolicy, policy)
if len(filteredPolicies) == 0 {
logger.V(4).Info("no policy found with key", "namespace", polNamespace, "name", polName)
return nil, nil, nil, nil, nil
}
policy = filteredPolicies[0]
spec := policy.GetSpec()
if spec.HasValidate() {
policies = append(policies, policy)
}
if spec.HasGenerate() {
generatePolicies = append(generatePolicies, policy)
}
if spec.HasMutate() {
mutatePolicies = append(mutatePolicies, policy)
}
if spec.HasVerifyImages() {
policies = append(policies, policy)
}
}
return policies, mutatePolicies, generatePolicies, imageVerifyValidatePolicies, nil
}
func filterPolicies(ctx context.Context, failurePolicy string, policies ...kyvernov1.PolicyInterface) []kyvernov1.PolicyInterface {
var results []kyvernov1.PolicyInterface
for _, policy := range policies {

View file

@ -285,4 +285,6 @@ func registerWebhookHandlers(
mux.HandlerFunc("POST", basePath, builder(all).ToHandlerFunc(name))
mux.HandlerFunc("POST", basePath+"/ignore", builder(ignore).ToHandlerFunc(name))
mux.HandlerFunc("POST", basePath+"/fail", builder(fail).ToHandlerFunc(name))
mux.HandlerFunc("POST", basePath+"/ignore"+config.FineGrainedWebhookPath+"/*policy", builder(ignore).ToHandlerFunc(name))
mux.HandlerFunc("POST", basePath+"/fail"+config.FineGrainedWebhookPath+"/*policy", builder(fail).ToHandlerFunc(name))
}