diff --git a/pkg/hook/config/config_test.go b/pkg/hook/config/config_test.go index 5d1b828a..eb333b82 100644 --- a/pkg/hook/config/config_test.go +++ b/pkg/hook/config/config_test.go @@ -614,6 +614,72 @@ kubernetesValidating: g.Expect(*wh.TimeoutSeconds).To(BeEquivalentTo(30)) }, }, + { + "v1 kubernetesMutating reinvocationPolicy", + ` +configVersion: v1 +kubernetesMutating: +- name: default.example.com + rules: + - apiVersions: ["v1"] + apiGroups: ["crd-domain.io"] + resources: ["MyCustomResource"] + operations: ["*"] +- name: reinvoke.example.com + reinvocationPolicy: IfNeeded + rules: + - apiVersions: ["v1"] + apiGroups: ["crd-domain.io"] + resources: ["MyCustomResource"] + operations: ["*"] +`, + func() { + g.Expect(err).ShouldNot(HaveOccurred()) + g.Expect(hookConfig.KubernetesMutating).Should(HaveLen(2)) + + // Unset: nil, so apiserver defaults to Never. + g.Expect(hookConfig.KubernetesMutating[0].Webhook.ReinvocationPolicy).Should(BeNil()) + + // Set: passed through. + rp := hookConfig.KubernetesMutating[1].Webhook.ReinvocationPolicy + g.Expect(rp).ShouldNot(BeNil()) + g.Expect(*rp).To(Equal(v1.IfNeededReinvocationPolicy)) + }, + }, + { + "v1 kubernetesMutating reinvocationPolicy invalid", + ` +configVersion: v1 +kubernetesMutating: +- name: bad.example.com + reinvocationPolicy: Sometimes + rules: + - apiVersions: ["v1"] + apiGroups: ["crd-domain.io"] + resources: ["MyCustomResource"] + operations: ["*"] +`, + func() { + g.Expect(err).Should(HaveOccurred()) + }, + }, + { + "v1 kubernetesValidating rejects reinvocationPolicy", + ` +configVersion: v1 +kubernetesValidating: +- name: nope.example.com + reinvocationPolicy: Never + rules: + - apiVersions: ["v1"] + apiGroups: ["crd-domain.io"] + resources: ["MyCustomResource"] + operations: ["*"] +`, + func() { + g.Expect(err).Should(HaveOccurred()) + }, + }, { "v1 kubernetesValidating name error", ` diff --git a/pkg/hook/config/config_v1.go b/pkg/hook/config/config_v1.go index 80d57de7..8dee752f 100644 --- a/pkg/hook/config/config_v1.go +++ b/pkg/hook/config/config_v1.go @@ -83,6 +83,9 @@ type KubernetesAdmissionConfigV1 struct { SideEffects *v1.SideEffectClass `json:"sideEffects"` TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` MatchConditions []v1.MatchCondition `json:"matchConditions,omitempty"` + // ReinvocationPolicy is honored only for kubernetesMutating; the schema + // rejects it on kubernetesValidating (the k8s type has no such field). + ReinvocationPolicy *v1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` } // version 1 of kubernetes conversion configuration @@ -518,6 +521,8 @@ func convertMutating(cfgV1 KubernetesAdmissionConfigV1) htypes.MutatingConfig { webhook.MatchConditions = cfgV1.MatchConditions + webhook.ReinvocationPolicy = cfgV1.ReinvocationPolicy + cfg.Webhook = &admission.MutatingWebhookConfig{ MutatingWebhook: webhook, } diff --git a/pkg/hook/config/schemas.go b/pkg/hook/config/schemas.go index 6853a49a..480227fc 100644 --- a/pkg/hook/config/schemas.go +++ b/pkg/hook/config/schemas.go @@ -230,6 +230,11 @@ properties: timeoutSeconds: type: integer example: 10 + reinvocationPolicy: + type: string + enum: + - Never + - IfNeeded matchConditions: type: array items: