@@ -17,12 +17,18 @@ limitations under the License.
17
17
package controllerutil_test
18
18
19
19
import (
20
+ "context"
21
+ "fmt"
22
+ "math/rand"
23
+
20
24
. "github.com/onsi/ginkgo"
21
25
. "github.com/onsi/gomega"
22
26
appsv1 "k8s.io/api/apps/v1"
27
+ corev1 "k8s.io/api/core/v1"
23
28
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
24
29
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25
30
"k8s.io/apimachinery/pkg/runtime"
31
+ "k8s.io/apimachinery/pkg/types"
26
32
"k8s.io/client-go/kubernetes/scheme"
27
33
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
28
34
)
@@ -108,10 +114,162 @@ var _ = Describe("Controllerutil", func() {
108
114
}))
109
115
})
110
116
})
117
+
118
+ Describe ("CreateOrUpdate" , func () {
119
+ var deploy * appsv1.Deployment
120
+ var deplSpec appsv1.DeploymentSpec
121
+ var deplKey types.NamespacedName
122
+
123
+ BeforeEach (func () {
124
+ deploy = & appsv1.Deployment {
125
+ ObjectMeta : metav1.ObjectMeta {
126
+ Name : fmt .Sprintf ("deploy-%d" , rand .Int31 ()),
127
+ Namespace : "default" ,
128
+ },
129
+ }
130
+
131
+ deplSpec = appsv1.DeploymentSpec {
132
+ Selector : & metav1.LabelSelector {
133
+ MatchLabels : map [string ]string {"foo" : "bar" },
134
+ },
135
+ Template : corev1.PodTemplateSpec {
136
+ ObjectMeta : metav1.ObjectMeta {
137
+ Labels : map [string ]string {
138
+ "foo" : "bar" ,
139
+ },
140
+ },
141
+ Spec : corev1.PodSpec {
142
+ Containers : []corev1.Container {
143
+ corev1.Container {
144
+ Name : "busybox" ,
145
+ Image : "busybox" ,
146
+ },
147
+ },
148
+ },
149
+ },
150
+ }
151
+
152
+ deplKey = types.NamespacedName {
153
+ Name : deploy .Name ,
154
+ Namespace : deploy .Namespace ,
155
+ }
156
+ })
157
+
158
+ It ("creates a new object if one doesn't exists" , func () {
159
+ op , err := controllerutil .CreateOrUpdate (context .TODO (), c , deploy , deploymentSpecr (deplSpec ))
160
+
161
+ By ("returning OperationResultCreatedd" )
162
+ Expect (op ).To (BeEquivalentTo (controllerutil .OperationResultCreated ))
163
+
164
+ By ("returning no error" )
165
+ Expect (err ).NotTo (HaveOccurred ())
166
+
167
+ By ("actually having the deployment created" )
168
+ fetched := & appsv1.Deployment {}
169
+ Expect (c .Get (context .TODO (), deplKey , fetched )).To (Succeed ())
170
+ })
171
+
172
+ It ("updates existing object" , func () {
173
+ var scale int32 = 2
174
+ op , err := controllerutil .CreateOrUpdate (context .TODO (), c , deploy , deploymentSpecr (deplSpec ))
175
+ Expect (err ).NotTo (HaveOccurred ())
176
+ Expect (op ).To (BeEquivalentTo (controllerutil .OperationResultCreated ))
177
+
178
+ op , err = controllerutil .CreateOrUpdate (context .TODO (), c , deploy , deploymentScaler (scale ))
179
+ By ("returning OperationResultUpdatedd" )
180
+ Expect (op ).To (BeEquivalentTo (controllerutil .OperationResultUpdated ))
181
+
182
+ By ("returning no error" )
183
+ Expect (err ).NotTo (HaveOccurred ())
184
+
185
+ By ("actually having the deployment scaled" )
186
+ fetched := & appsv1.Deployment {}
187
+ Expect (c .Get (context .TODO (), deplKey , fetched )).To (Succeed ())
188
+ Expect (* fetched .Spec .Replicas ).To (Equal (scale ))
189
+ })
190
+
191
+ It ("updates only changed objects" , func () {
192
+ op , err := controllerutil .CreateOrUpdate (context .TODO (), c , deploy , deploymentSpecr (deplSpec ))
193
+
194
+ Expect (op ).To (BeEquivalentTo (controllerutil .OperationResultCreated ))
195
+ Expect (err ).NotTo (HaveOccurred ())
196
+
197
+ op , err = controllerutil .CreateOrUpdate (context .TODO (), c , deploy , deploymentIdentity )
198
+
199
+ By ("returning OperationResultNone" )
200
+ Expect (op ).To (BeEquivalentTo (controllerutil .OperationResultNone ))
201
+
202
+ By ("returning no error" )
203
+ Expect (err ).NotTo (HaveOccurred ())
204
+ })
205
+
206
+ It ("errors when reconcile renames an object" , func () {
207
+ op , err := controllerutil .CreateOrUpdate (context .TODO (), c , deploy , deploymentSpecr (deplSpec ))
208
+
209
+ Expect (op ).To (BeEquivalentTo (controllerutil .OperationResultCreated ))
210
+ Expect (err ).NotTo (HaveOccurred ())
211
+
212
+ op , err = controllerutil .CreateOrUpdate (context .TODO (), c , deploy , deploymentRenamer )
213
+
214
+ By ("returning OperationResultNone" )
215
+ Expect (op ).To (BeEquivalentTo (controllerutil .OperationResultNone ))
216
+
217
+ By ("returning error" )
218
+ Expect (err ).To (HaveOccurred ())
219
+ })
220
+
221
+ It ("errors when object namespace changes" , func () {
222
+ op , err := controllerutil .CreateOrUpdate (context .TODO (), c , deploy , deploymentSpecr (deplSpec ))
223
+
224
+ Expect (op ).To (BeEquivalentTo (controllerutil .OperationResultCreated ))
225
+ Expect (err ).NotTo (HaveOccurred ())
226
+
227
+ op , err = controllerutil .CreateOrUpdate (context .TODO (), c , deploy , deploymentNamespaceChanger )
228
+
229
+ By ("returning OperationResultNone" )
230
+ Expect (op ).To (BeEquivalentTo (controllerutil .OperationResultNone ))
231
+
232
+ By ("returning error" )
233
+ Expect (err ).To (HaveOccurred ())
234
+ })
235
+ })
111
236
})
112
237
113
238
var _ metav1.Object = & errMetaObj {}
114
239
115
240
type errMetaObj struct {
116
241
metav1.ObjectMeta
117
242
}
243
+
244
+ func deploymentSpecr (spec appsv1.DeploymentSpec ) controllerutil.MutateFn {
245
+ return func (obj runtime.Object ) error {
246
+ deploy := obj .(* appsv1.Deployment )
247
+ deploy .Spec = spec
248
+ return nil
249
+ }
250
+ }
251
+
252
+ var deploymentIdentity controllerutil.MutateFn = func (obj runtime.Object ) error {
253
+ return nil
254
+ }
255
+
256
+ var deploymentRenamer controllerutil.MutateFn = func (obj runtime.Object ) error {
257
+ deploy := obj .(* appsv1.Deployment )
258
+ deploy .Name = fmt .Sprintf ("%s-1" , deploy .Name )
259
+ return nil
260
+ }
261
+
262
+ var deploymentNamespaceChanger controllerutil.MutateFn = func (obj runtime.Object ) error {
263
+ deploy := obj .(* appsv1.Deployment )
264
+ deploy .Namespace = fmt .Sprintf ("%s-1" , deploy .Namespace )
265
+ return nil
266
+ }
267
+
268
+ func deploymentScaler (replicas int32 ) controllerutil.MutateFn {
269
+ fn := func (obj runtime.Object ) error {
270
+ deploy := obj .(* appsv1.Deployment )
271
+ deploy .Spec .Replicas = & replicas
272
+ return nil
273
+ }
274
+ return fn
275
+ }
0 commit comments