SQL-Migration: enable cross subscription service migration (#22876)

* x subscription migration support

* refresh after cutover

* fix service irregular status load behavior

* queue service status requests, fix typo

* add migationTargetServerName helper method

* save context before api call
This commit is contained in:
brian-harris
2023-04-27 16:28:32 -07:00
committed by GitHub
parent 65f8915b7e
commit fe32180c71
15 changed files with 347 additions and 240 deletions

View File

@@ -61,7 +61,7 @@ export class CreateSqlMigrationServiceDialog {
this._dialogObject.okButton.position = 'left';
this._dialogObject.cancelButton.position = 'left';
let tab = azdata.window.createTab('');
const tab = azdata.window.createTab('');
this._dialogObject.registerCloseValidator(async () => {
return true;
});
@@ -73,70 +73,64 @@ export class CreateSqlMigrationServiceDialog {
width: '80px'
}).component();
this._disposables.push(this._formSubmitButton.onDidClick(async (e) => {
this._dialogObject.message = {
text: ''
};
this._statusLoadingComponent.loading = true;
this.migrationServiceResourceGroupDropdown.loading = false;
this.setFormEnabledState(false);
const subscription = this._model._targetSubscription;
const resourceGroup = this._selectedResourceGroup;
const location = this._model._targetServerInstance.location;
const serviceName = this.migrationServiceNameText.value;
const formValidationErrors = this.validateCreateServiceForm(subscription, resourceGroup.name, location, serviceName);
if (formValidationErrors.length > 0) {
this.setDialogMessage(formValidationErrors);
this._statusLoadingComponent.loading = false;
this.setFormEnabledState(true);
return;
}
try {
this._disposables.push(
this._formSubmitButton.onDidClick(async (e) => {
utils.clearDialogMessage(this._dialogObject);
this._selectedResourceGroup = resourceGroup;
this._createdMigrationService = await createSqlMigrationService(
this._model._azureAccount,
subscription,
resourceGroup.name,
location,
serviceName!,
this._model._sessionId);
if (this._createdMigrationService.error) {
this.setDialogMessage(`${this._createdMigrationService.error.code} : ${this._createdMigrationService.error.message}`);
this._statusLoadingComponent.loading = false;
this._statusLoadingComponent.loading = true;
this.migrationServiceResourceGroupDropdown.loading = false;
this.setFormEnabledState(false);
const subscription = this._model._sqlMigrationServiceSubscription;
const resourceGroup = this._selectedResourceGroup;
const location = this._model._location.name;
const serviceName = this.migrationServiceNameText.value;
const formValidationErrors = this.validateCreateServiceForm(subscription, resourceGroup.name, location, serviceName);
try {
if (formValidationErrors.length > 0) {
this.setDialogMessage(formValidationErrors);
this.setFormEnabledState(true);
return;
}
utils.clearDialogMessage(this._dialogObject);
this._createdMigrationService = await createSqlMigrationService(
this._model._azureAccount,
subscription,
resourceGroup.name,
location,
serviceName!,
this._model._sessionId);
if (this._createdMigrationService.error) {
this.setDialogMessage(`${this._createdMigrationService.error.code} : ${this._createdMigrationService.error.message}`);
this.setFormEnabledState(true);
return;
}
if (this._isBlobContainerUsed && !this._model.isSqlDbTarget) {
this._dialogObject.okButton.enabled = true;
this._setupContainer.display = 'none';
this._dialogObject.message = {
text: constants.DATA_MIGRATION_SERVICE_CREATED_SUCCESSFULLY,
level: azdata.window.MessageLevel.Information
};
} else {
await this.refreshStatus();
await this.refreshAuthTable();
this._setupContainer.display = 'inline';
this._testConnectionButton.hidden = false;
}
} catch (e) {
console.log(e);
this.setDialogMessage(e.message);
this.setFormEnabledState(true);
return;
}
if (this._isBlobContainerUsed && !this._model.isSqlDbTarget) {
this._dialogObject.okButton.enabled = true;
this._statusLoadingComponent.loading = false;
this._setupContainer.display = 'none';
this._dialogObject.message = {
text: constants.DATA_MIGRATION_SERVICE_CREATED_SUCCESSFULLY,
level: azdata.window.MessageLevel.Information
};
} else {
await this.refreshStatus();
await this.refreshAuthTable();
this._setupContainer.display = 'inline';
this._testConnectionButton.hidden = false;
} finally {
this._statusLoadingComponent.loading = false;
}
} catch (e) {
console.log(e);
this.setDialogMessage(e.message);
this._statusLoadingComponent.loading = false;
this.setFormEnabledState(true);
return;
}
}));
}));
this._statusLoadingComponent = view.modelBuilder.loadingComponent().withProps({
loadingText: constants.LOADING_MIGRATION_SERVICES,
@@ -289,7 +283,11 @@ export class CreateSqlMigrationServiceDialog {
}).component();
this._disposables.push(this._createResourceGroupLink.onDidClick(async e => {
const createResourceGroupDialog = new CreateResourceGroupDialog(this._model._azureAccount, this._model._targetSubscription, this._model._targetServerInstance.location);
const createResourceGroupDialog = new CreateResourceGroupDialog(
this._model._azureAccount,
this._model._sqlMigrationServiceSubscription,
this._model._location.name);
const createdResourceGroup = await createResourceGroupDialog.initialize();
if (createdResourceGroup) {
this._resourceGroups.push(createdResourceGroup);
@@ -324,7 +322,7 @@ export class CreateSqlMigrationServiceDialog {
this.migrationServiceLocation = this._view.modelBuilder.text().withProps({
enabled: false,
value: await this._model.getLocationDisplayName(this._model._targetServerInstance.location),
value: this._model._location.displayName,
CSSStyles: {
'margin': '-1em 0 0'
}
@@ -386,7 +384,7 @@ export class CreateSqlMigrationServiceDialog {
private async populateSubscriptions(): Promise<void> {
this.migrationServiceResourceGroupDropdown.loading = true;
this.migrationServiceSubscription.value = this._model._targetSubscription.name;
this.migrationServiceSubscription.value = this._model._sqlMigrationServiceSubscription.name;
await this.populateResourceGroups();
}
@@ -395,7 +393,7 @@ export class CreateSqlMigrationServiceDialog {
try {
this._resourceGroups = await utils.getAllResourceGroups(
this._model._azureAccount,
this._model._targetSubscription);
this._model._sqlMigrationServiceSubscription);
this.migrationServiceResourceGroupDropdown.values = utils.getResourceDropdownValues(
this._resourceGroups,
constants.RESOURCE_GROUP_NOT_FOUND);
@@ -510,10 +508,10 @@ export class CreateSqlMigrationServiceDialog {
}
private async refreshStatus(): Promise<void> {
const subscription = this._model._targetSubscription;
const subscription = this._model._sqlMigrationServiceSubscription;
const resourceGroupId = (this.migrationServiceResourceGroupDropdown.value as azdata.CategoryValue).name;
const resourceGroup = getResourceName(resourceGroupId);
const location = this._model._targetServerInstance.location;
const location = this._model._location.name;
const maxRetries = 5;
let migrationServiceStatus!: SqlMigrationService;
@@ -558,7 +556,6 @@ export class CreateSqlMigrationServiceDialog {
...styles.BODY_CSS
}
});
this._dialogObject.okButton.enabled = true;
} else {
this._connectionStatus.text = constants.SERVICE_NOT_READY(this._createdMigrationService!.name);
await this._connectionStatus.updateProperties(<azdata.InfoBoxComponentProperties>{
@@ -568,16 +565,16 @@ export class CreateSqlMigrationServiceDialog {
...styles.BODY_CSS
}
});
this._dialogObject.okButton.enabled = false;
}
this._dialogObject.okButton.enabled = true;
}
}
private async refreshAuthTable(): Promise<void> {
const subscription = this._model._targetSubscription;
const subscription = this._model._sqlMigrationServiceSubscription;
const resourceGroupId = (this.migrationServiceResourceGroupDropdown.value as azdata.CategoryValue).name;
const resourceGroup = getResourceName(resourceGroupId);
const location = this._model._targetServerInstance.location;
const location = this._model._location.name;
const keys = await getSqlMigrationServiceAuthKeys(
this._model._azureAccount,
subscription,