Repository: kubernetes-sigs/cloud-provider-azure
Pull request #4805 (2023-10-16 07:07:15)

[release-1.27] report vmPowerStateUnknown when vmssVM intanceView is nil
This is an automated cherry-pick of #4798

/assign jwtty

```release-note
Fix the potential error that a deleting vmss instance is considered as shutdown.
```


Patch:
diff --git a/pkg/provider/azure.go b/pkg/provider/azure.go
index a918440db..64b63d457 100644
--- a/pkg/provider/azure.go
+++ b/pkg/provider/azure.go
@@ -1207,7 +1207,7 @@ func (az *Cloud) updateNodeTaint(node *v1.Node) {
 				klog.Errorf("failed to add taint %s to the node %s", v1.TaintNodeOutOfService, node.Name)
 			}
 		} else {
-			klog.V(2).Infof("node %s is not ready but node shutdown taint is not added, skip adding node out-of-service taint", node.Name)
+			klog.V(2).Infof("node %s is not ready but either shutdown taint is missing or out-of-service taint is already added, skip adding node out-of-service taint", node.Name)
 		}
 	}
 }
diff --git a/pkg/provider/azure_instances.go b/pkg/provider/azure_instances.go
index 753c11e2e..55e7ea3f2 100644
--- a/pkg/provider/azure_instances.go
+++ b/pkg/provider/azure_instances.go
@@ -39,6 +39,7 @@ const (
 	vmPowerStateStopped      = "stopped"
 	vmPowerStateDeallocated  = "deallocated"
 	vmPowerStateDeallocating = "deallocating"
+	vmPowerStateUnknown      = "unknown"
 
 	// nodeNameEnvironmentName is the environment variable name for getting node name.
 	// It is only used for out-of-tree cloud provider.
diff --git a/pkg/provider/azure_standard.go b/pkg/provider/azure_standard.go
index 620854c29..75a080e31 100644
--- a/pkg/provider/azure_standard.go
+++ b/pkg/provider/azure_standard.go
@@ -652,8 +652,8 @@ func (as *availabilitySet) GetPowerStatusByNodeName(name string) (powerState str
 	}
 
 	// vm.InstanceView or vm.InstanceView.Statuses are nil when the VM is under deleting.
-	klog.V(3).Infof("InstanceView for node %q is nil, assuming it's stopped", name)
-	return vmPowerStateStopped, nil
+	klog.V(3).Infof("InstanceView for node %q is nil, assuming it's deleting", name)
+	return vmPowerStateUnknown, nil
 }
 
 // GetProvisioningStateByNodeName returns the provisioningState for the specified node.
diff --git a/pkg/provider/azure_vmss.go b/pkg/provider/azure_vmss.go
index cc0328f25..b2c116d2c 100644
--- a/pkg/provider/azure_vmss.go
+++ b/pkg/provider/azure_vmss.go
@@ -293,8 +293,8 @@ func (ss *ScaleSet) GetPowerStatusByNodeName(name string) (powerState string, er
 	}
 
 	// vm.InstanceView or vm.InstanceView.Statuses are nil when the VM is under deleting.
-	klog.V(3).Infof("InstanceView for node %q is nil, assuming it's stopped", name)
-	return vmPowerStateStopped, nil
+	klog.V(3).Infof("InstanceView for node %q is nil, assuming it's deleting", name)
+	return vmPowerStateUnknown, nil
 }
 
 // GetProvisioningStateByNodeName returns the provisioningState for the specified node.
diff --git a/pkg/provider/azure_vmssflex.go b/pkg/provider/azure_vmssflex.go
index 1f72f5bcf..5befc7c9c 100644
--- a/pkg/provider/azure_vmssflex.go
+++ b/pkg/provider/azure_vmssflex.go
@@ -280,8 +280,8 @@ func (fs *FlexScaleSet) GetPowerStatusByNodeName(name string) (powerState string
 	}
 
 	// vm.InstanceView or vm.InstanceView.Statuses are nil when the VM is under deleting.
