mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
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:
@@ -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_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_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_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_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_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");
|
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_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_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 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 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_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.");
|
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 {
|
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);
|
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_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 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: ");
|
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_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 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 = 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 = 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_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");
|
export const BLOB_CONTAINER_RESOURCE_GROUP = localize('sql.migration.blob.container.label', "Blob container resource group");
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export class RetryMigrationDialog {
|
|||||||
targetSubscription: migration.subscription,
|
targetSubscription: migration.subscription,
|
||||||
targetDatabaseNames: [migration.migrationContext.name],
|
targetDatabaseNames: [migration.migrationContext.name],
|
||||||
networkContainerType: null,
|
networkContainerType: null,
|
||||||
networkShare: null,
|
networkShares: [],
|
||||||
blobs: [],
|
blobs: [],
|
||||||
|
|
||||||
// Integration Runtime
|
// Integration Runtime
|
||||||
@@ -90,14 +90,16 @@ export class RetryMigrationDialog {
|
|||||||
if (sourceLocation?.fileShare) {
|
if (sourceLocation?.fileShare) {
|
||||||
savedInfo.networkContainerType = NetworkContainerType.NETWORK_SHARE;
|
savedInfo.networkContainerType = NetworkContainerType.NETWORK_SHARE;
|
||||||
const storageAccountResourceId = migration.migrationContext.properties.backupConfiguration.targetLocation?.storageAccountResourceId!;
|
const storageAccountResourceId = migration.migrationContext.properties.backupConfiguration.targetLocation?.storageAccountResourceId!;
|
||||||
savedInfo.networkShare = {
|
savedInfo.networkShares = [
|
||||||
|
{
|
||||||
password: '',
|
password: '',
|
||||||
networkShareLocation: sourceLocation?.fileShare?.path!,
|
networkShareLocation: sourceLocation?.fileShare?.path!,
|
||||||
windowsUser: sourceLocation?.fileShare?.username!,
|
windowsUser: sourceLocation?.fileShare?.username!,
|
||||||
storageAccount: getStorageAccount(storageAccountResourceId!),
|
storageAccount: getStorageAccount(storageAccountResourceId!),
|
||||||
resourceGroup: getStorageAccountResourceGroup(storageAccountResourceId!),
|
resourceGroup: getStorageAccountResourceGroup(storageAccountResourceId!),
|
||||||
storageKey: ''
|
storageKey: ''
|
||||||
};
|
}
|
||||||
|
];
|
||||||
} else if (sourceLocation?.azureBlob) {
|
} else if (sourceLocation?.azureBlob) {
|
||||||
savedInfo.networkContainerType = NetworkContainerType.BLOB_CONTAINER;
|
savedInfo.networkContainerType = NetworkContainerType.BLOB_CONTAINER;
|
||||||
const storageAccountResourceId = sourceLocation?.azureBlob?.storageAccountResourceId!;
|
const storageAccountResourceId = sourceLocation?.azureBlob?.storageAccountResourceId!;
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ export class TargetDatabaseSummaryDialog {
|
|||||||
this._tableLength = 800;
|
this._tableLength = 800;
|
||||||
dialogWidth = 900;
|
dialogWidth = 900;
|
||||||
} else {
|
} else {
|
||||||
this._tableLength = 200;
|
this._tableLength = 700;
|
||||||
dialogWidth = 'narrow';
|
dialogWidth = 'medium';
|
||||||
}
|
}
|
||||||
this._dialogObject = azdata.window.createModelViewDialog(
|
this._dialogObject = azdata.window.createModelViewDialog(
|
||||||
constants.DATABASE_TO_BE_MIGRATED,
|
constants.DATABASE_TO_BE_MIGRATED,
|
||||||
@@ -119,6 +119,15 @@ export class TargetDatabaseSummaryDialog {
|
|||||||
headerCssStyles: headerCssStyle,
|
headerCssStyles: headerCssStyle,
|
||||||
hidden: this._model._databaseBackup.migrationMode === MigrationMode.ONLINE
|
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[][] = [];
|
const tableRows: azdata.DeclarativeTableCellValue[][] = [];
|
||||||
@@ -146,6 +155,10 @@ export class TargetDatabaseSummaryDialog {
|
|||||||
value: this._model._databaseBackup.blobs[index].lastBackupFile!
|
value: this._model._databaseBackup.blobs[index].lastBackupFile!
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
tableRow.push({
|
||||||
|
value: this._model._databaseBackup.networkShares[index].networkShareLocation
|
||||||
|
});
|
||||||
}
|
}
|
||||||
tableRows.push(tableRow);
|
tableRows.push(tableRow);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export enum WizardEntryPoint {
|
|||||||
export interface DatabaseBackupModel {
|
export interface DatabaseBackupModel {
|
||||||
migrationMode: MigrationMode;
|
migrationMode: MigrationMode;
|
||||||
networkContainerType: NetworkContainerType;
|
networkContainerType: NetworkContainerType;
|
||||||
networkShare: NetworkShare;
|
networkShares: NetworkShare[];
|
||||||
subscription: azureResource.AzureResourceSubscription;
|
subscription: azureResource.AzureResourceSubscription;
|
||||||
blobs: Blob[];
|
blobs: Blob[];
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ export interface SavedInfo {
|
|||||||
migrationMode: MigrationMode | null;
|
migrationMode: MigrationMode | null;
|
||||||
databaseAssessment: string[] | null;
|
databaseAssessment: string[] | null;
|
||||||
networkContainerType: NetworkContainerType | null;
|
networkContainerType: NetworkContainerType | null;
|
||||||
networkShare: NetworkShare | null;
|
networkShares: NetworkShare[];
|
||||||
targetSubscription: azureResource.AzureResourceSubscription | null;
|
targetSubscription: azureResource.AzureResourceSubscription | null;
|
||||||
blobs: Blob[];
|
blobs: Blob[];
|
||||||
targetDatabaseNames: string[];
|
targetDatabaseNames: string[];
|
||||||
@@ -165,7 +165,6 @@ export class MigrationStateModel implements Model, vscode.Disposable {
|
|||||||
public _fileShares!: azureResource.FileShare[];
|
public _fileShares!: azureResource.FileShare[];
|
||||||
public _blobContainers!: azureResource.BlobContainer[];
|
public _blobContainers!: azureResource.BlobContainer[];
|
||||||
public _lastFileNames!: azureResource.Blob[];
|
public _lastFileNames!: azureResource.Blob[];
|
||||||
public _refreshNetworkShareLocation!: azureResource.BlobContainer[];
|
|
||||||
public _targetDatabaseNames!: string[];
|
public _targetDatabaseNames!: string[];
|
||||||
|
|
||||||
public _sqlMigrationServiceResourceGroup!: string;
|
public _sqlMigrationServiceResourceGroup!: string;
|
||||||
@@ -211,7 +210,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
|
|||||||
) {
|
) {
|
||||||
this._currentState = State.INIT;
|
this._currentState = State.INIT;
|
||||||
this._databaseBackup = {} as DatabaseBackupModel;
|
this._databaseBackup = {} as DatabaseBackupModel;
|
||||||
this._databaseBackup.networkShare = {} as NetworkShare;
|
this._databaseBackup.networkShares = [];
|
||||||
this._databaseBackup.blobs = [];
|
this._databaseBackup.blobs = [];
|
||||||
this.mementoString = 'sqlMigration.assessmentResults';
|
this.mementoString = 'sqlMigration.assessmentResults';
|
||||||
}
|
}
|
||||||
@@ -968,14 +967,14 @@ export class MigrationStateModel implements Model, vscode.Disposable {
|
|||||||
case NetworkContainerType.NETWORK_SHARE:
|
case NetworkContainerType.NETWORK_SHARE:
|
||||||
requestBody.properties.backupConfiguration = {
|
requestBody.properties.backupConfiguration = {
|
||||||
targetLocation: {
|
targetLocation: {
|
||||||
storageAccountResourceId: this._databaseBackup.networkShare.storageAccount.id,
|
storageAccountResourceId: this._databaseBackup.networkShares[i].storageAccount.id,
|
||||||
accountKey: this._databaseBackup.networkShare.storageKey,
|
accountKey: this._databaseBackup.networkShares[i].storageKey,
|
||||||
},
|
},
|
||||||
sourceLocation: {
|
sourceLocation: {
|
||||||
fileShare: {
|
fileShare: {
|
||||||
path: this._databaseBackup.networkShare.networkShareLocation,
|
path: this._databaseBackup.networkShares[i].networkShareLocation,
|
||||||
username: this._databaseBackup.networkShare.windowsUser,
|
username: this._databaseBackup.networkShares[i].windowsUser,
|
||||||
password: this._databaseBackup.networkShare.password,
|
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));
|
localize('sql.migration.starting.migration.error', "An error occurred while starting the migration: '{0}'", e.message));
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
await vscode.commands.executeCommand('sqlmigration.refreshMigrationTiles');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1066,7 +1063,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
|
|||||||
migrationMode: null,
|
migrationMode: null,
|
||||||
databaseAssessment: null,
|
databaseAssessment: null,
|
||||||
networkContainerType: null,
|
networkContainerType: null,
|
||||||
networkShare: null,
|
networkShares: [],
|
||||||
targetSubscription: null,
|
targetSubscription: null,
|
||||||
blobs: [],
|
blobs: [],
|
||||||
targetDatabaseNames: [],
|
targetDatabaseNames: [],
|
||||||
@@ -1080,7 +1077,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
|
|||||||
|
|
||||||
case Page.DatabaseBackup:
|
case Page.DatabaseBackup:
|
||||||
saveInfo.networkContainerType = this._databaseBackup.networkContainerType;
|
saveInfo.networkContainerType = this._databaseBackup.networkContainerType;
|
||||||
saveInfo.networkShare = this._databaseBackup.networkShare;
|
saveInfo.networkShares = this._databaseBackup.networkShares;
|
||||||
saveInfo.targetSubscription = this._databaseBackup.subscription;
|
saveInfo.targetSubscription = this._databaseBackup.subscription;
|
||||||
saveInfo.blobs = this._databaseBackup.blobs;
|
saveInfo.blobs = this._databaseBackup.blobs;
|
||||||
saveInfo.targetDatabaseNames = this._targetDatabaseNames;
|
saveInfo.targetDatabaseNames = this._targetDatabaseNames;
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
private _networkShareContainer!: azdata.FlexContainer;
|
private _networkShareContainer!: azdata.FlexContainer;
|
||||||
private _windowsUserAccountText!: azdata.InputBoxComponent;
|
private _windowsUserAccountText!: azdata.InputBoxComponent;
|
||||||
private _passwordText!: azdata.InputBoxComponent;
|
private _passwordText!: azdata.InputBoxComponent;
|
||||||
private _networkSharePath!: azdata.InputBoxComponent;
|
|
||||||
private _sourceHelpText!: azdata.TextComponent;
|
private _sourceHelpText!: azdata.TextComponent;
|
||||||
private _sqlSourceUsernameInput!: azdata.InputBoxComponent;
|
private _sqlSourceUsernameInput!: azdata.InputBoxComponent;
|
||||||
private _sqlSourcePassword!: azdata.InputBoxComponent;
|
private _sqlSourcePassword!: azdata.InputBoxComponent;
|
||||||
@@ -60,6 +59,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
private _blobTableContainer!: azdata.FlexContainer;
|
private _blobTableContainer!: azdata.FlexContainer;
|
||||||
private _networkShareTargetDatabaseNames: azdata.InputBoxComponent[] = [];
|
private _networkShareTargetDatabaseNames: azdata.InputBoxComponent[] = [];
|
||||||
private _blobContainerTargetDatabaseNames: azdata.InputBoxComponent[] = [];
|
private _blobContainerTargetDatabaseNames: azdata.InputBoxComponent[] = [];
|
||||||
|
private _networkShareLocations: azdata.InputBoxComponent[] = [];
|
||||||
|
|
||||||
private _existingDatabases: string[] = [];
|
private _existingDatabases: string[] = [];
|
||||||
private _disposables: vscode.Disposable[] = [];
|
private _disposables: vscode.Disposable[] = [];
|
||||||
@@ -257,40 +257,6 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
}
|
}
|
||||||
}).component();
|
}).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({
|
const networkShareInfoBox = this._view.modelBuilder.infoBox().withProps({
|
||||||
text: constants.DATABASE_SERVICE_ACCOUNT_INFO_TEXT,
|
text: constants.DATABASE_SERVICE_ACCOUNT_INFO_TEXT,
|
||||||
style: 'information',
|
style: 'information',
|
||||||
@@ -332,10 +298,12 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
return true;
|
return true;
|
||||||
}).component();
|
}).component();
|
||||||
if (this.migrationStateModel.retryMigration || (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.DatabaseBackup)) {
|
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._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()
|
const passwordLabel = this._view.modelBuilder.text()
|
||||||
@@ -359,7 +327,9 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
}
|
}
|
||||||
}).component();
|
}).component();
|
||||||
this._disposables.push(this._passwordText.onTextChanged((value) => {
|
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(
|
const flexContainer = this._view.modelBuilder.flexContainer().withItems(
|
||||||
@@ -372,8 +342,6 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
this._sqlSourcePassword,
|
this._sqlSourcePassword,
|
||||||
networkShareHeading,
|
networkShareHeading,
|
||||||
networkShareHelpText,
|
networkShareHelpText,
|
||||||
networkLocationInputBoxLabel,
|
|
||||||
this._networkSharePath,
|
|
||||||
networkShareInfoBox,
|
networkShareInfoBox,
|
||||||
windowsUserAccountLabel,
|
windowsUserAccountLabel,
|
||||||
this._windowsUserAccountText,
|
this._windowsUserAccountText,
|
||||||
@@ -506,6 +474,14 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
rowCssStyles: rowCssStyle,
|
rowCssStyles: rowCssStyle,
|
||||||
headerCssStyles: headerCssStyles,
|
headerCssStyles: headerCssStyles,
|
||||||
isReadOnly: true,
|
isReadOnly: true,
|
||||||
|
width: WIZARD_TABLE_COLUMN_WIDTH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: constants.NETWORK_SHARE_PATH,
|
||||||
|
valueType: azdata.DeclarativeDataType.component,
|
||||||
|
rowCssStyles: rowCssStyle,
|
||||||
|
headerCssStyles: headerCssStyles,
|
||||||
|
isReadOnly: true,
|
||||||
width: '300px'
|
width: '300px'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -675,7 +651,9 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
this._disposables.push(this._networkShareStorageAccountResourceGroupDropdown.onValueChanged(async (value) => {
|
this._disposables.push(this._networkShareStorageAccountResourceGroupDropdown.onValueChanged(async (value) => {
|
||||||
const selectedIndex = findDropDownItemIndex(this._networkShareStorageAccountResourceGroupDropdown, value);
|
const selectedIndex = findDropDownItemIndex(this._networkShareStorageAccountResourceGroupDropdown, value);
|
||||||
if (selectedIndex > -1) {
|
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();
|
await this.loadNetworkShareStorageDropdown();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -700,7 +678,9 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
this._disposables.push(this._networkShareContainerStorageAccountDropdown.onValueChanged((value) => {
|
this._disposables.push(this._networkShareContainerStorageAccountDropdown.onValueChanged((value) => {
|
||||||
const selectedIndex = findDropDownItemIndex(this._networkShareContainerStorageAccountDropdown, value);
|
const selectedIndex = findDropDownItemIndex(this._networkShareContainerStorageAccountDropdown, value);
|
||||||
if (selectedIndex > -1) {
|
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> {
|
public async onPageEnter(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise<void> {
|
||||||
if (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.DatabaseBackup) {
|
if (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.DatabaseBackup) {
|
||||||
this.migrationStateModel._databaseBackup.networkContainerType = <NetworkContainerType>this.migrationStateModel.savedInfo.networkContainerType;
|
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.subscription = <Subscription>this.migrationStateModel.savedInfo.targetSubscription;
|
||||||
this.migrationStateModel._databaseBackup.blobs = this.migrationStateModel.savedInfo.blobs;
|
this.migrationStateModel._databaseBackup.blobs = this.migrationStateModel.savedInfo.blobs;
|
||||||
this.migrationStateModel._targetDatabaseNames = this.migrationStateModel.savedInfo.targetDatabaseNames;
|
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._sqlSourcePassword.value = (await azdata.connection.getCredentials(this.migrationStateModel.sourceConnectionId)).password;
|
||||||
|
|
||||||
this._networkShareTargetDatabaseNames = [];
|
this._networkShareTargetDatabaseNames = [];
|
||||||
|
this._networkShareLocations = [];
|
||||||
this._blobContainerTargetDatabaseNames = [];
|
this._blobContainerTargetDatabaseNames = [];
|
||||||
this._blobContainerResourceGroupDropdowns = [];
|
this._blobContainerResourceGroupDropdowns = [];
|
||||||
this._blobContainerStorageAccountDropdowns = [];
|
this._blobContainerStorageAccountDropdowns = [];
|
||||||
@@ -820,9 +801,11 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
}
|
}
|
||||||
this.migrationStateModel._targetDatabaseNames = [];
|
this.migrationStateModel._targetDatabaseNames = [];
|
||||||
this.migrationStateModel._databaseBackup.blobs = [];
|
this.migrationStateModel._databaseBackup.blobs = [];
|
||||||
|
this.migrationStateModel._databaseBackup.networkShares = [];
|
||||||
this.migrationStateModel._migrationDbs.forEach((db, index) => {
|
this.migrationStateModel._migrationDbs.forEach((db, index) => {
|
||||||
this.migrationStateModel._targetDatabaseNames.push(db);
|
this.migrationStateModel._targetDatabaseNames.push(db);
|
||||||
this.migrationStateModel._databaseBackup.blobs.push(<Blob>{});
|
this.migrationStateModel._databaseBackup.blobs.push(<Blob>{});
|
||||||
|
this.migrationStateModel._databaseBackup.networkShares.push(<NetworkShare>{});
|
||||||
const targetDatabaseInput = this._view.modelBuilder.inputBox().withProps({
|
const targetDatabaseInput = this._view.modelBuilder.inputBox().withProps({
|
||||||
required: true,
|
required: true,
|
||||||
value: db,
|
value: db,
|
||||||
@@ -853,6 +836,32 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
}
|
}
|
||||||
this._networkShareTargetDatabaseNames.push(targetDatabaseInput);
|
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({
|
const blobTargetDatabaseInput = this._view.modelBuilder.inputBox().withProps({
|
||||||
required: true,
|
required: true,
|
||||||
value: db,
|
value: db,
|
||||||
@@ -971,6 +980,9 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
targetRow.push({
|
targetRow.push({
|
||||||
value: this._networkShareTargetDatabaseNames[index]
|
value: this._networkShareTargetDatabaseNames[index]
|
||||||
});
|
});
|
||||||
|
targetRow.push({
|
||||||
|
value: this._networkShareLocations[index]
|
||||||
|
});
|
||||||
data.push(targetRow);
|
data.push(targetRow);
|
||||||
});
|
});
|
||||||
await this._networkShareTargetDatabaseNamesTable.setDataValues(data);
|
await this._networkShareTargetDatabaseNamesTable.setDataValues(data);
|
||||||
@@ -1109,11 +1121,15 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NetworkContainerType.NETWORK_SHARE:
|
case NetworkContainerType.NETWORK_SHARE:
|
||||||
const storageAccount = this.migrationStateModel._databaseBackup.networkShare.storageAccount;
|
// All network share migrations use the same storage account
|
||||||
this.migrationStateModel._databaseBackup.networkShare.storageKey = (await getStorageAccountAccessKeys(
|
const storageAccount = this.migrationStateModel._databaseBackup.networkShares[0].storageAccount;
|
||||||
|
const storageKey = (await getStorageAccountAccessKeys(
|
||||||
this.migrationStateModel._azureAccount,
|
this.migrationStateModel._azureAccount,
|
||||||
this.migrationStateModel._databaseBackup.subscription,
|
this.migrationStateModel._databaseBackup.subscription,
|
||||||
storageAccount)).keyName1;
|
storageAccount)).keyName1;
|
||||||
|
for (let i = 0; i < this.migrationStateModel._databaseBackup.networkShares.length; i++) {
|
||||||
|
this.migrationStateModel._databaseBackup.networkShares[i].storageKey = storageKey;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1165,7 +1181,6 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
private async validateFields(): Promise<void> {
|
private async validateFields(): Promise<void> {
|
||||||
await this._sqlSourceUsernameInput.validate();
|
await this._sqlSourceUsernameInput.validate();
|
||||||
await this._sqlSourcePassword.validate();
|
await this._sqlSourcePassword.validate();
|
||||||
await this._networkSharePath.validate();
|
|
||||||
await this._windowsUserAccountText.validate();
|
await this._windowsUserAccountText.validate();
|
||||||
await this._passwordText.validate();
|
await this._passwordText.validate();
|
||||||
await this._networkShareContainerSubscription.validate();
|
await this._networkShareContainerSubscription.validate();
|
||||||
@@ -1174,6 +1189,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
await this._blobContainerSubscription.validate();
|
await this._blobContainerSubscription.validate();
|
||||||
for (let i = 0; i < this._networkShareTargetDatabaseNames.length; i++) {
|
for (let i = 0; i < this._networkShareTargetDatabaseNames.length; i++) {
|
||||||
await this._networkShareTargetDatabaseNames[i].validate();
|
await this._networkShareTargetDatabaseNames[i].validate();
|
||||||
|
await this._networkShareLocations[i].validate();
|
||||||
await this._blobContainerTargetDatabaseNames[i].validate();
|
await this._blobContainerTargetDatabaseNames[i].validate();
|
||||||
await this._blobContainerResourceGroupDropdowns[i].validate();
|
await this._blobContainerResourceGroupDropdowns[i].validate();
|
||||||
await this._blobContainerStorageAccountDropdowns[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);
|
this._networkShareStorageAccountResourceGroupDropdown.values = await this.migrationStateModel.getAzureResourceGroupDropdownValues(this.migrationStateModel._databaseBackup.subscription);
|
||||||
if (this.hasSavedInfo(NetworkContainerType.NETWORK_SHARE, this._networkShareStorageAccountResourceGroupDropdown.values)) {
|
if (this.hasSavedInfo(NetworkContainerType.NETWORK_SHARE, this._networkShareStorageAccountResourceGroupDropdown.values)) {
|
||||||
this._networkShareStorageAccountResourceGroupDropdown.values.forEach((resource, index) => {
|
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);
|
selectDropDownIndex(this._networkShareStorageAccountResourceGroupDropdown, index);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1227,7 +1243,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
|||||||
private async loadNetworkShareStorageDropdown(): Promise<void> {
|
private async loadNetworkShareStorageDropdown(): Promise<void> {
|
||||||
this._networkShareContainerStorageAccountDropdown.loading = true;
|
this._networkShareContainerStorageAccountDropdown.loading = true;
|
||||||
try {
|
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);
|
selectDropDownIndex(this._networkShareContainerStorageAccountDropdown, 0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { MigrationWizardPage } from '../models/migrationWizardPage';
|
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 * as constants from '../constants/strings';
|
||||||
import { createHeadingTextComponent, createInformationRow, createLabelTextComponent } from './wizardController';
|
import { createHeadingTextComponent, createInformationRow, createLabelTextComponent } from './wizardController';
|
||||||
import { getResourceGroupFromId, Subscription } from '../api/azure';
|
import { getResourceGroupFromId, Subscription } from '../api/azure';
|
||||||
@@ -49,7 +49,7 @@ export class SummaryPage extends MigrationWizardPage {
|
|||||||
public async onPageEnter(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise<void> {
|
public async onPageEnter(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise<void> {
|
||||||
if (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.Summary) {
|
if (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.Summary) {
|
||||||
this.migrationStateModel._databaseBackup.networkContainerType = <NetworkContainerType>this.migrationStateModel.savedInfo.networkContainerType;
|
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.subscription = <Subscription>this.migrationStateModel.savedInfo.targetSubscription;
|
||||||
this.migrationStateModel._databaseBackup.blobs = this.migrationStateModel.savedInfo.blobs;
|
this.migrationStateModel._databaseBackup.blobs = this.migrationStateModel.savedInfo.blobs;
|
||||||
this.migrationStateModel._targetDatabaseNames = this.migrationStateModel.savedInfo.targetDatabaseNames;
|
this.migrationStateModel._targetDatabaseNames = this.migrationStateModel.savedInfo.targetDatabaseNames;
|
||||||
@@ -158,13 +158,12 @@ export class SummaryPage extends MigrationWizardPage {
|
|||||||
flexContainer.addItems(
|
flexContainer.addItems(
|
||||||
[
|
[
|
||||||
createInformationRow(this._view, constants.BACKUP_LOCATION, constants.NETWORK_SHARE),
|
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.networkShares[0].windowsUser),
|
||||||
createInformationRow(this._view, constants.USER_ACCOUNT, this.migrationStateModel._databaseBackup.networkShare.windowsUser),
|
|
||||||
await createHeadingTextComponent(this._view, constants.AZURE_STORAGE_ACCOUNT_TO_UPLOAD_BACKUPS),
|
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.SUBSCRIPTION, this.migrationStateModel._databaseBackup.subscription.name),
|
||||||
createInformationRow(this._view, constants.LOCATION, this.migrationStateModel._databaseBackup.networkShare.storageAccount.location),
|
createInformationRow(this._view, constants.LOCATION, this.migrationStateModel._databaseBackup.networkShares[0].storageAccount?.location),
|
||||||
createInformationRow(this._view, constants.RESOURCE_GROUP, this.migrationStateModel._databaseBackup.networkShare.storageAccount.resourceGroup!),
|
createInformationRow(this._view, constants.RESOURCE_GROUP, this.migrationStateModel._databaseBackup.networkShares[0].storageAccount?.resourceGroup!),
|
||||||
createInformationRow(this._view, constants.STORAGE_ACCOUNT, this.migrationStateModel._databaseBackup.networkShare.storageAccount.name!),
|
createInformationRow(this._view, constants.STORAGE_ACCOUNT, this.migrationStateModel._databaseBackup.networkShares[0].storageAccount?.name!),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user