mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 01:25:37 -05:00
[SQL Migration] Properly respect user's encryptConnection and trustServerCertificate settings (#21824)
* WIP * Always get latest current connection * Update more references * Clean up * Clean up * vbump * Update comments * Address PR feedback * Separate into helper methods
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -628,6 +628,7 @@ export async function getLocationDisplayName(location: string): Promise<string>
|
||||
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;
|
||||
|
||||
@@ -130,6 +130,40 @@ export interface LoginTableInfo {
|
||||
status: string;
|
||||
}
|
||||
|
||||
export async function getSourceConnectionProfile(): Promise<azdata.connection.ConnectionProfile> {
|
||||
return await azdata.connection.getCurrentConnection();
|
||||
}
|
||||
|
||||
export async function getSourceConnectionId(): Promise<string> {
|
||||
return (await getSourceConnectionProfile()).connectionId;
|
||||
}
|
||||
|
||||
export async function getSourceConnectionServerInfo(): Promise<azdata.ServerInfo> {
|
||||
return await azdata.connection.getServerInfo(await getSourceConnectionId());
|
||||
}
|
||||
|
||||
export async function getSourceConnectionUri(): Promise<string> {
|
||||
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<azdata.QueryProvider> {
|
||||
return azdata.dataprotocol.getProvider<azdata.QueryProvider>(
|
||||
(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<TableInfo[]> {
|
||||
const ownerUri = await azdata.connection.getUriForConnection(sourceConnectionId);
|
||||
export async function getSourceConnectionString(): Promise<string> {
|
||||
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<string> {
|
||||
|
||||
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<TableInfo[]> {
|
||||
const ownerUri = await azdata.connection.getUriForConnection((await getSourceConnectionProfile()).connectionId);
|
||||
const connectionProvider = azdata.dataprotocol.getProvider<azdata.ConnectionProvider>(
|
||||
'MSSQL',
|
||||
azdata.DataProviderType.ConnectionProvider);
|
||||
@@ -272,11 +336,14 @@ export async function collectTargetDatabaseInfo(
|
||||
userName: string,
|
||||
password: string): Promise<TargetDatabaseInfo[]> {
|
||||
|
||||
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<string[]> {
|
||||
|
||||
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<boolean> {
|
||||
export async function isSourceConnectionSysAdmin(): Promise<boolean> {
|
||||
const sourceConnectionId = await getSourceConnectionId();
|
||||
const ownerUri = await azdata.connection.getUriForConnection(sourceConnectionId);
|
||||
const queryProvider = azdata.dataprotocol.getProvider<azdata.QueryProvider>(
|
||||
'MSSQL',
|
||||
|
||||
@@ -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<DashboardTab> {
|
||||
})
|
||||
.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();
|
||||
}
|
||||
|
||||
@@ -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<Mi
|
||||
|
||||
const sqlServerName = migration.properties.sourceServerName;
|
||||
const sourceDatabaseName = migration.properties.sourceDatabaseName;
|
||||
const sqlServerInfo = await azdata.connection.getServerInfo((await azdata.connection.getCurrentConnection()).connectionId);
|
||||
const sqlServerInfo = await getSourceConnectionServerInfo();
|
||||
const versionName = getSqlServerName(sqlServerInfo.serverMajorVersion!);
|
||||
const sqlServerVersion = versionName ? versionName : sqlServerInfo.serverVersion;
|
||||
const targetDatabaseName = migration.name;
|
||||
|
||||
@@ -15,6 +15,7 @@ import { getResourceName } from '../api/azure';
|
||||
import { EmptySettingValue } from './tabBase';
|
||||
import { InfoFieldSchema, infoFieldWidth, MigrationDetailsTabBase, MigrationTargetTypeName } from './migrationDetailsTabBase';
|
||||
import { DashboardStatusBar } from './DashboardStatusBar';
|
||||
import { getSourceConnectionServerInfo } from '../api/sqlUtils';
|
||||
|
||||
const MigrationDetailsFileShareTabId = 'MigrationDetailsFileShareTab';
|
||||
|
||||
@@ -92,7 +93,7 @@ export class MigrationDetailsFileShareTab extends MigrationDetailsTabBase<Migrat
|
||||
|
||||
const sqlServerName = migration.properties.sourceServerName;
|
||||
const sourceDatabaseName = migration.properties.sourceDatabaseName;
|
||||
const sqlServerInfo = await azdata.connection.getServerInfo((await azdata.connection.getCurrentConnection()).connectionId);
|
||||
const sqlServerInfo = await getSourceConnectionServerInfo();
|
||||
const versionName = getSqlServerName(sqlServerInfo.serverMajorVersion!);
|
||||
const sqlServerVersion = versionName ? versionName : sqlServerInfo.serverVersion;
|
||||
const targetDatabaseName = migration.name;
|
||||
|
||||
@@ -14,6 +14,7 @@ import { InfoFieldSchema, infoFieldLgWidth, MigrationDetailsTabBase, MigrationTa
|
||||
import { IconPathHelper } from '../constants/iconPathHelper';
|
||||
import { EOL } from 'os';
|
||||
import { DashboardStatusBar } from './DashboardStatusBar';
|
||||
import { getSourceConnectionServerInfo } from '../api/sqlUtils';
|
||||
|
||||
const MigrationDetailsTableTabId = 'MigrationDetailsTableTab';
|
||||
|
||||
@@ -110,7 +111,7 @@ export class MigrationDetailsTableTab extends MigrationDetailsTabBase<MigrationD
|
||||
|
||||
const sqlServerName = migration?.properties.sourceServerName;
|
||||
const sourceDatabaseName = migration?.properties.sourceDatabaseName;
|
||||
const sqlServerInfo = await azdata.connection.getServerInfo((await azdata.connection.getCurrentConnection()).connectionId);
|
||||
const sqlServerInfo = await getSourceConnectionServerInfo();
|
||||
const versionName = getSqlServerName(sqlServerInfo.serverMajorVersion!);
|
||||
const sqlServerVersion = versionName ? versionName : sqlServerInfo.serverVersion;
|
||||
const targetDatabaseName = migration?.name;
|
||||
|
||||
@@ -15,6 +15,7 @@ import { logError, TelemetryViews } from '../telemetry';
|
||||
import { SelectMigrationServiceDialog } from '../dialog/selectMigrationService/selectMigrationServiceDialog';
|
||||
import { AdsMigrationStatus, EmptySettingValue, ServiceContextChangeEvent, TabBase } from './tabBase';
|
||||
import { DashboardStatusBar } from './DashboardStatusBar';
|
||||
import { getSourceConnectionId } from '../api/sqlUtils';
|
||||
|
||||
export const MigrationsListTabId = 'MigrationsListTab';
|
||||
|
||||
@@ -174,11 +175,10 @@ export class MigrationsListTab extends TabBase<MigrationsListTab> {
|
||||
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<MigrationsListTab> {
|
||||
(<azdata.CategoryValue>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 [
|
||||
<azdata.HyperlinkColumnCellValue>{
|
||||
@@ -432,7 +432,7 @@ export class MigrationsListTab extends TabBase<MigrationsListTab> {
|
||||
<azdata.ContextMenuColumnCellValue>{
|
||||
title: '',
|
||||
context: {
|
||||
connectionId: connectionProfile.connectionId,
|
||||
connectionId: connectionProfileId,
|
||||
migrationId: migration.id,
|
||||
migrationOperationId: migration.properties.migrationOperationId,
|
||||
},
|
||||
|
||||
@@ -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<MigrationsTab> {
|
||||
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);
|
||||
|
||||
@@ -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<void> {
|
||||
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<void> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export class SavedAssessmentDialog {
|
||||
this.stateModel,
|
||||
this._serviceContextChangedEvent);
|
||||
|
||||
await wizardController.openWizard(this.stateModel.sourceConnectionId);
|
||||
await wizardController.openWizard();
|
||||
this._isOpen = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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<MigrationStateModel> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<void> {
|
||||
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<void> {
|
||||
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,
|
||||
|
||||
@@ -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<MigrationServiceContext> {
|
||||
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<ServiceContextChangeEvent>): Promise<void> {
|
||||
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));
|
||||
|
||||
@@ -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<string[]> {
|
||||
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<ServerAssessment> {
|
||||
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<azdata.QueryProvider>(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 = (<any>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 = (<any>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<string> {
|
||||
return await azdata.connection.getConnectionString(this._sourceConnectionId, true);
|
||||
}
|
||||
|
||||
public async getTargetConnectionString(): Promise<string> {
|
||||
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<Boolean> {
|
||||
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<Boolean> {
|
||||
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<boolean> {
|
||||
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<azdata.connection.ConnectionProfile> {
|
||||
const sqlConnections = await azdata.connection.getConnections();
|
||||
return sqlConnections.find(
|
||||
value => value.connectionId === this.sourceConnectionId)!;
|
||||
}
|
||||
|
||||
public getLocationDisplayName(location: string): Promise<string> {
|
||||
return getLocationDisplayName(location);
|
||||
}
|
||||
@@ -1103,7 +1096,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
|
||||
reportUpdate: (dbName: string, succeeded: boolean, message: string) => Promise<void>): Promise<OperationResult<TdeMigrationDbResult[]>> {
|
||||
|
||||
const tdeEnabledDatabases = this.tdeMigrationConfig.getTdeEnabledDatabases();
|
||||
const connectionString = await azdata.connection.getConnectionString(this.sourceConnectionId, true);
|
||||
const connectionString = await getSourceConnectionString();
|
||||
|
||||
const opResult: OperationResult<TdeMigrationDbResult[]> = {
|
||||
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,
|
||||
};
|
||||
|
||||
@@ -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<azdata.QueryProvider>(
|
||||
(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
|
||||
|
||||
@@ -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<void> {
|
||||
const allDatabases = (<azdata.DatabaseInfo[]>await getDatabasesList(await stateMachine.getSourceConnectionProfile()));
|
||||
const allDatabases = (<azdata.DatabaseInfo[]>await getDatabasesList(await getSourceConnectionProfile()));
|
||||
|
||||
const databaseList = allDatabases
|
||||
.filter(database => !excludeDatabases.includes(database.options.name))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<azdata.FormComponent> {
|
||||
|
||||
const connectionProfile = await this.migrationStateModel.getSourceConnectionProfile();
|
||||
const queryProvider = azdata.dataprotocol.getProvider<azdata.QueryProvider>((await this.migrationStateModel.getSourceConnectionProfile()).providerId, azdata.DataProviderType.QueryProvider);
|
||||
const connectionProfile = await getSourceConnectionProfile();
|
||||
const queryProvider = azdata.dataprotocol.getProvider<azdata.QueryProvider>(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
|
||||
|
||||
@@ -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<ServiceContextChangeEvent>) {
|
||||
}
|
||||
|
||||
public async openWizard(connectionId: string): Promise<void> {
|
||||
public async openWizard(): Promise<void> {
|
||||
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<void> {
|
||||
public async openLoginWizard(): Promise<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
const serverName = (await stateModel.getSourceConnectionProfile()).serverName;
|
||||
const serverName = (await getSourceConnectionProfile()).serverName;
|
||||
this._wizardObject = azdata.window.createWizard(
|
||||
loc.LOGIN_WIZARD_TITLE(serverName),
|
||||
'LoginMigrationWizard',
|
||||
|
||||
Reference in New Issue
Block a user