From a51a5b462236d5eb87e6d690065f884c281a833c Mon Sep 17 00:00:00 2001 From: Igor Velichkovich Date: Wed, 28 Feb 2024 10:45:51 -0600 Subject: [PATCH] kep-3716 GA, remove feature gate --- api/openapi-spec/swagger.json | 4 +- ...issionregistration.k8s.io__v1_openapi.json | 4 +- pkg/apis/admissionregistration/types.go | 6 - pkg/apis/admissionregistration/util.go | 66 --- pkg/apis/admissionregistration/util_test.go | 417 ------------------ pkg/features/kube_features.go | 2 +- pkg/generated/openapi/zz_generated.openapi.go | 8 +- .../mutatingwebhookconfiguration/strategy.go | 3 - .../strategy.go | 3 - .../admissionregistration/v1/generated.proto | 6 - .../api/admissionregistration/v1/types.go | 6 - .../v1/types_swagger_doc_generated.go | 4 +- .../v1beta1/generated.proto | 6 - .../admissionregistration/v1beta1/types.go | 6 - .../v1beta1/types_swagger_doc_generated.go | 4 +- .../apiserver/pkg/features/kube_features.go | 3 +- .../admissionwebhook/match_conditions_test.go | 196 -------- .../mutating_webhook_gvk_conversion_test.go | 4 - 18 files changed, 15 insertions(+), 733 deletions(-) delete mode 100644 pkg/apis/admissionregistration/util.go delete mode 100644 pkg/apis/admissionregistration/util_test.go diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index e330f014ddc..a16463d5c13 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -38,7 +38,7 @@ "type": "string" }, "matchConditions": { - "description": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + "description": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", "items": { "$ref": "#/definitions/io.k8s.api.admissionregistration.v1.MatchCondition" }, @@ -258,7 +258,7 @@ "type": "string" }, "matchConditions": { - "description": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + "description": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", "items": { "$ref": "#/definitions/io.k8s.api.admissionregistration.v1.MatchCondition" }, diff --git a/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1_openapi.json index 9b683b90223..e3933362f37 100644 --- a/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1_openapi.json @@ -47,7 +47,7 @@ "type": "string" }, "matchConditions": { - "description": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + "description": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", "items": { "allOf": [ { @@ -318,7 +318,7 @@ "type": "string" }, "matchConditions": { - "description": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + "description": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", "items": { "allOf": [ { diff --git a/pkg/apis/admissionregistration/types.go b/pkg/apis/admissionregistration/types.go index 578e8d52fe9..50d000484f7 100644 --- a/pkg/apis/admissionregistration/types.go +++ b/pkg/apis/admissionregistration/types.go @@ -868,9 +868,6 @@ type ValidatingWebhook struct { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // - // +featureGate=AdmissionWebhookMatchConditions // +optional MatchConditions []MatchCondition } @@ -1028,9 +1025,6 @@ type MutatingWebhook struct { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // - // +featureGate=AdmissionWebhookMatchConditions // +optional MatchConditions []MatchCondition } diff --git a/pkg/apis/admissionregistration/util.go b/pkg/apis/admissionregistration/util.go deleted file mode 100644 index dd6e1acaa15..00000000000 --- a/pkg/apis/admissionregistration/util.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 2023 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. -*/ - -package admissionregistration - -import ( - genericfeatures "k8s.io/apiserver/pkg/features" - utilfeature "k8s.io/apiserver/pkg/util/feature" -) - -// DropDisabledMutatingWebhookConfigurationFields removes disabled fields from the mutatingWebhookConfiguration metadata and spec. -// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a mutatingWebhookConfiguration -func DropDisabledMutatingWebhookConfigurationFields(mutatingWebhookConfiguration, oldMutatingWebhookConfiguration *MutatingWebhookConfiguration) { - if !utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AdmissionWebhookMatchConditions) && !matchConditionsInUseMutatingWebhook(oldMutatingWebhookConfiguration) { - for i := range mutatingWebhookConfiguration.Webhooks { - mutatingWebhookConfiguration.Webhooks[i].MatchConditions = nil - } - } -} - -func matchConditionsInUseMutatingWebhook(mutatingWebhookConfiguration *MutatingWebhookConfiguration) bool { - if mutatingWebhookConfiguration == nil { - return false - } - for _, webhook := range mutatingWebhookConfiguration.Webhooks { - if len(webhook.MatchConditions) != 0 { - return true - } - } - return false -} - -// DropDisabledValidatingWebhookConfigurationFields removes disabled fields from the validatingWebhookConfiguration metadata and spec. -// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a validatingWebhookConfiguration -func DropDisabledValidatingWebhookConfigurationFields(validatingWebhookConfiguration, oldValidatingWebhookConfiguration *ValidatingWebhookConfiguration) { - if !utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AdmissionWebhookMatchConditions) && !matchConditionsInUseValidatingWebhook(oldValidatingWebhookConfiguration) { - for i := range validatingWebhookConfiguration.Webhooks { - validatingWebhookConfiguration.Webhooks[i].MatchConditions = nil - } - } -} - -func matchConditionsInUseValidatingWebhook(validatingWebhookConfiguration *ValidatingWebhookConfiguration) bool { - if validatingWebhookConfiguration == nil { - return false - } - for _, webhook := range validatingWebhookConfiguration.Webhooks { - if len(webhook.MatchConditions) != 0 { - return true - } - } - return false -} diff --git a/pkg/apis/admissionregistration/util_test.go b/pkg/apis/admissionregistration/util_test.go deleted file mode 100644 index 299ebd298d3..00000000000 --- a/pkg/apis/admissionregistration/util_test.go +++ /dev/null @@ -1,417 +0,0 @@ -/* -Copyright 2023 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. -*/ - -package admissionregistration - -import ( - "testing" - - "github.com/stretchr/testify/require" - - genericfeatures "k8s.io/apiserver/pkg/features" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" -) - -func TestDropDisabledMutatingWebhookConfigurationFields(t *testing.T) { - tests := []struct { - name string - old *MutatingWebhookConfiguration - new *MutatingWebhookConfiguration - featureGateEnabled bool - expected []MatchCondition - }{ - { - name: "create with no match conditions, feature gate off", - old: nil, - new: &MutatingWebhookConfiguration{ - Webhooks: []MutatingWebhook{ - {}, - }, - }, - featureGateEnabled: false, - expected: nil, - }, - { - name: "create with match conditions, feature gate off", - old: nil, - new: &MutatingWebhookConfiguration{ - Webhooks: []MutatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - featureGateEnabled: false, - expected: nil, - }, - { - name: "create with no match conditions, feature gate on", - old: nil, - new: &MutatingWebhookConfiguration{ - Webhooks: []MutatingWebhook{ - {}, - {}, - }, - }, - featureGateEnabled: true, - expected: nil, - }, - { - name: "create with match conditions, feature gate on", - old: nil, - new: &MutatingWebhookConfiguration{ - Webhooks: []MutatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - featureGateEnabled: true, - expected: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - name: "update with old has match conditions feature gate on", - old: &MutatingWebhookConfiguration{ - Webhooks: []MutatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - new: &MutatingWebhookConfiguration{ - Webhooks: []MutatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - featureGateEnabled: true, - expected: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - name: "update with old has match conditions feature gate off", - old: &MutatingWebhookConfiguration{ - Webhooks: []MutatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - new: &MutatingWebhookConfiguration{ - Webhooks: []MutatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - featureGateEnabled: false, - expected: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AdmissionWebhookMatchConditions, test.featureGateEnabled)() - DropDisabledMutatingWebhookConfigurationFields(test.new, test.old) - - for _, hook := range test.new.Webhooks { - if test.expected == nil { - if hook.MatchConditions != nil { - t.Error("expected all hooks matchConditions to be nil") - } - } else { - require.Equal(t, len(test.expected), len(hook.MatchConditions)) - for i, matchCondition := range hook.MatchConditions { - require.Equal(t, test.expected[i], matchCondition) - } - } - } - }) - } -} - -func TestDropDisabledValidatingWebhookConfigurationFields(t *testing.T) { - tests := []struct { - name string - old *ValidatingWebhookConfiguration - new *ValidatingWebhookConfiguration - featureGateEnabled bool - expected []MatchCondition - }{ - { - name: "create with no match conditions, feature gate off", - old: nil, - new: &ValidatingWebhookConfiguration{ - Webhooks: []ValidatingWebhook{ - {}, - }, - }, - featureGateEnabled: false, - expected: nil, - }, - { - name: "create with match conditions, feature gate off", - old: nil, - new: &ValidatingWebhookConfiguration{ - Webhooks: []ValidatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - featureGateEnabled: false, - expected: nil, - }, - { - name: "create with no match conditions, feature gate on", - old: nil, - new: &ValidatingWebhookConfiguration{ - Webhooks: []ValidatingWebhook{ - {}, - {}, - }, - }, - featureGateEnabled: true, - expected: nil, - }, - { - name: "create with match conditions, feature gate on", - old: nil, - new: &ValidatingWebhookConfiguration{ - Webhooks: []ValidatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - featureGateEnabled: true, - expected: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - name: "update with old has match conditions feature gate on", - old: &ValidatingWebhookConfiguration{ - Webhooks: []ValidatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - new: &ValidatingWebhookConfiguration{ - Webhooks: []ValidatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - featureGateEnabled: true, - expected: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - name: "update with old has match conditions feature gate off", - old: &ValidatingWebhookConfiguration{ - Webhooks: []ValidatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - new: &ValidatingWebhookConfiguration{ - Webhooks: []ValidatingWebhook{ - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - { - MatchConditions: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - }, - }, - featureGateEnabled: false, - expected: []MatchCondition{ - { - Name: "test1", - }, - }, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AdmissionWebhookMatchConditions, test.featureGateEnabled)() - DropDisabledValidatingWebhookConfigurationFields(test.new, test.old) - - for _, hook := range test.new.Webhooks { - if test.expected == nil { - if hook.MatchConditions != nil { - t.Error("expected all hooks matchConditions to be nil") - } - } else { - require.Equal(t, len(test.expected), len(hook.MatchConditions)) - for i, matchCondition := range hook.MatchConditions { - require.Equal(t, test.expected[i], matchCondition) - } - } - } - }) - } -} diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 9951b602adc..fb96e5363c0 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -1173,7 +1173,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS // inherited features from generic apiserver, relisted here to get a conflict if it is changed // unintentionally on either side: - genericfeatures.AdmissionWebhookMatchConditions: {Default: true, PreRelease: featuregate.Beta}, + genericfeatures.AdmissionWebhookMatchConditions: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33 genericfeatures.AggregatedDiscoveryEndpoint: {Default: true, PreRelease: featuregate.Beta}, diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 85a7f8d8ecf..29d30cc9afa 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -1325,7 +1325,7 @@ func schema_k8sio_api_admissionregistration_v1_MutatingWebhook(ref common.Refere }, }, SchemaProps: spec.SchemaProps{ - Description: "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + Description: "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -1797,7 +1797,7 @@ func schema_k8sio_api_admissionregistration_v1_ValidatingWebhook(ref common.Refe }, }, SchemaProps: spec.SchemaProps{ - Description: "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + Description: "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -3148,7 +3148,7 @@ func schema_k8sio_api_admissionregistration_v1beta1_MutatingWebhook(ref common.R }, }, SchemaProps: spec.SchemaProps{ - Description: "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + Description: "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -4097,7 +4097,7 @@ func schema_k8sio_api_admissionregistration_v1beta1_ValidatingWebhook(ref common }, }, SchemaProps: spec.SchemaProps{ - Description: "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + Description: "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ diff --git a/pkg/registry/admissionregistration/mutatingwebhookconfiguration/strategy.go b/pkg/registry/admissionregistration/mutatingwebhookconfiguration/strategy.go index 252a3c3dde4..0ae88c5dd6c 100644 --- a/pkg/registry/admissionregistration/mutatingwebhookconfiguration/strategy.go +++ b/pkg/registry/admissionregistration/mutatingwebhookconfiguration/strategy.go @@ -46,8 +46,6 @@ func (mutatingWebhookConfigurationStrategy) NamespaceScoped() bool { func (mutatingWebhookConfigurationStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { ic := obj.(*admissionregistration.MutatingWebhookConfiguration) ic.Generation = 1 - - admissionregistration.DropDisabledMutatingWebhookConfigurationFields(ic, nil) } // WarningsOnCreate returns warnings for the creation of the given object. @@ -60,7 +58,6 @@ func (mutatingWebhookConfigurationStrategy) PrepareForUpdate(ctx context.Context newIC := obj.(*admissionregistration.MutatingWebhookConfiguration) oldIC := old.(*admissionregistration.MutatingWebhookConfiguration) - admissionregistration.DropDisabledMutatingWebhookConfigurationFields(newIC, oldIC) // Any changes to the spec increment the generation number, any changes to the // status should reflect the generation number of the corresponding object. // See metav1.ObjectMeta description for more information on Generation. diff --git a/pkg/registry/admissionregistration/validatingwebhookconfiguration/strategy.go b/pkg/registry/admissionregistration/validatingwebhookconfiguration/strategy.go index 67931f9d9a7..20bc653eeae 100644 --- a/pkg/registry/admissionregistration/validatingwebhookconfiguration/strategy.go +++ b/pkg/registry/admissionregistration/validatingwebhookconfiguration/strategy.go @@ -46,8 +46,6 @@ func (validatingWebhookConfigurationStrategy) NamespaceScoped() bool { func (validatingWebhookConfigurationStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { ic := obj.(*admissionregistration.ValidatingWebhookConfiguration) ic.Generation = 1 - - admissionregistration.DropDisabledValidatingWebhookConfigurationFields(ic, nil) } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -55,7 +53,6 @@ func (validatingWebhookConfigurationStrategy) PrepareForUpdate(ctx context.Conte newIC := obj.(*admissionregistration.ValidatingWebhookConfiguration) oldIC := old.(*admissionregistration.ValidatingWebhookConfiguration) - admissionregistration.DropDisabledValidatingWebhookConfigurationFields(newIC, oldIC) // Any changes to the spec increment the generation number, any changes to the // status should reflect the generation number of the corresponding object. // See metav1.ObjectMeta description for more information on Generation. diff --git a/staging/src/k8s.io/api/admissionregistration/v1/generated.proto b/staging/src/k8s.io/api/admissionregistration/v1/generated.proto index ab5baa57c68..96824490ae4 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1/generated.proto +++ b/staging/src/k8s.io/api/admissionregistration/v1/generated.proto @@ -217,13 +217,10 @@ message MutatingWebhook { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name - // +featureGate=AdmissionWebhookMatchConditions // +optional repeated MatchCondition matchConditions = 12; } @@ -479,13 +476,10 @@ message ValidatingWebhook { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name - // +featureGate=AdmissionWebhookMatchConditions // +optional repeated MatchCondition matchConditions = 11; } diff --git a/staging/src/k8s.io/api/admissionregistration/v1/types.go b/staging/src/k8s.io/api/admissionregistration/v1/types.go index e86268d78ec..87f63009f93 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1/types.go +++ b/staging/src/k8s.io/api/admissionregistration/v1/types.go @@ -326,13 +326,10 @@ type ValidatingWebhook struct { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name - // +featureGate=AdmissionWebhookMatchConditions // +optional MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,11,opt,name=matchConditions"` } @@ -497,13 +494,10 @@ type MutatingWebhook struct { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name - // +featureGate=AdmissionWebhookMatchConditions // +optional MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,12,opt,name=matchConditions"` } diff --git a/staging/src/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go index c41cceb2f24..2d4fe48c9c7 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go @@ -50,7 +50,7 @@ var map_MutatingWebhook = map[string]string{ "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", "reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", } func (MutatingWebhook) SwaggerDoc() map[string]string { @@ -122,7 +122,7 @@ var map_ValidatingWebhook = map[string]string{ "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.", "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", } func (ValidatingWebhook) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/api/admissionregistration/v1beta1/generated.proto b/staging/src/k8s.io/api/admissionregistration/v1beta1/generated.proto index 833393085a4..91479acc20b 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/admissionregistration/v1beta1/generated.proto @@ -366,13 +366,10 @@ message MutatingWebhook { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name - // +featureGate=AdmissionWebhookMatchConditions // +optional repeated MatchCondition matchConditions = 12; } @@ -896,13 +893,10 @@ message ValidatingWebhook { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name - // +featureGate=AdmissionWebhookMatchConditions // +optional repeated MatchCondition matchConditions = 11; } diff --git a/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go b/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go index ed3bce3ccfd..cf1e29a6cab 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go +++ b/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go @@ -893,13 +893,10 @@ type ValidatingWebhook struct { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name - // +featureGate=AdmissionWebhookMatchConditions // +optional MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,11,rep,name=matchConditions"` } @@ -1067,13 +1064,10 @@ type MutatingWebhook struct { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped // - // This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate. - // // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name - // +featureGate=AdmissionWebhookMatchConditions // +optional MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,12,rep,name=matchConditions"` } diff --git a/staging/src/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go index adaf4bc11db..cc1509b539a 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go @@ -83,7 +83,7 @@ var map_MutatingWebhook = map[string]string{ "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", "reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", } func (MutatingWebhook) SwaggerDoc() map[string]string { @@ -253,7 +253,7 @@ var map_ValidatingWebhook = map[string]string{ "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.", "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", } func (ValidatingWebhook) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/apiserver/pkg/features/kube_features.go b/staging/src/k8s.io/apiserver/pkg/features/kube_features.go index 9c90ca20403..85172591115 100644 --- a/staging/src/k8s.io/apiserver/pkg/features/kube_features.go +++ b/staging/src/k8s.io/apiserver/pkg/features/kube_features.go @@ -38,6 +38,7 @@ const ( // owner: @ivelichkovich, @tallclair // alpha: v1.27 // beta: v1.28 + // stable: v1.30 // kep: https://kep.k8s.io/3716 // // Enables usage of MatchConditions fields to use CEL expressions for matching on admission webhooks @@ -285,7 +286,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS AggregatedDiscoveryEndpoint: {Default: true, PreRelease: featuregate.Beta}, - AdmissionWebhookMatchConditions: {Default: true, PreRelease: featuregate.Beta}, + AdmissionWebhookMatchConditions: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33 APIListChunking: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32 diff --git a/test/integration/apiserver/admissionwebhook/match_conditions_test.go b/test/integration/apiserver/admissionwebhook/match_conditions_test.go index f05685206b5..4ff64102342 100644 --- a/test/integration/apiserver/admissionwebhook/match_conditions_test.go +++ b/test/integration/apiserver/admissionwebhook/match_conditions_test.go @@ -36,10 +36,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" - genericfeatures "k8s.io/apiserver/pkg/features" - utilfeature "k8s.io/apiserver/pkg/util/feature" clientset "k8s.io/client-go/kubernetes" - featuregatetesting "k8s.io/component-base/featuregate/testing" apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" "k8s.io/kubernetes/test/integration/framework" ) @@ -110,7 +107,6 @@ func newMatchConditionHandler(recorder *admissionRecorder) http.Handler { // TestMatchConditions tests ValidatingWebhookConfigurations and MutatingWebhookConfigurations that validates different cases of matchCondition fields func TestMatchConditions(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AdmissionWebhookMatchConditions, true)() fail := admissionregistrationv1.Fail ignore := admissionregistrationv1.Ignore @@ -567,7 +563,6 @@ func TestMatchConditions(t *testing.T) { } func TestMatchConditions_validation(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AdmissionWebhookMatchConditions, true)() server := apiservertesting.StartTestServerOrDie(t, nil, []string{ "--disable-admission-plugins=ServiceAccount", @@ -737,197 +732,6 @@ func TestMatchConditions_validation(t *testing.T) { } } -func TestFeatureGateEnablement(t *testing.T) { - testcases := []struct { - name string - matchConditionsFeatureGateInitiallyEnabled bool - matchConditions []admissionregistrationv1.MatchCondition - expectMatchConditionsPreSwitch bool - expectMatchConditionsPostSwitch bool - }{ - { - name: "start with match conditions enabled - no match conditions", - matchConditionsFeatureGateInitiallyEnabled: true, - expectMatchConditionsPreSwitch: false, - expectMatchConditionsPostSwitch: false, - }, - { - name: "start with match conditions enabled - with match conditions", - matchConditionsFeatureGateInitiallyEnabled: true, - matchConditions: []admissionregistrationv1.MatchCondition{{ - Name: "test-expression", - Expression: "true", - }}, - expectMatchConditionsPreSwitch: true, - expectMatchConditionsPostSwitch: true, - }, - { - name: "start with match conditions disabled - no match conditions", - matchConditionsFeatureGateInitiallyEnabled: false, - expectMatchConditionsPreSwitch: false, - expectMatchConditionsPostSwitch: false, - }, - { - name: "start with match conditions disabled - with match conditions", - matchConditionsFeatureGateInitiallyEnabled: false, - matchConditions: []admissionregistrationv1.MatchCondition{{ - Name: "test-expression", - Expression: "true", - }}, - expectMatchConditionsPreSwitch: false, - expectMatchConditionsPostSwitch: false, - }, - } - - server := apiservertesting.StartTestServerOrDie(t, nil, []string{ - "--disable-admission-plugins=ServiceAccount", - }, framework.SharedEtcd()) - defer server.TearDownFn() - - endpoint := "https://localhost:1234/server" - clientConfig := admissionregistrationv1.WebhookClientConfig{ - URL: &endpoint, - CABundle: localhostCert, - } - - rules := []admissionregistrationv1.RuleWithOperations{{ - Operations: []admissionregistrationv1.OperationType{admissionregistrationv1.Create}, - Rule: admissionregistrationv1.Rule{ - APIGroups: []string{""}, - APIVersions: []string{"v1"}, - Resources: []string{"pods"}, - }, - }} - versions := []string{"v1"} - - client := clientset.NewForConfigOrDie(server.ClientConfig) - - for _, testcase := range testcases { - t.Run(testcase.name, func(t *testing.T) { - if testcase.matchConditionsFeatureGateInitiallyEnabled { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AdmissionWebhookMatchConditions, true)() - } - - validatingwebhook := &admissionregistrationv1.ValidatingWebhookConfiguration{ - ObjectMeta: metav1.ObjectMeta{ - Name: "validating-webhook.integration.test", - }, - Webhooks: []admissionregistrationv1.ValidatingWebhook{ - { - Name: "admission.integration.test", - Rules: rules, - ClientConfig: clientConfig, - SideEffects: &noSideEffects, - AdmissionReviewVersions: versions, - MatchConditions: testcase.matchConditions, - }, - }, - } - - mutatingWebhook := &admissionregistrationv1.MutatingWebhookConfiguration{ - ObjectMeta: metav1.ObjectMeta{ - Name: "mutating-webhook.integration.test", - }, - Webhooks: []admissionregistrationv1.MutatingWebhook{ - { - Name: "admission.integration.test", - Rules: rules, - ClientConfig: clientConfig, - SideEffects: &noSideEffects, - AdmissionReviewVersions: versions, - MatchConditions: testcase.matchConditions, - }, - }, - } - - // Create the validating webhook - _, err := client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Create( - context.Background(), validatingwebhook, metav1.CreateOptions{}, - ) - if err != nil { - t.Fatalf("Unexpected error creating validating webhook: %v", err) - } - t.Cleanup(func() { - // Make sure to cleanup the validating webhook before running the next test case - err := client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Delete( - context.Background(), validatingwebhook.Name, metav1.DeleteOptions{}, - ) - if err != nil { - t.Fatalf("Unexpected error deleting validating webhook: %v", err) - } - }) - - // Create the mutating webhook - _, err = client.AdmissionregistrationV1().MutatingWebhookConfigurations().Create( - context.Background(), mutatingWebhook, metav1.CreateOptions{}, - ) - if err != nil { - t.Fatalf("Unexpected error creating mutating webhook: %v", err) - } - t.Cleanup(func() { - // Make sure to cleanup the mutating webhook before running the next test case - err := client.AdmissionregistrationV1().MutatingWebhookConfigurations().Delete( - context.Background(), mutatingWebhook.Name, metav1.DeleteOptions{}, - ) - if err != nil { - t.Fatalf("Unexpected error deleting mutating webhook: %v", err) - } - }) - - // Assert the validating webhook match conditions field - pre switch - validatingWebhookConfig, err := client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Get( - context.Background(), validatingwebhook.Name, metav1.GetOptions{}, - ) - if err != nil { - t.Fatalf("Unexpected error getting validating webhook: %v", err) - } - if testcase.expectMatchConditionsPreSwitch && validatingWebhookConfig.Webhooks[0].MatchConditions == nil { - t.Fatal("Expected match conditions to be present in the validating webhook pre switch; got: nil") - } - - // Assert the mutating webhook match conditions field - pre switch - mutatingWebhookConfig, err := client.AdmissionregistrationV1().MutatingWebhookConfigurations().Get( - context.Background(), mutatingWebhook.Name, metav1.GetOptions{}, - ) - if err != nil { - t.Fatalf("Unexpected error getting mutating webhook: %v", err) - } - if testcase.expectMatchConditionsPreSwitch && mutatingWebhookConfig.Webhooks[0].MatchConditions == nil { - t.Fatal("Expected match conditions to be present in the mutating webhook pre switch; got: nil") - } - - // Switch the featureGate state - if testcase.matchConditionsFeatureGateInitiallyEnabled { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AdmissionWebhookMatchConditions, false)() - } else { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AdmissionWebhookMatchConditions, true)() - } - - // Assert the validating webhook match conditions field - post switch - validatingWebhookConfig, err = client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Get( - context.Background(), validatingwebhook.Name, metav1.GetOptions{}, - ) - if err != nil { - t.Fatalf("Unexpected error getting validating webhook: %v", err) - } - if testcase.expectMatchConditionsPostSwitch && validatingWebhookConfig.Webhooks[0].MatchConditions == nil { - t.Fatal("Expected match conditions to be present in the validating webhook post switch; got: nil") - } - - // Assert the mutating webhook match conditions field - post switch - mutatingWebhookConfig, err = client.AdmissionregistrationV1().MutatingWebhookConfigurations().Get( - context.Background(), mutatingWebhook.Name, metav1.GetOptions{}, - ) - if err != nil { - t.Fatalf("Unexpected error getting mutating webhook: %v", err) - } - if testcase.expectMatchConditionsPostSwitch && mutatingWebhookConfig.Webhooks[0].MatchConditions == nil { - t.Fatal("Expected match conditions to be present in the mutating webhook post switch; got: nil") - } - }) - } -} - func matchConditionsTestPod(name, ns string) *corev1.Pod { return &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ diff --git a/test/integration/apiserver/admissionwebhook/mutating_webhook_gvk_conversion_test.go b/test/integration/apiserver/admissionwebhook/mutating_webhook_gvk_conversion_test.go index f4008caaa56..a984f813ab4 100644 --- a/test/integration/apiserver/admissionwebhook/mutating_webhook_gvk_conversion_test.go +++ b/test/integration/apiserver/admissionwebhook/mutating_webhook_gvk_conversion_test.go @@ -41,11 +41,8 @@ import ( "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" - genericfeatures "k8s.io/apiserver/pkg/features" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/dynamic" clientset "k8s.io/client-go/kubernetes" - featuregatetesting "k8s.io/component-base/featuregate/testing" apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" "k8s.io/kubernetes/test/integration/etcd" "k8s.io/kubernetes/test/integration/framework" @@ -156,7 +153,6 @@ func Test_MutatingWebhookConvertsGVKWithMatchPolicyEquivalent(t *testing.T) { defer webhookServer.Close() upCh := typeChecker.Reset() - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AdmissionWebhookMatchConditions, true)() server, err := apiservertesting.StartTestServer(t, nil, []string{ "--disable-admission-plugins=ServiceAccount", }, framework.SharedEtcd())