@@ -77,24 +77,25 @@ func TestOpenStackMachineSpecToOpenStackServerSpec(t *testing.T) {
77
77
},
78
78
}
79
79
portOptsWithAdditionalSecurityGroup := []infrav1.PortOpts {
80
- {
81
- Network : & infrav1.NetworkParam {
82
- ID : ptr .To (openStackCluster .Status .Network .ID ),
83
- },
84
- SecurityGroups : []infrav1.SecurityGroupParam {
85
- {
86
- ID : ptr .To (extraSecurityGroupUUID ),
87
- },
88
- },
89
- },
90
- }
80
+ {
81
+ Network : & infrav1.NetworkParam {
82
+ ID : ptr .To (openStackCluster .Status .Network .ID ),
83
+ },
84
+ SecurityGroups : []infrav1.SecurityGroupParam {
85
+ {
86
+ ID : ptr .To (extraSecurityGroupUUID ),
87
+ },
88
+ },
89
+ },
90
+ }
91
91
image := infrav1.ImageParam {Filter : & infrav1.ImageFilter {Name : ptr .To ("my-image" )}}
92
92
tags := []string {"tag1" , "tag2" }
93
93
userData := & corev1.LocalObjectReference {Name : "server-data-secret" }
94
94
tests := []struct {
95
- name string
96
- spec * infrav1.OpenStackMachineSpec
97
- want * infrav1alpha1.OpenStackServerSpec
95
+ name string
96
+ spec * infrav1.OpenStackMachineSpec
97
+ want * infrav1alpha1.OpenStackServerSpec
98
+ wantErr bool
98
99
}{
99
100
{
100
101
name : "Test a minimum OpenStackMachineSpec to OpenStackServerSpec conversion" ,
@@ -155,57 +156,68 @@ func TestOpenStackMachineSpecToOpenStackServerSpec(t *testing.T) {
155
156
},
156
157
},
157
158
{
158
- name : "Test an OpenStackMachineSpec to OpenStackServerSpec conversion with flavorID specified but not flavor" ,
159
- spec : & infrav1.OpenStackMachineSpec {
160
- FlavorID : ptr .To (flavorUUID ),
161
- Image : image ,
162
- SSHKeyName : sshKeyName ,
163
- },
164
- want : & infrav1alpha1.OpenStackServerSpec {
165
- FlavorID : ptr .To (flavorUUID ),
166
- IdentityRef : identityRef ,
167
- Image : image ,
168
- SSHKeyName : sshKeyName ,
169
- Ports : portOpts ,
170
- Tags : tags ,
171
- UserDataRef : userData ,
172
- },
173
- },
174
- {
175
- name : "Cluster network nil, machine defines port network and overrides SG" ,
176
- spec : & infrav1.OpenStackMachineSpec {
177
- Ports : []infrav1.PortOpts {{
178
- Network : & infrav1.NetworkParam {ID : ptr .To (networkUUID )},
179
- }},
180
- SecurityGroups : []infrav1.SecurityGroupParam {{ID : ptr .To (extraSecurityGroupUUID )}},
181
- },
182
- want : & infrav1alpha1.OpenStackServerSpec {
183
- IdentityRef : identityRef ,
184
- Ports : []infrav1.PortOpts {{
185
- Network : & infrav1.NetworkParam {ID : ptr .To (networkUUID )},
186
- SecurityGroups : []infrav1.SecurityGroupParam {{ID : ptr .To (extraSecurityGroupUUID )}},
187
- }},
188
- Tags : tags ,
189
- UserDataRef : userData ,
190
- },
191
- },
192
- {
193
- name : "Cluster network nil, machine defines port network and falls back to cluster SG" ,
194
- spec : & infrav1.OpenStackMachineSpec {
195
- Ports : []infrav1.PortOpts {{
196
- Network : & infrav1.NetworkParam {ID : ptr .To (networkUUID )},
197
- }},
198
- },
199
- want : & infrav1alpha1.OpenStackServerSpec {
200
- IdentityRef : identityRef ,
201
- Ports : []infrav1.PortOpts {{
202
- Network : & infrav1.NetworkParam {ID : ptr .To (networkUUID )},
203
- SecurityGroups : []infrav1.SecurityGroupParam {{ID : ptr .To (workerSecurityGroupUUID )}},
204
- }},
205
- Tags : tags ,
206
- UserDataRef : userData ,
207
- },
208
- },
159
+ name : "Test an OpenStackMachineSpec to OpenStackServerSpec conversion with flavorID specified but not flavor" ,
160
+ spec : & infrav1.OpenStackMachineSpec {
161
+ FlavorID : ptr .To (flavorUUID ),
162
+ Image : image ,
163
+ SSHKeyName : sshKeyName ,
164
+ },
165
+ want : & infrav1alpha1.OpenStackServerSpec {
166
+ FlavorID : ptr .To (flavorUUID ),
167
+ IdentityRef : identityRef ,
168
+ Image : image ,
169
+ SSHKeyName : sshKeyName ,
170
+ Ports : portOpts ,
171
+ Tags : tags ,
172
+ UserDataRef : userData ,
173
+ },
174
+ },
175
+ {
176
+ name : "Cluster network nil, machine defines port network and overrides SG" ,
177
+ spec : & infrav1.OpenStackMachineSpec {
178
+ Ports : []infrav1.PortOpts {{
179
+ Network : & infrav1.NetworkParam {ID : ptr .To (networkUUID )},
180
+ }},
181
+ SecurityGroups : []infrav1.SecurityGroupParam {{ID : ptr .To (extraSecurityGroupUUID )}},
182
+ },
183
+ want : & infrav1alpha1.OpenStackServerSpec {
184
+ IdentityRef : identityRef ,
185
+ Ports : []infrav1.PortOpts {{
186
+ Network : & infrav1.NetworkParam {ID : ptr .To (networkUUID )},
187
+ SecurityGroups : []infrav1.SecurityGroupParam {{ID : ptr .To (extraSecurityGroupUUID )}},
188
+ }},
189
+ Tags : tags ,
190
+ UserDataRef : userData ,
191
+ },
192
+ },
193
+ {
194
+ name : "Cluster network nil, machine defines port network and falls back to cluster SG" ,
195
+ spec : & infrav1.OpenStackMachineSpec {
196
+ Ports : []infrav1.PortOpts {{
197
+ Network : & infrav1.NetworkParam {ID : ptr .To (networkUUID )},
198
+ }},
199
+ },
200
+ want : & infrav1alpha1.OpenStackServerSpec {
201
+ IdentityRef : identityRef ,
202
+ Ports : []infrav1.PortOpts {{
203
+ Network : & infrav1.NetworkParam {ID : ptr .To (networkUUID )},
204
+ SecurityGroups : []infrav1.SecurityGroupParam {{ID : ptr .To (workerSecurityGroupUUID )}},
205
+ }},
206
+ Tags : tags ,
207
+ UserDataRef : userData ,
208
+ },
209
+ },
210
+ {
211
+ name : "Error case: no cluster network and no machine ports" ,
212
+ spec : & infrav1.OpenStackMachineSpec {
213
+ Flavor : ptr .To (flavorName ),
214
+ Image : image ,
215
+ SSHKeyName : sshKeyName ,
216
+ // No ports defined
217
+ },
218
+ want : nil ,
219
+ wantErr : true ,
220
+ },
209
221
}
210
222
for i := range tests {
211
223
tt := tests [i ]
@@ -215,8 +227,17 @@ func TestOpenStackMachineSpecToOpenStackServerSpec(t *testing.T) {
215
227
defaultNetID = openStackCluster .Status .Network .ID
216
228
}
217
229
218
- spec := openStackMachineSpecToOpenStackServerSpec (tt .spec , identityRef , tags , "" , userData , & openStackCluster .Status .WorkerSecurityGroup .ID , defaultNetID )
219
- if ! reflect .DeepEqual (spec , tt .want ) {
230
+ // For the error test case, simulate no cluster network
231
+ if tt .wantErr && tt .name == "Error case: no cluster network and no machine ports" {
232
+ defaultNetID = ""
233
+ }
234
+
235
+ spec , err := openStackMachineSpecToOpenStackServerSpec (tt .spec , identityRef , tags , "" , userData , & openStackCluster .Status .WorkerSecurityGroup .ID , defaultNetID )
236
+ if (err != nil ) != tt .wantErr {
237
+ t .Errorf ("openStackMachineSpecToOpenStackServerSpec() error = %v, wantErr %v" , err , tt .wantErr )
238
+ return
239
+ }
240
+ if ! tt .wantErr && ! reflect .DeepEqual (spec , tt .want ) {
220
241
t .Errorf ("openStackMachineSpecToOpenStackServerSpec() got = %+v, want %+v" , spec , tt .want )
221
242
}
222
243
})
@@ -332,7 +353,7 @@ func TestOpenStackMachineSpecToOpenStackServerSpec_NilNetworkCases(t *testing.T)
332
353
managedSecurityGroupID = & tt .openStackCluster .Status .WorkerSecurityGroup .ID
333
354
}
334
355
335
- spec := openStackMachineSpecToOpenStackServerSpec (
356
+ spec , err := openStackMachineSpecToOpenStackServerSpec (
336
357
tt .spec ,
337
358
identityRef ,
338
359
tags ,
@@ -341,73 +362,14 @@ func TestOpenStackMachineSpecToOpenStackServerSpec_NilNetworkCases(t *testing.T)
341
362
managedSecurityGroupID ,
342
363
defaultNetworkID ,
343
364
)
365
+ if err != nil {
366
+ t .Errorf ("Unexpected error: %v" , err )
367
+ return
368
+ }
344
369
345
370
if ! reflect .DeepEqual (spec .Ports , tt .expectedPorts ) {
346
371
t .Errorf ("Expected ports = %+v, got %+v" , tt .expectedPorts , spec .Ports )
347
372
}
348
373
})
349
374
}
350
375
}
351
-
352
- func TestValidateNetworkConfiguration (t * testing.T ) {
353
- tests := []struct {
354
- name string
355
- clusterNetworkID string
356
- machinePortsCount int
357
- expectError bool
358
- expectedErrorMsg string
359
- description string
360
- }{
361
- {
362
- name : "Valid: cluster has network, machine has no explicit ports" ,
363
- clusterNetworkID : networkUUID ,
364
- machinePortsCount : 0 ,
365
- expectError : false ,
366
- description : "Should succeed when cluster provides default network" ,
367
- },
368
- {
369
- name : "Valid: no cluster network, machine defines explicit ports" ,
370
- clusterNetworkID : "" ,
371
- machinePortsCount : 1 ,
372
- expectError : false ,
373
- description : "Should succeed when machine defines its own networking" ,
374
- },
375
- {
376
- name : "Invalid: no cluster network, no machine ports" ,
377
- clusterNetworkID : "" ,
378
- machinePortsCount : 0 ,
379
- expectError : true ,
380
- expectedErrorMsg : "no network configured: cluster network is missing and machine spec does not define ports with a network" ,
381
- description : "Should fail with terminal error when no networking is configured anywhere" ,
382
- },
383
- {
384
- name : "Valid: cluster network and machine ports both defined" ,
385
- clusterNetworkID : networkUUID ,
386
- machinePortsCount : 2 ,
387
- expectError : false ,
388
- description : "Should succeed when both cluster and machine define networking" ,
389
- },
390
- }
391
-
392
- for _ , tt := range tests {
393
- t .Run (tt .name , func (t * testing.T ) {
394
- // Simulate the validation logic from the controller
395
- hasClusterNetwork := tt .clusterNetworkID != ""
396
- hasMachinePorts := tt .machinePortsCount > 0
397
-
398
- shouldFail := ! hasClusterNetwork && ! hasMachinePorts
399
-
400
- if shouldFail != tt .expectError {
401
- t .Errorf ("Expected error: %v, but validation result: %v" , tt .expectError , shouldFail )
402
- }
403
-
404
- if tt .expectError && shouldFail {
405
- // In the real controller, this would be a terminal error
406
- actualError := "no network configured: cluster network is missing and machine spec does not define ports with a network"
407
- if actualError != tt .expectedErrorMsg {
408
- t .Errorf ("Expected error message: %q, got: %q" , tt .expectedErrorMsg , actualError )
409
- }
410
- }
411
- })
412
- }
413
- }
0 commit comments