Skip to content

Commit

Permalink
Merge pull request kubernetes#91398 from marwanad/implement-async-del…
Browse files Browse the repository at this point in the history
…etes

add method for async deletion in vmss client without waiting on future
  • Loading branch information
k8s-ci-robot authored May 26, 2020
2 parents 6d3edbc + 524a7f2 commit 1582077
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

0 comments on commit 1582077

Please sign in to comment.