Optionally deallocate a VM after performing a graceful stop VM action (#2630)

* Optionally deallocate a VM after performing a graceful shutdown stop VM

* Update docs

* Account for MSFT uppercase booleans
This commit is contained in:
David Newman 2023-01-16 23:09:49 +10:00 коммит произвёл GitHub
Родитель 530c5cccc5
Коммит 8080049aa6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 46 добавлений и 24 удалений

Просмотреть файл

@ -163,19 +163,25 @@
curl -X GET -k "https://localhost:8443/admin/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER/serialconsole?vmName=$VMNAME" --header "Content-Type: application/json" -d "{}"
```
* Redeploy node of a dev cluster
* Redeploy a VM in a dev cluster
```bash
VMNAME="aro-cluster-qplnw-master-0"
curl -X POST -k "https://localhost:8443/admin/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER/redeployvm?vmName=$VMNAME" --header "Content-Type: application/json" -d "{}"
```
* Stop node of a dev cluster
* Stop a VM in a dev cluster
```bash
VMNAME="aro-cluster-qplnw-master-0"
curl -X POST -k "https://localhost:8443/admin/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER/stopvm?vmName=$VMNAME" --header "Content-Type: application/json" -d "{}"
```
* Start node of a dev cluster
* Stop and deallocate a VM in a dev cluster
```bash
VMNAME="aro-cluster-qplnw-master-0"
curl -X POST -k "https://localhost:8443/admin/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER/stopvm?vmName=$VMNAME" --header "Content-Type: application/json" -d "{}"
```
* Start a VM in a dev cluster
```bash
VMNAME="aro-cluster-qplnw-master-0"
curl -X POST -k "https://localhost:8443/admin/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER/startvm?vmName=$VMNAME" --header "Content-Type: application/json" -d "{}"

Просмотреть файл

@ -25,11 +25,12 @@ func (f *frontend) postAdminOpenShiftClusterStopVM(w http.ResponseWriter, r *htt
func (f *frontend) _postAdminOpenShiftClusterStopVM(log *logrus.Entry, ctx context.Context, r *http.Request) error {
vars := mux.Vars(r)
vmName := r.URL.Query().Get("vmName")
vmName, deallocateVm := r.URL.Query().Get("vmName"), r.URL.Query().Get("deallocateVM")
action, _, err := f.prepareAdminActions(log, ctx, vmName, strings.TrimPrefix(r.URL.Path, "/admin"), vars)
if err != nil {
return err
}
return action.VMStopAndWait(ctx, vmName)
return action.VMStopAndWait(ctx, vmName, strings.EqualFold(deallocateVm, "True"))
}

Просмотреть файл

@ -32,6 +32,7 @@ func TestAdminStopVM(t *testing.T) {
resourceID string
fixture func(*testdatabase.Fixture)
vmName string
deallocateVM bool
mocks func(*test, *mock_adminactions.MockAzureActions)
wantStatusCode int
wantResponse []byte
@ -40,9 +41,10 @@ func TestAdminStopVM(t *testing.T) {
for _, tt := range []*test{
{
name: "basic coverage",
vmName: "aro-worker-australiasoutheast-7tcq7",
resourceID: testdatabase.GetResourcePath(mockSubID, "resourceName"),
name: "basic coverage",
vmName: "aro-worker-australiasoutheast-7tcq7",
deallocateVM: false,
resourceID: testdatabase.GetResourcePath(mockSubID, "resourceName"),
fixture: func(f *testdatabase.Fixture) {
f.AddOpenShiftClusterDocuments(&api.OpenShiftClusterDocument{
Key: strings.ToLower(testdatabase.GetResourcePath(mockSubID, "resourceName")),
@ -67,7 +69,7 @@ func TestAdminStopVM(t *testing.T) {
})
},
mocks: func(tt *test, a *mock_adminactions.MockAzureActions) {
a.EXPECT().VMStopAndWait(gomock.Any(), tt.vmName).Return(nil)
a.EXPECT().VMStopAndWait(gomock.Any(), tt.vmName, tt.deallocateVM).Return(nil)
},
wantStatusCode: http.StatusOK,
},
@ -95,7 +97,7 @@ func TestAdminStopVM(t *testing.T) {
go f.Run(ctx, nil, nil)
resp, b, err := ti.request(http.MethodPost,
fmt.Sprintf("https://server/admin%s/stopvm?vmName=%s", tt.resourceID, tt.vmName),
fmt.Sprintf("https://server/admin%s/stopvm?vmName=%s&deallocateVM=%t", tt.resourceID, tt.vmName, tt.deallocateVM),
nil, nil)
if err != nil {
t.Error(err)

Просмотреть файл

@ -32,7 +32,7 @@ type AzureActions interface {
NICReconcileFailedState(ctx context.Context, nicName string) error
VMRedeployAndWait(ctx context.Context, vmName string) error
VMStartAndWait(ctx context.Context, vmName string) error
VMStopAndWait(ctx context.Context, vmName string) error
VMStopAndWait(ctx context.Context, vmName string, deallocateVM bool) error
VMSizeList(ctx context.Context) ([]mgmtcompute.ResourceSku, error)
VMResize(ctx context.Context, vmName string, vmSize string) error
VMSerialConsole(ctx context.Context, w http.ResponseWriter, log *logrus.Entry, vmName string) error
@ -105,9 +105,9 @@ func (a *azureActions) VMStartAndWait(ctx context.Context, vmName string) error
return a.virtualMachines.StartAndWait(ctx, clusterRGName, vmName)
}
func (a *azureActions) VMStopAndWait(ctx context.Context, vmName string) error {
func (a *azureActions) VMStopAndWait(ctx context.Context, vmName string, deallocateVM bool) error {
clusterRGName := stringutils.LastTokenByte(a.oc.Properties.ClusterProfile.ResourceGroupID, '/')
return a.virtualMachines.StopAndWait(ctx, clusterRGName, vmName)
return a.virtualMachines.StopAndWait(ctx, clusterRGName, vmName, deallocateVM)
}
func (a *azureActions) VMSizeList(ctx context.Context) ([]mgmtcompute.ResourceSku, error) {

Просмотреть файл

@ -16,7 +16,7 @@ type VirtualMachinesClientAddons interface {
DeleteAndWait(ctx context.Context, resourceGroupName string, VMName string, forceDeletion *bool) error
RedeployAndWait(ctx context.Context, resourceGroupName string, VMName string) error
StartAndWait(ctx context.Context, resourceGroupName string, VMName string) error
StopAndWait(ctx context.Context, resourceGroupName string, VMName string) error
StopAndWait(ctx context.Context, resourceGroupName string, VMName string, deallocateVM bool) error
List(ctx context.Context, resourceGroupName string) (result []mgmtcompute.VirtualMachine, err error)
}
@ -56,13 +56,26 @@ func (c *virtualMachinesClient) StartAndWait(ctx context.Context, resourceGroupN
return future.WaitForCompletionRef(ctx, c.Client)
}
func (c *virtualMachinesClient) StopAndWait(ctx context.Context, resourceGroupName string, VMName string) error {
func (c *virtualMachinesClient) StopAndWait(ctx context.Context, resourceGroupName string, VMName string, deallocateVM bool) error {
future, err := c.PowerOff(ctx, resourceGroupName, VMName, to.BoolPtr(false))
if err != nil {
return err
}
return future.WaitForCompletionRef(ctx, c.Client)
err = future.WaitForCompletionRef(ctx, c.Client)
if err != nil {
return err
}
if deallocateVM {
future, deallocErr := c.Deallocate(ctx, resourceGroupName, VMName)
if deallocErr != nil {
return deallocErr
}
err = future.WaitForCompletionRef(ctx, c.Client)
}
return err
}
func (c *virtualMachinesClient) List(ctx context.Context, resourceGroupName string) (result []mgmtcompute.VirtualMachine, err error) {

Просмотреть файл

@ -351,17 +351,17 @@ func (mr *MockAzureActionsMockRecorder) VMStartAndWait(arg0, arg1 interface{}) *
}
// VMStopAndWait mocks base method.
func (m *MockAzureActions) VMStopAndWait(arg0 context.Context, arg1 string) error {
func (m *MockAzureActions) VMStopAndWait(arg0 context.Context, arg1 string, arg2 bool) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "VMStopAndWait", arg0, arg1)
ret := m.ctrl.Call(m, "VMStopAndWait", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// VMStopAndWait indicates an expected call of VMStopAndWait.
func (mr *MockAzureActionsMockRecorder) VMStopAndWait(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockAzureActionsMockRecorder) VMStopAndWait(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VMStopAndWait", reflect.TypeOf((*MockAzureActions)(nil).VMStopAndWait), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VMStopAndWait", reflect.TypeOf((*MockAzureActions)(nil).VMStopAndWait), arg0, arg1, arg2)
}
// WriteToStream mocks base method.

Просмотреть файл

@ -212,17 +212,17 @@ func (mr *MockVirtualMachinesClientMockRecorder) StartAndWait(arg0, arg1, arg2 i
}
// StopAndWait mocks base method.
func (m *MockVirtualMachinesClient) StopAndWait(arg0 context.Context, arg1, arg2 string) error {
func (m *MockVirtualMachinesClient) StopAndWait(arg0 context.Context, arg1, arg2 string, arg3 bool) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "StopAndWait", arg0, arg1, arg2)
ret := m.ctrl.Call(m, "StopAndWait", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(error)
return ret0
}
// StopAndWait indicates an expected call of StopAndWait.
func (mr *MockVirtualMachinesClientMockRecorder) StopAndWait(arg0, arg1, arg2 interface{}) *gomock.Call {
func (mr *MockVirtualMachinesClientMockRecorder) StopAndWait(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopAndWait", reflect.TypeOf((*MockVirtualMachinesClient)(nil).StopAndWait), arg0, arg1, arg2)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopAndWait", reflect.TypeOf((*MockVirtualMachinesClient)(nil).StopAndWait), arg0, arg1, arg2, arg3)
}
// MockUsageClient is a mock of UsageClient interface.