Skip to content

Commit

Permalink
Count with LoadBalancer IP in Service status
Browse files Browse the repository at this point in the history
On AKS for example, service type LoadBalancer doesn't expose Hostname
but direct IP.

We need to look at both properties

Signed-off-by: Dinar Valeev <[email protected]>
  • Loading branch information
k0da committed Jun 21, 2022
1 parent 010bb90 commit da5ec2c
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 11 deletions.
72 changes: 72 additions & 0 deletions controllers/gslb_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,78 @@ func TestCreatesDNSNSRecordsForExtDNS(t *testing.T) {
assert.Equal(t, wantEp, gotEp, "got:\n %s DNSEndpoint,\n\n want:\n %s", prettyGot, prettyWant)
}

func TestCreatesDNSNSRecordsForLoadBalancer(t *testing.T) {
// arrange
const dnsZone = "cloud.example.com"
const want = "extdns"
wantEp := []*externaldns.Endpoint{
{
DNSName: dnsZone,
RecordTTL: 30,
RecordType: "NS",
Targets: externaldns.Targets{
"gslb-ns-eu-cloud.example.com",
"gslb-ns-us-cloud.example.com",
"gslb-ns-za-cloud.example.com",
},
},
{
DNSName: "gslb-ns-eu-cloud.example.com",
RecordTTL: 30,
RecordType: "A",
Targets: externaldns.Targets{
defaultEdgeDNS1,
},
},
}
dnsEndpoint := &externaldns.DNSEndpoint{}
customConfig := predefinedConfig
customConfig.EdgeDNSServers = defaultEdgeDNSServers
customConfig.CoreDNSExposed = true
coreDNSService := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: defaultCoreDNSExtServiceName,
Namespace: predefinedConfig.K8gbNamespace,
Labels: map[string]string{
"app.kubernetes.io/name": "coredns",
},
},
}
serviceIPs := []corev1.LoadBalancerIngress{
{IP: "1.1.1.1"}, // rely on 1.1.1.1 response from Cloudflare
}
settings := provideSettings(t, customConfig)
err := settings.client.Create(context.TODO(), coreDNSService)
require.NoError(t, err, "Failed to create testing %s service", defaultCoreDNSExtServiceName)
coreDNSService.Status.LoadBalancer.Ingress = append(coreDNSService.Status.LoadBalancer.Ingress, serviceIPs...)
err = settings.client.Status().Update(context.TODO(), coreDNSService)
require.NoError(t, err, "Failed to update coredns service lb hostname")

// act
customConfig.EdgeDNSType = depresolver.DNSTypeExternal
customConfig.ClusterGeoTag = "eu"
customConfig.ExtClustersGeoTags = []string{"za", "us"}
customConfig.DNSZone = dnsZone
// apply new environment variables and update config only
settings.reconciler.Config = &customConfig
// If config is changed, new Route53 provider needs to be re-created. There is no way and reason to change provider
// configuration at another time than startup
f, _ := dns.NewDNSProviderFactory(settings.reconciler.Client, customConfig)
settings.reconciler.DNSProvider = f.Provider()

reconcileAndUpdateGslb(t, settings)
err = settings.client.Get(context.TODO(), client.ObjectKey{Namespace: predefinedConfig.K8gbNamespace, Name: "k8gb-ns-extdns"}, dnsEndpoint)
require.NoError(t, err, "Failed to get expected DNSEndpoint")
got := dnsEndpoint.Annotations["k8gb.absa.oss/dnstype"]
gotEp := dnsEndpoint.Spec.Endpoints
prettyGot := str.ToString(gotEp)
prettyWant := str.ToString(wantEp)

// assert
assert.Equal(t, want, got, "got:\n %q annotation value,\n\n want:\n %q", got, want)
assert.Equal(t, wantEp, gotEp, "got:\n %s DNSEndpoint,\n\n want:\n %s", prettyGot, prettyWant)
}

func TestResolvesLoadBalancerHostnameFromIngressStatus(t *testing.T) {
// arrange
customConfig := predefinedConfig
Expand Down
31 changes: 20 additions & 11 deletions controllers/providers/assistant/gslb.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,25 +90,34 @@ func (r *Gslb) CoreDNSExposedIPs() ([]string, error) {
}
coreDNSService := &serviceList.Items[0]

var lbHostname string
if len(coreDNSService.Status.LoadBalancer.Ingress) > 0 {
lbHostname = coreDNSService.Status.LoadBalancer.Ingress[0].Hostname
} else {
var lb corev1.LoadBalancerIngress
if len(coreDNSService.Status.LoadBalancer.Ingress) == 0 {
errMessage := "no LoadBalancer ExternalIPs are found"
log.Warn().
Str("serviceName", coreDNSService.Name).
Msg(errMessage)
err := coreerrors.New(errMessage)
return nil, err
}
IPs, err := utils.Dig(lbHostname, r.edgeDNSServers...)
if err != nil {
log.Warn().Err(err).
Str("loadBalancerHostname", lbHostname).
Msg("Can't dig CoreDNS service LoadBalancer FQDN")
return nil, err
lb = coreDNSService.Status.LoadBalancer.Ingress[0]
return extractIPFromLB(lb, r.edgeDNSServers)
}

func extractIPFromLB(lb corev1.LoadBalancerIngress, ns utils.DNSList) (ips []string, err error) {
if lb.Hostname != "" {
IPs, err := utils.Dig(lb.Hostname, ns...)
if err != nil {
log.Warn().Err(err).
Str("loadBalancerHostname", lb.Hostname).
Msg("Can't dig CoreDNS service LoadBalancer FQDN")
return nil, err
}
return IPs, nil
}
if lb.IP != "" {
return []string{lb.IP}, nil
}
return IPs, nil
return nil, nil
}

// GslbIngressExposedIPs retrieves list of IP's exposed by all GSLB ingresses
Expand Down

0 comments on commit da5ec2c

Please sign in to comment.