[SQL-Migration] Login Migration Improvements (#21694)

This PR adds various login migration improvements:

- Enabled windows login by prompting user for AAD domain name if a windows login is selected
image
- Adds new login details dialog which gives granular status on each step of the login migration for each login
image
- Checks if windows login migration is supported for selected target type, and only collections source windows logins accordingly
- Perf optimization by source and target login in background of step 1 in order to significantly speed up loading of page 2
This commit is contained in:
AkshayMata
2023-01-23 15:29:44 -08:00
committed by GitHub
parent 9d4d5374d7
commit 03f6a9b188
10 changed files with 820 additions and 93 deletions

View File

@@ -15,6 +15,7 @@ import { sendSqlMigrationActionEvent, TelemetryAction, TelemetryViews, logError
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';
const localize = nls.loadMessageBundle();
export enum ValidateIrState {
@@ -249,6 +250,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
public _aadDomainName!: string;
public _loginMigrationsResult!: mssql.StartLoginMigrationResult;
public _loginMigrationsError: any;
public _loginMigrationModel: LoginMigrationModel;
public readonly _refreshGetSkuRecommendationIntervalInMinutes = 10;
public readonly _performanceDataQueryIntervalInSeconds = 30;
@@ -303,6 +305,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
this._skuTargetPercentile = 95;
this._skuEnablePreview = false;
this._skuEnableElastic = false;
this._loginMigrationModel = new LoginMigrationModel();
}
public get validationTargetResults(): ValidationResult[] {
@@ -559,23 +562,22 @@ export class MigrationStateModel implements Model, vscode.Disposable {
public async migrateLogins(): Promise<Boolean> {
try {
this._loginMigrationModel.AddNewLogins(this._loginsForMigration.map(row => row.loginName));
const sourceConnectionString = await this.getSourceConnectionString();
const targetConnectionString = await this.getTargetConnectionString();
console.log('Starting Login Migration at: ', new Date());
console.time("migrateLogins")
var response = (await this.migrationService.migrateLogins(
sourceConnectionString,
targetConnectionString,
this._loginsForMigration.map(row => row.loginName),
this._aadDomainName
))!;
console.timeEnd("migrateLogins")
this.updateLoginMigrationResults(response)
this.updateLoginMigrationResults(response);
this._loginMigrationModel.AddLoginMigrationResults(LoginMigrationStep.MigrateLogins, response);
} catch (error) {
console.log('Failed Login Migration at: ', new Date());
logError(TelemetryViews.LoginMigrationWizard, 'StartLoginMigrationFailed', error);
this._loginMigrationModel.ReportException(LoginMigrationStep.MigrateLogins, error);
this._loginMigrationsError = error;
return false;
}
@@ -589,19 +591,18 @@ export class MigrationStateModel implements Model, vscode.Disposable {
const sourceConnectionString = await this.getSourceConnectionString();
const targetConnectionString = await this.getTargetConnectionString();
console.time("establishUserMapping")
var response = (await this.migrationService.establishUserMapping(
sourceConnectionString,
targetConnectionString,
this._loginsForMigration.map(row => row.loginName),
this._aadDomainName
))!;
console.timeEnd("establishUserMapping")
this.updateLoginMigrationResults(response)
this.updateLoginMigrationResults(response);
this._loginMigrationModel.AddLoginMigrationResults(LoginMigrationStep.EstablishUserMapping, response);
} catch (error) {
console.log('Failed Login Migration at: ', new Date());
logError(TelemetryViews.LoginMigrationWizard, 'StartLoginMigrationFailed', error);
this._loginMigrationModel.ReportException(LoginMigrationStep.MigrateLogins, error);
this._loginMigrationsError = error;
return false;
}
@@ -615,24 +616,19 @@ export class MigrationStateModel implements Model, vscode.Disposable {
const sourceConnectionString = await this.getSourceConnectionString();
const targetConnectionString = await this.getTargetConnectionString();
console.time("migrateServerRolesAndSetPermissions")
var response = (await this.migrationService.migrateServerRolesAndSetPermissions(
sourceConnectionString,
targetConnectionString,
this._loginsForMigration.map(row => row.loginName),
this._aadDomainName
))!;
console.timeEnd("migrateServerRolesAndSetPermissions")
this.updateLoginMigrationResults(response)
this.updateLoginMigrationResults(response);
this._loginMigrationModel.AddLoginMigrationResults(LoginMigrationStep.MigrateServerRolesAndSetPermissions, response);
console.log('Ending Login Migration at: ', new Date());
console.log('Login migration response: ', response);
console.log('AKMA DEBUG response: ', response);
} catch (error) {
console.log('Failed Login Migration at: ', new Date());
logError(TelemetryViews.LoginMigrationWizard, 'StartLoginMigrationFailed', error);
this._loginMigrationModel.ReportException(LoginMigrationStep.MigrateLogins, error);
this._loginMigrationsError = error;
return false;
}
@@ -1408,6 +1404,10 @@ export class MigrationStateModel implements Model, vscode.Disposable {
}
return "";
}
public get isWindowsAuthMigrationSupported(): boolean {
return this._targetType === MigrationTargetType.SQLMI;
}
}
export interface ServerAssessment {