1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: webhooks reconciliation with policies (#11233)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2024-09-25 14:12:08 +02:00 committed by GitHub
parent bfb00cffc8
commit 3de1cb3f4f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 26 additions and 5 deletions

View file

@ -18,7 +18,7 @@ type WebhookConfig struct {
} }
func parseWebhooks(in string) ([]WebhookConfig, error) { func parseWebhooks(in string) ([]WebhookConfig, error) {
webhookCfgs := make([]WebhookConfig, 0, 10) var webhookCfgs []WebhookConfig
if err := json.Unmarshal([]byte(in), &webhookCfgs); err != nil { if err := json.Unmarshal([]byte(in), &webhookCfgs); err != nil {
return nil, err return nil, err
} }

View file

@ -48,6 +48,7 @@ import (
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/retry" "k8s.io/client-go/util/retry"
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"k8s.io/utils/ptr"
) )
const ( const (
@ -714,6 +715,7 @@ func (c *controller) buildVerifyMutatingWebhookConfiguration(_ context.Context,
"app.kubernetes.io/name": kyverno.ValueKyvernoApp, "app.kubernetes.io/name": kyverno.ValueKyvernoApp,
}, },
}, },
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
}}, }},
}, },
nil nil
@ -737,6 +739,7 @@ func (c *controller) buildPolicyMutatingWebhookConfiguration(_ context.Context,
SideEffects: &noneOnDryRun, SideEffects: &noneOnDryRun,
ReinvocationPolicy: &ifNeeded, ReinvocationPolicy: &ifNeeded,
AdmissionReviewVersions: []string{"v1"}, AdmissionReviewVersions: []string{"v1"},
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
}}, }},
}, },
nil nil
@ -759,6 +762,7 @@ func (c *controller) buildPolicyValidatingWebhookConfiguration(_ context.Context
TimeoutSeconds: &c.defaultTimeout, TimeoutSeconds: &c.defaultTimeout,
SideEffects: &none, SideEffects: &none,
AdmissionReviewVersions: []string{"v1"}, AdmissionReviewVersions: []string{"v1"},
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
}}, }},
}, },
nil nil
@ -786,6 +790,7 @@ func (c *controller) buildDefaultResourceMutatingWebhookConfiguration(_ context.
AdmissionReviewVersions: []string{"v1"}, AdmissionReviewVersions: []string{"v1"},
TimeoutSeconds: &c.defaultTimeout, TimeoutSeconds: &c.defaultTimeout,
ReinvocationPolicy: &ifNeeded, ReinvocationPolicy: &ifNeeded,
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
}, { }, {
Name: config.MutatingWebhookName + "-fail", Name: config.MutatingWebhookName + "-fail",
ClientConfig: c.clientConfig(caBundle, config.MutatingWebhookServicePath+"/fail"), ClientConfig: c.clientConfig(caBundle, config.MutatingWebhookServicePath+"/fail"),
@ -805,6 +810,7 @@ func (c *controller) buildDefaultResourceMutatingWebhookConfiguration(_ context.
AdmissionReviewVersions: []string{"v1"}, AdmissionReviewVersions: []string{"v1"},
TimeoutSeconds: &c.defaultTimeout, TimeoutSeconds: &c.defaultTimeout,
ReinvocationPolicy: &ifNeeded, ReinvocationPolicy: &ifNeeded,
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
}}, }},
}, },
nil nil
@ -871,6 +877,10 @@ func (c *controller) buildResourceMutatingWebhookConfiguration(ctx context.Conte
func (c *controller) buildResourceMutatingWebhookRules(caBundle []byte, webhookCfg config.WebhookConfig, sideEffects *admissionregistrationv1.SideEffectClass, webhooks []*webhook, mapResourceToOpnType map[string][]admissionregistrationv1.OperationType) []admissionregistrationv1.MutatingWebhook { func (c *controller) buildResourceMutatingWebhookRules(caBundle []byte, webhookCfg config.WebhookConfig, sideEffects *admissionregistrationv1.SideEffectClass, webhooks []*webhook, mapResourceToOpnType map[string][]admissionregistrationv1.OperationType) []admissionregistrationv1.MutatingWebhook {
var mutatingWebhooks []admissionregistrationv1.MutatingWebhook //nolint:prealloc var mutatingWebhooks []admissionregistrationv1.MutatingWebhook //nolint:prealloc
objectSelector := webhookCfg.ObjectSelector
if objectSelector == nil {
objectSelector = &metav1.LabelSelector{}
}
for _, webhook := range webhooks { for _, webhook := range webhooks {
if webhook.isEmpty() { if webhook.isEmpty() {
continue continue
@ -888,10 +898,11 @@ func (c *controller) buildResourceMutatingWebhookRules(caBundle []byte, webhookC
SideEffects: sideEffects, SideEffects: sideEffects,
AdmissionReviewVersions: []string{"v1"}, AdmissionReviewVersions: []string{"v1"},
NamespaceSelector: webhookCfg.NamespaceSelector, NamespaceSelector: webhookCfg.NamespaceSelector,
ObjectSelector: webhookCfg.ObjectSelector, ObjectSelector: objectSelector,
TimeoutSeconds: &timeout, TimeoutSeconds: &timeout,
ReinvocationPolicy: &ifNeeded, ReinvocationPolicy: &ifNeeded,
MatchConditions: webhook.matchConditions, MatchConditions: webhook.matchConditions,
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
}, },
) )
} }
@ -925,6 +936,7 @@ func (c *controller) buildDefaultResourceValidatingWebhookConfiguration(_ contex
SideEffects: sideEffects, SideEffects: sideEffects,
AdmissionReviewVersions: []string{"v1"}, AdmissionReviewVersions: []string{"v1"},
TimeoutSeconds: &c.defaultTimeout, TimeoutSeconds: &c.defaultTimeout,
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
}, { }, {
Name: config.ValidatingWebhookName + "-fail", Name: config.ValidatingWebhookName + "-fail",
ClientConfig: c.clientConfig(caBundle, config.ValidatingWebhookServicePath+"/fail"), ClientConfig: c.clientConfig(caBundle, config.ValidatingWebhookServicePath+"/fail"),
@ -945,6 +957,7 @@ func (c *controller) buildDefaultResourceValidatingWebhookConfiguration(_ contex
SideEffects: sideEffects, SideEffects: sideEffects,
AdmissionReviewVersions: []string{"v1"}, AdmissionReviewVersions: []string{"v1"},
TimeoutSeconds: &c.defaultTimeout, TimeoutSeconds: &c.defaultTimeout,
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
}}, }},
}, },
nil nil
@ -1047,6 +1060,10 @@ func (c *controller) buildResourceValidatingWebhookConfiguration(ctx context.Con
func (c *controller) buildResourceValidatingWebhookRules(caBundle []byte, webhookCfg config.WebhookConfig, sideEffects *admissionregistrationv1.SideEffectClass, webhooks []*webhook, mapResourceToOpnType map[string][]admissionregistrationv1.OperationType) []admissionregistrationv1.ValidatingWebhook { func (c *controller) buildResourceValidatingWebhookRules(caBundle []byte, webhookCfg config.WebhookConfig, sideEffects *admissionregistrationv1.SideEffectClass, webhooks []*webhook, mapResourceToOpnType map[string][]admissionregistrationv1.OperationType) []admissionregistrationv1.ValidatingWebhook {
var validatingWebhooks []admissionregistrationv1.ValidatingWebhook //nolint:prealloc var validatingWebhooks []admissionregistrationv1.ValidatingWebhook //nolint:prealloc
objectSelector := webhookCfg.ObjectSelector
if objectSelector == nil {
objectSelector = &metav1.LabelSelector{}
}
for _, webhook := range webhooks { for _, webhook := range webhooks {
if webhook.isEmpty() { if webhook.isEmpty() {
continue continue
@ -1064,9 +1081,10 @@ func (c *controller) buildResourceValidatingWebhookRules(caBundle []byte, webhoo
SideEffects: sideEffects, SideEffects: sideEffects,
AdmissionReviewVersions: []string{"v1"}, AdmissionReviewVersions: []string{"v1"},
NamespaceSelector: webhookCfg.NamespaceSelector, NamespaceSelector: webhookCfg.NamespaceSelector,
ObjectSelector: webhookCfg.ObjectSelector, ObjectSelector: objectSelector,
TimeoutSeconds: &timeout, TimeoutSeconds: &timeout,
MatchConditions: webhook.matchConditions, MatchConditions: webhook.matchConditions,
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
}, },
) )
} }

View file

@ -108,6 +108,9 @@ func (wh *webhook) buildRulesWithOperations(final map[string][]admissionregistra
} }
rules = append(rules, ruleforset...) rules = append(rules, ruleforset...)
} }
for _, rule := range rules {
slices.Sort(rule.Resources)
}
less := func(a []string, b []string) (int, bool) { less := func(a []string, b []string) (int, bool) {
if x := cmp.Compare(len(a), len(b)); x != 0 { if x := cmp.Compare(len(a), len(b)); x != 0 {
return x, true return x, true
@ -140,7 +143,7 @@ func (wh *webhook) buildRulesWithOperations(final map[string][]admissionregistra
func appendResourceInRule(resource sets.Set[string], operations []admissionregistrationv1.OperationType, ruleforset []admissionregistrationv1.RuleWithOperations) ([]admissionregistrationv1.RuleWithOperations, bool) { func appendResourceInRule(resource sets.Set[string], operations []admissionregistrationv1.OperationType, ruleforset []admissionregistrationv1.RuleWithOperations) ([]admissionregistrationv1.RuleWithOperations, bool) {
for i, rule := range ruleforset { for i, rule := range ruleforset {
if reflect.DeepEqual(rule.Operations, operations) { if reflect.DeepEqual(rule.Operations, operations) {
ruleforset[i].Rule.Resources = append(rule.Rule.Resources, resource.UnsortedList()...) ruleforset[i].Rule.Resources = append(rule.Rule.Resources, sets.List(resource)...)
return ruleforset, true return ruleforset, true
} }
} }
@ -335,7 +338,7 @@ func mergeOperations(operationStatusMap map[string]bool, currentOps []admissionr
} }
} }
result := sets.New(currentOps...).Insert(operationReq...) result := sets.New(currentOps...).Insert(operationReq...)
return result.UnsortedList() return sets.List(result)
} }
func getOperationStatusMap() map[string]bool { func getOperationStatusMap() map[string]bool {