mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 07:26:55 +00:00
feat: add match conditions support in webhooks (#8042)
* feat: add match conditions support in webhooks Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * chart Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * release notes Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * changelog Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix configmap Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * warning Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Co-authored-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
parent
57a0f81040
commit
a3403131d6
10 changed files with 54 additions and 0 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
### Note
|
||||
|
||||
- Added match conditions support in kyverno config map.
|
||||
- Deprecated flag `--imageSignatureRepository`. Will be removed in 1.12. Use per rule configuration `verifyImages.Repository` instead.
|
||||
- Added `--aggregateReports` flag for reports controller to enable/disable aggregated reports (default value is `true`).
|
||||
- Added `--policyReports` flag for reports controller to enable/disable policy reports (default value is `true`).
|
||||
|
|
|
@ -64,3 +64,5 @@ annotations:
|
|||
description: Add helper to handle the labels for cleanup jobs, add component label
|
||||
- kind: added
|
||||
description: allow podSecurityContext and securityContext for webhooksCleanup
|
||||
- kind: added
|
||||
description: match conditions support in webhooks
|
||||
|
|
|
@ -272,6 +272,7 @@ The chart values are organised per component.
|
|||
| config.resourceFilters | list | See [values.yaml](values.yaml) | Resource types to be skipped by the Kyverno policy engine. Make sure to surround each entry in quotes so that it doesn't get parsed as a nested YAML list. These are joined together without spaces, run through `tpl`, and the result is set in the config map. |
|
||||
| config.webhooks | list | `[]` | Defines the `namespaceSelector` in the webhook configurations. Note that it takes a list of `namespaceSelector` and/or `objectSelector` in the JSON format, and only the first element will be forwarded to the webhook configurations. The Kyverno namespace is excluded if `excludeKyvernoNamespace` is `true` (default) |
|
||||
| config.webhookAnnotations | object | `{}` | Defines annotations to set on webhook configurations. |
|
||||
| config.matchConditions | list | `[]` | Defines match conditions to set on webhook configurations (requires Kubernetes 1.27+). |
|
||||
| config.excludeKyvernoNamespace | bool | `true` | Exclude Kyverno namespace Determines if default Kyverno namespace exclusion is enabled for webhooks and resourceFilters |
|
||||
| config.resourceFiltersExcludeNamespaces | list | `[]` | resourceFilter namespace exclude Namespaces to exclude from the default resourceFilters |
|
||||
|
||||
|
|
|
@ -32,3 +32,7 @@ The following components have been installed in your cluster:
|
|||
{{- if semverCompare "<1.21.0" .Capabilities.KubeVersion.Version }}
|
||||
⚠️ WARNING: The minimal Kubernetes version officially supported by Kyverno is 1.21. Earlier versions are untested and Kyverno is not guaranteed to work with Kubernetes {{ .Capabilities.KubeVersion.Version }}.
|
||||
{{- end }}
|
||||
|
||||
{{- with .Values.config.matchConditions }}
|
||||
⚠️ WARNING: Match conditions require a Kubernetes 1.27+ cluster with `AdmissionWebhookMatchConditions` feature gate enabled.
|
||||
{{- end }}
|
||||
|
|
|
@ -42,4 +42,7 @@ data:
|
|||
{{- with .Values.config.webhookAnnotations }}
|
||||
webhookAnnotations: {{ toJson . | quote }}
|
||||
{{- end }}
|
||||
{{- with .Values.config.matchConditions }}
|
||||
matchConditions: {{ toJson . | quote }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
|
|
@ -210,6 +210,9 @@ config:
|
|||
# Example to disable admission enforcer on AKS:
|
||||
# 'admissions.enforcer/disabled': 'true'
|
||||
|
||||
# -- Defines match conditions to set on webhook configurations (requires Kubernetes 1.27+).
|
||||
matchConditions: []
|
||||
|
||||
# -- Exclude Kyverno namespace
|
||||
# Determines if default Kyverno namespace exclusion is enabled for webhooks and resourceFilters
|
||||
excludeKyvernoNamespace: true
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
valid "github.com/asaskevich/govalidator"
|
||||
osutils "github.com/kyverno/kyverno/pkg/utils/os"
|
||||
"github.com/kyverno/kyverno/pkg/utils/wildcard"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
@ -87,6 +88,7 @@ const (
|
|||
generateSuccessEvents = "generateSuccessEvents"
|
||||
webhooks = "webhooks"
|
||||
webhookAnnotations = "webhookAnnotations"
|
||||
matchConditions = "matchConditions"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -160,6 +162,8 @@ type Configuration interface {
|
|||
GetWebhooks() []WebhookConfig
|
||||
// GetWebhookAnnotations returns annotations to set on webhook configs
|
||||
GetWebhookAnnotations() map[string]string
|
||||
// GetMatchConditions returns match conditions to set on webhook configs
|
||||
GetMatchConditions() []admissionregistrationv1.MatchCondition
|
||||
// Load loads configuration from a configmap
|
||||
Load(*corev1.ConfigMap)
|
||||
// OnChanged adds a callback to be invoked when the configuration is reloaded
|
||||
|
@ -177,6 +181,7 @@ type configuration struct {
|
|||
generateSuccessEvents bool
|
||||
webhooks []WebhookConfig
|
||||
webhookAnnotations map[string]string
|
||||
matchConditions []admissionregistrationv1.MatchCondition
|
||||
mux sync.RWMutex
|
||||
callbacks []func()
|
||||
}
|
||||
|
@ -295,6 +300,12 @@ func (cd *configuration) GetWebhookAnnotations() map[string]string {
|
|||
return cd.webhookAnnotations
|
||||
}
|
||||
|
||||
func (cd *configuration) GetMatchConditions() []admissionregistrationv1.MatchCondition {
|
||||
cd.mux.RLock()
|
||||
defer cd.mux.RUnlock()
|
||||
return cd.matchConditions
|
||||
}
|
||||
|
||||
func (cd *configuration) Load(cm *corev1.ConfigMap) {
|
||||
if cm != nil {
|
||||
cd.load(cm)
|
||||
|
@ -321,6 +332,7 @@ func (cd *configuration) load(cm *corev1.ConfigMap) {
|
|||
cd.generateSuccessEvents = false
|
||||
cd.webhooks = nil
|
||||
cd.webhookAnnotations = nil
|
||||
cd.matchConditions = nil
|
||||
// load filters
|
||||
cd.filters = parseKinds(data[resourceFilters])
|
||||
logger.Info("filters configured", "filters", cd.filters)
|
||||
|
@ -425,6 +437,20 @@ func (cd *configuration) load(cm *corev1.ConfigMap) {
|
|||
logger.Info("webhookAnnotations configured")
|
||||
}
|
||||
}
|
||||
// load match conditions
|
||||
matchConditions, ok := data[matchConditions]
|
||||
if !ok {
|
||||
logger.Info("matchConditions not set")
|
||||
} else {
|
||||
logger := logger.WithValues("matchConditions", matchConditions)
|
||||
matchConditions, err := parseMatchConditions(matchConditions)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to parse match conditions")
|
||||
} else {
|
||||
cd.matchConditions = matchConditions
|
||||
logger.Info("matchConditions configured")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cd *configuration) unload() {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strings"
|
||||
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
@ -52,6 +53,14 @@ func parseWebhookAnnotations(in string) (map[string]string, error) {
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func parseMatchConditions(in string) ([]admissionregistrationv1.MatchCondition, error) {
|
||||
var out []admissionregistrationv1.MatchCondition
|
||||
if err := json.Unmarshal([]byte(in), &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type namespacesConfig struct {
|
||||
IncludeNamespaces []string `json:"include,omitempty"`
|
||||
ExcludeNamespaces []string `json:"exclude,omitempty"`
|
||||
|
|
|
@ -178,6 +178,7 @@ func (c *controller) build(cfg config.Configuration, caBundle []byte) (*admissio
|
|||
SideEffects: c.sideEffects,
|
||||
AdmissionReviewVersions: []string{"v1"},
|
||||
ObjectSelector: c.labelSelector,
|
||||
MatchConditions: cfg.GetMatchConditions(),
|
||||
}},
|
||||
},
|
||||
nil
|
||||
|
|
|
@ -659,6 +659,7 @@ func (c *controller) buildResourceMutatingWebhookConfiguration(ctx context.Conte
|
|||
ObjectSelector: webhookCfg.ObjectSelector,
|
||||
TimeoutSeconds: &timeout,
|
||||
ReinvocationPolicy: &ifNeeded,
|
||||
MatchConditions: cfg.GetMatchConditions(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -677,6 +678,7 @@ func (c *controller) buildResourceMutatingWebhookConfiguration(ctx context.Conte
|
|||
ObjectSelector: webhookCfg.ObjectSelector,
|
||||
TimeoutSeconds: &timeout,
|
||||
ReinvocationPolicy: &ifNeeded,
|
||||
MatchConditions: cfg.GetMatchConditions(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -786,6 +788,7 @@ func (c *controller) buildResourceValidatingWebhookConfiguration(ctx context.Con
|
|||
NamespaceSelector: webhookCfg.NamespaceSelector,
|
||||
ObjectSelector: webhookCfg.ObjectSelector,
|
||||
TimeoutSeconds: &timeout,
|
||||
MatchConditions: cfg.GetMatchConditions(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -803,6 +806,7 @@ func (c *controller) buildResourceValidatingWebhookConfiguration(ctx context.Con
|
|||
NamespaceSelector: webhookCfg.NamespaceSelector,
|
||||
ObjectSelector: webhookCfg.ObjectSelector,
|
||||
TimeoutSeconds: &timeout,
|
||||
MatchConditions: cfg.GetMatchConditions(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue