diff --git a/extensions/sql-migration/package.json b/extensions/sql-migration/package.json index 5c35c18f21..6777e273ea 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.1.2", + "version": "1.1.3", "publisher": "Microsoft", "preview": false, "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt", @@ -10,7 +10,7 @@ "aiKey": "29a207bb14f84905966a8f22524cb730-25407f35-11b6-4d4e-8114-ab9e843cb52f-7380", "engines": { "vscode": "*", - "azdata": ">=1.39.0" + "azdata": ">=1.40.0" }, "activationEvents": [ "onDashboardOpen", diff --git a/extensions/sql-migration/src/api/azure.ts b/extensions/sql-migration/src/api/azure.ts index 7f84123c60..7e6475b0b1 100644 --- a/extensions/sql-migration/src/api/azure.ts +++ b/extensions/sql-migration/src/api/azure.ts @@ -38,8 +38,8 @@ export async function getLocations(account: azdata.Account, subscription: Subscr const response = await api.getLocations(account, subscription, true); const path = `/subscriptions/${subscription.id}/providers/Microsoft.DataMigration?api-version=${ARM_MGMT_API_VERSION}`; - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const dataMigrationResourceProvider = (await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true)).response.data; + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const dataMigrationResourceProvider = (await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host)).response.data; const sqlMigratonResource = dataMigrationResourceProvider.resourceTypes.find((r: any) => r.resourceType === 'SqlMigrationServices'); const sqlMigrationResourceLocations = sqlMigratonResource.locations; @@ -206,8 +206,8 @@ export type SqlVMServer = { export async function getAvailableSqlDatabaseServers(account: azdata.Account, subscription: Subscription): Promise { const api = await getAzureCoreAPI(); const path = encodeURI(`/subscriptions/${subscription.id}/providers/Microsoft.Sql/servers?api-version=${SQL_SQLDB_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -218,8 +218,8 @@ export async function getAvailableSqlDatabaseServers(account: azdata.Account, su export async function getAvailableSqlDatabases(account: azdata.Account, subscription: Subscription, resourceGroupName: string, serverName: string): Promise { const api = await getAzureCoreAPI(); const path = encodeURI(`/subscriptions/${subscription.id}/resourceGroups/${resourceGroupName}/providers/Microsoft.Sql/servers/${serverName}/databases?api-version=${SQL_SQLDB_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -230,8 +230,8 @@ export async function getAvailableSqlDatabases(account: azdata.Account, subscrip export async function getAvailableSqlVMs(account: azdata.Account, subscription: Subscription): Promise { const api = await getAzureCoreAPI(); const path = encodeURI(`/subscriptions/${subscription.id}/providers/Microsoft.SqlVirtualMachine/sqlVirtualMachines?api-version=${SQL_VM_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); @@ -280,8 +280,8 @@ export async function getSqlMigrationService(account: azdata.Account, subscripti export async function getSqlMigrationServiceById(account: azdata.Account, subscription: Subscription, sqlMigrationServiceId: string): Promise { const api = await getAzureCoreAPI(); const path = encodeURI(`${sqlMigrationServiceId}?api-version=${DMSV2_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -292,8 +292,8 @@ export async function getSqlMigrationServiceById(account: azdata.Account, subscr export async function getSqlMigrationServicesByResourceGroup(account: azdata.Account, subscription: Subscription, resouceGroupName: string): Promise { const api = await getAzureCoreAPI(); const path = encodeURI(`/subscriptions/${subscription.id}/resourceGroups/${resouceGroupName}/providers/Microsoft.DataMigration/sqlMigrationServices?api-version=${DMSV2_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -307,8 +307,8 @@ export async function getSqlMigrationServicesByResourceGroup(account: azdata.Acc export async function getSqlMigrationServices(account: azdata.Account, subscription: Subscription): Promise { const api = await getAzureCoreAPI(); const path = encodeURI(`/subscriptions/${subscription.id}/providers/Microsoft.DataMigration/sqlMigrationServices?api-version=${DMSV2_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -322,11 +322,11 @@ export async function getSqlMigrationServices(account: azdata.Account, subscript export async function createSqlMigrationService(account: azdata.Account, subscription: Subscription, resourceGroupName: string, regionName: string, sqlMigrationServiceName: string, sessionId: string): Promise { const api = await getAzureCoreAPI(); const path = encodeURI(`/subscriptions/${subscription.id}/resourceGroups/${resourceGroupName}/providers/Microsoft.DataMigration/sqlMigrationServices/${sqlMigrationServiceName}?api-version=${DMSV2_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; const requestBody = { 'location': regionName }; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.PUT, requestBody, true, 'https://management.azure.com', getSessionIdHeader(sessionId)); + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.PUT, requestBody, true, host, getSessionIdHeader(sessionId)); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -336,7 +336,7 @@ export async function createSqlMigrationService(account: azdata.Account, subscri const maxRetry = 24; let i = 0; for (i = 0; i < maxRetry; i++) { - const asyncResponse = await api.makeAzureRestRequest(account, subscription, asyncPath, azurecore.HttpRequestMethod.GET, undefined, true); + const asyncResponse = await api.makeAzureRestRequest(account, subscription, asyncPath, azurecore.HttpRequestMethod.GET, undefined, true, host); const creationStatus = asyncResponse.response.data.status; if (creationStatus === constants.ProvisioningState.Succeeded) { break; @@ -354,8 +354,8 @@ export async function createSqlMigrationService(account: azdata.Account, subscri export async function getSqlMigrationServiceAuthKeys(account: azdata.Account, subscription: Subscription, resourceGroupName: string, regionName: string, sqlMigrationServiceName: string): Promise { const api = await getAzureCoreAPI(); const path = encodeURI(`/subscriptions/${subscription.id}/resourceGroups/${resourceGroupName}/providers/Microsoft.DataMigration/sqlMigrationServices/${sqlMigrationServiceName}/ListAuthKeys?api-version=${DMSV2_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -372,8 +372,8 @@ export async function regenerateSqlMigrationServiceAuthKey(account: azdata.Accou 'location': regionName, 'keyName': keyName, }; - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, requestBody, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, requestBody, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -398,8 +398,8 @@ export async function getStorageAccountAccessKeys(account: azdata.Account, subsc export async function getSqlMigrationServiceMonitoringData(account: azdata.Account, subscription: Subscription, resourceGroupName: string, regionName: string, sqlMigrationService: string): Promise { const api = await getAzureCoreAPI(); const path = encodeURI(`/subscriptions/${subscription.id}/resourceGroups/${resourceGroupName}/providers/Microsoft.DataMigration/sqlMigrationServices/${sqlMigrationService}/listMonitoringData?api-version=${DMSV2_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -417,8 +417,8 @@ export async function startDatabaseMigration( const api = await getAzureCoreAPI(); const path = encodeURI(`${targetServer.id}/providers/Microsoft.DataMigration/databaseMigrations/${targetDatabaseName}?api-version=${DMSV2_API_VERSION}`); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.PUT, requestBody, true, 'https://management.azure.com', getSessionIdHeader(sessionId)); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.PUT, requestBody, true, host, getSessionIdHeader(sessionId)); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -437,8 +437,8 @@ export async function getMigrationDetails(account: azdata.Account, subscription: : encodeURI(`${migrationId}?migrationOperationId=${migrationOperationId}&$expand=MigrationStatusDetails&api-version=${DMSV2_API_VERSION}`); const api = await getAzureCoreAPI(); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host, undefined); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -449,8 +449,8 @@ export async function getMigrationDetails(account: azdata.Account, subscription: export async function getServiceMigrations(account: azdata.Account, subscription: Subscription, resourceId: string): Promise { const path = encodeURI(`${resourceId}/listMigrations?&api-version=${DMSV2_API_VERSION}`); const api = await getAzureCoreAPI(); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -462,8 +462,8 @@ export async function getMigrationTargetInstance(account: azdata.Account, subscr const targetServerId = getMigrationTargetId(migration); const path = encodeURI(`${targetServerId}?api-version=${SQL_MI_API_VERSION}`); const api = await getAzureCoreAPI(); - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -474,8 +474,8 @@ export async function getMigrationTargetInstance(account: azdata.Account, subscr export async function getMigrationAsyncOperationDetails(account: azdata.Account, subscription: Subscription, url: string): Promise { const api = await getAzureCoreAPI(); const path = url.replace((new URL(url)).origin + '/', ''); // path is everything after the hostname, e.g. the 'test' part of 'https://management.azure.com/test' - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.GET, undefined, true, host); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -486,8 +486,8 @@ export async function startMigrationCutover(account: azdata.Account, subscriptio const api = await getAzureCoreAPI(); const path = encodeURI(`${migration.id}/cutover?api-version=${DMSV2_API_VERSION}`); const requestBody = { migrationOperationId: migration.properties.migrationOperationId }; - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, requestBody, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, requestBody, true, host, undefined); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } @@ -498,8 +498,8 @@ export async function stopMigration(account: azdata.Account, subscription: Subsc const api = await getAzureCoreAPI(); const path = encodeURI(`${migration.id}/cancel?api-version=${DMSV2_API_VERSION}`); const requestBody = { migrationOperationId: migration.properties.migrationOperationId }; - // const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; - const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, requestBody, true); + const host = api.getProviderMetadataForAccount(account).settings.armResource?.endpoint; + const response = await api.makeAzureRestRequest(account, subscription, path, azurecore.HttpRequestMethod.POST, requestBody, true, host, undefined); if (response.errors.length > 0) { throw new Error(response.errors.toString()); } diff --git a/extensions/sql-migration/src/api/utils.ts b/extensions/sql-migration/src/api/utils.ts index 628bedc8ac..a0e81b2e38 100644 --- a/extensions/sql-migration/src/api/utils.ts +++ b/extensions/sql-migration/src/api/utils.ts @@ -12,7 +12,7 @@ import { azureResource, Tenant } from 'azurecore'; import * as constants from '../constants/strings'; import { logError, TelemetryViews } from '../telemtery'; import { AdsMigrationStatus } from '../dashboard/tabBase'; -import { getMigrationMode, getMigrationStatus, getMigrationTargetType, PipelineStatusCodes } from '../constants/helper'; +import { getMigrationMode, getMigrationStatus, getMigrationTargetType, hasRestoreBlockingReason, PipelineStatusCodes } from '../constants/helper'; export type TargetServerType = azure.SqlVMServer | azureResource.AzureSqlManagedInstance | azure.AzureSqlDatabaseServer; @@ -286,7 +286,7 @@ export function getMigrationStatusWithErrors(migration: azure.DatabaseMigration) warningCount += properties.migrationStatusWarnings?.fileUploadBlockingErrorCount ?? 0; // restore blocking reason - warningCount += (properties.migrationStatusWarnings?.restoreBlockingReason ?? '').length > 0 ? 1 : 0; + warningCount += hasRestoreBlockingReason(migration) ? 1 : 0; // complete restore error message warningCount += (properties.migrationStatusWarnings?.completeRestoreErrorMessage ?? '').length > 0 ? 1 : 0; diff --git a/extensions/sql-migration/src/constants/helper.ts b/extensions/sql-migration/src/constants/helper.ts index 2502e86940..021fc0bb34 100644 --- a/extensions/sql-migration/src/constants/helper.ts +++ b/extensions/sql-migration/src/constants/helper.ts @@ -155,6 +155,10 @@ export function hasMigrationOperationId(migration: DatabaseMigration | undefined && migationOperationId.length > 0; } +export function hasRestoreBlockingReason(migration: DatabaseMigration | undefined): boolean { + return (migration?.properties.migrationStatusWarnings?.restoreBlockingReason ?? '').length > 0; +} + export function canCancelMigration(migration: DatabaseMigration | undefined): boolean { const status = getMigrationStatus(migration); return hasMigrationOperationId(migration) @@ -187,8 +191,10 @@ export function canCutoverMigration(migration: DatabaseMigration | undefined): b const status = getMigrationStatus(migration); return hasMigrationOperationId(migration) && isOnlineMigration(migration) - && (status === loc.MigrationState.ReadyForCutover || status === loc.MigrationState.InProgress) // TODO: InProgress condition can be eventually deprecated - && isFullBackupRestored(migration); + && (status === loc.MigrationState.ReadyForCutover || status === loc.MigrationState.InProgress) + && isFullBackupRestored(migration) + // if MI migration, must have no restore blocking reason + && !(getMigrationTargetType(migration) === loc.SQL_MANAGED_INSTANCE && hasRestoreBlockingReason(migration)); } export function isActiveMigration(migration: DatabaseMigration | undefined): boolean {