@@ -19,6 +19,7 @@ package apivalidations
19
19
import (
20
20
. "github.com/onsi/ginkgo/v2"
21
21
. "github.com/onsi/gomega"
22
+ "github.com/onsi/gomega/format"
22
23
corev1 "k8s.io/api/core/v1"
23
24
"k8s.io/apimachinery/pkg/types"
24
25
"k8s.io/utils/ptr"
@@ -33,16 +34,6 @@ import (
33
34
var _ = Describe ("OpenStackCluster API validations" , func () {
34
35
var namespace * corev1.Namespace
35
36
36
- create := func (obj client.Object ) error {
37
- err := k8sClient .Create (ctx , obj )
38
- if err == nil {
39
- DeferCleanup (func () error {
40
- return k8sClient .Delete (ctx , obj )
41
- })
42
- }
43
- return err
44
- }
45
-
46
37
BeforeEach (func () {
47
38
namespace = createNamespace ()
48
39
})
@@ -58,12 +49,12 @@ var _ = Describe("OpenStackCluster API validations", func() {
58
49
})
59
50
60
51
It ("should allow the smallest permissible cluster spec" , func () {
61
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
52
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
62
53
})
63
54
64
55
It ("should only allow controlPlaneEndpoint to be set once" , func () {
65
56
By ("Creating a bare cluster" )
66
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
57
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
67
58
68
59
By ("Setting the control plane endpoint" )
69
60
cluster .Spec .ControlPlaneEndpoint = & clusterv1.APIEndpoint {
@@ -79,12 +70,12 @@ var _ = Describe("OpenStackCluster API validations", func() {
79
70
80
71
It ("should allow an empty managed security groups definition" , func () {
81
72
cluster .Spec .ManagedSecurityGroups = & infrav1.ManagedSecurityGroups {}
82
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
73
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
83
74
})
84
75
85
76
It ("should default enabled to true if APIServerLoadBalancer is specified without enabled=true" , func () {
86
77
cluster .Spec .APIServerLoadBalancer = & infrav1.APIServerLoadBalancer {}
87
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
78
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
88
79
89
80
// Fetch the cluster and check the defaulting
90
81
fetchedCluster := & infrav1.OpenStackCluster {}
@@ -95,7 +86,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
95
86
})
96
87
97
88
It ("should not default APIServerLoadBalancer if it is not specifid" , func () {
98
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
89
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
99
90
100
91
// Fetch the cluster and check the defaulting
101
92
fetchedCluster := & infrav1.OpenStackCluster {}
@@ -116,19 +107,19 @@ var _ = Describe("OpenStackCluster API validations", func() {
116
107
},
117
108
},
118
109
}
119
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
110
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
120
111
})
121
112
122
113
It ("should not allow bastion.enabled=true without a spec" , func () {
123
114
cluster .Spec .Bastion = & infrav1.Bastion {
124
115
Enabled : ptr .To (true ),
125
116
}
126
- Expect (create (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
117
+ Expect (createObj (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
127
118
})
128
119
129
120
It ("should not allow an empty Bastion" , func () {
130
121
cluster .Spec .Bastion = & infrav1.Bastion {}
131
- Expect (create (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
122
+ Expect (createObj (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
132
123
})
133
124
134
125
It ("should default bastion.enabled=true" , func () {
@@ -141,7 +132,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
141
132
},
142
133
},
143
134
}
144
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should not succeed" )
135
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should not succeed" )
145
136
146
137
// Fetch the cluster and check the defaulting
147
138
fetchedCluster := & infrav1.OpenStackCluster {}
@@ -162,7 +153,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
162
153
},
163
154
FloatingIP : ptr .To ("10.0.0.0" ),
164
155
}
165
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
156
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
166
157
})
167
158
168
159
It ("should not allow non-IPv4 as bastion floating IP" , func () {
@@ -176,7 +167,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
176
167
},
177
168
FloatingIP : ptr .To ("foobar" ),
178
169
}
179
- Expect (create (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
170
+ Expect (createObj (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
180
171
})
181
172
})
182
173
@@ -196,7 +187,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
196
187
Kind : "FakeKind" ,
197
188
Name : "identity-ref" ,
198
189
}
199
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
190
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
200
191
201
192
// Fetch the infrav1 version of the cluster
202
193
infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -218,7 +209,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
218
209
219
210
It ("should not enable an explicitly disabled bastion when converting to v1beta1" , func () {
220
211
cluster .Spec .Bastion = & infrav1alpha7.Bastion {Enabled : false }
221
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
212
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
222
213
223
214
// Fetch the infrav1 version of the cluster
224
215
infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -233,6 +224,26 @@ var _ = Describe("OpenStackCluster API validations", func() {
233
224
Expect (infrav1Bastion ).ToNot (BeNil (), "Bastion should not have been removed" )
234
225
Expect (infrav1Bastion .Enabled ).To (Equal (ptr .To (false )), "Bastion should remain disabled" )
235
226
})
227
+
228
+ It ("should downgrade cleanly from infrav1" , func () {
229
+ infrav1Cluster := & infrav1.OpenStackCluster {}
230
+ infrav1Cluster .Namespace = namespace .Name
231
+ infrav1Cluster .GenerateName = clusterNamePrefix
232
+ infrav1Cluster .Spec .IdentityRef .CloudName = "test-cloud"
233
+ infrav1Cluster .Spec .IdentityRef .Name = "test-credentials"
234
+ Expect (createObj (infrav1Cluster )).To (Succeed (), "infrav1 OpenStackCluster creation should succeed" )
235
+
236
+ // Just fetching the object as v1alpha6 doesn't trigger
237
+ // validation failure, so we first fetch it and then
238
+ // patch the object with identical contents. The patch
239
+ // triggers a validation failure.
240
+ cluster := & infrav1alpha7.OpenStackCluster {}
241
+ Expect (k8sClient .Get (ctx , types.NamespacedName {Name : infrav1Cluster .Name , Namespace : infrav1Cluster .Namespace }, cluster )).To (Succeed (), "OpenStackCluster fetch should succeed" )
242
+
243
+ setObjectGVK (cluster )
244
+ cluster .ManagedFields = nil
245
+ Expect (k8sClient .Patch (ctx , cluster , client .Apply , client .FieldOwner ("test" ), client .ForceOwnership )).To (Succeed (), format .Object (cluster , 4 ))
246
+ })
236
247
})
237
248
238
249
Context ("v1alpha6" , func () {
@@ -251,7 +262,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
251
262
Kind : "FakeKind" ,
252
263
Name : "identity-ref" ,
253
264
}
254
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
265
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
255
266
256
267
// Fetch the infrav1 version of the cluster
257
268
infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -273,7 +284,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
273
284
274
285
It ("should not enable an explicitly disabled bastion when converting to v1beta1" , func () {
275
286
cluster .Spec .Bastion = & infrav1alpha6.Bastion {Enabled : false }
276
- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
287
+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
277
288
278
289
// Fetch the infrav1 version of the cluster
279
290
infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -288,5 +299,25 @@ var _ = Describe("OpenStackCluster API validations", func() {
288
299
Expect (infrav1Bastion ).ToNot (BeNil (), "Bastion should not have been removed" )
289
300
Expect (infrav1Bastion .Enabled ).To (Equal (ptr .To (false )), "Bastion should remain disabled" )
290
301
})
302
+
303
+ It ("should downgrade cleanly from infrav1" , func () {
304
+ infrav1Cluster := & infrav1.OpenStackCluster {}
305
+ infrav1Cluster .Namespace = namespace .Name
306
+ infrav1Cluster .GenerateName = clusterNamePrefix
307
+ infrav1Cluster .Spec .IdentityRef .CloudName = "test-cloud"
308
+ infrav1Cluster .Spec .IdentityRef .Name = "test-credentials"
309
+ Expect (createObj (infrav1Cluster )).To (Succeed (), "infrav1 OpenStackCluster creation should succeed" )
310
+
311
+ // Just fetching the object as v1alpha6 doesn't trigger
312
+ // validation failure, so we first fetch it and then
313
+ // patch the object with identical contents. The patch
314
+ // triggers a validation failure.
315
+ cluster := & infrav1alpha6.OpenStackCluster {} //nolint:staticcheck
316
+ Expect (k8sClient .Get (ctx , types.NamespacedName {Name : infrav1Cluster .Name , Namespace : infrav1Cluster .Namespace }, cluster )).To (Succeed (), "OpenStackCluster fetch should succeed" )
317
+
318
+ setObjectGVK (cluster )
319
+ cluster .ManagedFields = nil
320
+ Expect (k8sClient .Patch (ctx , cluster , client .Apply , client .FieldOwner ("test" ), client .ForceOwnership )).To (Succeed (), format .Object (cluster , 4 ))
321
+ })
291
322
})
292
323
})
0 commit comments