mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +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:
parent
f4aba55e0a
commit
7170cbb0c2
28 changed files with 1371 additions and 126 deletions
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -293,6 +293,21 @@ If is set to “true” create & update for generate rules will use
|
|||
Defaults to “false” 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 “true” create & update for generate rules will use
|
|||
Defaults to “false” 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 “true” create & update for generate rules will use
|
|||
Defaults to “false” 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 “true” create & update for generate rules will use
|
|||
Defaults to “false” 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 “true” create & update for generate rules will use
|
|||
Defaults to “false” 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 “true” create & update for generate rules will use
|
|||
Defaults to “false” 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>
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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"):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,6 +23,8 @@ type AdmissionRequest struct {
|
|||
|
||||
// GroupVersionKind is the top level GVK.
|
||||
GroupVersionKind schema.GroupVersionKind
|
||||
|
||||
URLParams string
|
||||
}
|
||||
|
||||
type AdmissionResponse = admissionv1.AdmissionResponse
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue