@@ -17,8 +17,10 @@ limitations under the License.
1717package loadbalancer
1818
1919import (
20+ "context"
2021 "errors"
2122 "fmt"
23+ "net"
2224 "reflect"
2325 "time"
2426
@@ -27,7 +29,7 @@ import (
2729 "github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/monitors"
2830 "github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/pools"
2931 "k8s.io/apimachinery/pkg/util/wait"
30- "k8s.io/utils/net"
32+ utilsnet "k8s.io/utils/net"
3133 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3234 "sigs.k8s.io/cluster-api/util"
3335
@@ -42,10 +44,28 @@ import (
4244const (
4345 networkPrefix string = "k8s-clusterapi"
4446 kubeapiLBSuffix string = "kubeapi"
47+ resolvedMsg string = "ControlPlaneEndpoint.Host is not an IP address, using the first resolved IP address"
4548)
4649
4750const loadBalancerProvisioningStatusActive = "ACTIVE"
4851
52+ // We wrap the LookupHost function in a variable to allow overriding it in unit tests.
53+ //
54+ //nolint:gocritic
55+ var lookupHost = func (host string ) (string , error ) {
56+ ctx , cancel := context .WithTimeout (context .TODO (), 30 * time .Second )
57+ defer cancel ()
58+ ips , err := net .DefaultResolver .LookupHost (ctx , host )
59+ if err != nil {
60+ return "" , err
61+ }
62+ if ip := net .ParseIP (ips [0 ]); ip == nil {
63+ return "" , fmt .Errorf ("failed to resolve IP address for host %s" , host )
64+ }
65+ return ips [0 ], nil
66+ }
67+
68+ // ReconcileLoadBalancer reconciles the load balancer for the given cluster.
4969func (s * Service ) ReconcileLoadBalancer (openStackCluster * infrav1.OpenStackCluster , clusterName string , apiServerPort int ) (bool , error ) {
5070 loadBalancerName := getLoadBalancerName (clusterName )
5171 s .scope .Logger ().Info ("Reconciling load balancer" , "name" , loadBalancerName )
@@ -57,13 +77,18 @@ func (s *Service) ReconcileLoadBalancer(openStackCluster *infrav1.OpenStackClust
5777 }
5878
5979 var fixedIPAddress string
80+ var err error
81+
6082 switch {
6183 case lbStatus .InternalIP != "" :
6284 fixedIPAddress = lbStatus .InternalIP
6385 case openStackCluster .Spec .APIServerFixedIP != "" :
6486 fixedIPAddress = openStackCluster .Spec .APIServerFixedIP
6587 case openStackCluster .Spec .DisableAPIServerFloatingIP && openStackCluster .Spec .ControlPlaneEndpoint .IsValid ():
66- fixedIPAddress = openStackCluster .Spec .ControlPlaneEndpoint .Host
88+ fixedIPAddress , err = lookupHost (openStackCluster .Spec .ControlPlaneEndpoint .Host )
89+ if err != nil {
90+ return false , fmt .Errorf ("lookup host: %w" , err )
91+ }
6792 }
6893
6994 providers , err := s .loadbalancerClient .ListLoadBalancerProviders ()
@@ -108,7 +133,10 @@ func (s *Service) ReconcileLoadBalancer(openStackCluster *infrav1.OpenStackClust
108133 case openStackCluster .Spec .APIServerFloatingIP != "" :
109134 floatingIPAddress = openStackCluster .Spec .APIServerFloatingIP
110135 case openStackCluster .Spec .ControlPlaneEndpoint .IsValid ():
111- floatingIPAddress = openStackCluster .Spec .ControlPlaneEndpoint .Host
136+ floatingIPAddress , err = lookupHost (openStackCluster .Spec .ControlPlaneEndpoint .Host )
137+ if err != nil {
138+ return false , fmt .Errorf ("lookup host: %w" , err )
139+ }
112140 }
113141 fp , err := s .networkingService .GetOrCreateFloatingIP (openStackCluster , openStackCluster , clusterName , floatingIPAddress )
114142 if err != nil {
@@ -307,9 +335,9 @@ func validateIPs(openStackCluster *infrav1.OpenStackCluster, definedCIDRs []stri
307335
308336 for _ , v := range definedCIDRs {
309337 switch {
310- case net .IsIPv4String (v ):
338+ case utilsnet .IsIPv4String (v ):
311339 marshaledCIDRs = append (marshaledCIDRs , v + "/32" )
312- case net .IsIPv4CIDRString (v ):
340+ case utilsnet .IsIPv4CIDRString (v ):
313341 marshaledCIDRs = append (marshaledCIDRs , v )
314342 default :
315343 record .Warnf (openStackCluster , "FailedIPAddressValidation" , "%s is not a valid IPv4 nor CIDR address and will not get applied to allowed_cidrs" , v )
0 commit comments