From 7ea39c562b9f464501399933a923ada39fb684d0 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 3 Jun 2020 15:28:08 -0700 Subject: [PATCH] Add -resolve-hostnames flag Add a -resolve-hostnames flag to the service-address command that defaults to false. If true, any service with a hostname as its address will have that hostname resolved and the first ip written. If false, the hostname will be written. This is useful in the case of EKS where load balancers have hostnames. For WAN federation we want to use the hostname because the underlying IPs can change. For ingress gateways this command is used to set the address field in the service definition which only accepts IPs. This flag allows the service-address command to be used so the service registration is valid and then we document that in the EKS case users shouldn't use the ingress consul DNS and should instead set up their own DNS that resolves to the load balancer. --- subcommand/service-address/command.go | 21 +++++++++++---------- subcommand/service-address/command_test.go | 19 +++++++++++++++---- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/subcommand/service-address/command.go b/subcommand/service-address/command.go index 83e24c29b1..8175e30c89 100644 --- a/subcommand/service-address/command.go +++ b/subcommand/service-address/command.go @@ -27,9 +27,10 @@ type Command struct { flags *flag.FlagSet k8sFlags *k8sflags.K8SFlags - flagNamespace string - flagServiceName string - flagOutputFile string + flagNamespace string + flagServiceName string + flagOutputFile string + flagResolveHostnames bool retryDuration time.Duration k8sClient kubernetes.Interface @@ -45,6 +46,8 @@ func (c *Command) init() { "Name of the service") c.flags.StringVar(&c.flagOutputFile, "output-file", "", "Path to file to write load balancer address") + c.flags.BoolVar(&c.flagResolveHostnames, "resolve-hostnames", false, + "If true we will resolve any hostnames and use their first IP address") c.k8sFlags = &k8sflags.K8SFlags{} flags.Merge(c.flags, c.k8sFlags.Flags()) @@ -104,13 +107,11 @@ func (c *Command) Run(args []string) int { address = ingr.IP return nil } else if ingr.Hostname != "" { - // todo: for now we're resolving this hostname to an IP - // because Consul doesn't yet support hostnames for its mesh - // gateway addresses. We will want to remove this when it's - // supported because in the case of EKS (the only cloud - // that returns hostnames for its LBs) the IPs may change - // so only the hostname is safe. - address, unretryableErr = resolveHostname(ingr.Hostname) + if c.flagResolveHostnames { + address, unretryableErr = resolveHostname(ingr.Hostname) + } else { + address = ingr.Hostname + } return nil } } diff --git a/subcommand/service-address/command_test.go b/subcommand/service-address/command_test.go index f45989634d..79d1012367 100644 --- a/subcommand/service-address/command_test.go +++ b/subcommand/service-address/command_test.go @@ -105,6 +105,7 @@ func TestRun_UnresolvableHostname(t *testing.T) { "-k8s-namespace", k8sNS, "-name", svcName, "-output-file", outputFile, + "-resolve-hostnames=true", }) require.Equal(1, responseCode) require.Contains(ui.ErrorWriter.String(), "Unable to get service address: unable to resolve hostname:") @@ -118,6 +119,7 @@ func TestRun_ServiceTypes(t *testing.T) { cases := map[string]struct { Service *v1.Service ServiceModificationF func(*v1.Service) + ResolveHostnames bool ExpErr string ExpAddress string }{ @@ -133,9 +135,14 @@ func TestRun_ServiceTypes(t *testing.T) { Service: kubeLoadBalancerSvc("service-name", "1.2.3.4", ""), ExpAddress: "1.2.3.4", }, - "LoadBalancer Hostname": { + "LoadBalancer hostname": { Service: kubeLoadBalancerSvc("service-name", "", "localhost"), - ExpAddress: "127.0.0.1", + ExpAddress: "localhost", + }, + "LoadBalancer hostname with resolve-hostnames=true": { + Service: kubeLoadBalancerSvc("service-name", "", "localhost"), + ResolveHostnames: true, + ExpAddress: "127.0.0.1", }, "LoadBalancer IP and hostname": { Service: kubeLoadBalancerSvc("service-name", "1.2.3.4", "example.com"), @@ -195,11 +202,15 @@ func TestRun_ServiceTypes(t *testing.T) { defer os.RemoveAll(tmpDir) outputFile := filepath.Join(tmpDir, "address.txt") - responseCode := cmd.Run([]string{ + args := []string{ "-k8s-namespace", k8sNS, "-name", svcName, "-output-file", outputFile, - }) + } + if c.ResolveHostnames { + args = append(args, "-resolve-hostnames=true") + } + responseCode := cmd.Run(args) if c.ExpErr != "" { require.Equal(1, responseCode) require.Contains(ui.ErrorWriter.String(), c.ExpErr)