-	klog.V(3).Infof("InstanceView for node %q is nil, assuming it's stopped", name)
-	return vmPowerStateStopped, nil
+	klog.V(3).Infof("InstanceView for node %q is nil, assuming it's deleting", name)
+	return vmPowerStateUnknown, nil
 }
 
 // GetPrimaryInterface gets machine primary network interface by node name.


Test patch:
diff --git a/pkg/provider/azure_standard_test.go b/pkg/provider/azure_standard_test.go
index 4f4f9e7ed..4641e82de 100644
--- a/pkg/provider/azure_standard_test.go
+++ b/pkg/provider/azure_standard_test.go
@@ -1297,7 +1297,7 @@ func TestGetStandardVMPowerStatusByNodeName(t *testing.T) {
 			expectedStatus: "Running",
 		},
 		{
-			name:     "GetPowerStatusByNodeName should get vmPowerStateStopped if vm.InstanceView is nil",
+			name:     "GetPowerStatusByNodeName should get vmPowerStateUnknown if vm.InstanceView is nil",
 			nodeName: "vm3",
 			vm: compute.VirtualMachine{
 				Name: pointer.String("vm3"),
@@ -1305,10 +1305,10 @@ func TestGetStandardVMPowerStatusByNodeName(t *testing.T) {
 					ProvisioningState: pointer.String("Succeeded"),
 				},
 			},
-			expectedStatus: vmPowerStateStopped,
+			expectedStatus: vmPowerStateUnknown,
 		},
 		{
-			name:     "GetPowerStatusByNodeName should get vmPowerStateStopped if vm.InstanceView.statuses is nil",
+			name:     "GetPowerStatusByNodeName should get vmPowerStateUnknown if vm.InstanceView.statuses is nil",
 			nodeName: "vm4",
 			vm: compute.VirtualMachine{
 				Name: pointer.String("vm4"),
@@ -1317,7 +1317,7 @@ func TestGetStandardVMPowerStatusByNodeName(t *testing.T) {
 					InstanceView:      &compute.VirtualMachineInstanceView{},
 				},
 			},
-			expectedStatus: vmPowerStateStopped,
+			expectedStatus: vmPowerStateUnknown,
 		},
 	}
 	for _, test := range testcases {
diff --git a/pkg/provider/azure_vmss_test.go b/pkg/provider/azure_vmss_test.go
index 9f3dd7779..63687ee92 100644
--- a/pkg/provider/azure_vmss_test.go
+++ b/pkg/provider/azure_vmss_test.go
@@ -787,10 +787,10 @@ func TestGetPowerStatusByNodeName(t *testing.T) {
 			expectedPowerState: "Running",
 		},
 		{
-			description:        "GetPowerStatusByNodeName should return vmPowerStateStopped when the vm.InstanceView.Statuses is nil",
+			description:        "GetPowerStatusByNodeName should return vmPowerStateUnknown when the vm.InstanceView.Statuses is nil",
 			vmList:             []string{"vmss-vm-000001"},
 			nilStatus:          true,
-			expectedPowerState: vmPowerStateStopped,
+			expectedPowerState: vmPowerStateUnknown,
 		},
 	}
 
diff --git a/pkg/provider/azure_vmssflex_test.go b/pkg/provider/azure_vmssflex_test.go
index 7d04d9de4..8fb584888 100644
--- a/pkg/provider/azure_vmssflex_test.go
+++ b/pkg/provider/azure_vmssflex_test.go
@@ -552,12 +552,12 @@ func TestGetPowerStatusByNodeNameVmssFlex(t *testing.T) {
 			expectedErr:                    cloudprovider.InstanceNotFound,
 		},
 		{
-			description:                    "GetPowerStatusByNodeName should return stopped if the node powerstate is nil",
+			description:                    "GetPowerStatusByNodeName should return unknown if the node powerstate is nil",
 			nodeName:                       "vmssflex1000003",
 			testVMListWithoutInstanceView:  testVMListWithoutInstanceView,
 			testVMListWithOnlyInstanceView: testVMListWithOnlyInstanceView,
 			vmListErr:                      nil,
-			expectedPowerStatus:            "stopped",
+			expectedPowerStatus:            "unknown",
 			expectedErr:                    nil,
 		},
 	}