Skip to content

Commit ac10e40

Browse files
authored
Merge pull request kubernetes#95578 from marwanad/add-deallocation-methods
add methods to deallocate and starts vms in a scale set
2 parents 722be66 + ede9d8c commit ac10e40

File tree

3 files changed

+237
-0
lines changed

3 files changed

+237
-0
lines changed

staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmssclient/azure_vmssclient.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,38 @@ func (c *Client) CreateOrUpdateAsync(ctx context.Context, resourceGroupName stri
272272
return future, nil
273273
}
274274

275+
// WaitForCreateOrUpdateResult waits for the response of the create or update request
276+
func (c *Client) WaitForCreateOrUpdateResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error) {
277+
mc := metrics.NewMetricContext("vmss", "wait_for_create_or_update_result", resourceGroupName, c.subscriptionID, "")
278+
res, err := c.armClient.WaitForAsyncOperationResult(ctx, future, "VMSSWaitForCreateOrUpdateResult")
279+
mc.Observe(err)
280+
return res, err
281+
}
282+
283+
// WaitForDeleteInstancesResult waits for the response of the delete instance request
284+
func (c *Client) WaitForDeleteInstancesResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error) {
285+
mc := metrics.NewMetricContext("vmss", "wait_for_delete_instances_result", resourceGroupName, c.subscriptionID, "")
286+
res, err := c.armClient.WaitForAsyncOperationResult(ctx, future, "VMSSWaitForDeleteInstancesResult")
287+
mc.Observe(err)
288+
return res, err
289+
}
290+
291+
// WaitForDeallocateInstancesResult waits for the response of the delete instance request
292+
func (c *Client) WaitForDeallocateInstancesResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error) {
293+
mc := metrics.NewMetricContext("vmss", "wait_for_deallocate_instances_result", resourceGroupName, c.subscriptionID, "")
294+
res, err := c.armClient.WaitForAsyncOperationResult(ctx, future, "VMSSWaitForDeallocateInstancesResult")
295+
mc.Observe(err)
296+
return res, err
297+
}
298+
299+
// WaitForStartInstancesResult waits for the response of the delete instance request
300+
func (c *Client) WaitForStartInstancesResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error) {
301+
mc := metrics.NewMetricContext("vmss", "wait_for_start_instances_result", resourceGroupName, c.subscriptionID, "")
302+
res, err := c.armClient.WaitForAsyncOperationResult(ctx, future, "VMSSWaitForStartInstancesResult")
303+
mc.Observe(err)
304+
return res, err
305+
}
306+
275307
// WaitForAsyncOperationResult waits for the response of the request
276308
func (c *Client) WaitForAsyncOperationResult(ctx context.Context, future *azure.Future) (*http.Response, error) {
277309
return c.armClient.WaitForAsyncOperationResult(ctx, future, "VMSSWaitForAsyncOperationResult")
@@ -473,6 +505,7 @@ func (c *Client) DeleteInstancesAsync(ctx context.Context, resourceGroupName str
473505
}
474506

475507
future, err := azure.NewFutureFromResponse(response)
508+
mc.Observe(err)
476509
if err != nil {
477510
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.deletevms.future", resourceID, rerr.Error())
478511
return nil, retry.NewError(false, err)
@@ -481,6 +514,102 @@ func (c *Client) DeleteInstancesAsync(ctx context.Context, resourceGroupName str
481514
return &future, nil
482515
}
483516

517+
// DeallocateInstancesAsync sends the deallocate request to ARM client and DOEST NOT wait on the future
518+
func (c *Client) DeallocateInstancesAsync(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error) {
519+
mc := metrics.NewMetricContext("vmss", "deallocate_instances_async", resourceGroupName, c.subscriptionID, "")
520+
521+
// Report errors if the client is rate limited.
522+
if !c.rateLimiterWriter.TryAccept() {
523+
mc.RateLimitedCount()
524+
return nil, retry.GetRateLimitError(true, "VMSSDeallocateInstancesAsync")
525+
}
526+
527+
// Report errors if the client is throttled.
528+
if c.RetryAfterWriter.After(time.Now()) {
529+
mc.ThrottledCount()
530+
rerr := retry.GetThrottlingError("VMSSDeallocateInstancesAsync", "client throttled", c.RetryAfterWriter)
531+
return nil, rerr
532+
}
533+
534+
resourceID := armclient.GetResourceID(
535+
c.subscriptionID,
536+
resourceGroupName,
537+
"Microsoft.Compute/virtualMachineScaleSets",
538+
vmScaleSetName,
539+
)
540+
541+
response, rerr := c.armClient.PostResource(ctx, resourceID, "deallocate", vmInstanceIDs)
542+
defer c.armClient.CloseResponse(ctx, response)
543+
544+
if rerr != nil {
545+
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.deallocatevms.request", resourceID, rerr.Error())
546+
return nil, rerr
547+
}
548+
549+
err := autorest.Respond(response, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted))
550+
if err != nil {
551+
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.deallocatevms.respond", resourceID, rerr.Error())
552+
return nil, retry.GetError(response, err)
553+
}
554+
555+
future, err := azure.NewFutureFromResponse(response)
556+
mc.Observe(err)
557+
if err != nil {
558+
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.deallocatevms.future", resourceID, rerr.Error())
559+
return nil, retry.NewError(false, err)
560+
}
561+
562+
return &future, nil
563+
}
564+
565+
// StartInstancesAsync sends the start request to ARM client and DOEST NOT wait on the future
566+
func (c *Client) StartInstancesAsync(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error) {
567+
mc := metrics.NewMetricContext("vmss", "start_instances_async", resourceGroupName, c.subscriptionID, "")
568+
569+
// Report errors if the client is rate limited.
570+
if !c.rateLimiterWriter.TryAccept() {
571+
mc.RateLimitedCount()
572+
return nil, retry.GetRateLimitError(true, "VMSSStartInstancesAsync")
573+
}
574+
575+
// Report errors if the client is throttled.
576+
if c.RetryAfterWriter.After(time.Now()) {
577+
mc.ThrottledCount()
578+
rerr := retry.GetThrottlingError("VMSSStartInstancesAsync", "client throttled", c.RetryAfterWriter)
579+
return nil, rerr
580+
}
581+
582+
resourceID := armclient.GetResourceID(
583+
c.subscriptionID,
584+
resourceGroupName,
585+
"Microsoft.Compute/virtualMachineScaleSets",
586+
vmScaleSetName,
587+
)
588+
589+
response, rerr := c.armClient.PostResource(ctx, resourceID, "start", vmInstanceIDs)
590+
defer c.armClient.CloseResponse(ctx, response)
591+
592+
if rerr != nil {
593+
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.startvms.request", resourceID, rerr.Error())
594+
return nil, rerr
595+
}
596+
597+
err := autorest.Respond(response, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted))
598+
if err != nil {
599+
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.startvms.respond", resourceID, rerr.Error())
600+
return nil, retry.GetError(response, err)
601+
}
602+
603+
future, err := azure.NewFutureFromResponse(response)
604+
mc.Observe(err)
605+
if err != nil {
606+
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmss.startvms.future", resourceID, rerr.Error())
607+
return nil, retry.NewError(false, err)
608+
}
609+
610+
return &future, nil
611+
}
612+
484613
// deleteVMSSInstances deletes the instances for a VirtualMachineScaleSet.
485614
func (c *Client) deleteVMSSInstances(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) *retry.Error {
486615
resourceID := armclient.GetResourceID(

staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmssclient/interface.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,22 @@ type Interface interface {
5757

5858
// DeleteInstancesAsync sends the delete request to the ARM client and DOEST NOT wait on the future
5959
DeleteInstancesAsync(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error)
60+
61+
// WaitForCreateOrUpdateResult waits for the response of the create or update request
62+
WaitForCreateOrUpdateResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error)
63+
64+
// WaitForDeleteInstancesResult waits for the response of the delete instances request
65+
WaitForDeleteInstancesResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error)
66+
67+
// DeallocateInstances sends the deallocate request to the ARM client and DOEST NOT wait on the future
68+
DeallocateInstancesAsync(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error)
69+
70+
// WaitForDeallocateInstancesResult waits for the response of the deallocate instances request
71+
WaitForDeallocateInstancesResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error)
72+
73+
// StartInstancesAsync starts the instances for a VirtualMachineScaleSet.
74+
StartInstancesAsync(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error)
75+
76+
// WaitForStartInstancesResult waits for the response of the start instances request
77+
WaitForStartInstancesResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error)
6078
}

staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient/interface.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,66 @@ func (mr *MockInterfaceMockRecorder) WaitForAsyncOperationResult(ctx, future int
126126
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForAsyncOperationResult", reflect.TypeOf((*MockInterface)(nil).WaitForAsyncOperationResult), ctx, future)
127127
}
128128

129+
// WaitForCreateOrUpdateResult mocks base method
130+
func (m *MockInterface) WaitForCreateOrUpdateResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error) {
131+
m.ctrl.T.Helper()
132+
ret := m.ctrl.Call(m, "WaitForCreateOrUpdateResult", ctx, future, resourceGroupName)
133+
ret0, _ := ret[0].(*http.Response)
134+
ret1, _ := ret[1].(error)
135+
return ret0, ret1
136+
}
137+
138+
// WaitForCreateOrUpdateResult indicates an expected call of WaitForCreateOrUpdateResult
139+
func (mr *MockInterfaceMockRecorder) WaitForCreateOrUpdateResult(ctx, future interface{}, resourceGroupName string) *gomock.Call {
140+
mr.mock.ctrl.T.Helper()
141+
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForCreateOrUpdateResult", reflect.TypeOf((*MockInterface)(nil).WaitForCreateOrUpdateResult), ctx, future, resourceGroupName)
142+
}
143+
144+
// WaitForDeleteInstancesResult mocks base method
145+
func (m *MockInterface) WaitForDeleteInstancesResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error) {
146+
m.ctrl.T.Helper()
147+
ret := m.ctrl.Call(m, "WaitForDeleteInstancesResult", ctx, future, resourceGroupName)
148+
ret0, _ := ret[0].(*http.Response)
149+
ret1, _ := ret[1].(error)
150+
return ret0, ret1
151+
}
152+
153+
// WaitForDeleteInstancesResult indicates an expected call of WaitForDeleteInstancesResult
154+
func (mr *MockInterfaceMockRecorder) WaitForDeleteInstancesResult(ctx, future interface{}, resourceGroupName string) *gomock.Call {
155+
mr.mock.ctrl.T.Helper()
156+
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForDeleteInstancesResult", reflect.TypeOf((*MockInterface)(nil).WaitForDeleteInstancesResult), ctx, future, resourceGroupName)
157+
}
158+
159+
// WaitForDeallocateInstancesResult mocks base method
160+
func (m *MockInterface) WaitForDeallocateInstancesResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error) {
161+
m.ctrl.T.Helper()
162+
ret := m.ctrl.Call(m, "WaitForDeallocateInstancesResult", ctx, future, resourceGroupName)
163+
ret0, _ := ret[0].(*http.Response)
164+
ret1, _ := ret[1].(error)
165+
return ret0, ret1
166+
}
167+
168+
// WaitForDeallocateInstancesResult indicates an expected call of WaitForDeallocateInstancesResult
169+
func (mr *MockInterfaceMockRecorder) WaitForDeallocateInstancesResult(ctx, future interface{}, resourceGroupName string) *gomock.Call {
170+
mr.mock.ctrl.T.Helper()
171+
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForDeallocateInstancesResult", reflect.TypeOf((*MockInterface)(nil).WaitForDeallocateInstancesResult), ctx, future, resourceGroupName)
172+
}
173+
174+
// WaitForStartInstancesResult mocks base method
175+
func (m *MockInterface) WaitForStartInstancesResult(ctx context.Context, future *azure.Future, resourceGroupName string) (*http.Response, error) {
176+
m.ctrl.T.Helper()
177+
ret := m.ctrl.Call(m, "WaitForStartInstancesResult", ctx, future, resourceGroupName)
178+
ret0, _ := ret[0].(*http.Response)
179+
ret1, _ := ret[1].(error)
180+
return ret0, ret1
181+
}
182+
183+
// WaitForStartInstancesResult indicates an expected call of WaitForStartInstancesResult
184+
func (mr *MockInterfaceMockRecorder) WaitForStartInstancesResult(ctx, future interface{}, resourceGroupName string) *gomock.Call {
185+
mr.mock.ctrl.T.Helper()
186+
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForStartInstancesResult", reflect.TypeOf((*MockInterface)(nil).WaitForStartInstancesResult), ctx, future, resourceGroupName)
187+
}
188+
129189
// DeleteInstances mocks base method
130190
func (m *MockInterface) DeleteInstances(ctx context.Context, resourceGroupName, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) *retry.Error {
131191
m.ctrl.T.Helper()
@@ -154,3 +214,33 @@ func (mr *MockInterfaceMockRecorder) DeleteInstancesAsync(ctx, resourceGroupName
154214
mr.mock.ctrl.T.Helper()
155215
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteInstancesAsync", reflect.TypeOf((*MockInterface)(nil).DeleteInstancesAsync), ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs)
156216
}
217+
218+
// DeallocateInstancesAsync mocks base method
219+
func (m *MockInterface) DeallocateInstancesAsync(ctx context.Context, resourceGroupName, VMScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error) {
220+
m.ctrl.T.Helper()
221+
ret := m.ctrl.Call(m, "DeallocateInstancesAsync", ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs)
222+
ret0, _ := ret[0].(*azure.Future)
223+
ret1, _ := ret[1].(*retry.Error)
224+
return ret0, ret1
225+
}
226+
227+
// DeallocateInstancesAsync indicates an expected call of DeleteInstancesAsync
228+
func (mr *MockInterfaceMockRecorder) DeallocateInstancesAsync(ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs interface{}) *gomock.Call {
229+
mr.mock.ctrl.T.Helper()
230+
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeallocateInstancesAsync", reflect.TypeOf((*MockInterface)(nil).DeallocateInstancesAsync), ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs)
231+
}
232+
233+
// StartInstancesAsync mocks base method
234+
func (m *MockInterface) StartInstancesAsync(ctx context.Context, resourceGroupName, VMScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) (*azure.Future, *retry.Error) {
235+
m.ctrl.T.Helper()
236+
ret := m.ctrl.Call(m, "StartInstancesAsync", ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs)
237+
ret0, _ := ret[0].(*azure.Future)
238+
ret1, _ := ret[1].(*retry.Error)
239+
return ret0, ret1
240+
}
241+
242+
// StartInstancesAsync indicates an expected call of DeleteInstancesAsync
243+
func (mr *MockInterfaceMockRecorder) StartInstancesAsync(ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs interface{}) *gomock.Call {
244+
mr.mock.ctrl.T.Helper()
245+
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartInstancesAsync", reflect.TypeOf((*MockInterface)(nil).StartInstancesAsync), ctx, resourceGroupName, VMScaleSetName, vmInstanceIDs)
246+
}

0 commit comments

Comments
 (0)