k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/registry/networking/ingress/strategy.go (about) 1 /* 2 Copyright 2014 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 ingress 18 19 import ( 20 "context" 21 "fmt" 22 23 apiequality "k8s.io/apimachinery/pkg/api/equality" 24 "k8s.io/apimachinery/pkg/runtime" 25 "k8s.io/apimachinery/pkg/util/validation/field" 26 "k8s.io/apiserver/pkg/storage/names" 27 "k8s.io/kubernetes/pkg/api/legacyscheme" 28 "k8s.io/kubernetes/pkg/apis/networking" 29 "k8s.io/kubernetes/pkg/apis/networking/validation" 30 "sigs.k8s.io/structured-merge-diff/v4/fieldpath" 31 ) 32 33 const ( 34 annotationIngressClass = "kubernetes.io/ingress.class" 35 ) 36 37 // ingressStrategy implements verification logic for Replication Ingress. 38 type ingressStrategy struct { 39 runtime.ObjectTyper 40 names.NameGenerator 41 } 42 43 // Strategy is the default logic that applies when creating and updating Replication Ingress objects. 44 var Strategy = ingressStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} 45 46 // NamespaceScoped returns true because all Ingress' need to be within a namespace. 47 func (ingressStrategy) NamespaceScoped() bool { 48 return true 49 } 50 51 // GetResetFields returns the set of fields that get reset by the strategy 52 // and should not be modified by the user. 53 func (ingressStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set { 54 fields := map[fieldpath.APIVersion]*fieldpath.Set{ 55 "extensions/v1beta1": fieldpath.NewSet( 56 fieldpath.MakePathOrDie("status"), 57 ), 58 "networking.k8s.io/v1beta1": fieldpath.NewSet( 59 fieldpath.MakePathOrDie("status"), 60 ), 61 "networking.k8s.io/v1": fieldpath.NewSet( 62 fieldpath.MakePathOrDie("status"), 63 ), 64 } 65 66 return fields 67 } 68 69 // PrepareForCreate clears the status of an Ingress before creation. 70 func (ingressStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { 71 ingress := obj.(*networking.Ingress) 72 // create cannot set status 73 ingress.Status = networking.IngressStatus{} 74 75 ingress.Generation = 1 76 } 77 78 // PrepareForUpdate clears fields that are not allowed to be set by end users on update. 79 func (ingressStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { 80 newIngress := obj.(*networking.Ingress) 81 oldIngress := old.(*networking.Ingress) 82 // Update is not allowed to set status 83 newIngress.Status = oldIngress.Status 84 85 // Any changes to the spec increment the generation number, any changes to the 86 // status should reflect the generation number of the corresponding object. 87 // See metav1.ObjectMeta description for more information on Generation. 88 if !apiequality.Semantic.DeepEqual(oldIngress.Spec, newIngress.Spec) { 89 newIngress.Generation = oldIngress.Generation + 1 90 } 91 92 } 93 94 // Validate validates ingresses on create. 95 func (ingressStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { 96 ingress := obj.(*networking.Ingress) 97 return validation.ValidateIngressCreate(ingress) 98 } 99 100 // WarningsOnCreate returns warnings for the creation of the given object. 101 func (ingressStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { 102 var warnings []string 103 ingress := obj.(*networking.Ingress) 104 _, annotationIsSet := ingress.Annotations[annotationIngressClass] 105 if annotationIsSet && ingress.Spec.IngressClassName == nil { 106 warnings = append(warnings, fmt.Sprintf("annotation %q is deprecated, please use 'spec.ingressClassName' instead", annotationIngressClass)) 107 } 108 return warnings 109 } 110 111 // Canonicalize normalizes the object after validation. 112 func (ingressStrategy) Canonicalize(obj runtime.Object) { 113 } 114 115 // AllowCreateOnUpdate is false for Ingress; this means POST is needed to create one. 116 func (ingressStrategy) AllowCreateOnUpdate() bool { 117 return false 118 } 119 120 // ValidateUpdate validates ingresses on update. 121 func (ingressStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { 122 return validation.ValidateIngressUpdate(obj.(*networking.Ingress), old.(*networking.Ingress)) 123 } 124 125 // WarningsOnUpdate returns warnings for the given update. 126 func (ingressStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { 127 return nil 128 } 129 130 // AllowUnconditionalUpdate is the default update policy for Ingress objects. 131 func (ingressStrategy) AllowUnconditionalUpdate() bool { 132 return true 133 } 134 135 type ingressStatusStrategy struct { 136 ingressStrategy 137 } 138 139 // StatusStrategy implements logic used to validate and prepare for updates of the status subresource 140 var StatusStrategy = ingressStatusStrategy{Strategy} 141 142 // GetResetFields returns the set of fields that get reset by the strategy 143 // and should not be modified by the user. 144 func (ingressStatusStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set { 145 fields := map[fieldpath.APIVersion]*fieldpath.Set{ 146 "extensions/v1beta1": fieldpath.NewSet( 147 fieldpath.MakePathOrDie("spec"), 148 ), 149 "networking.k8s.io/v1beta1": fieldpath.NewSet( 150 fieldpath.MakePathOrDie("spec"), 151 ), 152 "networking.k8s.io/v1": fieldpath.NewSet( 153 fieldpath.MakePathOrDie("spec"), 154 ), 155 } 156 157 return fields 158 } 159 160 // PrepareForUpdate clears fields that are not allowed to be set by end users on update of status 161 func (ingressStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { 162 newIngress := obj.(*networking.Ingress) 163 oldIngress := old.(*networking.Ingress) 164 // status changes are not allowed to update spec 165 newIngress.Spec = oldIngress.Spec 166 } 167 168 // ValidateUpdate is the default update validation for an end user updating status 169 func (ingressStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { 170 return validation.ValidateIngressStatusUpdate(obj.(*networking.Ingress), old.(*networking.Ingress)) 171 } 172 173 // WarningsOnUpdate returns warnings for the given update. 174 func (ingressStatusStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { 175 return nil 176 }