@@ -23,6 +23,8 @@ import (
23
23
"reflect"
24
24
"time"
25
25
26
+ "github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
27
+ "github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
26
28
corev1 "k8s.io/api/core/v1"
27
29
apierrors "k8s.io/apimachinery/pkg/api/errors"
28
30
"k8s.io/client-go/tools/record"
@@ -496,36 +498,41 @@ func reconcileNetworkComponents(scope scope.Scope, cluster *clusterv1.Cluster, o
496
498
if openStackCluster .Spec .NodeCIDR == "" {
497
499
scope .Logger ().V (4 ).Info ("No need to reconcile network, searching network and subnet instead" )
498
500
499
- netOpts := openStackCluster .Spec .Network .ToListOpt ()
500
- networkList , err := networkingService .GetNetworksByFilter (& netOpts )
501
- if err != nil {
502
- handleUpdateOSCError (openStackCluster , fmt .Errorf ("failed to find network: %w" , err ))
503
- return fmt .Errorf ("failed to find network: %w" , err )
504
- }
505
- if len (networkList ) == 0 {
506
- handleUpdateOSCError (openStackCluster , fmt .Errorf ("failed to find any network" ))
507
- return fmt .Errorf ("failed to find any network" )
508
- }
509
- if len (networkList ) > 1 {
510
- handleUpdateOSCError (openStackCluster , fmt .Errorf ("found multiple networks (result: %v)" , networkList ))
511
- return fmt .Errorf ("found multiple networks (result: %v)" , networkList )
512
- }
513
501
if openStackCluster .Status .Network == nil {
514
502
openStackCluster .Status .Network = & infrav1.NetworkStatusWithSubnets {}
515
503
}
516
- openStackCluster .Status .Network .ID = networkList [0 ].ID
517
- openStackCluster .Status .Network .Name = networkList [0 ].Name
518
- openStackCluster .Status .Network .Tags = networkList [0 ].Tags
519
504
520
- subnets , err := filterSubnets ( networkingService , openStackCluster )
505
+ err := getCAPONetwork ( openStackCluster , networkingService )
521
506
if err != nil {
522
507
return err
523
508
}
524
509
510
+ filteredSubnets , err := filterSubnets (networkingService , openStackCluster )
511
+ if err != nil {
512
+ return err
513
+ }
514
+
515
+ var subnets []infrav1.Subnet
516
+ for subnet := range filteredSubnets {
517
+ filterSubnet := & filteredSubnets [subnet ]
518
+ subnets = append (subnets , infrav1.Subnet {
519
+ ID : filterSubnet .ID ,
520
+ Name : filterSubnet .Name ,
521
+ CIDR : filterSubnet .CIDR ,
522
+ Tags : filterSubnet .Tags ,
523
+ })
524
+ }
525
+
525
526
if err := utils .ValidateSubnets (subnets ); err != nil {
526
527
return err
527
528
}
528
529
openStackCluster .Status .Network .Subnets = subnets
530
+
531
+ // If network is not yet populated on the Status, use networkID defined in the filtered subnets to get the Network.
532
+ err = populateCAPONetworkFromSubnet (networkingService , filteredSubnets , openStackCluster )
533
+ if err != nil {
534
+ return err
535
+ }
529
536
} else {
530
537
err := networkingService .ReconcileNetwork (openStackCluster , clusterName )
531
538
if err != nil {
@@ -674,18 +681,23 @@ func handleUpdateOSCError(openstackCluster *infrav1.OpenStackCluster, message er
674
681
}
675
682
676
683
// filterSubnets retrieves the subnets based on the Subnet filters specified on OpenstackCluster.
677
- func filterSubnets (networkingService * networking.Service , openStackCluster * infrav1.OpenStackCluster ) ([]infrav1.Subnet , error ) {
678
- var subnets []infrav1.Subnet
684
+ func filterSubnets (networkingService * networking.Service , openStackCluster * infrav1.OpenStackCluster ) ([]subnets.Subnet , error ) {
685
+ var filteredSubnets []subnets.Subnet
686
+ var err error
679
687
openStackClusterSubnets := openStackCluster .Spec .Subnets
680
- if openStackCluster .Status .Network == nil {
681
- return nil , nil
688
+ networkID := ""
689
+ if openStackCluster .Status .Network != nil {
690
+ networkID = openStackCluster .Status .Network .ID
682
691
}
683
- networkID := openStackCluster . Status . Network . ID
692
+
684
693
if len (openStackClusterSubnets ) == 0 {
694
+ if networkID == "" {
695
+ return nil , nil
696
+ }
685
697
empty := & infrav1.SubnetFilter {}
686
698
listOpt := empty .ToListOpt ()
687
699
listOpt .NetworkID = networkID
688
- filteredSubnets , err : = networkingService .GetSubnetsByFilter (listOpt )
700
+ filteredSubnets , err = networkingService .GetSubnetsByFilter (listOpt )
689
701
if err != nil {
690
702
err = fmt .Errorf ("failed to find subnets: %w" , err )
691
703
if errors .Is (err , networking .ErrFilterMatch ) {
@@ -696,9 +708,6 @@ func filterSubnets(networkingService *networking.Service, openStackCluster *infr
696
708
if len (filteredSubnets ) > 2 {
697
709
return nil , fmt .Errorf ("more than two subnets found in the Network. Specify the subnets in the OpenStackCluster.Spec instead" )
698
710
}
699
- for subnet := range filteredSubnets {
700
- subnets = networkingService .ConvertOpenStackSubnetToCAPOSubnet (subnets , & filteredSubnets [subnet ])
701
- }
702
711
} else {
703
712
for subnet := range openStackClusterSubnets {
704
713
filteredSubnet , err := networkingService .GetNetworkSubnetByFilter (networkID , & openStackClusterSubnets [subnet ])
@@ -709,8 +718,55 @@ func filterSubnets(networkingService *networking.Service, openStackCluster *infr
709
718
}
710
719
return nil , err
711
720
}
712
- subnets = networkingService . ConvertOpenStackSubnetToCAPOSubnet ( subnets , filteredSubnet )
721
+ filteredSubnets = append ( filteredSubnets , * filteredSubnet )
713
722
}
714
723
}
715
- return subnets , nil
724
+ return filteredSubnets , nil
725
+ }
726
+
727
+ // convertOpenStackNetworkToCAPONetwork converts an OpenStack network to a capo network.
728
+ // It returns the converted subnet.
729
+ func convertOpenStackNetworkToCAPONetwork (openStackCluster * infrav1.OpenStackCluster , network * networks.Network ) {
730
+ openStackCluster .Status .Network .ID = network .ID
731
+ openStackCluster .Status .Network .Name = network .Name
732
+ openStackCluster .Status .Network .Tags = network .Tags
733
+ }
734
+
735
+ // populateCAPONetworkFromSubnet gets a network based on the networkID of the subnets and converts it to the CAPO format.
736
+ // It returns an error in case it failed to retrieve the network.
737
+ func populateCAPONetworkFromSubnet (networkingService * networking.Service , subnets []subnets.Subnet , openStackCluster * infrav1.OpenStackCluster ) error {
738
+ if openStackCluster .Status .Network .ID == "" && len (subnets ) > 0 {
739
+ if len (subnets ) > 1 && subnets [0 ].NetworkID != subnets [1 ].NetworkID {
740
+ return fmt .Errorf ("unable to identify the Network to use. NetworkID from Subnets differ: %s, %s" , subnets [0 ].NetworkID , subnets [1 ].NetworkID )
741
+ }
742
+
743
+ network , err := networkingService .GetNetworkByID (subnets [0 ].NetworkID )
744
+ if err != nil {
745
+ return err
746
+ }
747
+ convertOpenStackNetworkToCAPONetwork (openStackCluster , network )
748
+ }
749
+ return nil
750
+ }
751
+
752
+ // getCAPONetwork gets a network based on a filter.
753
+ // It returns an error in case it failed to retrieve the network.
754
+ func getCAPONetwork (openStackCluster * infrav1.OpenStackCluster , networkingService * networking.Service ) error {
755
+ emptyNetwork := infrav1.NetworkFilter {}
756
+ if openStackCluster .Spec .Network != emptyNetwork {
757
+ netOpts := openStackCluster .Spec .Network .ToListOpt ()
758
+ networkList , err := networkingService .GetNetworksByFilter (& netOpts )
759
+ if err != nil {
760
+ handleUpdateOSCError (openStackCluster , fmt .Errorf ("failed to find network: %w" , err ))
761
+ return fmt .Errorf ("failed to find network: %w" , err )
762
+ }
763
+ if len (networkList ) == 0 {
764
+ handleUpdateOSCError (openStackCluster , fmt .Errorf ("failed to find any network" ))
765
+ return fmt .Errorf ("failed to find any network" )
766
+ }
767
+ if len (networkList ) == 1 {
768
+ convertOpenStackNetworkToCAPONetwork (openStackCluster , & networkList [0 ])
769
+ }
770
+ }
771
+ return nil
716
772
}
0 commit comments