Skip to content

Commit d41b4ea

Browse files
committed
loadbalancer: resolve ControlPlaneEndpoint.Host when needed
`ControlPlaneEndpoint.Host` is not guaranteed to be an IP address, it can also be an hostname. Now we'll try to lookup the hostname if it's not an IP and set that for the LB VipAddress.
1 parent 292abc1 commit d41b4ea

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

pkg/cloud/services/loadbalancer/loadbalancer.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package loadbalancer
1919
import (
2020
"errors"
2121
"fmt"
22+
"net"
2223
"reflect"
2324
"time"
2425

@@ -27,7 +28,7 @@ import (
2728
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/monitors"
2829
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/pools"
2930
"k8s.io/apimachinery/pkg/util/wait"
30-
"k8s.io/utils/net"
31+
utilsnet "k8s.io/utils/net"
3132
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3233
"sigs.k8s.io/cluster-api/util"
3334

@@ -46,16 +47,30 @@ const (
4647

4748
const loadBalancerProvisioningStatusActive = "ACTIVE"
4849

50+
// Wrapper for net.LookupHost so we can override in the test
51+
var lookupHost = func(host string) (addrs []string, err error) {
52+
if net.ParseIP(host) != nil {
53+
return []string{host}, nil
54+
}
55+
return net.LookupHost(host)
56+
}
57+
4958
func (s *Service) ReconcileLoadBalancer(openStackCluster *infrav1.OpenStackCluster, clusterName string, apiServerPort int) (bool, error) {
5059
loadBalancerName := getLoadBalancerName(clusterName)
5160
s.scope.Logger().Info("Reconciling load balancer", "name", loadBalancerName)
5261

5362
var fixedIPAddress string
63+
var err error
64+
5465
switch {
5566
case openStackCluster.Spec.APIServerFixedIP != "":
5667
fixedIPAddress = openStackCluster.Spec.APIServerFixedIP
5768
case openStackCluster.Spec.DisableAPIServerFloatingIP && openStackCluster.Spec.ControlPlaneEndpoint.IsValid():
58-
fixedIPAddress = openStackCluster.Spec.ControlPlaneEndpoint.Host
69+
ips, err := lookupHost(openStackCluster.Spec.ControlPlaneEndpoint.Host)
70+
if err != nil {
71+
return false, err
72+
}
73+
fixedIPAddress = ips[0]
5974
}
6075

6176
providers, err := s.loadbalancerClient.ListLoadBalancerProviders()
@@ -93,7 +108,11 @@ func (s *Service) ReconcileLoadBalancer(openStackCluster *infrav1.OpenStackClust
93108
case openStackCluster.Spec.APIServerFloatingIP != "":
94109
floatingIPAddress = openStackCluster.Spec.APIServerFloatingIP
95110
case openStackCluster.Spec.ControlPlaneEndpoint.IsValid():
96-
floatingIPAddress = openStackCluster.Spec.ControlPlaneEndpoint.Host
111+
ips, err := lookupHost(openStackCluster.Spec.ControlPlaneEndpoint.Host)
112+
if err != nil {
113+
return false, err
114+
}
115+
floatingIPAddress = ips[0]
97116
}
98117
fp, err := s.networkingService.GetOrCreateFloatingIP(openStackCluster, openStackCluster, clusterName, floatingIPAddress)
99118
if err != nil {
@@ -294,9 +313,9 @@ func validateIPs(openStackCluster *infrav1.OpenStackCluster, definedCIDRs []stri
294313

295314
for _, v := range definedCIDRs {
296315
switch {
297-
case net.IsIPv4String(v):
316+
case utilsnet.IsIPv4String(v):
298317
marshaledCIDRs = append(marshaledCIDRs, v+"/32")
299-
case net.IsIPv4CIDRString(v):
318+
case utilsnet.IsIPv4CIDRString(v):
300319
marshaledCIDRs = append(marshaledCIDRs, v)
301320
default:
302321
record.Warnf(openStackCluster, "FailedIPAddressValidation", "%s is not a valid IPv4 nor CIDR address and will not get applied to allowed_cidrs", v)

pkg/cloud/services/loadbalancer/loadbalancer_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package loadbalancer
1818

1919
import (
20+
"errors"
21+
"net"
2022
"testing"
2123

2224
"github.com/go-logr/logr"
@@ -32,15 +34,32 @@ import (
3234
infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7"
3335
"sigs.k8s.io/cluster-api-provider-openstack/pkg/clients/mock"
3436
"sigs.k8s.io/cluster-api-provider-openstack/pkg/scope"
37+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3538
)
3639

3740
func Test_ReconcileLoadBalancer(t *testing.T) {
3841
mockCtrl := gomock.NewController(t)
3942
defer mockCtrl.Finish()
4043

44+
// Stub the call to net.LookupHost
45+
lookupHost = func(host string) (addrs []string, err error) {
46+
if net.ParseIP(host) != nil {
47+
return []string{host}, nil
48+
} else if host == "api.test-cluster.test" {
49+
ips := []string{"192.168.100.10"}
50+
return ips, nil
51+
} else {
52+
return nil, errors.New("Unknown Host " + host)
53+
}
54+
}
55+
4156
openStackCluster := &infrav1.OpenStackCluster{
4257
Spec: infrav1.OpenStackClusterSpec{
4358
DisableAPIServerFloatingIP: true,
59+
ControlPlaneEndpoint: clusterv1.APIEndpoint{
60+
Host: "api.test-cluster.test",
61+
Port: 6443,
62+
},
4463
},
4564
Status: infrav1.OpenStackClusterStatus{
4665
ExternalNetwork: &infrav1.NetworkStatus{

0 commit comments

Comments
 (0)