Junierch/mi tde (#21573)

* WIP

* wip tde wizard

* wip for merge w master

* wip

* wip share

* tde wizard

* PR reviews updates

* PR review updates

* PR updates

* PR review updates

* PR reviews updates

* Bump STS to 4.4.0.22

* PR reviews updates

* fix localize build issue

* fix build issue with localize

* remove unused function

* Windows only flag. Bug Bash fixes

* Use azdata with latest STS changes

* revert azdata, other PR comments

* sts and extesion version upgraded. logins back
This commit is contained in:
junierch
2023-01-25 09:58:07 -05:00
committed by GitHub
parent 0e0fade5d8
commit 5157508dd5
16 changed files with 1406 additions and 11 deletions

View File

@@ -16,6 +16,7 @@ import { hashString, deepClone } from '../api/utils';
import { SKURecommendationPage } from '../wizard/skuRecommendationPage';
import { excludeDatabases, getConnectionProfile, LoginTableInfo, SourceDatabaseInfo, TargetDatabaseInfo } from '../api/sqlUtils';
import { LoginMigrationModel, LoginMigrationStep } from './loginMigrationModel';
import { TdeMigrationDbResult, TdeMigrationModel } from './tdeModels';
const localize = nls.loadMessageBundle();
export enum ValidateIrState {
@@ -65,6 +66,10 @@ export enum MigrationSourceAuthenticationType {
Sql = 'SqlAuthentication'
}
export enum AssessmentRuleId {
TdeEnabled = 'TdeEnabled'
}
export enum MigrationMode {
ONLINE,
OFFLINE
@@ -173,6 +178,7 @@ export interface SkuRecommendationSavedInfo {
}
export class MigrationStateModel implements Model, vscode.Disposable {
public _azureAccounts!: azdata.Account[];
public _azureAccount!: azdata.Account;
public _accountTenants!: azurecore.Tenant[];
@@ -276,6 +282,8 @@ export class MigrationStateModel implements Model, vscode.Disposable {
public _sessionId: string = uuidv4();
public serverName!: string;
public tdeMigrationConfig: TdeMigrationModel = new TdeMigrationModel();
private _stateChangeEventEmitter = new vscode.EventEmitter<StateChangeEvent>();
private _currentState: State;
private _gatheringInformationError: string | undefined;
@@ -289,7 +297,8 @@ export class MigrationStateModel implements Model, vscode.Disposable {
constructor(
public extensionContext: vscode.ExtensionContext,
private readonly _sourceConnectionId: string,
public readonly migrationService: mssql.ISqlMigrationService
public readonly migrationService: mssql.ISqlMigrationService,
public readonly tdeMigrationService: mssql.ITdeMigrationService
) {
this._currentState = State.INIT;
this._databaseBackup = {} as DatabaseBackupModel;
@@ -300,6 +309,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
this._assessmentReportFilePath = '';
this._skuRecommendationReportFilePaths = [];
this.mementoString = 'sqlMigration.assessmentResults';
this._targetManagedInstances = [];
this._skuScalingFactor = 100;
this._skuTargetPercentile = 95;
@@ -1074,6 +1084,55 @@ export class MigrationStateModel implements Model, vscode.Disposable {
).map(t => t.name);
}
public async startTdeMigration(
accessToken: string,
reportUpdate: (dbName: string, succeeded: boolean, message: string) => Promise<void>): Promise<OperationResult<TdeMigrationDbResult[]>> {
const tdeEnabledDatabases = this.tdeMigrationConfig.getTdeEnabledDatabases();
const connectionString = await azdata.connection.getConnectionString(this.sourceConnectionId, true);
const opResult: OperationResult<TdeMigrationDbResult[]> = {
success: false,
result: [],
errors: []
};
try {
const migrationResult = await this.tdeMigrationService.migrateCertificate(
tdeEnabledDatabases,
connectionString,
this._targetSubscription?.id,
this._resourceGroup?.name,
this._targetServerInstance.name,
this.tdeMigrationConfig._networkPath,
accessToken,
reportUpdate);
opResult.errors = migrationResult.migrationStatuses
.filter(entry => !entry.success)
.map(entry => constants.TDE_MIGRATION_ERROR_DB(entry.dbName, entry.message));
opResult.result = migrationResult.migrationStatuses.map(m => ({
name: m.dbName,
success: m.success,
message: m.message
}));
} catch (e) {
opResult.errors = [constants.TDE_MIGRATION_ERROR(e.message)];
opResult.result = tdeEnabledDatabases.map(m => ({
name: m,
success: false,
message: e.message
}));
}
opResult.success = opResult.errors.length === 0; //Set success when there are no errors.
return opResult;
}
public async startMigration() {
const sqlConnections = await azdata.connection.getConnections();
const currentConnection = sqlConnections.find(
@@ -1329,7 +1388,6 @@ export class MigrationStateModel implements Model, vscode.Disposable {
await this.extensionContext.globalState.update(`${this.mementoString}.${serverName}`, saveInfo);
}
}
public async loadSavedInfo(): Promise<Boolean> {
try {
this._targetType = this.savedInfo.migrationTargetType || undefined!;
@@ -1391,6 +1449,8 @@ export class MigrationStateModel implements Model, vscode.Disposable {
} catch {
return false;
}
}
public GetTargetType(): string {
@@ -1425,3 +1485,9 @@ export interface SkuRecommendation {
recommendations?: mssql.SkuRecommendationResult;
recommendationError?: Error;
}
export interface OperationResult<T> {
success: boolean;
result: T;
errors: string[];
}