Support multiple database migrations using network share (#17796)

* update database backup model to take list of network shares

* remove refreshMigrationTiles after startMigration in statemachine; add null checks
This commit is contained in:
Rachel Kim
2021-12-03 17:07:11 -08:00
committed by GitHub
parent 6aab9d41a3
commit 8d8b3983a9
6 changed files with 110 additions and 82 deletions

View File

@@ -116,7 +116,7 @@ export const DATABASE_BACKUP_NETWORK_SHARE_HEADER_TEXT = localize('sql.migration
export const DATABASE_BACKUP_NETWORK_SHARE_LOCATION_INFO = localize('sql.migration.network.share.location.info', "Network share path for your database backups. The migration process will automatically retrieve valid backup files from this network share.");
export const DATABASE_BACKUP_NETWORK_SHARE_WINDOWS_USER_INFO = localize('sql.migration.network.share.windows.user.info', "Windows user account with read access to the network share location.");
export const DATABASE_BACKUP_NC_NETWORK_SHARE_HELP_TEXT = localize('sql.migration.network.share.help.text', "Provide the network share location where the backups are stored, and the user credentials used to access the share.");
export const DATABASE_BACKUP_NETWORK_SHARE_TABLE_HELP_TEXT = localize('sql.migration.network.share.storage.table.help', "Enter target database name for the selected source databases.");
export const DATABASE_BACKUP_NETWORK_SHARE_TABLE_HELP_TEXT = localize('sql.migration.network.share.storage.table.help', "Enter target database name and network share path information for the selected source databases.");
export const DATABASE_BACKUP_NETWORK_SHARE_LOCATION_LABEL = localize('sql.migration.network.share.location.label', "Network share location where the backups are stored");
export const DATABASE_SERVICE_ACCOUNT_INFO_TEXT = localize('sql.migration.service.account.info.text', "Ensure that the service account running the source SQL Server instance has read privileges on the network share.");
export const DATABASE_BACKUP_NETWORK_SHARE_WINDOWS_USER_LABEL = localize('sql.migration.network.share.windows.user.label', "Windows user account with read access to the network share location");
@@ -138,7 +138,7 @@ export const DATABASE_BACKUP_MIGRATION_MODE_ONLINE_LABEL = localize('sql.migrati
export const DATABASE_BACKUP_MIGRATION_MODE_ONLINE_DESCRIPTION = localize('sql.migration.database.migration.mode.online.description', "Application downtime is limited to cutover at the end of migration.");
export const DATABASE_BACKUP_MIGRATION_MODE_OFFLINE_LABEL = localize('sql.migration.database.migration.mode.offline.label', "Offline migration");
export const DATABASE_BACKUP_MIGRATION_MODE_OFFLINE_DESCRIPTION = localize('sql.migration.database.migration.mode.offline.description', "Application downtime will start when the migration starts.");
export const NETWORK_SHARE_PATH = localize('sql.migration.network.share.path', "\\\\Servername.domainname.com\\Backupfolder");
export const NETWORK_SHARE_PATH_FORMAT = localize('sql.migration.network.share.path.format', "\\\\Servername.domainname.com\\Backupfolder");
export const WINDOWS_USER_ACCOUNT = localize('sql.migration.windows.user.account', "Domain\\username");
export const NO_SUBSCRIPTIONS_FOUND = localize('sql.migration.no.subscription.found', "No subscription found.");
export const NO_LOCATION_FOUND = localize('sql.migration.no.location.found', "No location found.");
@@ -161,7 +161,7 @@ export function INVALID_BLOB_CONTAINER_ERROR(sourceDb: string): string {
export function INVALID_BLOB_LAST_BACKUP_FILE_ERROR(sourceDb: string): string {
return localize('sql.migration.invalid.blob.lastBackupFile.error', "To continue, select a valid last backup file for source database '{0}'.", sourceDb);
}
export const INVALID_NETWORK_SHARE_LOCATION = localize('sql.migration.invalid.network.share.location', "Invalid network share location format. Example: {0}", NETWORK_SHARE_PATH);
export const INVALID_NETWORK_SHARE_LOCATION = localize('sql.migration.invalid.network.share.location', "Invalid network share location format. Example: {0}", NETWORK_SHARE_PATH_FORMAT);
export const INVALID_USER_ACCOUNT = localize('sql.migration.invalid.user.account', "Invalid user account format. Example: {0}", WINDOWS_USER_ACCOUNT);
export const INVALID_TARGET_NAME_ERROR = localize('sql.migration.invalid.target.name.error', "Enter a valid name for the target database.");
export const PROVIDE_UNIQUE_CONTAINERS = localize('sql.migration.provide.unique.containers', "Provide a unique container for each target database. Databases affected: ");
@@ -282,6 +282,7 @@ export const SUMMARY_DATABASE_COUNT_LABEL = localize('sql.migration.summary.data
export const SUMMARY_AZURE_STORAGE_SUBSCRIPTION = localize('sql.migration.summary.azure.storage.subscription', "Azure storage subscription");
export const SUMMARY_AZURE_STORAGE = localize('sql.migration.summary.azure.storage', "Azure storage");
export const NETWORK_SHARE = localize('sql.migration.network.share', "Network share");
export const NETWORK_SHARE_PATH = localize('sql.migration.network.share.path', "Network share path");
export const BLOB_CONTAINER = localize('sql.migration.blob.container.title', "Blob container");
export const BLOB_CONTAINER_LAST_BACKUP_FILE = localize('sql.migration.blob.container.last.backup.file.label', "Last backup file");
export const BLOB_CONTAINER_RESOURCE_GROUP = localize('sql.migration.blob.container.label', "Blob container resource group");

View File

@@ -60,7 +60,7 @@ export class RetryMigrationDialog {
targetSubscription: migration.subscription,
targetDatabaseNames: [migration.migrationContext.name],
networkContainerType: null,
networkShare: null,
networkShares: [],
blobs: [],
// Integration Runtime
@@ -90,14 +90,16 @@ export class RetryMigrationDialog {
if (sourceLocation?.fileShare) {
savedInfo.networkContainerType = NetworkContainerType.NETWORK_SHARE;
const storageAccountResourceId = migration.migrationContext.properties.backupConfiguration.targetLocation?.storageAccountResourceId!;
savedInfo.networkShare = {
password: '',
networkShareLocation: sourceLocation?.fileShare?.path!,
windowsUser: sourceLocation?.fileShare?.username!,
storageAccount: getStorageAccount(storageAccountResourceId!),
resourceGroup: getStorageAccountResourceGroup(storageAccountResourceId!),
storageKey: ''
};
savedInfo.networkShares = [
{
password: '',
networkShareLocation: sourceLocation?.fileShare?.path!,
windowsUser: sourceLocation?.fileShare?.username!,
storageAccount: getStorageAccount(storageAccountResourceId!),
resourceGroup: getStorageAccountResourceGroup(storageAccountResourceId!),
storageKey: ''
}
];
} else if (sourceLocation?.azureBlob) {
savedInfo.networkContainerType = NetworkContainerType.BLOB_CONTAINER;
const storageAccountResourceId = sourceLocation?.azureBlob?.storageAccountResourceId!;

View File

@@ -19,8 +19,8 @@ export class TargetDatabaseSummaryDialog {
this._tableLength = 800;
dialogWidth = 900;
} else {
this._tableLength = 200;
dialogWidth = 'narrow';
this._tableLength = 700;
dialogWidth = 'medium';
}
this._dialogObject = azdata.window.createModelViewDialog(
constants.DATABASE_TO_BE_MIGRATED,
@@ -119,6 +119,15 @@ export class TargetDatabaseSummaryDialog {
headerCssStyles: headerCssStyle,
hidden: this._model._databaseBackup.migrationMode === MigrationMode.ONLINE
});
} else {
columns.push({
valueType: azdata.DeclarativeDataType.string,
displayName: constants.NETWORK_SHARE_PATH,
isReadOnly: true,
width: columnWidth,
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyle
});
}
const tableRows: azdata.DeclarativeTableCellValue[][] = [];
@@ -146,6 +155,10 @@ export class TargetDatabaseSummaryDialog {
value: this._model._databaseBackup.blobs[index].lastBackupFile!
});
}
} else {
tableRow.push({
value: this._model._databaseBackup.networkShares[index].networkShareLocation
});
}
tableRows.push(tableRow);
});

View File

@@ -77,7 +77,7 @@ export enum WizardEntryPoint {
export interface DatabaseBackupModel {
migrationMode: MigrationMode;
networkContainerType: NetworkContainerType;
networkShare: NetworkShare;
networkShares: NetworkShare[];
subscription: azureResource.AzureResourceSubscription;
blobs: Blob[];
}
@@ -129,7 +129,7 @@ export interface SavedInfo {
migrationMode: MigrationMode | null;
databaseAssessment: string[] | null;
networkContainerType: NetworkContainerType | null;
networkShare: NetworkShare | null;
networkShares: NetworkShare[];
targetSubscription: azureResource.AzureResourceSubscription | null;
blobs: Blob[];
targetDatabaseNames: string[];
@@ -165,7 +165,6 @@ export class MigrationStateModel implements Model, vscode.Disposable {
public _fileShares!: azureResource.FileShare[];
public _blobContainers!: azureResource.BlobContainer[];
public _lastFileNames!: azureResource.Blob[];
public _refreshNetworkShareLocation!: azureResource.BlobContainer[];
public _targetDatabaseNames!: string[];
public _sqlMigrationServiceResourceGroup!: string;
@@ -211,7 +210,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
) {
this._currentState = State.INIT;
this._databaseBackup = {} as DatabaseBackupModel;
this._databaseBackup.networkShare = {} as NetworkShare;
this._databaseBackup.networkShares = [];
this._databaseBackup.blobs = [];
this.mementoString = 'sqlMigration.assessmentResults';
}
@@ -968,14 +967,14 @@ export class MigrationStateModel implements Model, vscode.Disposable {
case NetworkContainerType.NETWORK_SHARE:
requestBody.properties.backupConfiguration = {
targetLocation: {
storageAccountResourceId: this._databaseBackup.networkShare.storageAccount.id,
accountKey: this._databaseBackup.networkShare.storageKey,
storageAccountResourceId: this._databaseBackup.networkShares[i].storageAccount.id,
accountKey: this._databaseBackup.networkShares[i].storageKey,
},
sourceLocation: {
fileShare: {
path: this._databaseBackup.networkShare.networkShareLocation,
username: this._databaseBackup.networkShare.windowsUser,
password: this._databaseBackup.networkShare.password,
path: this._databaseBackup.networkShares[i].networkShareLocation,
username: this._databaseBackup.networkShares[i].windowsUser,
password: this._databaseBackup.networkShares[i].password,
}
}
};
@@ -1043,8 +1042,6 @@ export class MigrationStateModel implements Model, vscode.Disposable {
localize('sql.migration.starting.migration.error', "An error occurred while starting the migration: '{0}'", e.message));
console.log(e);
}
await vscode.commands.executeCommand('sqlmigration.refreshMigrationTiles');
}
}
@@ -1066,7 +1063,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
migrationMode: null,
databaseAssessment: null,
networkContainerType: null,
networkShare: null,
networkShares: [],
targetSubscription: null,
blobs: [],
targetDatabaseNames: [],
@@ -1080,7 +1077,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
case Page.DatabaseBackup:
saveInfo.networkContainerType = this._databaseBackup.networkContainerType;
saveInfo.networkShare = this._databaseBackup.networkShare;
saveInfo.networkShares = this._databaseBackup.networkShares;
saveInfo.targetSubscription = this._databaseBackup.subscription;
saveInfo.blobs = this._databaseBackup.blobs;
saveInfo.targetDatabaseNames = this._targetDatabaseNames;

View File

@@ -33,7 +33,6 @@ export class DatabaseBackupPage extends MigrationWizardPage {
private _networkShareContainer!: azdata.FlexContainer;
private _windowsUserAccountText!: azdata.InputBoxComponent;
private _passwordText!: azdata.InputBoxComponent;
private _networkSharePath!: azdata.InputBoxComponent;
private _sourceHelpText!: azdata.TextComponent;
private _sqlSourceUsernameInput!: azdata.InputBoxComponent;
private _sqlSourcePassword!: azdata.InputBoxComponent;
@@ -60,6 +59,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
private _blobTableContainer!: azdata.FlexContainer;
private _networkShareTargetDatabaseNames: azdata.InputBoxComponent[] = [];
private _blobContainerTargetDatabaseNames: azdata.InputBoxComponent[] = [];
private _networkShareLocations: azdata.InputBoxComponent[] = [];
private _existingDatabases: string[] = [];
private _disposables: vscode.Disposable[] = [];
@@ -257,40 +257,6 @@ export class DatabaseBackupPage extends MigrationWizardPage {
}
}).component();
const networkLocationInputBoxLabel = this._view.modelBuilder.text().withProps({
value: constants.DATABASE_BACKUP_NETWORK_SHARE_LOCATION_LABEL,
description: constants.DATABASE_BACKUP_NETWORK_SHARE_LOCATION_INFO,
width: WIZARD_INPUT_COMPONENT_WIDTH,
requiredIndicator: true,
CSSStyles: {
...styles.LABEL_CSS
}
}).component();
this._networkSharePath = this._view.modelBuilder.inputBox().withProps({
placeHolder: constants.NETWORK_SHARE_PATH,
validationErrorMessage: constants.INVALID_NETWORK_SHARE_LOCATION,
width: WIZARD_INPUT_COMPONENT_WIDTH,
CSSStyles: {
'margin-top': '-1em'
}
}).withValidation((component) => {
if (this.migrationStateModel._databaseBackup.networkContainerType === NetworkContainerType.NETWORK_SHARE) {
if (component.value) {
if (!/^[\\\/]{2,}[^\\\/]+[\\\/]+[^\\\/]+/.test(component.value)) {
return false;
}
}
}
return true;
}).component();
if (this.migrationStateModel.retryMigration || (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.DatabaseBackup)) {
this._networkSharePath.value = this.migrationStateModel.savedInfo.networkShare?.networkShareLocation;
}
this._disposables.push(this._networkSharePath.onTextChanged(async (value) => {
await this.validateFields();
this.migrationStateModel._databaseBackup.networkShare.networkShareLocation = value;
}));
const networkShareInfoBox = this._view.modelBuilder.infoBox().withProps({
text: constants.DATABASE_SERVICE_ACCOUNT_INFO_TEXT,
style: 'information',
@@ -332,10 +298,12 @@ export class DatabaseBackupPage extends MigrationWizardPage {
return true;
}).component();
if (this.migrationStateModel.retryMigration || (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.DatabaseBackup)) {
this._windowsUserAccountText.value = this.migrationStateModel.savedInfo.networkShare?.windowsUser;
this._windowsUserAccountText.value = this.migrationStateModel.savedInfo.networkShares[0].windowsUser;
}
this._disposables.push(this._windowsUserAccountText.onTextChanged((value) => {
this.migrationStateModel._databaseBackup.networkShare.windowsUser = value;
for (let i = 0; i < this.migrationStateModel._databaseBackup.networkShares.length; i++) {
this.migrationStateModel._databaseBackup.networkShares[i].windowsUser = value;
}
}));
const passwordLabel = this._view.modelBuilder.text()
@@ -359,7 +327,9 @@ export class DatabaseBackupPage extends MigrationWizardPage {
}
}).component();
this._disposables.push(this._passwordText.onTextChanged((value) => {
this.migrationStateModel._databaseBackup.networkShare.password = value;
for (let i = 0; i < this.migrationStateModel._databaseBackup.networkShares.length; i++) {
this.migrationStateModel._databaseBackup.networkShares[i].password = value;
}
}));
const flexContainer = this._view.modelBuilder.flexContainer().withItems(
@@ -372,8 +342,6 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._sqlSourcePassword,
networkShareHeading,
networkShareHelpText,
networkLocationInputBoxLabel,
this._networkSharePath,
networkShareInfoBox,
windowsUserAccountLabel,
this._windowsUserAccountText,
@@ -506,6 +474,14 @@ export class DatabaseBackupPage extends MigrationWizardPage {
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles,
isReadOnly: true,
width: WIZARD_TABLE_COLUMN_WIDTH
},
{
displayName: constants.NETWORK_SHARE_PATH,
valueType: azdata.DeclarativeDataType.component,
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles,
isReadOnly: true,
width: '300px'
}
]
@@ -675,7 +651,9 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._disposables.push(this._networkShareStorageAccountResourceGroupDropdown.onValueChanged(async (value) => {
const selectedIndex = findDropDownItemIndex(this._networkShareStorageAccountResourceGroupDropdown, value);
if (selectedIndex > -1) {
this.migrationStateModel._databaseBackup.networkShare.resourceGroup = this.migrationStateModel.getAzureResourceGroup(selectedIndex);
for (let i = 0; i < this.migrationStateModel._databaseBackup.networkShares.length; i++) {
this.migrationStateModel._databaseBackup.networkShares[i].resourceGroup = this.migrationStateModel.getAzureResourceGroup(selectedIndex);
}
await this.loadNetworkShareStorageDropdown();
}
}));
@@ -700,7 +678,9 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._disposables.push(this._networkShareContainerStorageAccountDropdown.onValueChanged((value) => {
const selectedIndex = findDropDownItemIndex(this._networkShareContainerStorageAccountDropdown, value);
if (selectedIndex > -1) {
this.migrationStateModel._databaseBackup.networkShare.storageAccount = this.migrationStateModel.getStorageAccount(selectedIndex);
for (let i = 0; i < this.migrationStateModel._databaseBackup.networkShares.length; i++) {
this.migrationStateModel._databaseBackup.networkShares[i].storageAccount = this.migrationStateModel.getStorageAccount(selectedIndex);
}
}
}));
@@ -757,7 +737,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
public async onPageEnter(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise<void> {
if (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.DatabaseBackup) {
this.migrationStateModel._databaseBackup.networkContainerType = <NetworkContainerType>this.migrationStateModel.savedInfo.networkContainerType;
this.migrationStateModel._databaseBackup.networkShare = <NetworkShare>this.migrationStateModel.savedInfo.networkShare;
this.migrationStateModel._databaseBackup.networkShares = this.migrationStateModel.savedInfo.networkShares;
this.migrationStateModel._databaseBackup.subscription = <Subscription>this.migrationStateModel.savedInfo.targetSubscription;
this.migrationStateModel._databaseBackup.blobs = this.migrationStateModel.savedInfo.blobs;
this.migrationStateModel._targetDatabaseNames = this.migrationStateModel.savedInfo.targetDatabaseNames;
@@ -809,6 +789,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._sqlSourcePassword.value = (await azdata.connection.getCredentials(this.migrationStateModel.sourceConnectionId)).password;
this._networkShareTargetDatabaseNames = [];
this._networkShareLocations = [];
this._blobContainerTargetDatabaseNames = [];
this._blobContainerResourceGroupDropdowns = [];
this._blobContainerStorageAccountDropdowns = [];
@@ -820,9 +801,11 @@ export class DatabaseBackupPage extends MigrationWizardPage {
}
this.migrationStateModel._targetDatabaseNames = [];
this.migrationStateModel._databaseBackup.blobs = [];
this.migrationStateModel._databaseBackup.networkShares = [];
this.migrationStateModel._migrationDbs.forEach((db, index) => {
this.migrationStateModel._targetDatabaseNames.push(db);
this.migrationStateModel._databaseBackup.blobs.push(<Blob>{});
this.migrationStateModel._databaseBackup.networkShares.push(<NetworkShare>{});
const targetDatabaseInput = this._view.modelBuilder.inputBox().withProps({
required: true,
value: db,
@@ -853,6 +836,32 @@ export class DatabaseBackupPage extends MigrationWizardPage {
}
this._networkShareTargetDatabaseNames.push(targetDatabaseInput);
const networkShareLocationInput = this._view.modelBuilder.inputBox().withProps({
required: true,
placeHolder: constants.NETWORK_SHARE_PATH_FORMAT,
validationErrorMessage: constants.INVALID_NETWORK_SHARE_LOCATION,
width: '300px'
}).withValidation(c => {
if (this.migrationStateModel._databaseBackup.networkContainerType === NetworkContainerType.NETWORK_SHARE) {
if (c.value) {
if (!/^[\\\/]{2,}[^\\\/]+[\\\/]+[^\\\/]+/.test(c.value)) {
return false;
}
}
}
return true;
}).component();
this._disposables.push(networkShareLocationInput.onTextChanged(async (value) => {
this.migrationStateModel._databaseBackup.networkShares[index].networkShareLocation = value.trim();
await this.validateFields();
}));
if (this.migrationStateModel.retryMigration || (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.DatabaseBackup)) {
networkShareLocationInput.value = this.migrationStateModel.savedInfo.networkShares[index].networkShareLocation;
} else {
networkShareLocationInput.value = this.migrationStateModel._databaseBackup.networkShares[index]?.networkShareLocation;
}
this._networkShareLocations.push(networkShareLocationInput);
const blobTargetDatabaseInput = this._view.modelBuilder.inputBox().withProps({
required: true,
value: db,
@@ -971,6 +980,9 @@ export class DatabaseBackupPage extends MigrationWizardPage {
targetRow.push({
value: this._networkShareTargetDatabaseNames[index]
});
targetRow.push({
value: this._networkShareLocations[index]
});
data.push(targetRow);
});
await this._networkShareTargetDatabaseNamesTable.setDataValues(data);
@@ -1109,11 +1121,15 @@ export class DatabaseBackupPage extends MigrationWizardPage {
}
break;
case NetworkContainerType.NETWORK_SHARE:
const storageAccount = this.migrationStateModel._databaseBackup.networkShare.storageAccount;
this.migrationStateModel._databaseBackup.networkShare.storageKey = (await getStorageAccountAccessKeys(
// All network share migrations use the same storage account
const storageAccount = this.migrationStateModel._databaseBackup.networkShares[0].storageAccount;
const storageKey = (await getStorageAccountAccessKeys(
this.migrationStateModel._azureAccount,
this.migrationStateModel._databaseBackup.subscription,
storageAccount)).keyName1;
for (let i = 0; i < this.migrationStateModel._databaseBackup.networkShares.length; i++) {
this.migrationStateModel._databaseBackup.networkShares[i].storageKey = storageKey;
}
break;
}
}
@@ -1165,7 +1181,6 @@ export class DatabaseBackupPage extends MigrationWizardPage {
private async validateFields(): Promise<void> {
await this._sqlSourceUsernameInput.validate();
await this._sqlSourcePassword.validate();
await this._networkSharePath.validate();
await this._windowsUserAccountText.validate();
await this._passwordText.validate();
await this._networkShareContainerSubscription.validate();
@@ -1174,6 +1189,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
await this._blobContainerSubscription.validate();
for (let i = 0; i < this._networkShareTargetDatabaseNames.length; i++) {
await this._networkShareTargetDatabaseNames[i].validate();
await this._networkShareLocations[i].validate();
await this._blobContainerTargetDatabaseNames[i].validate();
await this._blobContainerResourceGroupDropdowns[i].validate();
await this._blobContainerStorageAccountDropdowns[i].validate();
@@ -1209,7 +1225,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._networkShareStorageAccountResourceGroupDropdown.values = await this.migrationStateModel.getAzureResourceGroupDropdownValues(this.migrationStateModel._databaseBackup.subscription);
if (this.hasSavedInfo(NetworkContainerType.NETWORK_SHARE, this._networkShareStorageAccountResourceGroupDropdown.values)) {
this._networkShareStorageAccountResourceGroupDropdown.values.forEach((resource, index) => {
if ((<azdata.CategoryValue>resource).name.toLowerCase() === this.migrationStateModel.savedInfo?.networkShare?.resourceGroup?.id?.toLowerCase()) {
if ((<azdata.CategoryValue>resource).name.toLowerCase() === this.migrationStateModel.savedInfo?.networkShares[0].resourceGroup?.id?.toLowerCase()) {
selectDropDownIndex(this._networkShareStorageAccountResourceGroupDropdown, index);
}
});
@@ -1227,7 +1243,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
private async loadNetworkShareStorageDropdown(): Promise<void> {
this._networkShareContainerStorageAccountDropdown.loading = true;
try {
this._networkShareContainerStorageAccountDropdown.values = await this.migrationStateModel.getStorageAccountValues(this.migrationStateModel._databaseBackup.subscription, this.migrationStateModel._databaseBackup.networkShare.resourceGroup);
this._networkShareContainerStorageAccountDropdown.values = await this.migrationStateModel.getStorageAccountValues(this.migrationStateModel._databaseBackup.subscription, this.migrationStateModel._databaseBackup.networkShares[0].resourceGroup);
selectDropDownIndex(this._networkShareContainerStorageAccountDropdown, 0);
} catch (error) {
console.log(error);

View File

@@ -6,7 +6,7 @@
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { MigrationWizardPage } from '../models/migrationWizardPage';
import { MigrationMode, MigrationStateModel, MigrationTargetType, NetworkContainerType, NetworkShare, Page, StateChangeEvent } from '../models/stateMachine';
import { MigrationMode, MigrationStateModel, MigrationTargetType, NetworkContainerType, Page, StateChangeEvent } from '../models/stateMachine';
import * as constants from '../constants/strings';
import { createHeadingTextComponent, createInformationRow, createLabelTextComponent } from './wizardController';
import { getResourceGroupFromId, Subscription } from '../api/azure';
@@ -49,7 +49,7 @@ export class SummaryPage extends MigrationWizardPage {
public async onPageEnter(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise<void> {
if (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.Summary) {
this.migrationStateModel._databaseBackup.networkContainerType = <NetworkContainerType>this.migrationStateModel.savedInfo.networkContainerType;
this.migrationStateModel._databaseBackup.networkShare = <NetworkShare>this.migrationStateModel.savedInfo.networkShare;
this.migrationStateModel._databaseBackup.networkShares = this.migrationStateModel.savedInfo.networkShares;
this.migrationStateModel._databaseBackup.subscription = <Subscription>this.migrationStateModel.savedInfo.targetSubscription;
this.migrationStateModel._databaseBackup.blobs = this.migrationStateModel.savedInfo.blobs;
this.migrationStateModel._targetDatabaseNames = this.migrationStateModel.savedInfo.targetDatabaseNames;
@@ -158,13 +158,12 @@ export class SummaryPage extends MigrationWizardPage {
flexContainer.addItems(
[
createInformationRow(this._view, constants.BACKUP_LOCATION, constants.NETWORK_SHARE),
createInformationRow(this._view, constants.NETWORK_SHARE, this.migrationStateModel._databaseBackup.networkShare.networkShareLocation),
createInformationRow(this._view, constants.USER_ACCOUNT, this.migrationStateModel._databaseBackup.networkShare.windowsUser),
createInformationRow(this._view, constants.USER_ACCOUNT, this.migrationStateModel._databaseBackup.networkShares[0].windowsUser),
await createHeadingTextComponent(this._view, constants.AZURE_STORAGE_ACCOUNT_TO_UPLOAD_BACKUPS),
createInformationRow(this._view, constants.SUBSCRIPTION, this.migrationStateModel._databaseBackup.subscription.name),
createInformationRow(this._view, constants.LOCATION, this.migrationStateModel._databaseBackup.networkShare.storageAccount.location),
createInformationRow(this._view, constants.RESOURCE_GROUP, this.migrationStateModel._databaseBackup.networkShare.storageAccount.resourceGroup!),
createInformationRow(this._view, constants.STORAGE_ACCOUNT, this.migrationStateModel._databaseBackup.networkShare.storageAccount.name!),
createInformationRow(this._view, constants.LOCATION, this.migrationStateModel._databaseBackup.networkShares[0].storageAccount?.location),
createInformationRow(this._view, constants.RESOURCE_GROUP, this.migrationStateModel._databaseBackup.networkShares[0].storageAccount?.resourceGroup!),
createInformationRow(this._view, constants.STORAGE_ACCOUNT, this.migrationStateModel._databaseBackup.networkShares[0].storageAccount?.name!),
]
);
break;