@@ -925,6 +925,95 @@ var _ = Describe("OpenStackCluster controller", func() {
925925 Expect (conditions .IsTrue (testCluster , infrav1 .APIEndpointReadyCondition )).To (BeTrue ())
926926 })
927927
928+ It ("should set NetworkReadyCondition to False when ManagedSubnets has more than one element" , func () {
929+ testCluster .SetName ("managed-subnets-too-many" )
930+ testCluster .Spec = infrav1.OpenStackClusterSpec {
931+ IdentityRef : infrav1.OpenStackIdentityReference {
932+ Name : "test-creds" ,
933+ CloudName : "openstack" ,
934+ },
935+ DisableExternalNetwork : ptr .To (true ),
936+ DisableAPIServerFloatingIP : ptr .To (true ),
937+ APIServerFixedIP : ptr .To ("192.168.0.10" ),
938+ ManagedSubnets : []infrav1.SubnetSpec {
939+ {CIDR : "192.168.0.0/24" , DNSNameservers : []string {"8.8.8.8" }},
940+ },
941+ }
942+ err := k8sClient .Create (ctx , testCluster )
943+ Expect (err ).To (BeNil ())
944+ err = k8sClient .Create (ctx , capiCluster )
945+ Expect (err ).To (BeNil ())
946+
947+ // Add a second managed subnet in memory to bypass CRD validation
948+ // (maxItems: 1) and test the controller-level check.
949+ testCluster .Spec .ManagedSubnets = append (testCluster .Spec .ManagedSubnets ,
950+ infrav1.SubnetSpec {CIDR : "192.168.1.0/24" , DNSNameservers : []string {"8.8.8.8" }},
951+ )
952+
953+ log := GinkgoLogr
954+ clientScope , err := mockScopeFactory .NewClientScopeFromObject (ctx , k8sClient , nil , log , testCluster )
955+ Expect (err ).To (BeNil ())
956+ scope := scope .NewWithLogger (clientScope , log )
957+
958+ err = reconcileNetworkComponents (scope , capiCluster , testCluster )
959+ Expect (err ).ToNot (BeNil ())
960+ Expect (err .Error ()).To (ContainSubstring ("ManagedSubnets only supports one element" ))
961+
962+ // Verify NetworkReadyCondition is set to False
963+ Expect (conditions .IsFalse (testCluster , infrav1 .NetworkReadyCondition )).To (BeTrue ())
964+ condition := conditions .Get (testCluster , infrav1 .NetworkReadyCondition )
965+ Expect (condition ).ToNot (BeNil ())
966+ Expect (condition .Reason ).To (Equal (infrav1 .NetworkReconcileFailedReason ))
967+
968+ // Verify ReadyCondition is set to False
969+ Expect (conditions .IsFalse (testCluster , clusterv1 .ReadyCondition )).To (BeTrue ())
970+ })
971+
972+ It ("should set NetworkReadyCondition to False when external network reconciliation fails" , func () {
973+ const externalNetworkID = "a42211a2-4d2c-426f-9413-830e4b4abbbc"
974+
975+ testCluster .SetName ("external-network-failure" )
976+ testCluster .Spec = infrav1.OpenStackClusterSpec {
977+ IdentityRef : infrav1.OpenStackIdentityReference {
978+ Name : "test-creds" ,
979+ CloudName : "openstack" ,
980+ },
981+ ExternalNetwork : & infrav1.NetworkParam {
982+ ID : ptr .To (externalNetworkID ),
983+ },
984+ DisableAPIServerFloatingIP : ptr .To (true ),
985+ APIServerFixedIP : ptr .To ("192.168.0.10" ),
986+ }
987+ err := k8sClient .Create (ctx , testCluster )
988+ Expect (err ).To (BeNil ())
989+ err = k8sClient .Create (ctx , capiCluster )
990+ Expect (err ).To (BeNil ())
991+
992+ log := GinkgoLogr
993+ clientScope , err := mockScopeFactory .NewClientScopeFromObject (ctx , k8sClient , nil , log , testCluster )
994+ Expect (err ).To (BeNil ())
995+ scope := scope .NewWithLogger (clientScope , log )
996+
997+ networkClientRecorder := mockScopeFactory .NetworkClient .EXPECT ()
998+
999+ // External network lookup fails
1000+ networkClientRecorder .GetNetwork (externalNetworkID ).Return (nil , fmt .Errorf ("external network not found" ))
1001+
1002+ err = reconcileNetworkComponents (scope , capiCluster , testCluster )
1003+ Expect (err ).ToNot (BeNil ())
1004+ Expect (err .Error ()).To (ContainSubstring ("failed to reconcile external network" ))
1005+
1006+ // Verify NetworkReadyCondition is set to False
1007+ Expect (conditions .IsFalse (testCluster , infrav1 .NetworkReadyCondition )).To (BeTrue ())
1008+ condition := conditions .Get (testCluster , infrav1 .NetworkReadyCondition )
1009+ Expect (condition ).ToNot (BeNil ())
1010+ Expect (condition .Reason ).To (Equal (infrav1 .NetworkReconcileFailedReason ))
1011+ Expect (condition .Message ).To (ContainSubstring ("Failed to reconcile external network" ))
1012+
1013+ // Verify ReadyCondition is set to False
1014+ Expect (conditions .IsFalse (testCluster , clusterv1 .ReadyCondition )).To (BeTrue ())
1015+ })
1016+
9281017 It ("should set NetworkReadyCondition to False when network lookup fails" , func () {
9291018 const clusterNetworkID = "6c90b532-7ba0-418a-a276-5ae55060b5b0"
9301019
0 commit comments