From 64c426a90232e34853d9b9cfdaad5409371c191a Mon Sep 17 00:00:00 2001 From: Igor Velichkovich Date: Fri, 3 Mar 2023 14:04:29 -0600 Subject: [PATCH] migrate versionedattr to avoid circular dependency --- .../webhook/generic => }/conversion.go | 34 ++++++++++++++--- .../webhook/generic => }/conversion_test.go | 11 +++--- .../pkg/admission/plugin/cel/filter.go | 3 +- .../pkg/admission/plugin/cel/filter_test.go | 5 +-- .../pkg/admission/plugin/cel/interface.go | 4 +- .../admission_test.go | 37 +++++++++---------- .../validatingadmissionpolicy/controller.go | 5 +-- .../validatingadmissionpolicy/interface.go | 3 +- .../validatingadmissionpolicy/validator.go | 4 +- .../validator_test.go | 7 ++-- .../plugin/webhook/generic/interfaces.go | 26 ------------- .../plugin/webhook/mutating/dispatcher.go | 12 +++--- .../plugin/webhook/request/admissionreview.go | 7 ++-- .../webhook/request/admissionreview_test.go | 6 +-- .../plugin/webhook/validating/dispatcher.go | 6 +-- 15 files changed, 81 insertions(+), 89 deletions(-) rename staging/src/k8s.io/apiserver/pkg/admission/{plugin/webhook/generic => }/conversion.go (73%) rename staging/src/k8s.io/apiserver/pkg/admission/{plugin/webhook/generic => }/conversion_test.go (97%) diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/conversion.go b/staging/src/k8s.io/apiserver/pkg/admission/conversion.go similarity index 73% rename from staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/conversion.go rename to staging/src/k8s.io/apiserver/pkg/admission/conversion.go index f0e0ed79c1b..a2b313a9834 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/conversion.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/conversion.go @@ -14,16 +14,40 @@ See the License for the specific language governing permissions and limitations under the License. */ -package generic +package admission import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/admission" ) +// VersionedAttributes is a wrapper around the original admission attributes, adding versioned +// variants of the object and old object. +type VersionedAttributes struct { + // Attributes holds the original admission attributes + Attributes + // VersionedOldObject holds Attributes.OldObject (if non-nil), converted to VersionedKind. + // It must never be mutated. + VersionedOldObject runtime.Object + // VersionedObject holds Attributes.Object (if non-nil), converted to VersionedKind. + // If mutated, Dirty must be set to true by the mutator. + VersionedObject runtime.Object + // VersionedKind holds the fully qualified kind + VersionedKind schema.GroupVersionKind + // Dirty indicates VersionedObject has been modified since being converted from Attributes.Object + Dirty bool +} + +// GetObject overrides the Attributes.GetObject() +func (v *VersionedAttributes) GetObject() runtime.Object { + if v.VersionedObject != nil { + return v.VersionedObject + } + return v.Attributes.GetObject() +} + // ConvertToGVK converts object to the desired gvk. -func ConvertToGVK(obj runtime.Object, gvk schema.GroupVersionKind, o admission.ObjectInterfaces) (runtime.Object, error) { +func ConvertToGVK(obj runtime.Object, gvk schema.GroupVersionKind, o ObjectInterfaces) (runtime.Object, error) { // Unlike other resources, custom resources do not have internal version, so // if obj is a custom resource, it should not need conversion. if obj.GetObjectKind().GroupVersionKind() == gvk { @@ -43,7 +67,7 @@ func ConvertToGVK(obj runtime.Object, gvk schema.GroupVersionKind, o admission.O } // NewVersionedAttributes returns versioned attributes with the old and new object (if non-nil) converted to the requested kind -func NewVersionedAttributes(attr admission.Attributes, gvk schema.GroupVersionKind, o admission.ObjectInterfaces) (*VersionedAttributes, error) { +func NewVersionedAttributes(attr Attributes, gvk schema.GroupVersionKind, o ObjectInterfaces) (*VersionedAttributes, error) { // convert the old and new objects to the requested version versionedAttr := &VersionedAttributes{ Attributes: attr, @@ -72,7 +96,7 @@ func NewVersionedAttributes(attr admission.Attributes, gvk schema.GroupVersionKi // * attr.VersionedObject is used as the source for the new object if Dirty=true (and is round-tripped through attr.Attributes.Object, clearing Dirty in the process) // * attr.Attributes.Object is used as the source for the new object if Dirty=false // * attr.Attributes.OldObject is used as the source for the old object -func ConvertVersionedAttributes(attr *VersionedAttributes, gvk schema.GroupVersionKind, o admission.ObjectInterfaces) error { +func ConvertVersionedAttributes(attr *VersionedAttributes, gvk schema.GroupVersionKind, o ObjectInterfaces) error { // we already have the desired kind, we're done if attr.VersionedKind == gvk { return nil diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/conversion_test.go b/staging/src/k8s.io/apiserver/pkg/admission/conversion_test.go similarity index 97% rename from staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/conversion_test.go rename to staging/src/k8s.io/apiserver/pkg/admission/conversion_test.go index 23c66bb06a3..720512ff0bc 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/conversion_test.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/conversion_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package generic +package admission import ( "encoding/json" @@ -28,7 +28,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/diff" - "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/apis/example" examplev1 "k8s.io/apiserver/pkg/apis/example/v1" example2v1 "k8s.io/apiserver/pkg/apis/example2/v1" @@ -44,7 +43,7 @@ func initiateScheme(t *testing.T) *runtime.Scheme { func TestConvertToGVK(t *testing.T) { scheme := initiateScheme(t) - o := admission.NewObjectInterfacesFromScheme(scheme) + o := NewObjectInterfacesFromScheme(scheme) table := map[string]struct { obj runtime.Object gvk schema.GroupVersionKind @@ -165,13 +164,13 @@ func TestRuntimeSchemeConvert(t *testing.T) { func TestConvertVersionedAttributes(t *testing.T) { scheme := initiateScheme(t) - o := admission.NewObjectInterfacesFromScheme(scheme) + o := NewObjectInterfacesFromScheme(scheme) gvk := func(g, v, k string) schema.GroupVersionKind { return schema.GroupVersionKind{Group: g, Version: v, Kind: k} } - attrs := func(obj, oldObj runtime.Object) admission.Attributes { - return admission.NewAttributesRecord(obj, oldObj, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", "", nil, false, nil) + attrs := func(obj, oldObj runtime.Object) Attributes { + return NewAttributesRecord(obj, oldObj, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", "", nil, false, nil) } u := func(data string) *unstructured.Unstructured { t.Helper() diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go index 1b516f6724f..cb9d4702e73 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go @@ -32,7 +32,6 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/admission" - "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" "k8s.io/apiserver/pkg/cel/library" ) @@ -120,7 +119,7 @@ func objectToResolveVal(r runtime.Object) (interface{}, error) { // ForInput evaluates the compiled CEL expressions converting them into CELEvaluations // errors per evaluation are returned on the Evaluation object // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. -func (f *filter) ForInput(ctx context.Context, versionedAttr *generic.VersionedAttributes, request *admissionv1.AdmissionRequest, inputs OptionalVariableBindings, runtimeCELCostBudget int64) ([]EvaluationResult, error) { +func (f *filter) ForInput(ctx context.Context, versionedAttr *admission.VersionedAttributes, request *admissionv1.AdmissionRequest, inputs OptionalVariableBindings, runtimeCELCostBudget int64) ([]EvaluationResult, error) { // TODO: replace unstructured with ref.Val for CEL variables when native type support is available evaluations := make([]EvaluationResult, len(f.compilationResults)) var err error diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/filter_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/filter_test.go index 3a2871d5a34..07627a576af 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/filter_test.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/filter_test.go @@ -34,7 +34,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" - "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" celconfig "k8s.io/apiserver/pkg/apis/cel" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" @@ -655,7 +654,7 @@ func TestFilter(t *testing.T) { CompilationResults := f.(*filter).compilationResults require.Equal(t, len(validations), len(CompilationResults)) - versionedAttr, err := generic.NewVersionedAttributes(tc.attributes, tc.attributes.GetKind(), newObjectInterfacesForTest()) + versionedAttr, err := admission.NewVersionedAttributes(tc.attributes, tc.attributes.GetKind(), newObjectInterfacesForTest()) if err != nil { t.Fatalf("unexpected error on conversion: %v", err) } @@ -758,7 +757,7 @@ func TestRuntimeCELCostBudget(t *testing.T) { CompilationResults := f.(*filter).compilationResults require.Equal(t, len(validations), len(CompilationResults)) - versionedAttr, err := generic.NewVersionedAttributes(tc.attributes, tc.attributes.GetKind(), newObjectInterfacesForTest()) + versionedAttr, err := admission.NewVersionedAttributes(tc.attributes, tc.attributes.GetKind(), newObjectInterfacesForTest()) if err != nil { t.Fatalf("unexpected error on conversion: %v", err) } diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go index 1c7fad6aa7f..0b11f247fe4 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go @@ -25,7 +25,7 @@ import ( v1 "k8s.io/api/admission/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" + "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/authorization/authorizer" ) @@ -94,7 +94,7 @@ type OptionalVariableBindings struct { type Filter interface { // ForInput converts compiled CEL-typed values into evaluated CEL-typed values // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. - ForInput(ctx context.Context, versionedAttr *generic.VersionedAttributes, request *v1.AdmissionRequest, optionalVars OptionalVariableBindings, runtimeCELCostBudget int64) ([]EvaluationResult, error) + ForInput(ctx context.Context, versionedAttr *admission.VersionedAttributes, request *v1.AdmissionRequest, optionalVars OptionalVariableBindings, runtimeCELCostBudget int64) ([]EvaluationResult, error) // CompilationErrors returns a list of errors from the compilation of the evaluator CompilationErrors() []error diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission_test.go index 9eb430ed16a..e5f3257c225 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission_test.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission_test.go @@ -47,7 +47,6 @@ import ( "k8s.io/apiserver/pkg/admission/initializer" "k8s.io/apiserver/pkg/admission/plugin/cel" "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic" - whgeneric "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" auditinternal "k8s.io/apiserver/pkg/apis/audit" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/features" @@ -253,7 +252,7 @@ type fakeFilter struct { keyId string } -func (f *fakeFilter) ForInput(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, request *admissionv1.AdmissionRequest, inputs cel.OptionalVariableBindings, runtimeCELCostBudget int64) ([]cel.EvaluationResult, error) { +func (f *fakeFilter) ForInput(ctx context.Context, versionedAttr *admission.VersionedAttributes, request *admissionv1.AdmissionRequest, inputs cel.OptionalVariableBindings, runtimeCELCostBudget int64) ([]cel.EvaluationResult, error) { return []cel.EvaluationResult{}, nil } @@ -265,10 +264,10 @@ var _ Validator = &fakeValidator{} type fakeValidator struct { validationFilter, auditAnnotationFilter *fakeFilter - ValidateFunc func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult + ValidateFunc func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult } -func (f *fakeValidator) RegisterDefinition(definition *v1alpha1.ValidatingAdmissionPolicy, validateFunc func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult) { +func (f *fakeValidator) RegisterDefinition(definition *v1alpha1.ValidatingAdmissionPolicy, validateFunc func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult) { //Key must be something that we can decipher from the inputs to Validate so using message which will be on the validationCondition object of evalResult var key string if len(definition.Spec.Validations) > 0 { @@ -285,7 +284,7 @@ func (f *fakeValidator) RegisterDefinition(definition *v1alpha1.ValidatingAdmiss validatorMap[key] = f } -func (f *fakeValidator) Validate(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { +func (f *fakeValidator) Validate(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return f.ValidateFunc(ctx, versionedAttr, versionedParams, runtimeCELCostBudget) } @@ -769,7 +768,7 @@ func TestBasicPolicyDefinitionFailure(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -839,7 +838,7 @@ func TestDefinitionDoesntMatch(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -952,7 +951,7 @@ func TestReconfigureBinding(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -1062,7 +1061,7 @@ func TestRemoveDefinition(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -1131,7 +1130,7 @@ func TestRemoveBinding(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -1241,7 +1240,7 @@ func TestInvalidParamSourceInstanceName(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -1309,7 +1308,7 @@ func TestEmptyParamSource(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -1411,7 +1410,7 @@ func TestMultiplePoliciesSharedParamType(t *testing.T) { } }) - validator1.RegisterDefinition(&policy1, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator1.RegisterDefinition(&policy1, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { evaluations1.Add(1) return ValidateResult{ Decisions: []PolicyDecision{ @@ -1430,7 +1429,7 @@ func TestMultiplePoliciesSharedParamType(t *testing.T) { } }) - validator2.RegisterDefinition(&policy2, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator2.RegisterDefinition(&policy2, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { evaluations2.Add(1) return ValidateResult{ Decisions: []PolicyDecision{ @@ -1540,7 +1539,7 @@ func TestNativeTypeParam(t *testing.T) { } }) - validator.RegisterDefinition(&nativeTypeParamPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(&nativeTypeParamPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { evaluations.Add(1) if _, ok := versionedParams.(*v1.ConfigMap); ok { return ValidateResult{ @@ -1622,7 +1621,7 @@ func TestAuditValidationAction(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -1693,7 +1692,7 @@ func TestWarnValidationAction(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -1752,7 +1751,7 @@ func TestAllValidationActions(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { return ValidateResult{ Decisions: []PolicyDecision{ { @@ -1823,7 +1822,7 @@ func TestAuditAnnotations(t *testing.T) { } }) - validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + validator.RegisterDefinition(denyPolicy, func(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { o, err := meta.Accessor(versionedParams) if err != nil { t.Fatal(err) diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go index 3bbb8e70db3..b4dea874188 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go @@ -41,7 +41,6 @@ import ( "k8s.io/apiserver/pkg/admission/plugin/cel" "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic" "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching" - whgeneric "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" celconfig "k8s.io/apiserver/pkg/apis/cel" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/warning" @@ -267,7 +266,7 @@ func (c *celAdmissionController) Validate( // is scoped outside of the param loop so we only convert once. We defer // conversion so that it is only performed when we know a policy matches, // saving the cost of converting non-matching requests. - var versionedAttr *whgeneric.VersionedAttributes + var versionedAttr *admission.VersionedAttributes // If definition has paramKind, paramRef is required in binding. // If definition has no paramKind, paramRef set in binding will be ignored. @@ -320,7 +319,7 @@ func (c *celAdmissionController) Validate( } if versionedAttr == nil { - va, err := whgeneric.NewVersionedAttributes(a, matchKind, o) + va, err := admission.NewVersionedAttributes(a, matchKind, o) if err != nil { wrappedErr := fmt.Errorf("failed to convert object version: %w", err) addConfigError(wrappedErr, definition, binding) diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go index 4d5a71b2381..0f84152e8b4 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go @@ -27,7 +27,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/plugin/cel" - "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" ) var _ cel.ExpressionAccessor = &ValidationCondition{} @@ -86,5 +85,5 @@ type ValidateResult struct { type Validator interface { // Validate is used to take cel evaluations and convert into decisions // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. - Validate(ctx context.Context, versionedAttr *generic.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult + Validate(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult } diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go index 1740e0125e2..02fe24333a0 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go @@ -28,8 +28,8 @@ import ( v1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/plugin/cel" - "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" "k8s.io/apiserver/pkg/authorization/authorizer" ) @@ -66,7 +66,7 @@ func auditAnnotationEvaluationForError(f v1.FailurePolicyType) PolicyAuditAnnota // Validate takes a list of Evaluation and a failure policy and converts them into actionable PolicyDecisions // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. -func (v *validator) Validate(ctx context.Context, versionedAttr *generic.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { +func (v *validator) Validate(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { var f v1.FailurePolicyType if v.failPolicy == nil { f = v1.Fail diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator_test.go index 06d8bfe25d1..78de36d615a 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator_test.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator_test.go @@ -33,7 +33,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/plugin/cel" - "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" celconfig "k8s.io/apiserver/pkg/apis/cel" ) @@ -44,7 +43,7 @@ type fakeCelFilter struct { throwError bool } -func (f *fakeCelFilter) ForInput(context.Context, *generic.VersionedAttributes, *admissionv1.AdmissionRequest, cel.OptionalVariableBindings, int64) ([]cel.EvaluationResult, error) { +func (f *fakeCelFilter) ForInput(context.Context, *admission.VersionedAttributes, *admissionv1.AdmissionRequest, cel.OptionalVariableBindings, int64) ([]cel.EvaluationResult, error) { if f.throwError { return nil, errors.New("test error") } @@ -63,7 +62,7 @@ func TestValidate(t *testing.T) { unauthorizedReason := metav1.StatusReasonUnauthorized fakeAttr := admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "default", "foo", schema.GroupVersionResource{}, "", admission.Create, nil, false, nil) - fakeVersionedAttr, _ := generic.NewVersionedAttributes(fakeAttr, schema.GroupVersionKind{}, nil) + fakeVersionedAttr, _ := admission.NewVersionedAttributes(fakeAttr, schema.GroupVersionKind{}, nil) cases := []struct { name string @@ -625,7 +624,7 @@ func TestContextCanceled(t *testing.T) { fail := v1.Fail fakeAttr := admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "default", "foo", schema.GroupVersionResource{}, "", admission.Create, nil, false, nil) - fakeVersionedAttr, _ := generic.NewVersionedAttributes(fakeAttr, schema.GroupVersionKind{}, nil) + fakeVersionedAttr, _ := admission.NewVersionedAttributes(fakeAttr, schema.GroupVersionKind{}, nil) fc := cel.NewFilterCompiler() f := fc.Compile([]cel.ExpressionAccessor{&ValidationCondition{Expression: "[1,2,3,4,5,6,7,8,9,10].map(x, [1,2,3,4,5,6,7,8,9,10].map(y, x*y)) == []"}}, cel.OptionalVariableDeclarations{HasParams: false, HasAuthorizer: false}, celconfig.PerCallLimit) v := validator{ diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/interfaces.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/interfaces.go index 4381691ef81..79666d934c9 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/interfaces.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/interfaces.go @@ -19,7 +19,6 @@ package generic import ( "context" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/plugin/webhook" @@ -31,31 +30,6 @@ type Source interface { HasSynced() bool } -// VersionedAttributes is a wrapper around the original admission attributes, adding versioned -// variants of the object and old object. -type VersionedAttributes struct { - // Attributes holds the original admission attributes - admission.Attributes - // VersionedOldObject holds Attributes.OldObject (if non-nil), converted to VersionedKind. - // It must never be mutated. - VersionedOldObject runtime.Object - // VersionedObject holds Attributes.Object (if non-nil), converted to VersionedKind. - // If mutated, Dirty must be set to true by the mutator. - VersionedObject runtime.Object - // VersionedKind holds the fully qualified kind - VersionedKind schema.GroupVersionKind - // Dirty indicates VersionedObject has been modified since being converted from Attributes.Object - Dirty bool -} - -// GetObject overrides the Attributes.GetObject() -func (v *VersionedAttributes) GetObject() runtime.Object { - if v.VersionedObject != nil { - return v.VersionedObject - } - return v.Attributes.GetObject() -} - // WebhookInvocation describes how to call a webhook, including the resource and subresource the webhook registered for, // and the kind that should be sent to the webhook. type WebhookInvocation struct { diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/dispatcher.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/dispatcher.go index cadf753e3cb..ef46eafb5c5 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/dispatcher.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/dispatcher.go @@ -95,7 +95,7 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attrib defer func() { webhookReinvokeCtx.SetLastWebhookInvocationOutput(attr.GetObject()) }() - var versionedAttr *generic.VersionedAttributes + var versionedAttr *admission.VersionedAttributes for i, hook := range hooks { attrForCheck := attr if versionedAttr != nil { @@ -124,12 +124,12 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attrib if versionedAttr == nil { // First webhook, create versioned attributes var err error - if versionedAttr, err = generic.NewVersionedAttributes(attr, invocation.Kind, o); err != nil { + if versionedAttr, err = admission.NewVersionedAttributes(attr, invocation.Kind, o); err != nil { return apierrors.NewInternalError(err) } } else { // Subsequent webhook, convert existing versioned attributes to this webhook's version - if err := generic.ConvertVersionedAttributes(versionedAttr, invocation.Kind, o); err != nil { + if err := admission.ConvertVersionedAttributes(versionedAttr, invocation.Kind, o); err != nil { return apierrors.NewInternalError(err) } } @@ -212,7 +212,7 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attrib // note that callAttrMutatingHook updates attr -func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *admissionregistrationv1.MutatingWebhook, invocation *generic.WebhookInvocation, attr *generic.VersionedAttributes, annotator *webhookAnnotator, o admission.ObjectInterfaces, round, idx int) (bool, error) { +func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *admissionregistrationv1.MutatingWebhook, invocation *generic.WebhookInvocation, attr *admission.VersionedAttributes, annotator *webhookAnnotator, o admission.ObjectInterfaces, round, idx int) (bool, error) { configurationName := invocation.Webhook.GetConfigurationName() changed := false defer func() { annotator.addMutationAnnotation(changed) }() @@ -363,7 +363,7 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *admiss } type webhookAnnotator struct { - attr *generic.VersionedAttributes + attr *admission.VersionedAttributes failedOpenAnnotationKey string patchAnnotationKey string mutationAnnotationKey string @@ -371,7 +371,7 @@ type webhookAnnotator struct { configuration string } -func newWebhookAnnotator(attr *generic.VersionedAttributes, round, idx int, webhook, configuration string) *webhookAnnotator { +func newWebhookAnnotator(attr *admission.VersionedAttributes, round, idx int, webhook, configuration string) *webhookAnnotator { return &webhookAnnotator{ attr: attr, failedOpenAnnotationKey: fmt.Sprintf("%sround_%d_index_%d", MutationAuditAnnotationFailedOpenKeyPrefix, round, idx), diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go index c60d0fb9e75..91b070a3e7c 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" ) @@ -130,7 +131,7 @@ func VerifyAdmissionResponse(uid types.UID, mutating bool, review runtime.Object // CreateAdmissionObjects returns the unique request uid, the AdmissionReview object to send the webhook and to decode the response into, // or an error if the webhook does not support receiving any of the admission review versions we know to send -func CreateAdmissionObjects(versionedAttributes *generic.VersionedAttributes, invocation *generic.WebhookInvocation) (uid types.UID, request, response runtime.Object, err error) { +func CreateAdmissionObjects(versionedAttributes *admission.VersionedAttributes, invocation *generic.WebhookInvocation) (uid types.UID, request, response runtime.Object, err error) { for _, version := range invocation.Webhook.GetAdmissionReviewVersions() { switch version { case admissionv1.SchemeGroupVersion.Version: @@ -151,7 +152,7 @@ func CreateAdmissionObjects(versionedAttributes *generic.VersionedAttributes, in } // CreateV1AdmissionReview creates an AdmissionReview for the provided admission.Attributes -func CreateV1AdmissionReview(uid types.UID, versionedAttributes *generic.VersionedAttributes, invocation *generic.WebhookInvocation) *admissionv1.AdmissionReview { +func CreateV1AdmissionReview(uid types.UID, versionedAttributes *admission.VersionedAttributes, invocation *generic.WebhookInvocation) *admissionv1.AdmissionReview { attr := versionedAttributes.Attributes gvk := invocation.Kind gvr := invocation.Resource @@ -217,7 +218,7 @@ func CreateV1AdmissionReview(uid types.UID, versionedAttributes *generic.Version } // CreateV1beta1AdmissionReview creates an AdmissionReview for the provided admission.Attributes -func CreateV1beta1AdmissionReview(uid types.UID, versionedAttributes *generic.VersionedAttributes, invocation *generic.WebhookInvocation) *admissionv1beta1.AdmissionReview { +func CreateV1beta1AdmissionReview(uid types.UID, versionedAttributes *admission.VersionedAttributes, invocation *generic.WebhookInvocation) *admissionv1beta1.AdmissionReview { attr := versionedAttributes.Attributes gvk := invocation.Kind gvr := invocation.Resource diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview_test.go index dd70409ab8a..8e24df2c1a4 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview_test.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview_test.go @@ -476,7 +476,7 @@ func TestCreateAdmissionObjects(t *testing.T) { testcases := []struct { name string - attrs *generic.VersionedAttributes + attrs *admission.VersionedAttributes invocation *generic.WebhookInvocation expectRequest func(uid types.UID) runtime.Object @@ -501,7 +501,7 @@ func TestCreateAdmissionObjects(t *testing.T) { }, { name: "v1", - attrs: &generic.VersionedAttributes{ + attrs: &admission.VersionedAttributes{ VersionedObject: versionedObj.DeepCopyObject(), VersionedOldObject: versionedObjOld.DeepCopyObject(), Attributes: attrs, @@ -544,7 +544,7 @@ func TestCreateAdmissionObjects(t *testing.T) { }, { name: "v1beta1", - attrs: &generic.VersionedAttributes{ + attrs: &admission.VersionedAttributes{ VersionedObject: versionedObj.DeepCopyObject(), VersionedOldObject: versionedObjOld.DeepCopyObject(), Attributes: attrs, diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/dispatcher.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/dispatcher.go index 025e4fe3880..19c6cdf14c4 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/dispatcher.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/dispatcher.go @@ -67,7 +67,7 @@ var _ generic.Dispatcher = &validatingDispatcher{} func (d *validatingDispatcher) Dispatch(ctx context.Context, attr admission.Attributes, o admission.ObjectInterfaces, hooks []webhook.WebhookAccessor) error { var relevantHooks []*generic.WebhookInvocation // Construct all the versions we need to call our webhooks - versionedAttrs := map[schema.GroupVersionKind]*generic.VersionedAttributes{} + versionedAttrs := map[schema.GroupVersionKind]*admission.VersionedAttributes{} for _, hook := range hooks { invocation, statusError := d.plugin.ShouldCallHook(hook, attr, o) if statusError != nil { @@ -81,7 +81,7 @@ func (d *validatingDispatcher) Dispatch(ctx context.Context, attr admission.Attr if _, ok := versionedAttrs[invocation.Kind]; ok { continue } - versionedAttr, err := generic.NewVersionedAttributes(attr, invocation.Kind, o) + versionedAttr, err := admission.NewVersionedAttributes(attr, invocation.Kind, o) if err != nil { return apierrors.NewInternalError(err) } @@ -215,7 +215,7 @@ func (d *validatingDispatcher) Dispatch(ctx context.Context, attr admission.Attr return errs[0] } -func (d *validatingDispatcher) callHook(ctx context.Context, h *v1.ValidatingWebhook, invocation *generic.WebhookInvocation, attr *generic.VersionedAttributes) error { +func (d *validatingDispatcher) callHook(ctx context.Context, h *v1.ValidatingWebhook, invocation *generic.WebhookInvocation, attr *admission.VersionedAttributes) error { if attr.Attributes.IsDryRun() { if h.SideEffects == nil { return &webhookutil.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook SideEffects is nil"), Status: apierrors.NewBadRequest("Webhook SideEffects is nil")}