Refactor functionality into LoginMigrationsModel (#21933)

This PR refactors to encapsulate all login migration functionality into LoginMigrationModel
This commit is contained in:
AkshayMata
2023-02-14 06:05:53 -08:00
committed by GitHub
parent 385e4a2245
commit 5e7446af6c
4 changed files with 213 additions and 203 deletions

View File

@@ -15,8 +15,8 @@ import { v4 as uuidv4 } from 'uuid';
import { sendSqlMigrationActionEvent, TelemetryAction, TelemetryViews, logError } from '../telemetry';
import { hashString, deepClone } from '../api/utils';
import { SKURecommendationPage } from '../wizard/skuRecommendationPage';
import { excludeDatabases, getEncryptConnectionValue, getSourceConnectionId, getSourceConnectionProfile, getSourceConnectionServerInfo, getSourceConnectionString, getSourceConnectionUri, getTargetConnectionString, getTrustServerCertificateValue, LoginTableInfo, SourceDatabaseInfo, TargetDatabaseInfo } from '../api/sqlUtils';
import { LoginMigrationModel, LoginMigrationStep } from './loginMigrationModel';
import { excludeDatabases, getEncryptConnectionValue, getSourceConnectionId, getSourceConnectionProfile, getSourceConnectionServerInfo, getSourceConnectionString, getSourceConnectionUri, getTrustServerCertificateValue, SourceDatabaseInfo, TargetDatabaseInfo } from '../api/sqlUtils';
import { LoginMigrationModel } from './loginMigrationModel';
import { TdeMigrationDbResult, TdeMigrationModel } from './tdeModels';
import { NetworkInterfaceModel } from '../api/dataModels/azure/networkInterfaceModel';
const localize = nls.loadMessageBundle();
@@ -253,10 +253,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
public _perfDataCollectionErrors!: string[];
public _perfDataCollectionIsCollecting!: boolean;
public _loginsForMigration!: LoginTableInfo[];
public _aadDomainName!: string;
public _loginMigrationsResult!: contracts.StartLoginMigrationResult;
public _loginMigrationsError: any;
public _loginMigrationModel: LoginMigrationModel;
public readonly _refreshGetSkuRecommendationIntervalInMinutes = 10;
@@ -523,142 +520,6 @@ export class MigrationStateModel implements Model, vscode.Disposable {
return this._skuRecommendationResults;
}
public setTargetServerName(): void {
switch (this._targetType) {
case MigrationTargetType.SQLMI:
const sqlMi = this._targetServerInstance as SqlManagedInstance;
this._targetServerName = sqlMi.properties.fullyQualifiedDomainName;
case MigrationTargetType.SQLDB:
const sqlDb = this._targetServerInstance as AzureSqlDatabaseServer;
this._targetServerName = sqlDb.properties.fullyQualifiedDomainName;
case MigrationTargetType.SQLVM:
// For sqlvm, we need to use ip address from the network interface to connect to the server
const sqlVm = this._targetServerInstance as SqlVMServer;
const networkInterfaces = Array.from(sqlVm.networkInterfaces.values());
this._targetServerName = NetworkInterfaceModel.getIpAddress(networkInterfaces);
}
}
public get targetServerName(): string {
// If the target server name is not already set, return it
if (!this._targetServerName) {
this.setTargetServerName();
}
return this._targetServerName;
}
private updateLoginMigrationResults(newResult: contracts.StartLoginMigrationResult): void {
if (this._loginMigrationsResult && this._loginMigrationsResult.exceptionMap) {
for (var key in newResult.exceptionMap) {
this._loginMigrationsResult.exceptionMap[key] = [...this._loginMigrationsResult.exceptionMap[key] || [], newResult.exceptionMap[key]]
}
} else {
this._loginMigrationsResult = newResult;
}
}
public async migrateLogins(): Promise<Boolean> {
try {
this._loginMigrationModel.AddNewLogins(this._loginsForMigration.map(row => row.loginName));
const sourceConnectionString = await getSourceConnectionString();
const targetConnectionString = await getTargetConnectionString(
this.targetServerName,
this._targetServerInstance.id,
this._targetUserName,
this._targetPassword,
// for login migration, connect to target Azure SQL with true/true
// to-do: take as input from the user, should be true/false for DB/MI but true/true for VM
true /* encryptConnection */,
true /* trustServerCertificate */);
var response = (await this.migrationService.migrateLogins(
sourceConnectionString,
targetConnectionString,
this._loginsForMigration.map(row => row.loginName),
this._aadDomainName
))!;
this.updateLoginMigrationResults(response);
this._loginMigrationModel.AddLoginMigrationResults(LoginMigrationStep.MigrateLogins, response);
} catch (error) {
logError(TelemetryViews.LoginMigrationWizard, 'StartLoginMigrationFailed', error);
this._loginMigrationModel.ReportException(LoginMigrationStep.MigrateLogins, error);
this._loginMigrationsError = error;
return false;
}
// TODO AKMA : emit telemetry
return true;
}
public async establishUserMappings(): Promise<Boolean> {
try {
const sourceConnectionString = await getSourceConnectionString();
const targetConnectionString = await getTargetConnectionString(
this.targetServerName,
this._targetServerInstance.id,
this._targetUserName,
this._targetPassword,
// for login migration, connect to target Azure SQL with true/true
// to-do: take as input from the user, should be true/false for DB/MI but true/true for VM
true /* encryptConnection */,
true /* trustServerCertificate */);
var response = (await this.migrationService.establishUserMapping(
sourceConnectionString,
targetConnectionString,
this._loginsForMigration.map(row => row.loginName),
this._aadDomainName
))!;
this.updateLoginMigrationResults(response);
this._loginMigrationModel.AddLoginMigrationResults(LoginMigrationStep.EstablishUserMapping, response);
} catch (error) {
logError(TelemetryViews.LoginMigrationWizard, 'StartLoginMigrationFailed', error);
this._loginMigrationModel.ReportException(LoginMigrationStep.MigrateLogins, error);
this._loginMigrationsError = error;
return false;
}
// TODO AKMA : emit telemetry
return true;
}
public async migrateServerRolesAndSetPermissions(): Promise<Boolean> {
try {
const sourceConnectionString = await getSourceConnectionString();
const targetConnectionString = await getTargetConnectionString(
this.targetServerName,
this._targetServerInstance.id,
this._targetUserName,
this._targetPassword,
// for login migration, connect to target Azure SQL with true/true
// to-do: take as input from the user, should be true/false for DB/MI but true/true for VM
true /* encryptConnection */,
true /* trustServerCertificate */);
var response = (await this.migrationService.migrateServerRolesAndSetPermissions(
sourceConnectionString,
targetConnectionString,
this._loginsForMigration.map(row => row.loginName),
this._aadDomainName
))!;
this.updateLoginMigrationResults(response);
this._loginMigrationModel.AddLoginMigrationResults(LoginMigrationStep.MigrateServerRolesAndSetPermissions, response);
} catch (error) {
logError(TelemetryViews.LoginMigrationWizard, 'StartLoginMigrationFailed', error);
this._loginMigrationModel.ReportException(LoginMigrationStep.MigrateLogins, error);
this._loginMigrationsError = error;
return false;
}
// TODO AKMA : emit telemetry
return true;
}
private async generateSkuRecommendationTelemetry(): Promise<void> {
try {
@@ -1474,6 +1335,31 @@ export class MigrationStateModel implements Model, vscode.Disposable {
public get isWindowsAuthMigrationSupported(): boolean {
return this._targetType === MigrationTargetType.SQLMI;
}
public setTargetServerName(): void {
switch (this._targetType) {
case MigrationTargetType.SQLMI:
const sqlMi = this._targetServerInstance as SqlManagedInstance;
this._targetServerName = sqlMi.properties.fullyQualifiedDomainName;
case MigrationTargetType.SQLDB:
const sqlDb = this._targetServerInstance as AzureSqlDatabaseServer;
this._targetServerName = sqlDb.properties.fullyQualifiedDomainName;
case MigrationTargetType.SQLVM:
// For sqlvm, we need to use ip address from the network interface to connect to the server
const sqlVm = this._targetServerInstance as SqlVMServer;
const networkInterfaces = Array.from(sqlVm.networkInterfaces.values());
this._targetServerName = NetworkInterfaceModel.getIpAddress(networkInterfaces);
}
}
public get targetServerName(): string {
// If the target server name is not already set, return it
if (!this._targetServerName) {
this.setTargetServerName();
}
return this._targetServerName;
}
}
export interface ServerAssessment {