mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #91398 from marwanad/implement-async-deletes
add method for async deletion in vmss client without waiting on future
This commit is contained in:
		@@ -434,6 +434,53 @@ func (c *Client) DeleteInstances(ctx context.Context, resourceGroupName string,
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteInstancesAsync sends the delete request to ARM client and DOEST NOT wait on the future
 | 
			
		||||
func (c *Client) DeleteInstancesAsync(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error) {
 | 
			
		||||
	mc := metrics.NewMetricContext("vmss", "delete_instances_async", resourceGroupName, c.subscriptionID, "")
 | 
			
		||||
 | 
			
		||||
	// Report errors if the client is rate limited.
 | 
			
		||||
	if !c.rateLimiterWriter.TryAccept() {
 | 
			
		||||
		mc.RateLimitedCount()
 | 
			
		||||
		return nil, retry.GetRateLimitError(true, "VMSSDeleteInstancesAsync")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Report errors if the client is throttled.
 | 
			
		||||
	if c.RetryAfterWriter.After(time.Now()) {
 | 
			
		||||
		mc.ThrottledCount()
 | 
			
		||||
		rerr := retry.GetThrottlingError("VMSSDeleteInstancesAsync", "client throttled", c.RetryAfterWriter)
 | 
			
		||||
		return nil, rerr
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resourceID := armclient.GetResourceID(
 | 
			
		||||
		c.subscriptionID,
 | 
			
		||||
		resourceGroupName,
 | 
			
		||||
		"Microsoft.Compute/virtualMachineScaleSets",
 | 
			
		||||
		vmScaleSetName,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	response, rerr := c.armClient.PostResource(ctx, resourceID, "delete", vmInstanceIDs)
 | 
			
		||||
	defer c.armClient.CloseResponse(ctx, response)
 | 
			
		||||
 | 
			
		||||
	if rerr != nil {
 | 
			
		||||
		klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.deletevms.request", resourceID, rerr.Error())
 | 
			
		||||
		return nil, rerr
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := autorest.Respond(response, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.deletevms.respond", resourceID, rerr.Error())
 | 
			
		||||
		return nil, retry.GetError(response, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	future, err := azure.NewFutureFromResponse(response)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.deletevms.future", resourceID, rerr.Error())
 | 
			
		||||
		return nil, retry.NewError(false, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &future, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// deleteVMSSInstances deletes the instances for a VirtualMachineScaleSet.
 | 
			
		||||
func (c *Client) deleteVMSSInstances(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) *retry.Error {
 | 
			
		||||
	resourceID := armclient.GetResourceID(
 | 
			
		||||
 
 | 
			
		||||
@@ -755,6 +755,35 @@ func TestDeleteInstancesWaitError(t *testing.T) {
 | 
			
		||||
	assert.NotNil(t, rerr)
 | 
			
		||||
	assert.Equal(t, vmssDeleteInstancesErr, rerr)
 | 
			
		||||
}
 | 
			
		||||
func TestDeleteInstancesAsync(t *testing.T) {
 | 
			
		||||
	ctrl := gomock.NewController(t)
 | 
			
		||||
	defer ctrl.Finish()
 | 
			
		||||
 | 
			
		||||
	vmss := getTestVMSS("vmss1")
 | 
			
		||||
	vmInstanceIDs := compute.VirtualMachineScaleSetVMInstanceRequiredIDs{
 | 
			
		||||
		InstanceIds: &[]string{"0", "1", "2"},
 | 
			
		||||
	}
 | 
			
		||||
	response := &http.Response{
 | 
			
		||||
		StatusCode: http.StatusOK,
 | 
			
		||||
		Request:    &http.Request{Method: "POST"},
 | 
			
		||||
		Body:       ioutil.NopCloser(bytes.NewReader([]byte("{}"))),
 | 
			
		||||
	}
 | 
			
		||||
	armClient := mockarmclient.NewMockInterface(ctrl)
 | 
			
		||||
	armClient.EXPECT().PostResource(gomock.Any(), to.String(vmss.ID), "delete", vmInstanceIDs).Return(response, nil).Times(1)
 | 
			
		||||
	armClient.EXPECT().CloseResponse(gomock.Any(), gomock.Any()).Times(1)
 | 
			
		||||
 | 
			
		||||
	vmssClient := getTestVMSSClient(armClient)
 | 
			
		||||
	future, rerr := vmssClient.DeleteInstancesAsync(context.TODO(), "rg", "vmss1", vmInstanceIDs)
 | 
			
		||||
	assert.Nil(t, rerr)
 | 
			
		||||
	assert.Equal(t, future.Status(), "Succeeded")
 | 
			
		||||
 | 
			
		||||
	// on error
 | 
			
		||||
	retryErr := &retry.Error{RawError: fmt.Errorf("error")}
 | 
			
		||||
	armClient.EXPECT().PostResource(gomock.Any(), to.String(vmss.ID), "delete", vmInstanceIDs).Return(&http.Response{StatusCode: http.StatusBadRequest}, retryErr).Times(1)
 | 
			
		||||
	armClient.EXPECT().CloseResponse(gomock.Any(), gomock.Any()).Times(1)
 | 
			
		||||
	_, rerr = vmssClient.DeleteInstancesAsync(context.TODO(), "rg", "vmss1", vmInstanceIDs)
 | 
			
		||||
	assert.Equal(t, retryErr, rerr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getTestVMSS(name string) compute.VirtualMachineScaleSet {
 | 
			
		||||
	return compute.VirtualMachineScaleSet{
 | 
			
		||||
 
 | 
			
		||||
@@ -54,4 +54,7 @@ type Interface interface {
 | 
			
		||||
 | 
			
		||||
	// DeleteInstances deletes the instances for a VirtualMachineScaleSet.
 | 
			
		||||
	DeleteInstances(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) *retry.Error
 | 
			
		||||
 | 
			
		||||
	// DeleteInstancesAsync sends the delete request to the ARM client and DOEST NOT wait on the future
 | 
			
		||||
	DeleteInstancesAsync(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -139,3 +139,18 @@ func (mr *MockInterfaceMockRecorder) DeleteInstances(ctx, resourceGroupName, vmS
 | 
			
		||||
	mr.mock.ctrl.T.Helper()
 | 
			
		||||
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteInstances", reflect.TypeOf((*MockInterface)(nil).DeleteInstances), ctx, resourceGroupName, vmScaleSetName, vmInstanceIDs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteInstancesAsync mocks base method
 | 
			
		||||
func (m *MockInterface) DeleteInstancesAsync(ctx context.Context, resourceGroupName, VMScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error) {
 | 
			
		||||
	m.ctrl.T.Helper()
 | 
			
		||||
	ret := m.ctrl.Call(m, "DeleteInstancesAsync", ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs)
 | 
			
		||||
	ret0, _ := ret[0].(*azure.Future)
 | 
			
		||||
	ret1, _ := ret[1].(*retry.Error)
 | 
			
		||||
	return ret0, ret1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteInstancesAsync indicates an expected call of DeleteInstancesAsync
 | 
			
		||||
func (mr *MockInterfaceMockRecorder) DeleteInstancesAsync(ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs interface{}) *gomock.Call {
 | 
			
		||||
	mr.mock.ctrl.T.Helper()
 | 
			
		||||
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteInstancesAsync", reflect.TypeOf((*MockInterface)(nil).DeleteInstancesAsync), ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user