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

@@ -6,7 +6,10 @@
import * as mssql from 'mssql';
import { MultiStepResult, MultiStepState } from '../dialog/generic/multiStepStatusDialog';
import * as constants from '../constants/strings';
import { LoginTableInfo } from '../api/sqlUtils';
import { getSourceConnectionString, getTargetConnectionString, LoginTableInfo } from '../api/sqlUtils';
import { MigrationStateModel } from './stateMachine';
import { logError, TelemetryViews } from '../telemetry';
import * as contracts from '../service/contracts';
type ExceptionMap = { [login: string]: any }
@@ -59,14 +62,17 @@ export class LoginMigrationModel {
public collectedTargetLogins: boolean = false;;
public loginsOnSource: LoginTableInfo[] = [];
public loginsOnTarget: string[] = [];
private _currentStepIdx: number = 0;;
public loginMigrationsResult!: contracts.StartLoginMigrationResult;
public loginMigrationsError: any;
public loginsForMigration!: LoginTableInfo[];
private _currentStepIdx: number = 0;
private _logins: Map<string, Login>;
private _loginMigrationSteps: LoginMigrationStep[] = [];
constructor() {
this.resultsPerStep = new Map<mssql.LoginMigrationStep, mssql.StartLoginMigrationResult>();
this._logins = new Map<string, Login>();
this.SetLoginMigrationSteps();
this.setLoginMigrationSteps();
}
public get currentStep(): LoginMigrationStep {
@@ -77,39 +83,29 @@ export class LoginMigrationModel {
return this._currentStepIdx === this._loginMigrationSteps.length;
}
public AddLoginMigrationResults(step: LoginMigrationStep, newResult: mssql.StartLoginMigrationResult): void {
const exceptionMap = this._getExceptionMapWithNormalizedKeys(newResult.exceptionMap);
this._currentStepIdx = this._loginMigrationSteps.findIndex(s => s === step) + 1;
public async MigrateLogins(stateMachine: MigrationStateModel): Promise<boolean> {
this.addNewLogins(stateMachine._loginMigrationModel.loginsForMigration.map(row => row.loginName));
return await this.runLoginMigrationStep(LoginMigrationStep.MigrateLogins, stateMachine);
for (const loginName of this._logins.keys()) {
const status = loginName in exceptionMap ? MultiStepState.Failed : MultiStepState.Succeeded;
const errors = loginName in exceptionMap ? this._extractErrors(exceptionMap, loginName) : [];
this._addStepStateForLogin(loginName, step, status, errors);
if (this.isMigrationComplete) {
const loginStatus = this._didAnyStepFail(loginName) ? MultiStepState.Failed : MultiStepState.Succeeded;
this._markLoginStatus(loginName, loginStatus);
}
}
// TODO AKMA : emit telemetry
}
public ReportException(step: LoginMigrationStep, error: any): void {
this._currentStepIdx = this._loginMigrationSteps.findIndex(s => s === step) + 1;
public async EstablishUserMappings(stateMachine: MigrationStateModel): Promise<boolean> {
return await this.runLoginMigrationStep(LoginMigrationStep.EstablishUserMapping, stateMachine);
for (const loginName of this._logins.keys()) {
// Mark current step as failed with the error message and mark remaining messages as canceled
let errors = [error.message];
this._addStepStateForLogin(loginName, step, MultiStepState.Failed, errors);
this._markRemainingSteps(loginName, MultiStepState.Canceled);
this._markLoginStatus(loginName, MultiStepState.Failed);
}
this._markMigrationComplete();
// TODO AKMA : emit telemetry
}
public async MigrateServerRolesAndSetPermissions(stateMachine: MigrationStateModel): Promise<boolean> {
return await this.runLoginMigrationStep(LoginMigrationStep.MigrateServerRolesAndSetPermissions, stateMachine);
// TODO AKMA : emit telemetry
}
public GetLoginMigrationResults(loginName: string): MultiStepResult[] {
let loginResults: MultiStepResult[] = [];
let login = this._getLogin(loginName);
let login = this.getLogin(loginName);
for (const step of this._loginMigrationSteps) {
// The default steps and state will be added if no steps have completed
@@ -134,11 +130,7 @@ export class LoginMigrationModel {
return loginResults;
}
public AddNewLogins(logins: string[]) {
logins.forEach(login => this._addNewLogin(login));
}
public SetLoginMigrationSteps(steps: LoginMigrationStep[] = []) {
private setLoginMigrationSteps(steps: LoginMigrationStep[] = []) {
this._loginMigrationSteps = [];
if (steps.length === 0) {
@@ -150,12 +142,144 @@ export class LoginMigrationModel {
}
}
private addNewLogins(logins: string[]) {
logins.forEach(login => this.addNewLogin(login));
}
private _getLogin(loginName: string) {
public addLoginMigrationResults(step: LoginMigrationStep, newResult: mssql.StartLoginMigrationResult): void {
const exceptionMap = this.getExceptionMapWithNormalizedKeys(newResult.exceptionMap);
this._currentStepIdx = this._loginMigrationSteps.findIndex(s => s === step) + 1;
for (const loginName of this._logins.keys()) {
const status = loginName in exceptionMap ? MultiStepState.Failed : MultiStepState.Succeeded;
const errors = loginName in exceptionMap ? this.extractErrors(exceptionMap, loginName) : [];
this.addStepStateForLogin(loginName, step, status, errors);
if (this.isMigrationComplete) {
const loginStatus = this.didAnyStepFail(loginName) ? MultiStepState.Failed : MultiStepState.Succeeded;
this.markLoginStatus(loginName, loginStatus);
}
}
}
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 reportException(step: LoginMigrationStep, error: any): void {
this._currentStepIdx = this._loginMigrationSteps.findIndex(s => s === step) + 1;
for (const loginName of this._logins.keys()) {
// Mark current step as failed with the error message and mark remaining messages as canceled
let errors = [error.message];
this.addStepStateForLogin(loginName, step, MultiStepState.Failed, errors);
this.markRemainingSteps(loginName, MultiStepState.Canceled);
this.markLoginStatus(loginName, MultiStepState.Failed);
}
this.markMigrationComplete();
}
private async runMigrateLoginsTask(sourceConnStr: string, targetConnStr: string, stateMachine: MigrationStateModel): Promise<boolean> {
try {
var response = (await stateMachine.migrationService.migrateLogins(
sourceConnStr,
targetConnStr,
stateMachine._loginMigrationModel.loginsForMigration.map(row => row.loginName),
stateMachine._aadDomainName
))!;
this.updateLoginMigrationResults(response);
this.addLoginMigrationResults(LoginMigrationStep.MigrateLogins, response);
return true;
} catch (error) {
logError(TelemetryViews.LoginMigrationWizard, 'MigratinLoginsFailed', error);
this.reportException(LoginMigrationStep.MigrateLogins, error);
this.loginMigrationsError = error;
return false;
}
}
private async runEstablishUserMappingTask(sourceConnStr: string, targetConnStr: string, stateMachine: MigrationStateModel): Promise<boolean> {
try {
var response = (await stateMachine.migrationService.establishUserMapping(
sourceConnStr,
targetConnStr,
stateMachine._loginMigrationModel.loginsForMigration.map(row => row.loginName),
stateMachine._aadDomainName
))!;
this.updateLoginMigrationResults(response);
this.addLoginMigrationResults(LoginMigrationStep.EstablishUserMapping, response);
return false;
} catch (error) {
logError(TelemetryViews.LoginMigrationWizard, 'EstablishingUserMappingFailed', error);
this.reportException(LoginMigrationStep.EstablishUserMapping, error);
this.loginMigrationsError = error;
return false;
}
}
private async runMigrateServerRolesAndSetPermissionsTask(sourceConnStr: string, targetConnStr: string, stateMachine: MigrationStateModel): Promise<boolean> {
try {
var response = (await stateMachine.migrationService.migrateServerRolesAndSetPermissions(
sourceConnStr,
targetConnStr,
stateMachine._loginMigrationModel.loginsForMigration.map(row => row.loginName),
stateMachine._aadDomainName
))!;
this.updateLoginMigrationResults(response);
this.addLoginMigrationResults(LoginMigrationStep.MigrateServerRolesAndSetPermissions, response);
return false;
} catch (error) {
logError(TelemetryViews.LoginMigrationWizard, 'MigratingServerRolesAndSettingPermissionsFailed', error);
this.reportException(LoginMigrationStep.MigrateServerRolesAndSetPermissions, error);
this.loginMigrationsError = error;
return true;
}
}
private async runLoginMigrationStep(step: LoginMigrationStep, stateMachine: MigrationStateModel): Promise<boolean> {
const sourceConnectionString = await getSourceConnectionString();
const targetConnectionString = await getTargetConnectionString(
stateMachine.targetServerName,
stateMachine._targetServerInstance.id,
stateMachine._targetUserName,
stateMachine._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 */);
// Get telemtry values
switch (step) {
case LoginMigrationStep.MigrateLogins:
return await this.runMigrateLoginsTask(sourceConnectionString, targetConnectionString, stateMachine);
case LoginMigrationStep.EstablishUserMapping:
return await this.runEstablishUserMappingTask(sourceConnectionString, targetConnectionString, stateMachine);
case LoginMigrationStep.MigrateServerRolesAndSetPermissions:
return await this.runMigrateServerRolesAndSetPermissionsTask(sourceConnectionString, targetConnectionString, stateMachine);
}
return false;
}
private getLogin(loginName: string) {
return this._logins.get(loginName.toLocaleLowerCase());
}
private _addNewLogin(loginName: string, status: MultiStepState = MultiStepState.Pending) {
private addNewLogin(loginName: string, status: MultiStepState = MultiStepState.Pending) {
let newLogin: Login = {
loginName: loginName,
overallStatus: status,
@@ -165,14 +289,14 @@ export class LoginMigrationModel {
this._logins.set(loginName.toLocaleLowerCase(), newLogin);
}
private _addStepStateForLogin(loginName: string, step: LoginMigrationStep, stepStatus: MultiStepState, errors: string[] = []) {
private addStepStateForLogin(loginName: string, step: LoginMigrationStep, stepStatus: MultiStepState, errors: string[] = []) {
const loginExist = this._logins.has(loginName);
if (!loginExist) {
this._addNewLogin(loginName, MultiStepState.Running);
this.addNewLogin(loginName, MultiStepState.Running);
}
const login = this._getLogin(loginName);
const login = this.getLogin(loginName);
if (login) {
login.overallStatus = MultiStepState.Running;
@@ -188,22 +312,22 @@ export class LoginMigrationModel {
}
}
private _markLoginStatus(loginName: string, status: MultiStepState) {
private markLoginStatus(loginName: string, status: MultiStepState) {
const loginExist = this._logins.has(loginName);
if (!loginExist) {
this._addNewLogin(loginName, MultiStepState.Running);
this.addNewLogin(loginName, MultiStepState.Running);
}
let login = this._getLogin(loginName);
let login = this.getLogin(loginName);
if (login) {
login.overallStatus = status;
}
}
private _didAnyStepFail(loginName: string) {
const login = this._getLogin(loginName);
private didAnyStepFail(loginName: string) {
const login = this.getLogin(loginName);
if (login) {
return Object.values(login.statusPerStep).every(status => status === MultiStepState.Failed);
}
@@ -211,25 +335,25 @@ export class LoginMigrationModel {
return false;
}
private _getExceptionMapWithNormalizedKeys(exceptionMap: ExceptionMap): ExceptionMap {
private getExceptionMapWithNormalizedKeys(exceptionMap: ExceptionMap): ExceptionMap {
return Object.keys(exceptionMap).reduce((result: ExceptionMap, key: string) => {
result[key.toLocaleLowerCase()] = exceptionMap[key];
return result;
}, {});
}
private _extractErrors(exceptionMap: ExceptionMap, loginName: string): string[] {
private extractErrors(exceptionMap: ExceptionMap, loginName: string): string[] {
return exceptionMap[loginName].map((exception: any) => typeof exception.InnerException !== 'undefined'
&& exception.InnerException !== null ? exception.InnerException.Message : exception.Message);
}
private _markMigrationComplete() {
private markMigrationComplete() {
this._currentStepIdx = this._loginMigrationSteps.length;
}
private _markRemainingSteps(loginName: string, status: MultiStepState) {
private markRemainingSteps(loginName: string, status: MultiStepState) {
for (let i = this._currentStepIdx; i < this._loginMigrationSteps.length; i++) {
this._addStepStateForLogin(loginName, this._loginMigrationSteps[i], status, []);
this.addStepStateForLogin(loginName, this._loginMigrationSteps[i], status, []);
}
}
}

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 {

View File

@@ -88,7 +88,7 @@ export class LoginMigrationStatusPage extends MigrationWizardPage {
this.wizard.message = {
text: constants.LOGIN_MIGRATIONS_FAILED,
level: azdata.window.MessageLevel.Error,
description: constants.LOGIN_MIGRATIONS_ERROR(this.migrationStateModel._loginMigrationsError.message),
description: constants.LOGIN_MIGRATIONS_ERROR(this.migrationStateModel._loginMigrationModel.loginMigrationsError.message),
};
this._progressLoader.loading = false;
@@ -292,7 +292,7 @@ export class LoginMigrationStatusPage extends MigrationWizardPage {
}
private async _loadMigratingLoginsList(stateMachine: MigrationStateModel): Promise<void> {
const loginList = stateMachine._loginsForMigration || [];
const loginList = stateMachine._loginMigrationModel.loginsForMigration || [];
loginList.sort((a, b) => a.loginName.localeCompare(b.loginName));
this._loginsTableValues = loginList.map(login => {
@@ -300,13 +300,13 @@ export class LoginMigrationStatusPage extends MigrationWizardPage {
var status = LoginMigrationStatusCodes.InProgress;
var title = constants.LOGIN_MIGRATION_STATUS_IN_PROGRESS;
if (stateMachine._loginMigrationsError) {
if (stateMachine._loginMigrationModel.loginMigrationsError) {
status = LoginMigrationStatusCodes.Failed;
title = constants.LOGIN_MIGRATION_STATUS_FAILED;
} else if (stateMachine._loginMigrationsResult) {
} else if (stateMachine._loginMigrationModel.loginMigrationsResult) {
status = LoginMigrationStatusCodes.Succeeded;
title = constants.LOGIN_MIGRATION_STATUS_SUCCEEDED;
var didLoginFail = Object.keys(stateMachine._loginMigrationsResult.exceptionMap).some(key => key.toLocaleLowerCase() === loginName.toLocaleLowerCase());
var didLoginFail = Object.keys(stateMachine._loginMigrationModel.loginMigrationsResult.exceptionMap).some(key => key.toLocaleLowerCase() === loginName.toLocaleLowerCase());
if (didLoginFail) {
status = LoginMigrationStatusCodes.Failed;
title = constants.LOGIN_MIGRATION_STATUS_FAILED;
@@ -352,7 +352,7 @@ export class LoginMigrationStatusPage extends MigrationWizardPage {
'value': constants.STARTING_LOGIN_MIGRATION
});
var result = await this.migrationStateModel.migrateLogins();
var result = await this.migrationStateModel._loginMigrationModel.MigrateLogins(this.migrationStateModel);
if (!result) {
await this._migrationProgressDetails.updateProperties({
@@ -366,7 +366,7 @@ export class LoginMigrationStatusPage extends MigrationWizardPage {
'value': constants.ESTABLISHING_USER_MAPPINGS
});
result = await this.migrationStateModel.establishUserMappings();
result = await this.migrationStateModel._loginMigrationModel.EstablishUserMappings(this.migrationStateModel);
if (!result) {
await this._migrationProgressDetails.updateProperties({
@@ -380,7 +380,7 @@ export class LoginMigrationStatusPage extends MigrationWizardPage {
'value': constants.MIGRATING_SERVER_ROLES_AND_SET_PERMISSIONS
});
result = await this.migrationStateModel.migrateServerRolesAndSetPermissions();
result = await this.migrationStateModel._loginMigrationModel.MigrateServerRolesAndSetPermissions(this.migrationStateModel);
if (!result) {
await this._migrationProgressDetails.updateProperties({

View File

@@ -92,7 +92,7 @@ export class LoginSelectorPage extends MigrationWizardPage {
await this._loadLoginList(false);
// load unfiltered table list and pre-select list of logins saved in state
await this._filterTableList('', this.migrationStateModel._loginsForMigration);
await this._filterTableList('', this.migrationStateModel._loginMigrationModel.loginsForMigration);
}
public async onPageLeave(): Promise<void> {
@@ -115,7 +115,7 @@ export class LoginSelectorPage extends MigrationWizardPage {
}).component();
this._disposables.push(
resourceSearchBox.onTextChanged(value => this._filterTableList(value, this.migrationStateModel._loginsForMigration || [])));
resourceSearchBox.onTextChanged(value => this._filterTableList(value, this.migrationStateModel._loginMigrationModel.loginsForMigration || [])));
const searchContainer = this._view.modelBuilder.divContainer().withItems([resourceSearchBox]).withProps({
CSSStyles: {
@@ -326,7 +326,7 @@ export class LoginSelectorPage extends MigrationWizardPage {
}));
// load unfiltered table list and pre-select list of logins saved in state
await this._filterTableList('', this.migrationStateModel._loginsForMigration);
await this._filterTableList('', this.migrationStateModel._loginMigrationModel.loginsForMigration);
const flex = view.modelBuilder.flexContainer().withLayout({
flexFlow: 'column',
@@ -416,7 +416,7 @@ export class LoginSelectorPage extends MigrationWizardPage {
private async _loadLoginList(runQuery: boolean = true): Promise<void> {
const stateMachine: MigrationStateModel = this.migrationStateModel;
const selectedLogins: LoginTableInfo[] = stateMachine._loginsForMigration || [];
const selectedLogins: LoginTableInfo[] = stateMachine._loginMigrationModel.loginsForMigration || [];
// Get source logins if caller asked us to or if we haven't collected in the past
if (runQuery || !stateMachine._loginMigrationModel.collectedSourceLogins) {
@@ -488,7 +488,7 @@ export class LoginSelectorPage extends MigrationWizardPage {
await utils.updateControlDisplay(this._aadDomainNameContainer, hasSelectedWindowsLogins);
await this._loginSelectorTable.updateProperty("height", hasSelectedWindowsLogins ? 600 : 650);
this.migrationStateModel._loginsForMigration = selectedLogins;
this.migrationStateModel._loginMigrationModel.loginsForMigration = selectedLogins;
this.updateNextButton();
}
@@ -496,7 +496,7 @@ export class LoginSelectorPage extends MigrationWizardPage {
// Only uppdate next label if we are currently on this page
if (this._isCurrentPage) {
this.wizard.nextButton.label = constants.LOGIN_MIGRATE_BUTTON_TEXT;
this.wizard.nextButton.enabled = this.migrationStateModel?._loginsForMigration?.length > 0;
this.wizard.nextButton.enabled = this.migrationStateModel?._loginMigrationModel.loginsForMigration?.length > 0;
}
}