diff --git a/extensions/sql-migration/package.json b/extensions/sql-migration/package.json index 3d0f0eb0e9..bdfdc8ad17 100644 --- a/extensions/sql-migration/package.json +++ b/extensions/sql-migration/package.json @@ -2,7 +2,7 @@ "name": "sql-migration", "displayName": "%displayName%", "description": "%description%", - "version": "1.3.0", + "version": "1.3.1", "publisher": "Microsoft", "preview": false, "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt", diff --git a/extensions/sql-migration/src/api/azure.ts b/extensions/sql-migration/src/api/azure.ts index 17eaee0abc..5e663cc9af 100644 --- a/extensions/sql-migration/src/api/azure.ts +++ b/extensions/sql-migration/src/api/azure.ts @@ -628,6 +628,7 @@ export async function getLocationDisplayName(location: string): Promise export async function validateIrSqlDatabaseMigrationSettings( migration: MigrationStateModel, sourceServerName: string, + encryptConnection: boolean, trustServerCertificate: boolean, sourceDatabaseName: string, targetDatabaseName: string, @@ -654,17 +655,18 @@ export async function validateIrSqlDatabaseMigrationSettings( userName: migration._sqlServerUsername, password: migration._sqlServerPassword, authentication: migration._authenticationType, + encryptConnection: encryptConnection, trustServerCertificate: trustServerCertificate, - // encryptConnection: true, }, targetSqlConnection: { testConnectivity: testTargetConnectivity, dataSource: targetDatabaseServer.properties.fullyQualifiedDomainName, userName: migration._targetUserName, password: migration._targetPassword, + authentication: MigrationSourceAuthenticationType.Sql, + // when connecting to a target Azure SQL DB, use true/false encryptConnection: true, trustServerCertificate: false, - authentication: MigrationSourceAuthenticationType.Sql, } }; @@ -686,6 +688,7 @@ export async function validateIrSqlDatabaseMigrationSettings( export async function validateIrDatabaseMigrationSettings( migration: MigrationStateModel, sourceServerName: string, + encryptConnection: boolean, trustServerCertificate: boolean, sourceDatabaseName: string, networkShare: NetworkShare, @@ -728,7 +731,7 @@ export async function validateIrDatabaseMigrationSettings( dataSource: sourceServerName, userName: migration._sqlServerUsername, password: migration._sqlServerPassword, - // to-do: use correct value of encryptConnection and trustServerCertificate + encryptConnection: encryptConnection, trustServerCertificate: trustServerCertificate, authentication: migration._authenticationType, } @@ -954,8 +957,8 @@ export interface ValdiateIrDatabaseMigrationResponse { sourceDatabaseName: string, sourceSqlConnection: { testConnectivity: boolean, - encryptConnection: true, - trustServerCertificate: false, + encryptConnection: boolean, + trustServerCertificate: boolean, dataSource: string, }, backupConfiguration: { @@ -1042,15 +1045,6 @@ export interface CopyProgressDetail { errors: string[]; } -export interface SqlConnectionInfo { - dataSource: string; - authentication: string; - username: string; - password: string; - encryptConnection: string; - trustServerCertificate: string; -} - export interface BackupConfiguration { sourceLocation?: SourceLocation; targetLocation?: TargetLocation; diff --git a/extensions/sql-migration/src/api/sqlUtils.ts b/extensions/sql-migration/src/api/sqlUtils.ts index 439d7068b4..797f157d71 100644 --- a/extensions/sql-migration/src/api/sqlUtils.ts +++ b/extensions/sql-migration/src/api/sqlUtils.ts @@ -130,6 +130,40 @@ export interface LoginTableInfo { status: string; } +export async function getSourceConnectionProfile(): Promise { + return await azdata.connection.getCurrentConnection(); +} + +export async function getSourceConnectionId(): Promise { + return (await getSourceConnectionProfile()).connectionId; +} + +export async function getSourceConnectionServerInfo(): Promise { + return await azdata.connection.getServerInfo(await getSourceConnectionId()); +} + +export async function getSourceConnectionUri(): Promise { + return await azdata.connection.getUriForConnection(await getSourceConnectionId()); +} + +export async function getSourceConnectionCredentials(): Promise<{ [name: string]: string }> { + return await azdata.connection.getCredentials(await getSourceConnectionId()); +} + +export async function getSourceConnectionQueryProvider(): Promise { + return azdata.dataprotocol.getProvider( + (await getSourceConnectionProfile()).providerId, + azdata.DataProviderType.QueryProvider); +} + +export function getEncryptConnectionValue(connection: azdata.connection.ConnectionProfile): boolean { + return connection?.options?.encrypt === true || connection?.options?.encrypt === 'true'; +} + +export function getTrustServerCertificateValue(connection: azdata.connection.ConnectionProfile): boolean { + return connection?.options?.trustServerCertificate === true || connection?.options?.trustServerCertificate === 'true'; +} + function getSqlDbConnectionProfile( serverName: string, tenantId: string, @@ -156,6 +190,7 @@ function getSqlDbConnectionProfile( password: password, connectionTimeout: 60, columnEncryptionSetting: 'Enabled', + // when connecting to a target Azure SQL DB, use true/false encrypt: true, trustServerCertificate: false, connectRetryCount: '1', @@ -168,12 +203,13 @@ function getSqlDbConnectionProfile( }; } -export function getConnectionProfile( +export function getTargetConnectionProfile( serverName: string, azureResourceId: string, userName: string, password: string, - trustServerCert: boolean = false): azdata.IConnectionProfile { + encryptConnection: boolean, + trustServerCert: boolean): azdata.IConnectionProfile { const connectId = generateGuid(); return { @@ -197,7 +233,7 @@ export function getConnectionProfile( password: password, connectionTimeout: 60, columnEncryptionSetting: 'Enabled', - encrypt: true, + encrypt: encryptConnection, trustServerCertificate: trustServerCert, connectRetryCount: '1', connectRetryInterval: '10', @@ -206,8 +242,36 @@ export function getConnectionProfile( }; } -export async function collectSourceDatabaseTableInfo(sourceConnectionId: string, sourceDatabase: string): Promise { - const ownerUri = await azdata.connection.getUriForConnection(sourceConnectionId); +export async function getSourceConnectionString(): Promise { + return await azdata.connection.getConnectionString((await getSourceConnectionProfile()).connectionId, true); +} + +export async function getTargetConnectionString( + serverName: string, + azureResourceId: string, + username: string, + password: string, + encryptConnection: boolean, + trustServerCertificate: boolean): Promise { + + const connectionProfile = getTargetConnectionProfile( + serverName, + azureResourceId, + username, + password, + encryptConnection, + trustServerCertificate); + + const result = await azdata.connection.connect(connectionProfile, false, false); + if (result.connected && result.connectionId) { + return azdata.connection.getConnectionString(result.connectionId, true); + } + + return ''; +} + +export async function collectSourceDatabaseTableInfo(sourceDatabase: string): Promise { + const ownerUri = await azdata.connection.getUriForConnection((await getSourceConnectionProfile()).connectionId); const connectionProvider = azdata.dataprotocol.getProvider( 'MSSQL', azdata.DataProviderType.ConnectionProvider); @@ -272,11 +336,14 @@ export async function collectTargetDatabaseInfo( userName: string, password: string): Promise { - const connectionProfile = getConnectionProfile( + const connectionProfile = getTargetConnectionProfile( targetServer.properties.fullyQualifiedDomainName, targetServer.id, userName, - password); + password, + // when connecting to a target Azure SQL DB, use true/false + true /* encryptConnection */, + false /* trustServerCertificate */); const result = await azdata.connection.connect(connectionProfile, false, false); if (result.connected && result.connectionId) { @@ -397,11 +464,14 @@ export async function collectTargetLogins( password: string, includeWindowsAuth: boolean = true): Promise { - const connectionProfile = getConnectionProfile( + const connectionProfile = getTargetConnectionProfile( serverName, azureResourceId, userName, password, + // 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 */); const result = await azdata.connection.connect(connectionProfile, false, false); @@ -422,7 +492,8 @@ export async function collectTargetLogins( throw new Error(result.errorMessage); } -export async function isSysAdmin(sourceConnectionId: string): Promise { +export async function isSourceConnectionSysAdmin(): Promise { + const sourceConnectionId = await getSourceConnectionId(); const ownerUri = await azdata.connection.getUriForConnection(sourceConnectionId); const queryProvider = azdata.dataprotocol.getProvider( 'MSSQL', diff --git a/extensions/sql-migration/src/dashboard/dashboardTab.ts b/extensions/sql-migration/src/dashboard/dashboardTab.ts index 0dd2bfeff0..4cf22aa78a 100644 --- a/extensions/sql-migration/src/dashboard/dashboardTab.ts +++ b/extensions/sql-migration/src/dashboard/dashboardTab.ts @@ -15,6 +15,7 @@ import { SelectMigrationServiceDialog } from '../dialog/selectMigrationService/s import { logError, TelemetryViews } from '../telemetry'; import { AdsMigrationStatus, ServiceContextChangeEvent, TabBase } from './tabBase'; import { DashboardStatusBar } from './DashboardStatusBar'; +import { getSourceConnectionId } from '../api/sqlUtils'; interface IActionMetadata { title?: string, @@ -764,11 +765,10 @@ export class DashboardTab extends TabBase { }) .component(); - const connectionProfile = await azdata.connection.getCurrentConnection(); this.disposables.push( this.serviceContextChangedEvent.event( async (e) => { - if (e.connectionId === connectionProfile.connectionId) { + if (e.connectionId === await getSourceConnectionId()) { await this.updateServiceContext(this._serviceContextButton); await this.refresh(); } diff --git a/extensions/sql-migration/src/dashboard/migrationDetailsBlobContainerTab.ts b/extensions/sql-migration/src/dashboard/migrationDetailsBlobContainerTab.ts index 01733a1920..864d1a8a86 100644 --- a/extensions/sql-migration/src/dashboard/migrationDetailsBlobContainerTab.ts +++ b/extensions/sql-migration/src/dashboard/migrationDetailsBlobContainerTab.ts @@ -13,6 +13,7 @@ import { getResourceName } from '../api/azure'; import { InfoFieldSchema, infoFieldWidth, MigrationDetailsTabBase, MigrationTargetTypeName } from './migrationDetailsTabBase'; import { EmptySettingValue } from './tabBase'; import { DashboardStatusBar } from './DashboardStatusBar'; +import { getSourceConnectionServerInfo } from '../api/sqlUtils'; const MigrationDetailsBlobContainerTabId = 'MigrationDetailsBlobContainerTab'; @@ -79,7 +80,7 @@ export class MigrationDetailsBlobContainerTab extends MigrationDetailsTabBase { await dialog.initialize(); })); - const connectionProfile = await azdata.connection.getCurrentConnection(); this.disposables.push( this.serviceContextChangedEvent.event( async (e) => { - if (e.connectionId === connectionProfile.connectionId) { + if (e.connectionId === await getSourceConnectionId()) { await this.updateServiceContext(this._serviceContextButton); await this.refresh(); } @@ -408,7 +408,7 @@ export class MigrationsListTab extends TabBase { (this._columnSortDropdown.value).name, this._columnSortCheckbox.checked === true); - const connectionProfile = await azdata.connection.getCurrentConnection(); + const connectionProfileId = await getSourceConnectionId(); const data: any[] = this._filteredMigrations.map((migration, index) => { return [ { @@ -432,7 +432,7 @@ export class MigrationsListTab extends TabBase { { title: '', context: { - connectionId: connectionProfile.connectionId, + connectionId: connectionProfileId, migrationId: migration.id, migrationOperationId: migration.properties.migrationOperationId, }, diff --git a/extensions/sql-migration/src/dashboard/migrationsTab.ts b/extensions/sql-migration/src/dashboard/migrationsTab.ts index b1c08692a7..93fe871dbc 100644 --- a/extensions/sql-migration/src/dashboard/migrationsTab.ts +++ b/extensions/sql-migration/src/dashboard/migrationsTab.ts @@ -16,6 +16,7 @@ import { MigrationDetailsFileShareTab } from './migrationDetailsFileShareTab'; import { MigrationDetailsBlobContainerTab } from './migrationDetailsBlobContainerTab'; import { MigrationDetailsTableTab } from './migrationDetailsTableTab'; import { DashboardStatusBar } from './DashboardStatusBar'; +import { getSourceConnectionId } from '../api/sqlUtils'; export const MigrationsTabId = 'MigrationsTab'; @@ -110,11 +111,9 @@ export class MigrationsTab extends TabBase { this.statusBar); this.disposables.push(this._migrationDetailsFileShareTab); - const connectionProfile = await azdata.connection.getCurrentConnection(); - const connectionId = connectionProfile.connectionId; this.disposables.push( this._migrationDetailsEvent.event(async e => { - if (e.connectionId === connectionId) { + if (e.connectionId === await getSourceConnectionId()) { const migration = await this._getMigrationDetails(e.migrationId, e.migrationOperationId); if (migration) { await this.openMigrationDetails(migration); diff --git a/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts b/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts index 169a0f10cd..9bbe8fd0da 100644 --- a/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts +++ b/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts @@ -26,6 +26,7 @@ import { DashboardStatusBar, ErrorEvent } from './DashboardStatusBar'; import { DashboardTab } from './dashboardTab'; import { MigrationsTab, MigrationsTabId } from './migrationsTab'; import { AdsMigrationStatus, MigrationDetailsEvent, ServiceContextChangeEvent } from './tabBase'; +import { getSourceConnectionId, getSourceConnectionProfile } from '../api/sqlUtils'; export interface MenuCommandArgs { connectionId: string, @@ -73,10 +74,9 @@ export class DashboardWidget { CSSStyles: { 'font-size': '14px', 'display': 'none', }, }).component(); - const connectionProfile = await azdata.connection.getCurrentConnection(); const statusBar = new DashboardStatusBar( this._context, - connectionProfile.connectionId, + await getSourceConnectionId(), statusInfoBox, this._errorEvent); @@ -133,8 +133,7 @@ export class DashboardWidget { let migrationsTabInitialized = false; disposables.push( tabs.onTabChanged(async tabId => { - const connectionProfile = await azdata.connection.getCurrentConnection(); - await this.clearError(connectionProfile.connectionId); + await this.clearError(await getSourceConnectionId()); if (tabId === MigrationsTabId && !migrationsTabInitialized) { migrationsTabInitialized = true; await migrationsTab.refresh(); @@ -428,23 +427,20 @@ export class DashboardWidget { } public async launchMigrationWizard(): Promise { - const activeConnection = await azdata.connection.getCurrentConnection(); - let connectionId: string = ''; + const activeConnection = await getSourceConnectionProfile(); let serverName: string = ''; if (!activeConnection) { const connection = await azdata.connection.openConnectionDialog(); if (connection) { - connectionId = connection.connectionId; serverName = connection.options.server; } } else { - connectionId = activeConnection.connectionId; serverName = activeConnection.serverName; } if (serverName) { const api = (await vscode.extensions.getExtension(mssql.extension.name)?.activate()) as mssql.IExtension; if (api) { - this.stateModel = new MigrationStateModel(this._context, connectionId, api.sqlMigration, api.tdeMigration); + this.stateModel = new MigrationStateModel(this._context, api.sqlMigration, api.tdeMigration); this._context.subscriptions.push(this.stateModel); const savedInfo = this.checkSavedInfo(serverName); if (savedInfo) { @@ -460,36 +456,33 @@ export class DashboardWidget { this._context, this.stateModel, this._onServiceContextChanged); - await wizardController.openWizard(connectionId); + await wizardController.openWizard(); } } } } public async launchLoginMigrationWizard(): Promise { - const activeConnection = await azdata.connection.getCurrentConnection(); - let connectionId: string = ''; + const activeConnection = await getSourceConnectionProfile(); let serverName: string = ''; if (!activeConnection) { const connection = await azdata.connection.openConnectionDialog(); if (connection) { - connectionId = connection.connectionId; serverName = connection.options.server; } } else { - connectionId = activeConnection.connectionId; serverName = activeConnection.serverName; } if (serverName) { const api = (await vscode.extensions.getExtension(mssql.extension.name)?.activate()) as mssql.IExtension; if (api) { - this.stateModel = new MigrationStateModel(this._context, connectionId, api.sqlMigration, api.tdeMigration); + this.stateModel = new MigrationStateModel(this._context, api.sqlMigration, api.tdeMigration); this._context.subscriptions.push(this.stateModel); const wizardController = new WizardController( this._context, this.stateModel, this._onServiceContextChanged); - await wizardController.openLoginWizard(connectionId); + await wizardController.openLoginWizard(); } } } diff --git a/extensions/sql-migration/src/dialog/assessmentResults/savedAssessmentDialog.ts b/extensions/sql-migration/src/dialog/assessmentResults/savedAssessmentDialog.ts index 2ff6126531..824d212b04 100644 --- a/extensions/sql-migration/src/dialog/assessmentResults/savedAssessmentDialog.ts +++ b/extensions/sql-migration/src/dialog/assessmentResults/savedAssessmentDialog.ts @@ -91,7 +91,7 @@ export class SavedAssessmentDialog { this.stateModel, this._serviceContextChangedEvent); - await wizardController.openWizard(this.stateModel.sourceConnectionId); + await wizardController.openWizard(); this._isOpen = false; } diff --git a/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts b/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts index 3adab7d043..41b73e7768 100644 --- a/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts +++ b/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts @@ -12,6 +12,7 @@ import { IconPath, IconPathHelper } from '../../constants/iconPathHelper'; import * as styles from '../../constants/styles'; import { EOL } from 'os'; import { selectDatabasesFromList } from '../../constants/helper'; +import { getSourceConnectionProfile } from '../../api/sqlUtils'; const styleLeft: azdata.CssStyles = { 'border': 'none', @@ -835,7 +836,7 @@ export class SqlDatabaseTree { let instanceTableValues: azdata.DeclarativeTableCellValue[][] = []; this._databaseTableValues = []; this._dbNames = this._model._databasesForAssessment; - this._serverName = (await this._model.getSourceConnectionProfile()).serverName; + this._serverName = (await getSourceConnectionProfile()).serverName; // pre-select the entire list const selectedDbs = this._dbNames.filter(db => this._model._databasesForAssessment.includes(db)); diff --git a/extensions/sql-migration/src/dialog/retryMigration/retryMigrationDialog.ts b/extensions/sql-migration/src/dialog/retryMigration/retryMigrationDialog.ts index a62799ff82..f09d4f80ea 100644 --- a/extensions/sql-migration/src/dialog/retryMigration/retryMigrationDialog.ts +++ b/extensions/sql-migration/src/dialog/retryMigration/retryMigrationDialog.ts @@ -14,6 +14,7 @@ import { WizardController } from '../../wizard/wizardController'; import { getMigrationModeEnum, getMigrationTargetTypeEnum } from '../../constants/helper'; import * as constants from '../../constants/strings'; import { ServiceContextChangeEvent } from '../../dashboard/tabBase'; +import { getSourceConnectionProfile } from '../../api/sqlUtils'; export class RetryMigrationDialog { @@ -27,12 +28,11 @@ export class RetryMigrationDialog { private async createMigrationStateModel( serviceContext: MigrationServiceContext, migration: DatabaseMigration, - connectionId: string, serverName: string, api: mssql.IExtension, location: azureResource.AzureLocation): Promise { - const stateModel = new MigrationStateModel(this._context, connectionId, api.sqlMigration, api.tdeMigration); + const stateModel = new MigrationStateModel(this._context, api.sqlMigration, api.tdeMigration); const sourceDatabaseName = migration.properties.sourceDatabaseName; const savedInfo: SavedInfo = { closedPage: 0, @@ -149,29 +149,26 @@ export class RetryMigrationDialog { } }); - const activeConnection = await azdata.connection.getCurrentConnection(); - let connectionId: string = ''; + const activeConnection = await getSourceConnectionProfile(); let serverName: string = ''; if (!activeConnection) { const connection = await azdata.connection.openConnectionDialog(); if (connection) { - connectionId = connection.connectionId; serverName = connection.options.server; } } else { - connectionId = activeConnection.connectionId; serverName = activeConnection.serverName; } const api = (await vscode.extensions.getExtension(mssql.extension.name)?.activate()) as mssql.IExtension; - const stateModel = await this.createMigrationStateModel(this._serviceContext, this._migration, connectionId, serverName, api, location!); + const stateModel = await this.createMigrationStateModel(this._serviceContext, this._migration, serverName, api, location!); if (await stateModel.loadSavedInfo()) { const wizardController = new WizardController( this._context, stateModel, this._serviceContextChangedEvent); - await wizardController.openWizard(stateModel.sourceConnectionId); + await wizardController.openWizard(); } else { void vscode.window.showInformationMessage(constants.MIGRATION_CANNOT_RETRY); } diff --git a/extensions/sql-migration/src/dialog/skuRecommendationResults/getAzureRecommendationDialog.ts b/extensions/sql-migration/src/dialog/skuRecommendationResults/getAzureRecommendationDialog.ts index 828be5bc00..c9bd4ad194 100644 --- a/extensions/sql-migration/src/dialog/skuRecommendationResults/getAzureRecommendationDialog.ts +++ b/extensions/sql-migration/src/dialog/skuRecommendationResults/getAzureRecommendationDialog.ts @@ -11,6 +11,7 @@ import * as styles from '../../constants/styles'; import * as utils from '../../api/utils'; import { SKURecommendationPage } from '../../wizard/skuRecommendationPage'; import { EOL } from 'os'; +import { getSourceConnectionProfile } from '../../api/sqlUtils'; export class GetAzureRecommendationDialog { private static readonly StartButtonText: string = constants.AZURE_RECOMMENDATION_START; @@ -333,7 +334,7 @@ export class GetAzureRecommendationDialog { this.skuRecommendationPage); break; case PerformanceDataSourceOptions.OpenExisting: { - const serverName = (await this.migrationStateModel.getSourceConnectionProfile()).serverName; + const serverName = (await getSourceConnectionProfile()).serverName; const errors: string[] = []; try { await this.skuRecommendationPage.startCardLoading(); diff --git a/extensions/sql-migration/src/dialog/tableMigrationSelection/tableMigrationSelectionDialog.ts b/extensions/sql-migration/src/dialog/tableMigrationSelection/tableMigrationSelectionDialog.ts index 2c5e9a45d5..2de936d79b 100644 --- a/extensions/sql-migration/src/dialog/tableMigrationSelection/tableMigrationSelectionDialog.ts +++ b/extensions/sql-migration/src/dialog/tableMigrationSelection/tableMigrationSelectionDialog.ts @@ -45,7 +45,6 @@ export class TableMigrationSelectionDialog { const targetDatabaseInfo = this._model._sourceTargetMapping.get(this._sourceDatabaseName); if (targetDatabaseInfo) { const sourceTableList: TableInfo[] = await collectSourceDatabaseTableInfo( - this._model.sourceConnectionId, this._sourceDatabaseName); const targetTableList: TableInfo[] = await collectTargetDatabaseTableInfo( diff --git a/extensions/sql-migration/src/dialog/validationResults/validateIrDialog.ts b/extensions/sql-migration/src/dialog/validationResults/validateIrDialog.ts index f492df86e9..2e41152e39 100644 --- a/extensions/sql-migration/src/dialog/validationResults/validateIrDialog.ts +++ b/extensions/sql-migration/src/dialog/validationResults/validateIrDialog.ts @@ -10,6 +10,7 @@ import { validateIrDatabaseMigrationSettings, validateIrSqlDatabaseMigrationSett import { MigrationStateModel, MigrationTargetType, NetworkShare, ValidateIrState, ValidationResult } from '../../models/stateMachine'; import { EOL } from 'os'; import { IconPathHelper } from '../../constants/iconPathHelper'; +import { getEncryptConnectionValue, getSourceConnectionProfile, getTrustServerCertificateValue } from '../../api/sqlUtils'; const DialogName = 'ValidateIrDialog'; @@ -363,11 +364,10 @@ export class ValidateIrDialog { } private async _validateDatabaseMigration(): Promise { - const sqlConnections = await azdata.connection.getConnections(); - const currentConnection = sqlConnections.find( - value => value.connectionId === this._model.sourceConnectionId); + const currentConnection = await getSourceConnectionProfile(); const sourceServerName = currentConnection?.serverName!; - const trustServerCertificate = currentConnection?.options?.trustServerCertificate === true; + const encryptConnection = getEncryptConnectionValue(currentConnection); + const trustServerCertificate = getTrustServerCertificateValue(currentConnection); const databaseCount = this._model._databasesForMigration.length; const sourceDatabaseName = this._model._databasesForMigration[0]; const networkShare = this._model._databaseBackup.networkShares[0]; @@ -385,6 +385,7 @@ export class ValidateIrDialog { const response = await validateIrDatabaseMigrationSettings( this._model, sourceServerName, + encryptConnection, trustServerCertificate, sourceDatabase, network, @@ -447,11 +448,10 @@ export class ValidateIrDialog { } private async _validateSqlDbMigration(): Promise { - const sqlConnections = await azdata.connection.getConnections(); - const currentConnection = sqlConnections.find( - value => value.connectionId === this._model.sourceConnectionId); + const currentConnection = await getSourceConnectionProfile(); const sourceServerName = currentConnection?.serverName!; - const trustServerCertificate = currentConnection?.options['trustServerCertificate'] === true; + const encryptConnection = getEncryptConnectionValue(currentConnection); + const trustServerCertificate = getTrustServerCertificateValue(currentConnection); const databaseCount = this._model._databasesForMigration.length; const sourceDatabaseName = this._model._databasesForMigration[0]; const targetDatabaseName = this._model._sourceTargetMapping.get(sourceDatabaseName)?.databaseName ?? ''; @@ -469,6 +469,7 @@ export class ValidateIrDialog { const response = await validateIrSqlDatabaseMigrationSettings( this._model, sourceServerName, + encryptConnection, trustServerCertificate, sourceDatabase, targetDatabase, diff --git a/extensions/sql-migration/src/models/migrationLocalStorage.ts b/extensions/sql-migration/src/models/migrationLocalStorage.ts index c2fd3c32ea..6bfe9ce4cb 100644 --- a/extensions/sql-migration/src/models/migrationLocalStorage.ts +++ b/extensions/sql-migration/src/models/migrationLocalStorage.ts @@ -9,6 +9,7 @@ import { DatabaseMigration, SqlMigrationService, getSubscriptions, getServiceMig import { deepClone } from '../api/utils'; import * as loc from '../constants/strings'; import { ServiceContextChangeEvent } from '../dashboard/tabBase'; +import { getSourceConnectionProfile } from '../api/sqlUtils'; export class MigrationLocalStorage { private static context: vscode.ExtensionContext; @@ -19,7 +20,7 @@ export class MigrationLocalStorage { } public static async getMigrationServiceContext(): Promise { - const connectionProfile = await azdata.connection.getCurrentConnection(); + const connectionProfile = await getSourceConnectionProfile(); if (connectionProfile) { const serverContextKey = `${this.mementoToken}.${connectionProfile.serverName}.serviceContext`; return deepClone(await this.context.globalState.get(serverContextKey)) || {}; @@ -28,7 +29,7 @@ export class MigrationLocalStorage { } public static async saveMigrationServiceContext(serviceContext: MigrationServiceContext, serviceContextChangedEvent: vscode.EventEmitter): Promise { - const connectionProfile = await azdata.connection.getCurrentConnection(); + const connectionProfile = await getSourceConnectionProfile(); if (connectionProfile) { const serverContextKey = `${this.mementoToken}.${connectionProfile.serverName}.serviceContext`; await this.context.globalState.update(serverContextKey, deepClone(serviceContext)); diff --git a/extensions/sql-migration/src/models/stateMachine.ts b/extensions/sql-migration/src/models/stateMachine.ts index b4bd65aa98..dda6b5a242 100644 --- a/extensions/sql-migration/src/models/stateMachine.ts +++ b/extensions/sql-migration/src/models/stateMachine.ts @@ -14,7 +14,7 @@ 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, getConnectionProfile, LoginTableInfo, SourceDatabaseInfo, TargetDatabaseInfo } from '../api/sqlUtils'; +import { excludeDatabases, getEncryptConnectionValue, getSourceConnectionId, getSourceConnectionProfile, getSourceConnectionServerInfo, getSourceConnectionString, getSourceConnectionUri, getTargetConnectionString, getTrustServerCertificateValue, LoginTableInfo, SourceDatabaseInfo, TargetDatabaseInfo } from '../api/sqlUtils'; import { LoginMigrationModel, LoginMigrationStep } from './loginMigrationModel'; import { TdeMigrationDbResult, TdeMigrationModel } from './tdeModels'; import { NetworkInterfaceModel } from '../api/dataModels/azure/networkInterfaceModel'; @@ -134,7 +134,6 @@ export interface Blob { } export interface Model { - readonly sourceConnectionId: string; readonly currentState: State; gatheringInformationError: string | undefined; _azureAccount: azdata.Account | undefined; @@ -297,7 +296,6 @@ export class MigrationStateModel implements Model, vscode.Disposable { constructor( public extensionContext: vscode.ExtensionContext, - private readonly _sourceConnectionId: string, public readonly migrationService: mssql.ISqlMigrationService, public readonly tdeMigrationService: mssql.ITdeMigrationService ) { @@ -373,10 +371,6 @@ export class MigrationStateModel implements Model, vscode.Disposable { || this.isBackupContainerNetworkShare; } - public get sourceConnectionId(): string { - return this._sourceConnectionId; - } - public get currentState(): State { return this._currentState; } @@ -387,7 +381,7 @@ export class MigrationStateModel implements Model, vscode.Disposable { this._stateChangeEventEmitter.fire({ oldState, newState: this.currentState }); } public async getDatabases(): Promise { - const temp = await azdata.connection.listDatabases(this.sourceConnectionId); + const temp = await azdata.connection.listDatabases(await getSourceConnectionId()); const finalResult = temp.filter((name) => !excludeDatabases.includes(name)); return finalResult; } @@ -404,7 +398,7 @@ export class MigrationStateModel implements Model, vscode.Disposable { } public async getDatabaseAssessments(targetType: MigrationTargetType[]): Promise { - const ownerUri = await azdata.connection.getUriForConnection(this.sourceConnectionId); + const ownerUri = await getSourceConnectionUri(); try { const xEventsFilesFolderPath = ''; // to-do: collect by prompting the user in the UI - for now, blank = disabled const response = (await this.migrationService.getAssessments(ownerUri, this._databasesForAssessment, xEventsFilesFolderPath))!; @@ -472,8 +466,8 @@ export class MigrationStateModel implements Model, vscode.Disposable { let fullInstanceName: string; // execute a query against the source to get the correct instance name - const connectionProfile = await this.getSourceConnectionProfile(); - const connectionUri = await azdata.connection.getUriForConnection(this._sourceConnectionId); + const connectionProfile = await getSourceConnectionProfile(); + const connectionUri = await getSourceConnectionUri(); const queryProvider = azdata.dataprotocol.getProvider(connectionProfile.providerId, azdata.DataProviderType.QueryProvider); const queryString = 'SELECT SERVERPROPERTY(\'ServerName\');'; const queryResult = await queryProvider.runQueryAndReturn(connectionUri, queryString); @@ -482,9 +476,9 @@ export class MigrationStateModel implements Model, vscode.Disposable { fullInstanceName = queryResult.rows[0][0].displayValue; } else { // get the instance name from connection info in case querying for the instance name doesn't work for whatever reason - const serverInfo = await azdata.connection.getServerInfo(this.sourceConnectionId); - const machineName = (serverInfo)['machineName']; // contains the correct machine name but not necessarily the correct instance name - const instanceName = (await this.getSourceConnectionProfile()).serverName; // contains the correct instance name but not necessarily the correct machine name + const serverInfo = await getSourceConnectionServerInfo(); + const machineName = (serverInfo)['machineName']; // contains the correct machine name but not necessarily the correct instance name + const instanceName = connectionProfile.serverName; // contains the correct instance name but not necessarily the correct machine name if (instanceName.includes('\\')) { fullInstanceName = machineName + '\\' + instanceName.substring(instanceName.indexOf('\\') + 1); @@ -554,26 +548,6 @@ export class MigrationStateModel implements Model, vscode.Disposable { return this._targetServerName; } - public async getSourceConnectionString(): Promise { - return await azdata.connection.getConnectionString(this._sourceConnectionId, true); - } - - public async getTargetConnectionString(): Promise { - const connectionProfile = getConnectionProfile( - this.targetServerName, - this._targetServerInstance.id, - this._targetUserName, - this._targetPassword, - true /* trustServerCertificate */); - - const result = await azdata.connection.connect(connectionProfile, false, false); - if (result.connected && result.connectionId) { - return azdata.connection.getConnectionString(result.connectionId, true); - } - - return ''; - } - private updateLoginMigrationResults(newResult: mssql.StartLoginMigrationResult): void { if (this._loginMigrationsResult && this._loginMigrationsResult.exceptionMap) { for (var key in newResult.exceptionMap) { @@ -588,8 +562,17 @@ export class MigrationStateModel implements Model, vscode.Disposable { try { this._loginMigrationModel.AddNewLogins(this._loginsForMigration.map(row => row.loginName)); - const sourceConnectionString = await this.getSourceConnectionString(); - const targetConnectionString = await this.getTargetConnectionString(); + 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, @@ -612,8 +595,16 @@ export class MigrationStateModel implements Model, vscode.Disposable { public async establishUserMappings(): Promise { try { - const sourceConnectionString = await this.getSourceConnectionString(); - const targetConnectionString = await this.getTargetConnectionString(); + 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, @@ -637,8 +628,16 @@ export class MigrationStateModel implements Model, vscode.Disposable { public async migrateServerRolesAndSetPermissions(): Promise { try { - const sourceConnectionString = await this.getSourceConnectionString(); - const targetConnectionString = await this.getTargetConnectionString(); + 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, @@ -782,7 +781,7 @@ export class MigrationStateModel implements Model, vscode.Disposable { page: SKURecommendationPage): Promise { try { if (!this.performanceCollectionInProgress()) { - const ownerUri = await azdata.connection.getUriForConnection(this.sourceConnectionId); + const ownerUri = await getSourceConnectionUri(); const response = await this.migrationService.startPerfDataCollection( ownerUri, dataFolder, @@ -1080,12 +1079,6 @@ export class MigrationStateModel implements Model, vscode.Disposable { return this.extensionContext.extensionPath; } - public async getSourceConnectionProfile(): Promise { - const sqlConnections = await azdata.connection.getConnections(); - return sqlConnections.find( - value => value.connectionId === this.sourceConnectionId)!; - } - public getLocationDisplayName(location: string): Promise { return getLocationDisplayName(location); } @@ -1103,7 +1096,7 @@ export class MigrationStateModel implements Model, vscode.Disposable { reportUpdate: (dbName: string, succeeded: boolean, message: string) => Promise): Promise> { const tdeEnabledDatabases = this.tdeMigrationConfig.getTdeEnabledDatabases(); - const connectionString = await azdata.connection.getConnectionString(this.sourceConnectionId, true); + const connectionString = await getSourceConnectionString(); const opResult: OperationResult = { success: false, @@ -1148,10 +1141,7 @@ export class MigrationStateModel implements Model, vscode.Disposable { } public async startMigration() { - const sqlConnections = await azdata.connection.getConnections(); - const currentConnection = sqlConnections.find( - value => value.connectionId === this.sourceConnectionId); - + const currentConnection = await getSourceConnectionProfile(); const isOfflineMigration = this._databaseBackup.migrationMode === MigrationMode.OFFLINE; const isSqlDbTarget = this.isSqlDbTarget; @@ -1166,8 +1156,8 @@ export class MigrationStateModel implements Model, vscode.Disposable { authentication: this._authenticationType, userName: this._sqlServerUsername, password: this._sqlServerPassword, - // to-do: use correct value of encryptConnection and trustServerCertificate - trustServerCertificate: currentConnection?.options.trustServerCertificate ?? false + encryptConnection: getEncryptConnectionValue(currentConnection), + trustServerCertificate: getTrustServerCertificateValue(currentConnection) }, scope: this._targetServerInstance.id, offlineConfiguration: { @@ -1208,14 +1198,15 @@ export class MigrationStateModel implements Model, vscode.Disposable { authentication: this._authenticationType, userName: this._sqlServerUsername, password: this._sqlServerPassword, - encryptConnection: true, - trustServerCertificate: currentConnection?.options.trustServerCertificate ?? false, + encryptConnection: getEncryptConnectionValue(currentConnection), + trustServerCertificate: getTrustServerCertificateValue(currentConnection) }; requestBody.properties.targetSqlConnection = { dataSource: sqlDbTarget.properties.fullyQualifiedDomainName, authentication: MigrationSourceAuthenticationType.Sql, userName: this._targetUserName, password: this._targetPassword, + // when connecting to a target Azure SQL DB, use true/false encryptConnection: true, trustServerCertificate: false, }; diff --git a/extensions/sql-migration/src/wizard/databaseBackupPage.ts b/extensions/sql-migration/src/wizard/databaseBackupPage.ts index bc94c4addd..bd26b68f56 100644 --- a/extensions/sql-migration/src/wizard/databaseBackupPage.ts +++ b/extensions/sql-migration/src/wizard/databaseBackupPage.ts @@ -17,6 +17,7 @@ import { logError, TelemetryViews } from '../telemetry'; import * as styles from '../constants/styles'; import { TableMigrationSelectionDialog } from '../dialog/tableMigrationSelection/tableMigrationSelectionDialog'; import { ValidateIrDialog } from '../dialog/validationResults/validateIrDialog'; +import { getSourceConnectionCredentials, getSourceConnectionProfile, getSourceConnectionQueryProvider, getSourceConnectionUri } from '../api/sqlUtils'; const WIZARD_TABLE_COLUMN_WIDTH = '200px'; const WIZARD_TABLE_COLUMN_WIDTH_SMALL = '170px'; @@ -799,15 +800,12 @@ export class DatabaseBackupPage extends MigrationWizardPage { : WIZARD_TABLE_COLUMN_WIDTH; }); - const connectionProfile = await this.migrationStateModel.getSourceConnectionProfile(); - const queryProvider = azdata.dataprotocol.getProvider( - (await this.migrationStateModel.getSourceConnectionProfile()).providerId, - azdata.DataProviderType.QueryProvider); - + const connectionProfile = await getSourceConnectionProfile(); + const queryProvider = await getSourceConnectionQueryProvider(); let username = ''; try { const query = 'select SUSER_NAME()'; - const ownerUri = await azdata.connection.getUriForConnection(this.migrationStateModel.sourceConnectionId); + const ownerUri = await getSourceConnectionUri(); const results = await queryProvider.runQueryAndReturn(ownerUri, query); username = results.rows[0][0]?.displayValue; } catch (e) { @@ -825,7 +823,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { connectionProfile.serverName); this._sqlSourceUsernameInput.value = username; - this._sqlSourcePassword.value = (await azdata.connection.getCredentials(this.migrationStateModel.sourceConnectionId)).password; + this._sqlSourcePassword.value = (await getSourceConnectionCredentials()).password; this._windowsUserAccountText.value = this.migrationStateModel._databaseBackup.networkShares[0]?.windowsUser diff --git a/extensions/sql-migration/src/wizard/databaseSelectorPage.ts b/extensions/sql-migration/src/wizard/databaseSelectorPage.ts index 781f8326f7..7f6d043ebf 100644 --- a/extensions/sql-migration/src/wizard/databaseSelectorPage.ts +++ b/extensions/sql-migration/src/wizard/databaseSelectorPage.ts @@ -11,7 +11,7 @@ import * as constants from '../constants/strings'; import { debounce } from '../api/utils'; import * as styles from '../constants/styles'; import { IconPathHelper } from '../constants/iconPathHelper'; -import { getDatabasesList, excludeDatabases, SourceDatabaseInfo } from '../api/sqlUtils'; +import { getDatabasesList, excludeDatabases, SourceDatabaseInfo, getSourceConnectionProfile } from '../api/sqlUtils'; export class DatabaseSelectorPage extends MigrationWizardPage { private _view!: azdata.ModelView; @@ -228,7 +228,7 @@ export class DatabaseSelectorPage extends MigrationWizardPage { } private async _loadDatabaseList(stateMachine: MigrationStateModel, selectedDatabases: string[]): Promise { - const allDatabases = (await getDatabasesList(await stateMachine.getSourceConnectionProfile())); + const allDatabases = (await getDatabasesList(await getSourceConnectionProfile())); const databaseList = allDatabases .filter(database => !excludeDatabases.includes(database.options.name)) diff --git a/extensions/sql-migration/src/wizard/loginMigrationTargetSelectionPage.ts b/extensions/sql-migration/src/wizard/loginMigrationTargetSelectionPage.ts index df6924ad11..8fa7c2a791 100644 --- a/extensions/sql-migration/src/wizard/loginMigrationTargetSelectionPage.ts +++ b/extensions/sql-migration/src/wizard/loginMigrationTargetSelectionPage.ts @@ -14,7 +14,7 @@ import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController'; import * as utils from '../api/utils'; import { azureResource } from 'azurecore'; import { AzureSqlDatabaseServer, getVMInstanceView, SqlVMServer } from '../api/azure'; -import { collectSourceLogins, collectTargetLogins, isSysAdmin, LoginTableInfo } from '../api/sqlUtils'; +import { collectSourceLogins, collectTargetLogins, getSourceConnectionId, getSourceConnectionProfile, isSourceConnectionSysAdmin, LoginTableInfo } from '../api/sqlUtils'; import { NetworkInterfaceModel } from '../api/dataModels/azure/networkInterfaceModel'; export class LoginMigrationTargetSelectionPage extends MigrationWizardPage { @@ -66,8 +66,8 @@ export class LoginMigrationTargetSelectionPage extends MigrationWizardPage { CSSStyles: { ...styles.BODY_CSS } }).component(); - const hasSysAdminPermissions: boolean = await isSysAdmin(this.migrationStateModel.sourceConnectionId); - const connectionProfile: azdata.connection.ConnectionProfile = await this.migrationStateModel.getSourceConnectionProfile(); + const hasSysAdminPermissions: boolean = await isSourceConnectionSysAdmin(); + const connectionProfile: azdata.connection.ConnectionProfile = await getSourceConnectionProfile(); const permissionsInfoBox = this._view.modelBuilder.infoBox() .withProps({ style: 'warning', @@ -331,7 +331,7 @@ export class LoginMigrationTargetSelectionPage extends MigrationWizardPage { // Collect source login info here, as it will speed up loading the next page const sourceLogins: LoginTableInfo[] = []; sourceLogins.push(...await collectSourceLogins( - this.migrationStateModel.sourceConnectionId, + await getSourceConnectionId(), this.migrationStateModel.isWindowsAuthMigrationSupported)); this.migrationStateModel._loginMigrationModel.collectedSourceLogins = true; this.migrationStateModel._loginMigrationModel.loginsOnSource = sourceLogins; diff --git a/extensions/sql-migration/src/wizard/loginSelectorPage.ts b/extensions/sql-migration/src/wizard/loginSelectorPage.ts index b7002a9412..434e72b66d 100644 --- a/extensions/sql-migration/src/wizard/loginSelectorPage.ts +++ b/extensions/sql-migration/src/wizard/loginSelectorPage.ts @@ -10,7 +10,7 @@ import { MigrationStateModel, StateChangeEvent } from '../models/stateMachine'; import * as constants from '../constants/strings'; import { debounce, getLoginStatusImage, getLoginStatusMessage } from '../api/utils'; import * as styles from '../constants/styles'; -import { collectSourceLogins, collectTargetLogins, LoginTableInfo } from '../api/sqlUtils'; +import { collectSourceLogins, collectTargetLogins, getSourceConnectionId, LoginTableInfo } from '../api/sqlUtils'; import { IconPathHelper } from '../constants/iconPathHelper'; import * as utils from '../api/utils'; import { LoginType } from '../models/loginMigrationModel'; @@ -352,7 +352,7 @@ export class LoginSelectorPage extends MigrationWizardPage { // execute a query against the source to get the logins try { sourceLogins.push(...await collectSourceLogins( - stateMachine.sourceConnectionId, + await getSourceConnectionId(), stateMachine.isWindowsAuthMigrationSupported)); stateMachine._loginMigrationModel.collectedSourceLogins = true; stateMachine._loginMigrationModel.loginsOnSource = sourceLogins; diff --git a/extensions/sql-migration/src/wizard/skuRecommendationPage.ts b/extensions/sql-migration/src/wizard/skuRecommendationPage.ts index 802237a3a9..faf67a962f 100644 --- a/extensions/sql-migration/src/wizard/skuRecommendationPage.ts +++ b/extensions/sql-migration/src/wizard/skuRecommendationPage.ts @@ -22,6 +22,7 @@ import { logError, TelemetryViews } from '../telemetry'; import { TdeConfigurationDialog } from '../dialog/tdeConfiguration/tdeConfigurationDialog'; import { TdeMigrationModel } from '../models/tdeModels'; import * as os from 'os'; +import { getSourceConnectionProfile } from '../api/sqlUtils'; export interface Product { type: MigrationTargetType; @@ -404,7 +405,7 @@ export class SKURecommendationPage extends MigrationWizardPage { CSSStyles: { 'margin': '12px 0' } }).component(); - this._serverName = this.migrationStateModel.serverName || (await this.migrationStateModel.getSourceConnectionProfile()).serverName; + this._serverName = this.migrationStateModel.serverName || (await getSourceConnectionProfile()).serverName; const miDialog = new AssessmentResultsDialog('ownerUri', this.migrationStateModel, constants.ASSESSMENT_TILE(this._serverName), this, MigrationTargetType.SQLMI); const vmDialog = new AssessmentResultsDialog('ownerUri', this.migrationStateModel, constants.ASSESSMENT_TILE(this._serverName), this, MigrationTargetType.SQLVM); diff --git a/extensions/sql-migration/src/wizard/sqlSourceConfigurationPage.ts b/extensions/sql-migration/src/wizard/sqlSourceConfigurationPage.ts index 2cd53db22f..8e0a81cdbe 100644 --- a/extensions/sql-migration/src/wizard/sqlSourceConfigurationPage.ts +++ b/extensions/sql-migration/src/wizard/sqlSourceConfigurationPage.ts @@ -9,6 +9,7 @@ import { MigrationWizardPage } from '../models/migrationWizardPage'; import { MigrationSourceAuthenticationType, MigrationStateModel, StateChangeEvent } from '../models/stateMachine'; import * as constants from '../constants/strings'; import { createLabelTextComponent, createHeadingTextComponent, WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController'; +import { getSourceConnectionCredentials, getSourceConnectionProfile, getSourceConnectionUri } from '../api/sqlUtils'; export class SqlSourceConfigurationPage extends MigrationWizardPage { private _view!: azdata.ModelView; @@ -51,10 +52,10 @@ export class SqlSourceConfigurationPage extends MigrationWizardPage { private async createSourceCredentialContainer(): Promise { - const connectionProfile = await this.migrationStateModel.getSourceConnectionProfile(); - const queryProvider = azdata.dataprotocol.getProvider((await this.migrationStateModel.getSourceConnectionProfile()).providerId, azdata.DataProviderType.QueryProvider); + const connectionProfile = await getSourceConnectionProfile(); + const queryProvider = azdata.dataprotocol.getProvider(connectionProfile.providerId, azdata.DataProviderType.QueryProvider); const query = 'select SUSER_NAME()'; - const results = await queryProvider.runQueryAndReturn(await (azdata.connection.getUriForConnection(this.migrationStateModel.sourceConnectionId)), query); + const results = await queryProvider.runQueryAndReturn(await getSourceConnectionUri(), query); const username = results.rows[0][0].displayValue; this.migrationStateModel._authenticationType = connectionProfile.authenticationType === azdata.connection.AuthenticationType.SqlLogin ? MigrationSourceAuthenticationType.Sql @@ -129,7 +130,7 @@ export class SqlSourceConfigurationPage extends MigrationWizardPage { } }).component(); this._password = this._view.modelBuilder.inputBox().withProps({ - value: (await azdata.connection.getCredentials(this.migrationStateModel.sourceConnectionId)).password, + value: (await getSourceConnectionCredentials()).password, required: true, inputType: 'password', width: WIZARD_INPUT_COMPONENT_WIDTH diff --git a/extensions/sql-migration/src/wizard/wizardController.ts b/extensions/sql-migration/src/wizard/wizardController.ts index 8aa27b6e13..6e04956616 100644 --- a/extensions/sql-migration/src/wizard/wizardController.ts +++ b/extensions/sql-migration/src/wizard/wizardController.ts @@ -22,6 +22,7 @@ import * as styles from '../constants/styles'; import { MigrationLocalStorage, MigrationServiceContext } from '../models/migrationLocalStorage'; import { azureResource } from 'azurecore'; import { ServiceContextChangeEvent } from '../dashboard/tabBase'; +import { getSourceConnectionProfile } from '../api/sqlUtils'; export const WIZARD_INPUT_COMPONENT_WIDTH = '600px'; export class WizardController { @@ -33,7 +34,7 @@ export class WizardController { private readonly _serviceContextChangedEvent: vscode.EventEmitter) { } - public async openWizard(connectionId: string): Promise { + public async openWizard(): Promise { const api = (await vscode.extensions.getExtension(mssql.extension.name)?.activate()) as mssql.IExtension; if (api) { this.extensionContext.subscriptions.push(this._model); @@ -41,7 +42,7 @@ export class WizardController { } } - public async openLoginWizard(connectionId: string): Promise { + public async openLoginWizard(): Promise { const api = (await vscode.extensions.getExtension(mssql.extension.name)?.activate()) as mssql.IExtension; if (api) { this.extensionContext.subscriptions.push(this._model); @@ -50,7 +51,7 @@ export class WizardController { } private async createWizard(stateModel: MigrationStateModel): Promise { - const serverName = (await stateModel.getSourceConnectionProfile()).serverName; + const serverName = (await getSourceConnectionProfile()).serverName; this._wizardObject = azdata.window.createWizard( loc.WIZARD_TITLE(serverName), 'MigrationWizard', @@ -198,7 +199,7 @@ export class WizardController { } private async createLoginWizard(stateModel: MigrationStateModel): Promise { - const serverName = (await stateModel.getSourceConnectionProfile()).serverName; + const serverName = (await getSourceConnectionProfile()).serverName; this._wizardObject = azdata.window.createWizard( loc.LOGIN_WIZARD_TITLE(serverName), 'LoginMigrationWizard',