@@ -19,6 +19,7 @@ package apivalidations
1919import (
2020 . "github.com/onsi/ginkgo/v2"
2121 . "github.com/onsi/gomega"
22+ "github.com/onsi/gomega/format"
2223 corev1 "k8s.io/api/core/v1"
2324 "k8s.io/apimachinery/pkg/types"
2425 "k8s.io/utils/ptr"
@@ -33,16 +34,6 @@ import (
3334var _ = Describe ("OpenStackCluster API validations" , func () {
3435 var namespace * corev1.Namespace
3536
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-
4637 BeforeEach (func () {
4738 namespace = createNamespace ()
4839 })
@@ -58,12 +49,12 @@ var _ = Describe("OpenStackCluster API validations", func() {
5849 })
5950
6051 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" )
6253 })
6354
6455 It ("should only allow controlPlaneEndpoint to be set once" , func () {
6556 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" )
6758
6859 By ("Setting the control plane endpoint" )
6960 cluster .Spec .ControlPlaneEndpoint = & clusterv1.APIEndpoint {
@@ -79,12 +70,12 @@ var _ = Describe("OpenStackCluster API validations", func() {
7970
8071 It ("should allow an empty managed security groups definition" , func () {
8172 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" )
8374 })
8475
8576 It ("should default enabled to true if APIServerLoadBalancer is specified without enabled=true" , func () {
8677 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" )
8879
8980 // Fetch the cluster and check the defaulting
9081 fetchedCluster := & infrav1.OpenStackCluster {}
@@ -95,7 +86,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
9586 })
9687
9788 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" )
9990
10091 // Fetch the cluster and check the defaulting
10192 fetchedCluster := & infrav1.OpenStackCluster {}
@@ -116,19 +107,19 @@ var _ = Describe("OpenStackCluster API validations", func() {
116107 },
117108 },
118109 }
119- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
110+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
120111 })
121112
122113 It ("should not allow bastion.enabled=true without a spec" , func () {
123114 cluster .Spec .Bastion = & infrav1.Bastion {
124115 Enabled : ptr .To (true ),
125116 }
126- Expect (create (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
117+ Expect (createObj (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
127118 })
128119
129120 It ("should not allow an empty Bastion" , func () {
130121 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" )
132123 })
133124
134125 It ("should default bastion.enabled=true" , func () {
@@ -141,7 +132,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
141132 },
142133 },
143134 }
144- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should not succeed" )
135+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should not succeed" )
145136
146137 // Fetch the cluster and check the defaulting
147138 fetchedCluster := & infrav1.OpenStackCluster {}
@@ -162,7 +153,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
162153 },
163154 FloatingIP : ptr .To ("10.0.0.0" ),
164155 }
165- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
156+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
166157 })
167158
168159 It ("should not allow non-IPv4 as bastion floating IP" , func () {
@@ -176,7 +167,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
176167 },
177168 FloatingIP : ptr .To ("foobar" ),
178169 }
179- Expect (create (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
170+ Expect (createObj (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
180171 })
181172 })
182173
@@ -196,7 +187,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
196187 Kind : "FakeKind" ,
197188 Name : "identity-ref" ,
198189 }
199- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
190+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
200191
201192 // Fetch the infrav1 version of the cluster
202193 infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -218,7 +209,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
218209
219210 It ("should not enable an explicitly disabled bastion when converting to v1beta1" , func () {
220211 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" )
222213
223214 // Fetch the infrav1 version of the cluster
224215 infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -233,6 +224,26 @@ var _ = Describe("OpenStackCluster API validations", func() {
233224 Expect (infrav1Bastion ).ToNot (BeNil (), "Bastion should not have been removed" )
234225 Expect (infrav1Bastion .Enabled ).To (Equal (ptr .To (false )), "Bastion should remain disabled" )
235226 })
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+ })
236247 })
237248
238249 Context ("v1alpha6" , func () {
@@ -251,7 +262,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
251262 Kind : "FakeKind" ,
252263 Name : "identity-ref" ,
253264 }
254- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
265+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
255266
256267 // Fetch the infrav1 version of the cluster
257268 infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -273,7 +284,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
273284
274285 It ("should not enable an explicitly disabled bastion when converting to v1beta1" , func () {
275286 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" )
277288
278289 // Fetch the infrav1 version of the cluster
279290 infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -288,5 +299,25 @@ var _ = Describe("OpenStackCluster API validations", func() {
288299 Expect (infrav1Bastion ).ToNot (BeNil (), "Bastion should not have been removed" )
289300 Expect (infrav1Bastion .Enabled ).To (Equal (ptr .To (false )), "Bastion should remain disabled" )
290301 })
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+ })
291322 })
292323})
0 commit comments