From e03f02a5751c7165610008da97b9cd5a2fbfbf79 Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Wed, 19 Jul 2017 13:57:45 +0000 Subject: [PATCH] metadata improvements. --- .../azure/azure_instance_metadata.go | 10 ++-- .../providers/azure/azure_instances.go | 47 +++++++++++++++++-- .../providers/azure/azure_test.go | 2 +- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/pkg/cloudprovider/providers/azure/azure_instance_metadata.go b/pkg/cloudprovider/providers/azure/azure_instance_metadata.go index 6d547e30de2..6df99083272 100644 --- a/pkg/cloudprovider/providers/azure/azure_instance_metadata.go +++ b/pkg/cloudprovider/providers/azure/azure_instance_metadata.go @@ -54,7 +54,7 @@ type Subnet struct { Prefix string `json:"prefix"` } -// InstanceMetadata represents access to the Azure instance metadata server. +// InstanceMetadata knows how to query the Azure instance metadata server. type InstanceMetadata struct { baseURL string } @@ -71,8 +71,8 @@ func (i *InstanceMetadata) makeMetadataURL(path string) string { return i.baseURL + path } -// QueryMetadataJSON queries the metadata server and populates the passed in object -func (i *InstanceMetadata) QueryMetadataJSON(path string, obj interface{}) error { +// Object queries the metadata server and populates the passed in object +func (i *InstanceMetadata) Object(path string, obj interface{}) error { data, err := i.queryMetadataBytes(path, "json") if err != nil { return err @@ -80,8 +80,8 @@ func (i *InstanceMetadata) QueryMetadataJSON(path string, obj interface{}) error return json.Unmarshal(data, obj) } -// QueryMetadataText queries the metadata server and returns the corresponding text -func (i *InstanceMetadata) QueryMetadataText(path string) (string, error) { +// Text queries the metadata server and returns the corresponding text +func (i *InstanceMetadata) Text(path string) (string, error) { data, err := i.queryMetadataBytes(path, "text") if err != nil { return "", err diff --git a/pkg/cloudprovider/providers/azure/azure_instances.go b/pkg/cloudprovider/providers/azure/azure_instances.go index c095d060c5b..b94b8225d64 100644 --- a/pkg/cloudprovider/providers/azure/azure_instances.go +++ b/pkg/cloudprovider/providers/azure/azure_instances.go @@ -30,14 +30,23 @@ import ( // NodeAddresses returns the addresses of the specified instance. func (az *Cloud) NodeAddresses(name types.NodeName) ([]v1.NodeAddress, error) { if az.UseInstanceMetadata { - text, err := az.metadata.QueryMetadataText("instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress") + ipAddress := IPAddress{} + err := az.metadata.Object("instance/network/interface/0/ipv4/ipAddress/0", &ipAddress) if err != nil { return nil, err } - return []v1.NodeAddress{ - {Type: v1.NodeInternalIP, Address: text}, + addresses := []v1.NodeAddress{ + {Type: v1.NodeInternalIP, Address: ipAddress.PrivateIP}, {Type: v1.NodeHostName, Address: string(name)}, - }, nil + } + if len(ipAddress.PublicIP) > 0 { + addr := v1.NodeAddress{ + Type: v1.NodeExternalIP, + Address: ipAddress.PublicIP, + } + addresses = append(addresses, addr) + } + return addresses, nil } ip, err := az.getIPForMachine(name) if err != nil { @@ -77,9 +86,27 @@ func (az *Cloud) ExternalID(name types.NodeName) (string, error) { return az.InstanceID(name) } +func (az *Cloud) isCurrentInstance(name types.NodeName) (bool, error) { + nodeName := mapNodeNameToVMName(name) + metadataName, err := az.metadata.Text("instance/compute/name") + return (metadataName == nodeName), err +} + // InstanceID returns the cloud provider ID of the specified instance. // Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound) func (az *Cloud) InstanceID(name types.NodeName) (string, error) { + if az.UseInstanceMetadata { + isLocalInstance, err := az.isCurrentInstance(name) + if err != nil { + return "", err + } + if isLocalInstance { + externalInstanceID, err := az.metadata.Text("instance/compute/vmId") + if err == nil { + return externalInstanceID, nil + } + } + } var machine compute.VirtualMachine var exists bool var err error @@ -119,6 +146,18 @@ func (az *Cloud) InstanceTypeByProviderID(providerID string) (string, error) { // (Implementer Note): This is used by kubelet. Kubelet will label the node. Real log from kubelet: // Adding node label from cloud provider: beta.kubernetes.io/instance-type=[value] func (az *Cloud) InstanceType(name types.NodeName) (string, error) { + if az.UseInstanceMetadata { + isLocalInstance, err := az.isCurrentInstance(name) + if err != nil { + return "", err + } + if isLocalInstance { + machineType, err := az.metadata.Text("instance/compute/vmSize") + if err == nil { + return machineType, nil + } + } + } machine, exists, err := az.getVirtualMachine(name) if err != nil { glog.Errorf("error: az.InstanceType(%s), az.getVirtualMachine(%s) err=%v", name, name, err) diff --git a/pkg/cloudprovider/providers/azure/azure_test.go b/pkg/cloudprovider/providers/azure/azure_test.go index 8f6b64aa3e7..32ea4c68e07 100644 --- a/pkg/cloudprovider/providers/azure/azure_test.go +++ b/pkg/cloudprovider/providers/azure/azure_test.go @@ -879,7 +879,7 @@ func TestMetadataParsing(t *testing.T) { } networkJSON := NetworkMetadata{} - if err := metadata.QueryMetadataJSON("/some/path", &networkJSON); err != nil { + if err := metadata.Object("/some/path", &networkJSON); err != nil { t.Errorf("Unexpected error: %v", err) }