diff --git a/pkg/cloudprovider/providers/azure/azure_backoff.go b/pkg/cloudprovider/providers/azure/azure_backoff.go index ab5707656ad..16fb0dfe2a9 100644 --- a/pkg/cloudprovider/providers/azure/azure_backoff.go +++ b/pkg/cloudprovider/providers/azure/azure_backoff.go @@ -113,11 +113,11 @@ func (az *Cloud) VirtualMachineClientListWithRetry() ([]compute.VirtualMachine, } // GetIPForMachineWithRetry invokes az.getIPForMachine with exponential backoff retry -func (az *Cloud) GetIPForMachineWithRetry(name types.NodeName) (string, error) { - var ip string +func (az *Cloud) GetIPForMachineWithRetry(name types.NodeName) (string, string, error) { + var ip, publicIP string err := wait.ExponentialBackoff(az.requestBackoff(), func() (bool, error) { var retryErr error - ip, retryErr = az.getIPForMachine(name) + ip, publicIP, retryErr = az.getIPForMachine(name) if retryErr != nil { glog.Errorf("backoff: failure, will retry,err=%v", retryErr) return false, nil @@ -125,7 +125,7 @@ func (az *Cloud) GetIPForMachineWithRetry(name types.NodeName) (string, error) { glog.V(2).Info("backoff: success") return true, nil }) - return ip, err + return ip, publicIP, err } // CreateOrUpdateSGWithRetry invokes az.SecurityGroupsClient.CreateOrUpdate with exponential backoff retry diff --git a/pkg/cloudprovider/providers/azure/azure_fakes.go b/pkg/cloudprovider/providers/azure/azure_fakes.go index 8450dcbb759..69be811de3a 100644 --- a/pkg/cloudprovider/providers/azure/azure_fakes.go +++ b/pkg/cloudprovider/providers/azure/azure_fakes.go @@ -1126,16 +1126,16 @@ func (f *fakeVMSet) GetInstanceTypeByNodeName(name string) (string, error) { return "", fmt.Errorf("unimplemented") } -func (f *fakeVMSet) GetIPByNodeName(name, vmSetName string) (string, error) { +func (f *fakeVMSet) GetIPByNodeName(name, vmSetName string) (string, string, error) { nodes, found := f.NodeToIP[vmSetName] if !found { - return "", fmt.Errorf("not found") + return "", "", fmt.Errorf("not found") } ip, found := nodes[name] if !found { - return "", fmt.Errorf("not found") + return "", "", fmt.Errorf("not found") } - return ip, nil + return ip, "", nil } func (f *fakeVMSet) GetPrimaryInterface(nodeName, vmSetName string) (network.Interface, error) { diff --git a/pkg/cloudprovider/providers/azure/azure_routes.go b/pkg/cloudprovider/providers/azure/azure_routes.go index c78de23d730..486064290ea 100644 --- a/pkg/cloudprovider/providers/azure/azure_routes.go +++ b/pkg/cloudprovider/providers/azure/azure_routes.go @@ -111,7 +111,7 @@ func (az *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint s if err := az.createRouteTableIfNotExists(clusterName, kubeRoute); err != nil { return err } - targetIP, err := az.getIPForMachine(kubeRoute.TargetNode) + targetIP, _, err := az.getIPForMachine(kubeRoute.TargetNode) if err != nil { return err } diff --git a/pkg/cloudprovider/providers/azure/azure_standard.go b/pkg/cloudprovider/providers/azure/azure_standard.go index bb40eadfae2..9c5a9c33346 100644 --- a/pkg/cloudprovider/providers/azure/azure_standard.go +++ b/pkg/cloudprovider/providers/azure/azure_standard.go @@ -287,7 +287,7 @@ outer: return -1, fmt.Errorf("SecurityGroup priorities are exhausted") } -func (az *Cloud) getIPForMachine(nodeName types.NodeName) (string, error) { +func (az *Cloud) getIPForMachine(nodeName types.NodeName) (string, string, error) { return az.vmSet.GetIPByNodeName(string(nodeName), "") } @@ -424,21 +424,37 @@ func (as *availabilitySet) GetPrimaryVMSetName() string { return as.Config.PrimaryAvailabilitySetName } -// GetIPByNodeName gets machine IP by node name. -func (as *availabilitySet) GetIPByNodeName(name, vmSetName string) (string, error) { +// GetIPByNodeName gets machine private IP and public IP by node name. +func (as *availabilitySet) GetIPByNodeName(name, vmSetName string) (string, string, error) { nic, err := as.GetPrimaryInterface(name, vmSetName) if err != nil { - return "", err + return "", "", err } ipConfig, err := getPrimaryIPConfig(nic) if err != nil { glog.Errorf("error: as.GetIPByNodeName(%s), getPrimaryIPConfig(%v), err=%v", name, nic, err) - return "", err + return "", "", err } - targetIP := *ipConfig.PrivateIPAddress - return targetIP, nil + privateIP := *ipConfig.PrivateIPAddress + publicIP := "" + if ipConfig.PublicIPAddress != nil && ipConfig.PublicIPAddress.ID != nil { + pipID := *ipConfig.PublicIPAddress.ID + pipName, err := getLastSegment(pipID) + if err != nil { + return "", "", fmt.Errorf("failed to publicIP name for node %q with pipID %q", name, pipID) + } + pip, existsPip, err := as.getPublicIPAddress(as.ResourceGroup, pipName) + if err != nil { + return "", "", err + } + if existsPip { + publicIP = *pip.IPAddress + } + } + + return privateIP, publicIP, nil } // getAgentPoolAvailabiliySets lists the virtual machines for the resource group and then builds diff --git a/pkg/cloudprovider/providers/azure/azure_vmsets.go b/pkg/cloudprovider/providers/azure/azure_vmsets.go index c98db593844..4d78b759587 100644 --- a/pkg/cloudprovider/providers/azure/azure_vmsets.go +++ b/pkg/cloudprovider/providers/azure/azure_vmsets.go @@ -34,8 +34,8 @@ type VMSet interface { GetInstanceIDByNodeName(name string) (string, error) // GetInstanceTypeByNodeName gets the instance type by node name. GetInstanceTypeByNodeName(name string) (string, error) - // GetIPByNodeName gets machine IP by node name. - GetIPByNodeName(name, vmSetName string) (string, error) + // GetIPByNodeName gets machine private IP and public IP by node name. + GetIPByNodeName(name, vmSetName string) (string, string, error) // GetPrimaryInterface gets machine primary network interface by node name and vmSet. GetPrimaryInterface(nodeName, vmSetName string) (network.Interface, error) // GetNodeNameByProviderID gets the node name by provider ID. diff --git a/pkg/cloudprovider/providers/azure/azure_vmss.go b/pkg/cloudprovider/providers/azure/azure_vmss.go index ff93dd05093..bc064bbd2c4 100644 --- a/pkg/cloudprovider/providers/azure/azure_vmss.go +++ b/pkg/cloudprovider/providers/azure/azure_vmss.go @@ -243,22 +243,24 @@ func (ss *scaleSet) GetPrimaryVMSetName() string { return ss.Config.PrimaryScaleSetName } -// GetIPByNodeName gets machine IP by node name. -func (ss *scaleSet) GetIPByNodeName(nodeName, vmSetName string) (string, error) { +// GetIPByNodeName gets machine private IP and public IP by node name. +// TODO(feiskyer): Azure vmss doesn't support associating a public IP to single virtual machine yet, +// fix this after it is supported. +func (ss *scaleSet) GetIPByNodeName(nodeName, vmSetName string) (string, string, error) { nic, err := ss.GetPrimaryInterface(nodeName, vmSetName) if err != nil { glog.Errorf("error: ss.GetIPByNodeName(%s), GetPrimaryInterface(%q, %q), err=%v", nodeName, nodeName, vmSetName, err) - return "", err + return "", "", err } ipConfig, err := getPrimaryIPConfig(nic) if err != nil { glog.Errorf("error: ss.GetIPByNodeName(%s), getPrimaryIPConfig(%v), err=%v", nodeName, nic, err) - return "", err + return "", "", err } targetIP := *ipConfig.PrivateIPAddress - return targetIP, nil + return targetIP, "", nil } // This returns the full identifier of the primary NIC for the given VM.