@@ -285,6 +285,70 @@ var _ = Describe("StackitMachine Controller", func() {
285285 expectCondition (got .Status .Conditions , infrav1 .MachineReadyCondition , metav1 .ConditionFalse , "InvalidFailureDomain" )
286286 })
287287
288+ //nolint:dupl // Failure domain resolution cases test explicit failureDomain vs cluster default.
289+ It ("respects Machine.spec.failureDomain when StackitMachine.spec.availabilityZone is empty" , func () {
290+ got := & infrav1.StackitMachine {}
291+ Expect (k8sClient .Get (ctx , stackitKey , got )).To (Succeed ())
292+ got .Spec .AvailabilityZone = ""
293+ Expect (k8sClient .Update (ctx , got )).To (Succeed ())
294+
295+ ownerMachine := & clusterv1.Machine {}
296+ Expect (k8sClient .Get (ctx , types.NamespacedName {Name : machineName , Namespace : namespace }, ownerMachine )).To (Succeed ())
297+ ownerMachine .Spec .FailureDomain = "eu01-2"
298+ Expect (k8sClient .Update (ctx , ownerMachine )).To (Succeed ())
299+
300+ result , err := reconciler .Reconcile (ctx , request )
301+ Expect (err ).NotTo (HaveOccurred ())
302+ Expect (result ).To (Equal (reconcile.Result {}))
303+ Expect (fakeCloud .ServerCount ()).To (Equal (1 ))
304+ Expect (fakeCloud .LastCreateServerInput .AvailabilityZone ).To (Equal ("eu01-2" ))
305+
306+ Expect (k8sClient .Get (ctx , stackitKey , got )).To (Succeed ())
307+ Expect (got .Status .Ready ).To (BeTrue ())
308+ Expect (got .Status .AvailabilityZone ).To (Equal ("eu01-2" ))
309+ })
310+
311+ //nolint:dupl // Failure domain resolution cases test explicit failureDomain vs cluster default.
312+ It ("defaults to the first failure domain when neither failureDomain nor availabilityZone is set" , func () {
313+ got := & infrav1.StackitMachine {}
314+ Expect (k8sClient .Get (ctx , stackitKey , got )).To (Succeed ())
315+ got .Spec .AvailabilityZone = ""
316+ Expect (k8sClient .Update (ctx , got )).To (Succeed ())
317+
318+ ownerMachine := & clusterv1.Machine {}
319+ Expect (k8sClient .Get (ctx , types.NamespacedName {Name : machineName , Namespace : namespace }, ownerMachine )).To (Succeed ())
320+ ownerMachine .Spec .FailureDomain = ""
321+ Expect (k8sClient .Update (ctx , ownerMachine )).To (Succeed ())
322+
323+ result , err := reconciler .Reconcile (ctx , request )
324+ Expect (err ).NotTo (HaveOccurred ())
325+ Expect (result ).To (Equal (reconcile.Result {}))
326+ Expect (fakeCloud .ServerCount ()).To (Equal (1 ))
327+ Expect (fakeCloud .LastCreateServerInput .AvailabilityZone ).To (Equal ("eu01-1" ))
328+
329+ Expect (k8sClient .Get (ctx , stackitKey , got )).To (Succeed ())
330+ Expect (got .Status .Ready ).To (BeTrue ())
331+ Expect (got .Status .AvailabilityZone ).To (Equal ("eu01-1" ))
332+ })
333+
334+ It ("does not create a VM when Machine.spec.failureDomain is outside published failure domains" , func () {
335+ ownerMachine := & clusterv1.Machine {}
336+ Expect (k8sClient .Get (ctx , types.NamespacedName {Name : machineName , Namespace : namespace }, ownerMachine )).To (Succeed ())
337+ ownerMachine .Spec .FailureDomain = "eu01-9"
338+ Expect (k8sClient .Update (ctx , ownerMachine )).To (Succeed ())
339+
340+ result , err := reconciler .Reconcile (ctx , request )
341+ Expect (err ).NotTo (HaveOccurred ())
342+ Expect (result ).To (Equal (reconcile.Result {}))
343+ Expect (fakeCloud .ServerCount ()).To (Equal (0 ))
344+
345+ got := & infrav1.StackitMachine {}
346+ Expect (k8sClient .Get (ctx , stackitKey , got )).To (Succeed ())
347+ Expect (got .Status .Ready ).To (BeFalse ())
348+ expectCondition (got .Status .Conditions , infrav1 .MachineInstanceReadyCondition , metav1 .ConditionFalse , "InvalidFailureDomain" )
349+ expectCondition (got .Status .Conditions , infrav1 .MachineReadyCondition , metav1 .ConditionFalse , "InvalidFailureDomain" )
350+ })
351+
288352 It ("requeues on unauthorized credentials and recovers once they are corrected" , func () {
289353 reconciler .CloudClientFactory = func (context.Context , cloud.Credentials ) (cloud.Client , error ) {
290354 return nil , fmt .Errorf ("authenticate: %w" , cloud .ErrUnauthorized )
0 commit comments