k8s.io/kubernetes@v1.29.3/pkg/registry/admissionregistration/validatingadmissionpolicy/strategy.go (about) 1 /* 2 Copyright 2022 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package validatingadmissionpolicy 18 19 import ( 20 "context" 21 22 "sigs.k8s.io/structured-merge-diff/v4/fieldpath" 23 24 apiequality "k8s.io/apimachinery/pkg/api/equality" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/apimachinery/pkg/runtime" 27 "k8s.io/apimachinery/pkg/util/validation/field" 28 "k8s.io/apiserver/pkg/authorization/authorizer" 29 "k8s.io/apiserver/pkg/storage/names" 30 "k8s.io/kubernetes/pkg/api/legacyscheme" 31 "k8s.io/kubernetes/pkg/apis/admissionregistration" 32 "k8s.io/kubernetes/pkg/apis/admissionregistration/validation" 33 "k8s.io/kubernetes/pkg/registry/admissionregistration/resolver" 34 ) 35 36 // validatingAdmissionPolicyStrategy implements verification logic for ValidatingAdmissionPolicy. 37 type validatingAdmissionPolicyStrategy struct { 38 runtime.ObjectTyper 39 names.NameGenerator 40 authorizer authorizer.Authorizer 41 resourceResolver resolver.ResourceResolver 42 } 43 44 // NewStrategy is the default logic that applies when creating and updating validatingAdmissionPolicy objects. 45 func NewStrategy(authorizer authorizer.Authorizer, resourceResolver resolver.ResourceResolver) *validatingAdmissionPolicyStrategy { 46 return &validatingAdmissionPolicyStrategy{ 47 ObjectTyper: legacyscheme.Scheme, 48 NameGenerator: names.SimpleNameGenerator, 49 authorizer: authorizer, 50 resourceResolver: resourceResolver, 51 } 52 } 53 54 // NamespaceScoped returns false because ValidatingAdmissionPolicy is cluster-scoped resource. 55 func (v *validatingAdmissionPolicyStrategy) NamespaceScoped() bool { 56 return false 57 } 58 59 // PrepareForCreate clears the status of an validatingAdmissionPolicy before creation. 60 func (v *validatingAdmissionPolicyStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { 61 ic := obj.(*admissionregistration.ValidatingAdmissionPolicy) 62 ic.Status = admissionregistration.ValidatingAdmissionPolicyStatus{} 63 ic.Generation = 1 64 } 65 66 // PrepareForUpdate clears fields that are not allowed to be set by end users on update. 67 func (v *validatingAdmissionPolicyStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { 68 newIC := obj.(*admissionregistration.ValidatingAdmissionPolicy) 69 oldIC := old.(*admissionregistration.ValidatingAdmissionPolicy) 70 71 // Prevent any update on the Status object 72 newIC.Status = oldIC.Status 73 74 // Any changes to the spec increment the generation number, any changes to the 75 // status should reflect the generation number of the corresponding object. 76 // See metav1.ObjectMeta description for more information on Generation. 77 if !apiequality.Semantic.DeepEqual(oldIC.Spec, newIC.Spec) { 78 newIC.Generation = oldIC.Generation + 1 79 } 80 } 81 82 // Validate validates a new validatingAdmissionPolicy. 83 func (v *validatingAdmissionPolicyStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { 84 errs := validation.ValidateValidatingAdmissionPolicy(obj.(*admissionregistration.ValidatingAdmissionPolicy)) 85 if len(errs) == 0 { 86 // if the object is well-formed, also authorize the paramKind 87 if err := v.authorizeCreate(ctx, obj); err != nil { 88 errs = append(errs, field.Forbidden(field.NewPath("spec", "paramKind"), err.Error())) 89 } 90 } 91 return errs 92 } 93 94 // WarningsOnCreate returns warnings for the creation of the given object. 95 func (v *validatingAdmissionPolicyStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { 96 return nil 97 } 98 99 // Canonicalize normalizes the object after validation. 100 func (v *validatingAdmissionPolicyStrategy) Canonicalize(obj runtime.Object) { 101 } 102 103 // AllowCreateOnUpdate is true for validatingAdmissionPolicy; this means you may create one with a PUT request. 104 func (v *validatingAdmissionPolicyStrategy) AllowCreateOnUpdate() bool { 105 return false 106 } 107 108 // ValidateUpdate is the default update validation for an end user. 109 func (v *validatingAdmissionPolicyStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { 110 errs := validation.ValidateValidatingAdmissionPolicyUpdate(obj.(*admissionregistration.ValidatingAdmissionPolicy), old.(*admissionregistration.ValidatingAdmissionPolicy)) 111 if len(errs) == 0 { 112 // if the object is well-formed, also authorize the paramKind 113 if err := v.authorizeUpdate(ctx, obj, old); err != nil { 114 errs = append(errs, field.Forbidden(field.NewPath("spec", "paramKind"), err.Error())) 115 } 116 } 117 return errs 118 } 119 120 // WarningsOnUpdate returns warnings for the given update. 121 func (v *validatingAdmissionPolicyStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { 122 return nil 123 } 124 125 // AllowUnconditionalUpdate is the default update policy for validatingAdmissionPolicy objects. Status update should 126 // only be allowed if version match. 127 func (v *validatingAdmissionPolicyStrategy) AllowUnconditionalUpdate() bool { 128 return false 129 } 130 131 // GetResetFields returns the set of fields that get reset by the strategy 132 // and should not be modified by the user. 133 func (v *validatingAdmissionPolicyStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set { 134 fields := map[fieldpath.APIVersion]*fieldpath.Set{ 135 "admissionregistration.k8s.io/v1alpha1": fieldpath.NewSet( 136 fieldpath.MakePathOrDie("status"), 137 ), 138 "admissionregistration.k8s.io/v1beta1": fieldpath.NewSet( 139 fieldpath.MakePathOrDie("status"), 140 ), 141 } 142 143 return fields 144 } 145 146 type validatingAdmissionPolicyStatusStrategy struct { 147 *validatingAdmissionPolicyStrategy 148 } 149 150 // ValidateUpdate is the default update validation of an update to the status object. 151 func (s *validatingAdmissionPolicyStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { 152 return validation.ValidateValidatingAdmissionPolicyStatusUpdate(obj.(*admissionregistration.ValidatingAdmissionPolicy), old.(*admissionregistration.ValidatingAdmissionPolicy)) 153 } 154 155 // PrepareForUpdate differs from the main strategy where setting the spec is not 156 // allowed, but setting status is OK. 157 func (s *validatingAdmissionPolicyStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { 158 newIC := obj.(*admissionregistration.ValidatingAdmissionPolicy) 159 oldIC := old.(*admissionregistration.ValidatingAdmissionPolicy) 160 161 // Prevent any update on the Spec object from Status Strategy 162 newIC.Spec = oldIC.Spec 163 164 metav1.ResetObjectMetaForStatus(&newIC.ObjectMeta, &oldIC.ObjectMeta) 165 // No change in the generation. 166 } 167 168 // GetResetFields returns the set of fields that get reset by the strategy 169 // and should not be modified by the user. 170 func (s *validatingAdmissionPolicyStatusStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set { 171 return map[fieldpath.APIVersion]*fieldpath.Set{ 172 "admissionregistration.k8s.io/v1alpha1": fieldpath.NewSet( 173 fieldpath.MakePathOrDie("spec"), 174 fieldpath.MakePathOrDie("metadata"), 175 ), 176 "admissionregistration.k8s.io/v1beta1": fieldpath.NewSet( 177 fieldpath.MakePathOrDie("spec"), 178 fieldpath.MakePathOrDie("metadata"), 179 ), 180 } 181 } 182 183 // NewStatusStrategy creates a strategy for operating the status object. 184 func NewStatusStrategy(policyStrategy *validatingAdmissionPolicyStrategy) *validatingAdmissionPolicyStatusStrategy { 185 return &validatingAdmissionPolicyStatusStrategy{validatingAdmissionPolicyStrategy: policyStrategy} 186 }