From 54bee09f47b2ce448f5b7aa38ba2b5229c48ec12 Mon Sep 17 00:00:00 2001 From: andrewsykim Date: Mon, 19 Mar 2018 00:27:31 -0400 Subject: [PATCH] digitalocean: add kubelet hostname override --- pkg/model/components/kubelet.go | 1 + upup/pkg/fi/nodeup/command.go | 54 +++++++++++++++++++++------------ util/pkg/vfs/context.go | 3 ++ 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/pkg/model/components/kubelet.go b/pkg/model/components/kubelet.go index ca46214ba4..ad9ed25508 100644 --- a/pkg/model/components/kubelet.go +++ b/pkg/model/components/kubelet.go @@ -162,6 +162,7 @@ func (b *KubeletOptionsBuilder) BuildOptions(o interface{}) error { if cloudProvider == kops.CloudProviderDO { clusterSpec.Kubelet.CloudProvider = "external" + clusterSpec.Kubelet.HostnameOverride = "@digitalocean" } if cloudProvider == kops.CloudProviderGCE { diff --git a/upup/pkg/fi/nodeup/command.go b/upup/pkg/fi/nodeup/command.go index 569e1c4ea6..2d2206ce4c 100644 --- a/upup/pkg/fi/nodeup/command.go +++ b/upup/pkg/fi/nodeup/command.go @@ -17,6 +17,7 @@ limitations under the License. package nodeup import ( + "errors" "fmt" "io" "io/ioutil" @@ -337,29 +338,44 @@ func evaluateHostnameOverride(hostnameOverride string) (string, error) { k := strings.TrimSpace(hostnameOverride) k = strings.ToLower(k) - if k != "@aws" { - return hostnameOverride, nil + if k == "@aws" { + // We recognize @aws as meaning "the local-hostname from the aws metadata service" + vBytes, err := vfs.Context.ReadFile("metadata://aws/meta-data/local-hostname") + if err != nil { + return "", fmt.Errorf("error reading local hostname from AWS metadata: %v", err) + } + + // The local-hostname gets it's hostname from the AWS DHCP Option Set, which + // may provide multiple hostnames separated by spaces. For now just choose + // the first one as the hostname. + domains := strings.Fields(string(vBytes)) + if len(domains) == 0 { + glog.Warningf("Local hostname from AWS metadata service was empty") + return "", nil + } else { + domain := domains[0] + glog.Infof("Using hostname from AWS metadata service: %s", domain) + + return domain, nil + } } - // We recognize @aws as meaning "the local-hostname from the aws metadata service" - vBytes, err := vfs.Context.ReadFile("metadata://aws/meta-data/local-hostname") - if err != nil { - return "", fmt.Errorf("error reading local hostname from AWS metadata: %v", err) + if k == "@digitalocean" { + // @digitalocean means to use the private ipv4 address of a droplet as the hostname override + vBytes, err := vfs.Context.ReadFile("metadata://digitalocean/interfaces/private/0/ipv4/address") + if err != nil { + return "", fmt.Errorf("error reading droplet private IP from DigitalOcean metadata: %v", err) + } + + hostname := string(vBytes) + if hostname == "" { + return "", errors.New("private IP for digitalocean droplet was empty") + } + + return hostname, nil } - // The local-hostname gets it's hostname from the AWS DHCP Option Set, which - // may provide multiple hostnames separated by spaces. For now just choose - // the first one as the hostname. - domains := strings.Fields(string(vBytes)) - if len(domains) == 0 { - glog.Warningf("Local hostname from AWS metadata service was empty") - return "", nil - } else { - domain := domains[0] - glog.Infof("Using hostname from AWS metadata service: %s", domain) - - return domain, nil - } + return hostnameOverride, nil } // evaluateDockerSpec selects the first supported storage mode, if it is a list diff --git a/util/pkg/vfs/context.go b/util/pkg/vfs/context.go index 5125b0567e..2a76c02b93 100644 --- a/util/pkg/vfs/context.go +++ b/util/pkg/vfs/context.go @@ -79,6 +79,9 @@ func (c *VFSContext) ReadFile(location string) ([]byte, error) { case "aws": httpURL := "http://169.254.169.254/latest/" + u.Path return c.readHttpLocation(httpURL, nil) + case "digitalocean": + httpURL := "http://169.254.169.254/metadata/v1" + u.Path + return c.readHttpLocation(httpURL, nil) default: return nil, fmt.Errorf("unknown metadata type: %q in %q", u.Host, location)