1
16
17 package deployment
18
19 import (
20 "context"
21 "fmt"
22
23 appsv1beta1 "k8s.io/api/apps/v1beta1"
24 extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
25 apiequality "k8s.io/apimachinery/pkg/api/equality"
26 apivalidation "k8s.io/apimachinery/pkg/api/validation"
27 "k8s.io/apimachinery/pkg/runtime"
28 "k8s.io/apimachinery/pkg/runtime/schema"
29 utilvalidation "k8s.io/apimachinery/pkg/util/validation"
30 "k8s.io/apimachinery/pkg/util/validation/field"
31 genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
32 "k8s.io/apiserver/pkg/registry/rest"
33 "k8s.io/apiserver/pkg/storage/names"
34 "k8s.io/kubernetes/pkg/api/legacyscheme"
35 "k8s.io/kubernetes/pkg/api/pod"
36 "k8s.io/kubernetes/pkg/apis/apps"
37 appsvalidation "k8s.io/kubernetes/pkg/apis/apps/validation"
38 "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
39 )
40
41
42 type deploymentStrategy struct {
43 runtime.ObjectTyper
44 names.NameGenerator
45 }
46
47
48
49 var Strategy = deploymentStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
50
51
52 var _ = rest.GarbageCollectionDeleteStrategy(Strategy)
53
54
55 func (deploymentStrategy) DefaultGarbageCollectionPolicy(ctx context.Context) rest.GarbageCollectionPolicy {
56 return rest.DeleteDependents
57 }
58
59
60 func (deploymentStrategy) NamespaceScoped() bool {
61 return true
62 }
63
64
65
66 func (deploymentStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
67 fields := map[fieldpath.APIVersion]*fieldpath.Set{
68 "apps/v1": fieldpath.NewSet(
69 fieldpath.MakePathOrDie("status"),
70 ),
71 }
72
73 return fields
74 }
75
76
77 func (deploymentStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
78 deployment := obj.(*apps.Deployment)
79 deployment.Status = apps.DeploymentStatus{}
80 deployment.Generation = 1
81
82 pod.DropDisabledTemplateFields(&deployment.Spec.Template, nil)
83 }
84
85
86 func (deploymentStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
87 deployment := obj.(*apps.Deployment)
88 opts := pod.GetValidationOptionsFromPodTemplate(&deployment.Spec.Template, nil)
89 return appsvalidation.ValidateDeployment(deployment, opts)
90 }
91
92
93 func (deploymentStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string {
94 newDeployment := obj.(*apps.Deployment)
95 var warnings []string
96 if msgs := utilvalidation.IsDNS1123Label(newDeployment.Name); len(msgs) != 0 {
97 warnings = append(warnings, fmt.Sprintf("metadata.name: this is used in Pod names and hostnames, which can result in surprising behavior; a DNS label is recommended: %v", msgs))
98 }
99 warnings = append(warnings, pod.GetWarningsForPodTemplate(ctx, field.NewPath("spec", "template"), &newDeployment.Spec.Template, nil)...)
100 return warnings
101 }
102
103
104 func (deploymentStrategy) Canonicalize(obj runtime.Object) {
105 }
106
107
108 func (deploymentStrategy) AllowCreateOnUpdate() bool {
109 return false
110 }
111
112
113 func (deploymentStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
114 newDeployment := obj.(*apps.Deployment)
115 oldDeployment := old.(*apps.Deployment)
116 newDeployment.Status = oldDeployment.Status
117
118 pod.DropDisabledTemplateFields(&newDeployment.Spec.Template, &oldDeployment.Spec.Template)
119
120
121
122
123 if !apiequality.Semantic.DeepEqual(newDeployment.Spec, oldDeployment.Spec) ||
124 !apiequality.Semantic.DeepEqual(newDeployment.Annotations, oldDeployment.Annotations) {
125 newDeployment.Generation = oldDeployment.Generation + 1
126 }
127 }
128
129
130 func (deploymentStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
131 newDeployment := obj.(*apps.Deployment)
132 oldDeployment := old.(*apps.Deployment)
133
134 opts := pod.GetValidationOptionsFromPodTemplate(&newDeployment.Spec.Template, &oldDeployment.Spec.Template)
135 allErrs := appsvalidation.ValidateDeploymentUpdate(newDeployment, oldDeployment, opts)
136
137
138
139
140
141
142 if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found {
143 groupVersion := schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
144 switch groupVersion {
145 case appsv1beta1.SchemeGroupVersion, extensionsv1beta1.SchemeGroupVersion:
146
147 default:
148
149 allErrs = append(allErrs, apivalidation.ValidateImmutableField(newDeployment.Spec.Selector, oldDeployment.Spec.Selector, field.NewPath("spec").Child("selector"))...)
150 }
151 }
152
153 return allErrs
154 }
155
156
157 func (deploymentStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string {
158 var warnings []string
159 newDeployment := obj.(*apps.Deployment)
160 oldDeployment := old.(*apps.Deployment)
161 if newDeployment.Generation != oldDeployment.Generation {
162 warnings = pod.GetWarningsForPodTemplate(ctx, field.NewPath("spec", "template"), &newDeployment.Spec.Template, &oldDeployment.Spec.Template)
163 }
164 return warnings
165 }
166
167 func (deploymentStrategy) AllowUnconditionalUpdate() bool {
168 return true
169 }
170
171 type deploymentStatusStrategy struct {
172 deploymentStrategy
173 }
174
175
176 var StatusStrategy = deploymentStatusStrategy{Strategy}
177
178
179
180 func (deploymentStatusStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
181 return map[fieldpath.APIVersion]*fieldpath.Set{
182 "apps/v1": fieldpath.NewSet(
183 fieldpath.MakePathOrDie("spec"),
184 fieldpath.MakePathOrDie("metadata", "labels"),
185 ),
186 }
187 }
188
189
190 func (deploymentStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
191 newDeployment := obj.(*apps.Deployment)
192 oldDeployment := old.(*apps.Deployment)
193 newDeployment.Spec = oldDeployment.Spec
194 newDeployment.Labels = oldDeployment.Labels
195 }
196
197
198 func (deploymentStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
199 return appsvalidation.ValidateDeploymentStatusUpdate(obj.(*apps.Deployment), old.(*apps.Deployment))
200 }
201
202
203 func (deploymentStatusStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string {
204 return nil
205 }
206
View as plain text