Skip to content

Commit

Permalink
Use network.Interface.VirtualMachine.ID to get the binded VM
Browse files Browse the repository at this point in the history
  • Loading branch information
nilo19 authored and Miciah committed Dec 22, 2020
1 parent 87544c5 commit 91eef64
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 15 deletions.
Expand Up @@ -1133,6 +1133,10 @@ func (az *Cloud) reconcileLoadBalancer(clusterName string, service *v1.Service,
if err != nil {
return nil, err
}
if nodeName == "" {
// VM may under deletion
continue
}
// If a node is not supposed to be included in the LB, it
// would not be in the `nodes` slice. We need to check the nodes that
// have been added to the LB's backendpool, find the unwanted ones and
Expand Down
Expand Up @@ -3505,13 +3505,21 @@ func TestCleanBackendpoolForPrimarySLB(t *testing.T) {
})
existingVMForAS1 := buildDefaultTestVirtualMachine("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/availabilitySets/agentpool1-availabilitySet-00000000", []string{"/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Network/networkInterfaces/k8s-agentpool1-00000000-nic-1"})
existingVMForAS2 := buildDefaultTestVirtualMachine("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/availabilitySets/agentpool2-availabilitySet-00000000", []string{"/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Network/networkInterfaces/k8s-agentpool2-00000000-nic-1"})
existingNIC := buildDefaultTestInterface(true, []string{"/subscriptions/sub/resourceGroups/gh/providers/Microsoft.Network/loadBalancers/testCluster/backendAddressPools/testCluster"})
existingNICForAS1 := buildDefaultTestInterface(true, []string{"/subscriptions/sub/resourceGroups/gh/providers/Microsoft.Network/loadBalancers/testCluster/backendAddressPools/testCluster"})
existingNICForAS1.VirtualMachine = &network.SubResource{
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/k8s-agentpool1-00000000-1"),
}
existingNICForAS2 := buildDefaultTestInterface(true, []string{"/subscriptions/sub/resourceGroups/gh/providers/Microsoft.Network/loadBalancers/testCluster/backendAddressPools/testCluster"})
existingNICForAS2.VirtualMachine = &network.SubResource{
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/k8s-agentpool2-00000000-1"),
}
mockVMClient := mockvmclient.NewMockInterface(ctrl)
mockVMClient.EXPECT().Get(gomock.Any(), cloud.ResourceGroup, "k8s-agentpool1-00000000-1", gomock.Any()).Return(existingVMForAS1, nil)
mockVMClient.EXPECT().Get(gomock.Any(), cloud.ResourceGroup, "k8s-agentpool2-00000000-1", gomock.Any()).Return(existingVMForAS2, nil)
cloud.VirtualMachinesClient = mockVMClient
mockNICClient := mockinterfaceclient.NewMockInterface(ctrl)
mockNICClient.EXPECT().Get(gomock.Any(), "rg", "k8s-agentpool2-00000000-nic-1", gomock.Any()).Return(existingNIC, nil)
mockNICClient.EXPECT().Get(gomock.Any(), "rg", "k8s-agentpool1-00000000-nic-1", gomock.Any()).Return(existingNICForAS1, nil)
mockNICClient.EXPECT().Get(gomock.Any(), "rg", "k8s-agentpool2-00000000-nic-1", gomock.Any()).Return(existingNICForAS2, nil).Times(3)
mockNICClient.EXPECT().CreateOrUpdate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
cloud.InterfacesClient = mockNICClient
cleanedLB, err := cloud.cleanBackendpoolForPrimarySLB(&lb, &service, clusterName)
Expand Down
37 changes: 27 additions & 10 deletions staging/src/k8s.io/legacy-cloud-providers/azure/azure_standard.go
Expand Up @@ -76,7 +76,8 @@ var (
providerIDRE = regexp.MustCompile(`.*/subscriptions/(?:.*)/Microsoft.Compute/virtualMachines/(.+)$`)
backendPoolIDRE = regexp.MustCompile(`^/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Network/loadBalancers/(.+)/backendAddressPools/(?:.*)`)
nicResourceGroupRE = regexp.MustCompile(`.*/subscriptions/(?:.*)/resourceGroups/(.+)/providers/Microsoft.Network/networkInterfaces/(?:.*)`)
nicIDRE = regexp.MustCompile(`/subscriptions/(?:.*)/resourceGroups/(?:.+)/providers/Microsoft.Network/networkInterfaces/(.+)-nic-(.+)/ipConfigurations/(?:.*)`)
nicIDRE = regexp.MustCompile(`(?i)/subscriptions/(?:.*)/resourceGroups/(.+)/providers/Microsoft.Network/networkInterfaces/(.+)/ipConfigurations/(?:.*)`)
vmIDRE = regexp.MustCompile(`(?i)/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Compute/virtualMachines/(.+)`)
vmasIDRE = regexp.MustCompile(`/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Compute/availabilitySets/(.+)`)
)

Expand Down Expand Up @@ -1055,24 +1056,40 @@ func (as *availabilitySet) GetNodeNameByIPConfigurationID(ipConfigurationID stri
return "", "", fmt.Errorf("invalid ip config ID %s", ipConfigurationID)
}

