diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache.go index 90082f0e47c..2d59df140e4 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache.go @@ -156,13 +156,20 @@ func (ss *scaleSet) newVMSSVirtualMachinesCache() (*timedCache, error) { } computerName := strings.ToLower(*vm.OsProfile.ComputerName) - localCache.Store(computerName, &vmssVirtualMachinesEntry{ + vmssVMCacheEntry := &vmssVirtualMachinesEntry{ resourceGroup: resourceGroup, vmssName: ssName, instanceID: to.String(vm.InstanceID), virtualMachine: &vm, lastUpdate: time.Now().UTC(), - }) + } + // set cache entry to nil when the VM is under deleting. + if vm.VirtualMachineScaleSetVMProperties != nil && + strings.EqualFold(to.String(vm.VirtualMachineScaleSetVMProperties.ProvisioningState), string(compute.ProvisioningStateDeleting)) { + klog.V(4).Infof("VMSS virtualMachine %q is under deleting, setting its cache to nil", computerName) + vmssVMCacheEntry.virtualMachine = nil + } + localCache.Store(computerName, vmssVMCacheEntry) if _, exists := oldCache[computerName]; exists { delete(oldCache, computerName) diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache_test.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache_test.go index 84ff972a1ad..09b673c9ed7 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache_test.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache_test.go @@ -23,8 +23,10 @@ import ( "sync" "testing" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute" "github.com/Azure/go-autorest/autorest/to" "github.com/stretchr/testify/assert" + cloudprovider "k8s.io/cloud-provider" ) func TestExtractVmssVMName(t *testing.T) { @@ -112,3 +114,26 @@ func TestVMSSVMCache(t *testing.T) { assert.Equal(t, to.String(vm.InstanceID), instanceID) assert.Equal(t, &vm, realVM) } + +func TestVMSSVMCacheWithDeletingNodes(t *testing.T) { + vmssName := "vmss" + vmList := []string{"vmssee6c2000000", "vmssee6c2000001", "vmssee6c2000002"} + ss, err := newTestScaleSetWithState(vmssName, "", 0, vmList, "Deleting") + assert.NoError(t, err) + + virtualMachines, rerr := ss.VirtualMachineScaleSetVMsClient.List( + context.Background(), "rg", "vmss", "") + assert.Nil(t, rerr) + assert.Equal(t, 3, len(virtualMachines)) + for i := range virtualMachines { + vm := virtualMachines[i] + vmName := to.String(vm.OsProfile.ComputerName) + assert.Equal(t, vm.ProvisioningState, to.StringPtr(string(compute.ProvisioningStateDeleting))) + + ssName, instanceID, realVM, err := ss.getVmssVM(vmName, cacheReadTypeDefault) + assert.Nil(t, realVM) + assert.Equal(t, "", ssName) + assert.Equal(t, instanceID, ssName) + assert.Equal(t, cloudprovider.InstanceNotFound, err) + } +} diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_test.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_test.go index 7a6ee56baec..f77e966f693 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_test.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmss_test.go @@ -34,8 +34,12 @@ const ( ) func newTestScaleSet(scaleSetName, zone string, faultDomain int32, vmList []string) (*scaleSet, error) { + return newTestScaleSetWithState(scaleSetName, zone, faultDomain, vmList, "Running") +} + +func newTestScaleSetWithState(scaleSetName, zone string, faultDomain int32, vmList []string, state string) (*scaleSet, error) { cloud := getTestCloud() - setTestVirtualMachineCloud(cloud, scaleSetName, zone, faultDomain, vmList) + setTestVirtualMachineCloud(cloud, scaleSetName, zone, faultDomain, vmList, state) ss, err := newScaleSet(cloud) if err != nil { return nil, err @@ -44,7 +48,7 @@ func newTestScaleSet(scaleSetName, zone string, faultDomain int32, vmList []stri return ss.(*scaleSet), nil } -func setTestVirtualMachineCloud(ss *Cloud, scaleSetName, zone string, faultDomain int32, vmList []string) { +func setTestVirtualMachineCloud(ss *Cloud, scaleSetName, zone string, faultDomain int32, vmList []string, state string) { virtualMachineScaleSetsClient := newFakeVirtualMachineScaleSetsClient() virtualMachineScaleSetVMsClient := newFakeVirtualMachineScaleSetVMsClient() publicIPAddressesClient := newFakeAzurePIPClient("rg") @@ -99,6 +103,7 @@ func setTestVirtualMachineCloud(ss *Cloud, scaleSetName, zone string, faultDomai } vmssVM := compute.VirtualMachineScaleSetVM{ VirtualMachineScaleSetVMProperties: &compute.VirtualMachineScaleSetVMProperties{ + ProvisioningState: to.StringPtr(state), OsProfile: &compute.OSProfile{ ComputerName: &nodeName, }, diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_wrap.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_wrap.go index df936e13851..4b2eac0c274 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_wrap.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_wrap.go @@ -27,6 +27,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network" + "github.com/Azure/go-autorest/autorest/to" "k8s.io/apimachinery/pkg/types" cloudprovider "k8s.io/cloud-provider" @@ -193,6 +194,12 @@ func (az *Cloud) newVMCache() (*timedCache, error) { return nil, nil } + if vm.VirtualMachineProperties != nil && + strings.EqualFold(to.String(vm.VirtualMachineProperties.ProvisioningState), string(compute.ProvisioningStateDeleting)) { + klog.V(2).Infof("Virtual machine %q is under deleting", key) + return nil, nil + } + return &vm, nil }