@@ -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"
@@ -32,16 +33,6 @@ import (
3233var _ = Describe ("OpenStackCluster API validations" , func () {
3334 var namespace * corev1.Namespace
3435
35- create := func (obj client.Object ) error {
36- err := k8sClient .Create (ctx , obj )
37- if err == nil {
38- DeferCleanup (func () error {
39- return k8sClient .Delete (ctx , obj )
40- })
41- }
42- return err
43- }
44-
4536 BeforeEach (func () {
4637 namespace = createNamespace ()
4738 })
@@ -57,12 +48,12 @@ var _ = Describe("OpenStackCluster API validations", func() {
5748 })
5849
5950 It ("should allow the smallest permissible cluster spec" , func () {
60- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
51+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
6152 })
6253
6354 It ("should only allow controlPlaneEndpoint to be set once" , func () {
6455 By ("Creating a bare cluster" )
65- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
56+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
6657
6758 By ("Setting the control plane endpoint" )
6859 cluster .Spec .ControlPlaneEndpoint = & clusterv1.APIEndpoint {
@@ -78,12 +69,12 @@ var _ = Describe("OpenStackCluster API validations", func() {
7869
7970 It ("should allow an empty managed security groups definition" , func () {
8071 cluster .Spec .ManagedSecurityGroups = & infrav1.ManagedSecurityGroups {}
81- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
72+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
8273 })
8374
8475 It ("should default enabled to true if APIServerLoadBalancer is specified without enabled=true" , func () {
8576 cluster .Spec .APIServerLoadBalancer = & infrav1.APIServerLoadBalancer {}
86- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
77+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
8778
8879 // Fetch the cluster and check the defaulting
8980 fetchedCluster := & infrav1.OpenStackCluster {}
@@ -94,7 +85,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
9485 })
9586
9687 It ("should not default APIServerLoadBalancer if it is not specifid" , func () {
97- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
88+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
9889
9990 // Fetch the cluster and check the defaulting
10091 fetchedCluster := & infrav1.OpenStackCluster {}
@@ -115,19 +106,19 @@ var _ = Describe("OpenStackCluster API validations", func() {
115106 },
116107 },
117108 }
118- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
109+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
119110 })
120111
121112 It ("should not allow bastion.enabled=true without a spec" , func () {
122113 cluster .Spec .Bastion = & infrav1.Bastion {
123114 Enabled : ptr .To (true ),
124115 }
125- Expect (create (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
116+ Expect (createObj (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
126117 })
127118
128119 It ("should not allow an empty Bastion" , func () {
129120 cluster .Spec .Bastion = & infrav1.Bastion {}
130- Expect (create (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
121+ Expect (createObj (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
131122 })
132123
133124 It ("should default bastion.enabled=true" , func () {
@@ -140,7 +131,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
140131 },
141132 },
142133 }
143- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should not succeed" )
134+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should not succeed" )
144135
145136 // Fetch the cluster and check the defaulting
146137 fetchedCluster := & infrav1.OpenStackCluster {}
@@ -161,7 +152,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
161152 },
162153 FloatingIP : ptr .To ("10.0.0.0" ),
163154 }
164- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
155+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
165156 })
166157
167158 It ("should not allow non-IPv4 as bastion floating IP" , func () {
@@ -175,7 +166,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
175166 },
176167 FloatingIP : ptr .To ("foobar" ),
177168 }
178- Expect (create (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
169+ Expect (createObj (cluster )).NotTo (Succeed (), "OpenStackCluster creation should not succeed" )
179170 })
180171 })
181172
@@ -195,7 +186,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
195186 Kind : "FakeKind" ,
196187 Name : "identity-ref" ,
197188 }
198- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
189+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
199190
200191 // Fetch the infrav1 version of the cluster
201192 infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -217,7 +208,7 @@ var _ = Describe("OpenStackCluster API validations", func() {
217208
218209 It ("should not enable an explicitly disabled bastion when converting to v1beta1" , func () {
219210 cluster .Spec .Bastion = & infrav1alpha7.Bastion {Enabled : false }
220- Expect (create (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
211+ Expect (createObj (cluster )).To (Succeed (), "OpenStackCluster creation should succeed" )
221212
222213 // Fetch the infrav1 version of the cluster
223214 infrav1Cluster := & infrav1.OpenStackCluster {}
@@ -232,5 +223,25 @@ var _ = Describe("OpenStackCluster API validations", func() {
232223 Expect (infrav1Bastion ).ToNot (BeNil (), "Bastion should not have been removed" )
233224 Expect (infrav1Bastion .Enabled ).To (Equal (ptr .To (false )), "Bastion should remain disabled" )
234225 })
226+
227+ It ("should downgrade cleanly from infrav1" , func () {
228+ infrav1Cluster := & infrav1.OpenStackCluster {}
229+ infrav1Cluster .Namespace = namespace .Name
230+ infrav1Cluster .GenerateName = clusterNamePrefix
231+ infrav1Cluster .Spec .IdentityRef .CloudName = "test-cloud"
232+ infrav1Cluster .Spec .IdentityRef .Name = "test-credentials"
233+ Expect (createObj (infrav1Cluster )).To (Succeed (), "infrav1 OpenStackCluster creation should succeed" )
234+
235+ // Just fetching the object as v1alpha6 doesn't trigger
236+ // validation failure, so we first fetch it and then
237+ // patch the object with identical contents. The patch
238+ // triggers a validation failure.
239+ cluster := & infrav1alpha7.OpenStackCluster {} //nolint: staticcheck
240+ Expect (k8sClient .Get (ctx , types.NamespacedName {Name : infrav1Cluster .Name , Namespace : infrav1Cluster .Namespace }, cluster )).To (Succeed (), "OpenStackCluster fetch should succeed" )
241+
242+ setObjectGVK (cluster )
243+ cluster .ManagedFields = nil
244+ Expect (k8sClient .Patch (ctx , cluster , client .Apply , client .FieldOwner ("test" ), client .ForceOwnership )).To (Succeed (), format .Object (cluster , 4 ))
245+ })
235246 })
236247})
0 commit comments