Skip to content

Commit

Permalink
Resolve hostnames in service-address command
Browse files Browse the repository at this point in the history
Consul does not support hostnames for mesh gateway wan addresses. For
now to support running on EKS we will resolve the EKS load balancer
hostnames to IPs.

In the future when Consul supports hostnames we will want to remove this
change because the IPs may change and the hostname won't.
  • Loading branch information
lkysow committed May 12, 2020
1 parent 993ecf8 commit f4344bc
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 5 deletions.
29 changes: 28 additions & 1 deletion subcommand/service-address/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"flag"
"fmt"
"io/ioutil"
"net"
"os"
"sync"
"time"
Expand Down Expand Up @@ -103,7 +104,13 @@ func (c *Command) Run(args []string) int {
address = ingr.IP
return nil
} else if ingr.Hostname != "" {
address = 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)
return nil
}
}
Expand Down Expand Up @@ -149,6 +156,26 @@ func (c *Command) validateFlags(args []string) error {
return nil
}

// resolveHostname returns the first ipv4 address for host.
func resolveHostname(host string) (string, error) {
ips, err := net.LookupIP(host)
if err != nil {
return "", fmt.Errorf("unable to resolve hostname: %s", err)
}
if len(ips) < 1 {
return "", fmt.Errorf("hostname %q had no resolveable IPs", host)
}

for _, ip := range ips {
v4 := ip.To4()
if v4 == nil {
continue
}
return ip.String(), nil
}
return "", fmt.Errorf("hostname %q had no ipv4 IPs", host)
}

// withErrLogger runs op and logs if op returns an error.
// It returns the result of op.
func withErrLogger(log hclog.Logger, op func() error) func() error {
Expand Down
40 changes: 36 additions & 4 deletions subcommand/service-address/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,41 @@ func TestRun_UnableToWriteToFile(t *testing.T) {
"Unable to write address to file: open /this/filepath/does/not/exist: no such file or directory")
}

func TestRun_UnresolvableHostname(t *testing.T) {
t.Parallel()
require := require.New(t)

k8sNS := "default"
svcName := "service-name"

// Create the service.
k8s := fake.NewSimpleClientset()
_, err := k8s.CoreV1().Services(k8sNS).Create(kubeLoadBalancerSvc(svcName, "", "unresolvable"))
require.NoError(err)

// Run command.
ui := cli.NewMockUi()
cmd := Command{
UI: ui,
k8sClient: k8s,
}
tmpDir, err := ioutil.TempDir("", "")
require.NoError(err)
defer os.RemoveAll(tmpDir)
outputFile := filepath.Join(tmpDir, "address.txt")

responseCode := cmd.Run([]string{
"-k8s-namespace", k8sNS,
"-name", svcName,
"-output-file", outputFile,
})
require.Equal(1, responseCode)
require.Contains(ui.ErrorWriter.String(), "Unable to get service address: unable to resolve hostname:")
}

// Test running with different service types.
func TestRun_ServiceTypes(t *testing.T) {
t.Parallel()
require := require.New(t)

// All services will have the name "service-name"
cases := map[string]struct {
Expand All @@ -103,8 +134,8 @@ func TestRun_ServiceTypes(t *testing.T) {
ExpAddress: "1.2.3.4",
},
"LoadBalancer Hostname": {
Service: kubeLoadBalancerSvc("service-name", "", "example.com"),
ExpAddress: "example.com",
Service: kubeLoadBalancerSvc("service-name", "", "localhost"),
ExpAddress: "127.0.0.1",
},
"LoadBalancer IP and hostname": {
Service: kubeLoadBalancerSvc("service-name", "1.2.3.4", "example.com"),
Expand Down Expand Up @@ -140,7 +171,8 @@ func TestRun_ServiceTypes(t *testing.T) {
}

for name, c := range cases {
t.Run(name, func(t *testing.T) {
t.Run(name, func(tt *testing.T) {
require := require.New(tt)
k8sNS := "default"
svcName := "service-name"

Expand Down

0 comments on commit f4344bc

Please sign in to comment.