From dfbddf368eccd05cb2608a89c9252b2d103ead56 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Fri, 26 Aug 2022 09:43:18 +0000 Subject: add FindOurHostname() --- client/go/vespa/detect_hostname.go | 108 ++++++++++++++++++++++++++++++++ client/go/vespa/detect_hostname_test.go | 27 ++++++++ 2 files changed, 135 insertions(+) create mode 100644 client/go/vespa/detect_hostname.go create mode 100644 client/go/vespa/detect_hostname_test.go (limited to 'client') diff --git a/client/go/vespa/detect_hostname.go b/client/go/vespa/detect_hostname.go new file mode 100644 index 00000000000..2cd1e44db1f --- /dev/null +++ b/client/go/vespa/detect_hostname.go @@ -0,0 +1,108 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Author: arnej + +package vespa + +import ( + "fmt" + "net" + "os" + "strings" +) + +// detect if this host is IPv6-only, in which case we want to pass +// the flag "-Djava.net.preferIPv6Addresses=true" to any java command + +func HasOnlyIpV6() bool { + hostname, err := os.Hostname() + hostname, err = FindOurHostname(hostname) + if hostname == "" || err != nil { + return false + } + foundV4 := false + foundV6 := false + ipAddrs, err := net.LookupIP(hostname) + if err != nil { + return false + } + for _, addr := range ipAddrs { + switch { + case addr.IsLoopback(): + // skip + case addr.To4() != nil: + foundV4 = true + case addr.To16() != nil: + foundV6 = true + } + } + return foundV6 && !foundV4 +} + +func FindOurHostname(name string) (string, error) { + env := os.Getenv("VESPA_HOSTNAME") + if env != "" { + // assumes: env var is already validated and OK + fmt.Fprintln(os.Stderr, "from env:", env) + return env, nil + } + ifAddrs, _ := net.InterfaceAddrs() + fmt.Fprintln(os.Stderr, "interface addrs:", ifAddrs) + var checkIsMine = func(addr string) bool { + if len(ifAddrs) == 0 { + // no validation possible, assume OK + return true + } + for _, ifAddr := range ifAddrs { + if ipnet, ok := ifAddr.(*net.IPNet); ok { + if ipnet.IP.String() == addr { + return true + } + } + } + return false + } + if name != "" { + ipAddrs, _ := net.LookupIP(name) + fmt.Fprintln(os.Stderr, "LookupIP", name, "->", ipAddrs) + for _, addr := range ipAddrs { + switch { + case addr.IsLoopback(): + // skip + case addr.To4() != nil || addr.To16() != nil: + if checkIsMine(addr.String()) { + reverseNames, _ := net.LookupAddr(addr.String()) + for _, reverse := range reverseNames { + if strings.HasPrefix(reverse, name) { + fmt.Fprintln(os.Stderr, "hostname", name, "->", addr, "-> ", reverse) + return reverse, nil + } + } + if len(reverseNames) > 0 { + reverse := reverseNames[0] + fmt.Fprintln(os.Stderr, "hostname", name, "->", addr, "-> ", reverse) + return reverse, nil + } + } + } + } + } + for _, ifAddr := range ifAddrs { + if ipnet, ok := ifAddr.(*net.IPNet); ok { + ip := ipnet.IP + fmt.Fprintln(os.Stderr, "converted IP", ifAddr, "->", ip) + if ip == nil || ip.IsLoopback() { + continue + } + reverseNames, _ := net.LookupAddr(ip.String()) + if len(reverseNames) > 0 { + reverse := reverseNames[0] + fmt.Fprintln(os.Stderr, "interface", ifAddr, "->", reverse) + return reverse, nil + } + } + } + if name != "" { + return name, fmt.Errorf("unvalidated hostname '%s'", name) + } + return "localhost", fmt.Errorf("fallback to localhost, os.Hostname '%s'", name) +} diff --git a/client/go/vespa/detect_hostname_test.go b/client/go/vespa/detect_hostname_test.go new file mode 100644 index 00000000000..bb61e157b26 --- /dev/null +++ b/client/go/vespa/detect_hostname_test.go @@ -0,0 +1,27 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package vespa + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDetectHostname(t *testing.T) { + os.Setenv("VESPA_HOSTNAME", "foo.bar") + got, err := FindOurHostname("bar.foo") + assert.Equal(t, "foo.bar", got) + os.Unsetenv("VESPA_HOSTNAME") + got, err = FindOurHostname("bar.foo.123") + fmt.Fprintln(os.Stderr, "FindOurHostname() returns: ", got, "with error:", err) + assert.NotEqual(t, "", got) + parts := strings.Split(got, ".") + if len(parts) > 1 { + expanded, err2 := FindOurHostname(parts[0]) + fmt.Fprintln(os.Stderr, "FindOurHostname(", parts[0], ") returns: ", expanded, "with error:", err2) + assert.Equal(t, got, expanded) + } +} -- cgit v1.2.3