prefix := matches[1]
suffix := matches[2]
nodeName := fmt.Sprintf("%s-%s", prefix, suffix)
nicResourceGroup, nicName := matches[1], matches[2]
if nicResourceGroup == "" || nicName == "" {
return "", "", fmt.Errorf("invalid ip config ID %s", ipConfigurationID)
}
nic, rerr := as.InterfacesClient.Get(context.Background(), nicResourceGroup, nicName, "")
if rerr != nil {
return "", "", fmt.Errorf("GetNodeNameByIPConfigurationID(%s): failed to get interface of name %s: %s", ipConfigurationID, nicName, rerr.Error().Error())
}
vmID := ""
if nic.InterfacePropertiesFormat != nil && nic.VirtualMachine != nil {
vmID = to.String(nic.VirtualMachine.ID)
}
if vmID == "" {
klog.V(2).Infof("GetNodeNameByIPConfigurationID(%s): empty vmID", ipConfigurationID)
return "", "", nil
}

vm, err := as.getVirtualMachine(types.NodeName(nodeName), azcache.CacheReadTypeDefault)
matches = vmIDRE.FindStringSubmatch(vmID)
if len(matches) != 2 {
return "", "", fmt.Errorf("invalid virtual machine ID %s", vmID)
}
vmName := matches[1]

vm, err := as.getVirtualMachine(types.NodeName(vmName), azcache.CacheReadTypeDefault)
if err != nil {
return "", "", fmt.Errorf("cannot get the virtual machine by node name %s", nodeName)
return "", "", fmt.Errorf("cannot get the virtual machine by node name %s", vmName)
}
asID := ""
if vm.VirtualMachineProperties != nil && vm.AvailabilitySet != nil {
asID = to.String(vm.AvailabilitySet.ID)
}
if asID == "" {
return "", "", fmt.Errorf("cannot get the availability set ID from the virtual machine with node name %s", nodeName)
}
asName, err := getAvailabilitySetNameByID(asID)
if err != nil {
return "", "", fmt.Errorf("cannot get the availability set name by the availability set ID %s", asID)
}
return nodeName, strings.ToLower(asName), nil
return vmName, strings.ToLower(asName), nil
}
Expand Up @@ -1673,7 +1673,10 @@ func TestStandardEnsureBackendPoolDeleted(t *testing.T) {
mockVMClient.EXPECT().Get(gomock.Any(), cloud.ResourceGroup, "k8s-agentpool1-00000000-1", gomock.Any()).Return(test.existingVM, nil)
cloud.VirtualMachinesClient = mockVMClient
mockNICClient := mockinterfaceclient.NewMockInterface(ctrl)
mockNICClient.EXPECT().Get(gomock.Any(), "rg", "k8s-agentpool1-00000000-nic-1", gomock.Any()).Return(test.existingNIC, nil)
test.existingNIC.VirtualMachine = &network.SubResource{
ID: to.StringPtr("/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/k8s-agentpool1-00000000-1"),
}
mockNICClient.EXPECT().Get(gomock.Any(), "rg", "k8s-agentpool1-00000000-nic-1", gomock.Any()).Return(test.existingNIC, nil).Times(2)
mockNICClient.EXPECT().CreateOrUpdate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
cloud.InterfacesClient = mockNICClient

Expand Down Expand Up @@ -1729,11 +1732,18 @@ func TestStandardGetNodeNameByIPConfigurationID(t *testing.T) {
defer ctrl.Finish()
cloud := GetTestCloud(ctrl)
expectedVM := buildDefaultTestVirtualMachine("/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Compute/availabilitySets/AGENTPOOL1-AVAILABILITYSET-00000000", []string{})
expectedVM.Name = to.StringPtr("name")
mockVMClient := cloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
mockVMClient.EXPECT().Get(gomock.Any(), "rg", "k8s-agentpool1-00000000-0", gomock.Any()).Return(expectedVM, nil)
expectedNIC := buildDefaultTestInterface(true, []string{})
expectedNIC.VirtualMachine = &network.SubResource{
ID: to.StringPtr("/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/k8s-agentpool1-00000000-0"),
}
mockNICClient := cloud.InterfacesClient.(*mockinterfaceclient.MockInterface)
mockNICClient.EXPECT().Get(gomock.Any(), "rg", "k8s-agentpool1-00000000-nic-0", gomock.Any()).Return(expectedNIC, nil)
ipConfigurationID := `/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Network/networkInterfaces/k8s-agentpool1-00000000-nic-0/ipConfigurations/ipconfig1`
nodeName, asName, err := cloud.VMSet.GetNodeNameByIPConfigurationID(ipConfigurationID)
assert.NoError(t, err)
assert.Equal(t, nodeName, "k8s-agentpool1-00000000-0")
assert.Equal(t, asName, "agentpool1-availabilityset-00000000")
assert.Equal(t, "k8s-agentpool1-00000000-0", nodeName)
assert.Equal(t, "agentpool1-availabilityset-00000000", asName)
}

0 comments on commit 91eef64

Please sign in to comment.