diff --git a/extensions/azurecore/src/account-provider/auths/httpClient.ts b/extensions/azurecore/src/account-provider/auths/httpClient.ts index 224f3ef6b0..d1553579ec 100644 --- a/extensions/azurecore/src/account-provider/auths/httpClient.ts +++ b/extensions/azurecore/src/account-provider/auths/httpClient.ts @@ -14,9 +14,7 @@ import { NetworkUtils } from './networkUtils'; */ export enum HttpMethod { GET = 'get', - POST = 'post', - PUT = 'put', - DELETE = 'delete' + POST = 'post' } export enum HttpStatus { @@ -83,40 +81,6 @@ export class HttpClient implements INetworkModule { return networkRequestViaHttps(url, HttpMethod.POST, options, this.customAgentOptions as https.AgentOptions, cancellationToken); } } - - /** - * Http Put request - * @param url - * @param options - */ - async sendPutRequestAsync( - url: string, - options?: NetworkRequestOptions, - cancellationToken?: number - ): Promise> { - if (this.proxyUrl) { - return networkRequestViaProxy(url, this.proxyUrl, HttpMethod.PUT, options, this.customAgentOptions as http.AgentOptions, cancellationToken); - } else { - return networkRequestViaHttps(url, HttpMethod.PUT, options, this.customAgentOptions as https.AgentOptions, cancellationToken); - } - } - - /** - * Http Delete request - * @param url - * @param options - */ - async sendDeleteRequestAsync( - url: string, - options?: NetworkRequestOptions - ): Promise> { - if (this.proxyUrl) { - return networkRequestViaProxy(url, this.proxyUrl, HttpMethod.DELETE, options, this.customAgentOptions as http.AgentOptions); - } else { - return networkRequestViaHttps(url, HttpMethod.DELETE, options, this.customAgentOptions as https.AgentOptions); - } - } - } const networkRequestViaProxy = ( @@ -150,7 +114,7 @@ const networkRequestViaProxy = ( // compose a request string for the socket let postRequestStringContent: string = ''; - if (httpMethod === HttpMethod.POST || httpMethod === HttpMethod.PUT) { + if (httpMethod === HttpMethod.POST) { const body = options?.body || ''; postRequestStringContent = 'Content-Type: application/x-www-form-urlencoded\r\n' + @@ -283,7 +247,6 @@ const networkRequestViaHttps = ( timeout?: number ): Promise> => { const isPostRequest = httpMethod === HttpMethod.POST; - const isPutRequest = httpMethod === HttpMethod.PUT; const body: string = options?.body || ''; const url = new URL(urlString); const optionHeaders = options?.headers || {} as Record; @@ -301,7 +264,7 @@ const networkRequestViaHttps = ( customOptions.agent = new https.Agent(agentOptions); } - if (isPostRequest || isPutRequest) { + if (isPostRequest) { // needed for post request to work customOptions.headers = { ...customOptions.headers, diff --git a/extensions/azurecore/src/azureResource/utils.ts b/extensions/azurecore/src/azureResource/utils.ts index 83bf3fb7cc..6fdb90463d 100644 --- a/extensions/azurecore/src/azureResource/utils.ts +++ b/extensions/azurecore/src/azureResource/utils.ts @@ -5,6 +5,7 @@ import { ResourceGraphClient } from '@azure/arm-resourcegraph'; import { TokenCredentials } from '@azure/ms-rest-js'; +import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import * as azdata from 'azdata'; import { AzureRestResponse, GetResourceGroupsResult, GetSubscriptionsResult, ResourceQueryResult, GetBlobContainersResult, GetFileSharesResult, HttpRequestMethod, GetLocationsResult, GetManagedDatabasesResult, CreateResourceGroupResult, GetBlobsResult, GetStorageAccountAccessKeyResult, AzureAccount, azureResource, AzureAccountProviderMetadata } from 'azurecore'; import { EOL } from 'os'; @@ -17,19 +18,9 @@ import { AzureResourceGroupService } from './providers/resourceGroup/resourceGro import { BlobServiceClient, StorageSharedKeyCredential } from '@azure/storage-blob'; import providerSettings from '../account-provider/providerSettings'; import * as Constants from '../constants'; -import { getProxyEnabledHttpClient } from '../utils'; -import { HttpClient } from '../account-provider/auths/httpClient'; -import { NetworkRequestOptions } from '@azure/msal-common'; const localize = nls.loadMessageBundle(); -export interface HttpClientResponse { - body: any; - headers: any; - status: Number; - error: any; -} - function getErrorMessage(error: Error | string): string { return (error instanceof Error) ? error.message : error; } @@ -171,7 +162,7 @@ export async function getLocations(appContext: AppContext, account?: AzureAccoun const path = `/subscriptions/${subscription.id}/locations?api-version=2020-01-01`; const host = getProviderMetadataForAccount(account).settings.armResource.endpoint; const response = await makeHttpRequest(account, subscription, path, HttpRequestMethod.GET, undefined, ignoreErrors, host); - result.locations.push(...response.response.body.value); + result.locations.push(...response.response.data.value); result.errors.push(...response.errors); } catch (err) { const error = new Error(localize('azure.accounts.getLocations.queryError', "Error fetching locations for account {0} ({1}) subscription {2} ({3}) tenant {4} : {5}", @@ -350,7 +341,6 @@ export async function getSelectedSubscriptions(appContext: AppContext, account?: */ export async function makeHttpRequest(account: AzureAccount, subscription: azureResource.AzureResourceSubscription, path: string, requestType: HttpRequestMethod, requestBody?: any, ignoreErrors: boolean = false, host: string = 'https://management.azure.com', requestHeaders: { [key: string]: string } = {}): Promise { const result: AzureRestResponse = { response: {}, errors: [] }; - const httpClient: HttpClient = getProxyEnabledHttpClient(); if (!account?.properties?.tenants || !Array.isArray(account.properties.tenants)) { const error = new Error(invalidAzureAccount); @@ -390,15 +380,15 @@ export async function makeHttpRequest(account: AzureAccount, subscription: azure return result; } - let reqHeaders = { + const reqHeaders = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${securityToken.token}`, ...requestHeaders - } + }; - let networkRequestOptions: NetworkRequestOptions = { + const config: AxiosRequestConfig = { headers: reqHeaders, - body: requestBody + validateStatus: () => true // Never throw }; // Adding '/' if path does not begin with it. @@ -413,23 +403,19 @@ export async function makeHttpRequest(account: AzureAccount, subscription: azure requestUrl = `${account.properties.providerSettings.settings.armResource.endpoint}${path}`; } - let response; + let response: AxiosResponse | undefined; switch (requestType) { case HttpRequestMethod.GET: - response = await httpClient.sendGetRequestAsync(requestUrl, { - headers: reqHeaders - }); + response = await axios.get(requestUrl, config); break; case HttpRequestMethod.POST: - response = await httpClient.sendPostRequestAsync(requestUrl, networkRequestOptions); + response = await axios.post(requestUrl, requestBody, config); break; case HttpRequestMethod.PUT: - response = await httpClient.sendPutRequestAsync(requestUrl, networkRequestOptions); + response = await axios.put(requestUrl, requestBody, config); break; case HttpRequestMethod.DELETE: - response = await httpClient.sendDeleteRequestAsync(requestUrl, { - headers: reqHeaders - }); + response = await axios.delete(requestUrl, config); break; default: const error = new Error(`Unknown RequestType "${requestType}"`); @@ -448,8 +434,9 @@ export async function makeHttpRequest(account: AzureAccount, subscription: azure } else if (response.status < 200 || response.status > 299) { let errorMessage: string[] = []; errorMessage.push(response.status.toString()); - if (response.body && response.body.error) { - errorMessage.push(`${response.body.error.code} : ${response.body.error.message}`); + errorMessage.push(response.statusText); + if (response.data && response.data.error) { + errorMessage.push(`${response.data.error.code} : ${response.data.error.message}`); } const error = new Error(errorMessage.join(EOL)); if (!ignoreErrors) { @@ -468,7 +455,7 @@ export async function getManagedDatabases(account: AzureAccount, subscription: a const host = getProviderMetadataForAccount(account).settings.armResource.endpoint; const response = await makeHttpRequest(account, subscription, path, HttpRequestMethod.GET, undefined, ignoreErrors, host); return { - databases: response?.response?.body?.value ?? [], + databases: response?.response?.data?.value ?? [], errors: response.errors ? response.errors : [] }; } @@ -478,7 +465,7 @@ export async function getBlobContainers(account: AzureAccount, subscription: azu const host = getProviderMetadataForAccount(account).settings.armResource.endpoint; const response = await makeHttpRequest(account, subscription, path, HttpRequestMethod.GET, undefined, ignoreErrors, host); return { - blobContainers: response?.response?.body?.value ?? [], + blobContainers: response?.response?.data?.value ?? [], errors: response.errors ? response.errors : [] }; } @@ -488,7 +475,7 @@ export async function getFileShares(account: AzureAccount, subscription: azureRe const host = getProviderMetadataForAccount(account).settings.armResource.endpoint; const response = await makeHttpRequest(account, subscription, path, HttpRequestMethod.GET, undefined, ignoreErrors, host); return { - fileShares: response?.response?.body?.value ?? [], + fileShares: response?.response?.data?.value ?? [], errors: response.errors ? response.errors : [] }; } diff --git a/extensions/sql-migration/src/api/azure.ts b/extensions/sql-migration/src/api/azure.ts index a436830c8a..44196cfe20 100644 --- a/extensions/sql-migration/src/api/azure.ts +++ b/extensions/sql-migration/src/api/azure.ts @@ -43,7 +43,7 @@ export async function getLocations(account: azdata.Account, subscription: Subscr 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, host))?.response?.body; + 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 ?? []; if (response.errors?.length > 0) { @@ -245,8 +245,8 @@ export async function getAvailableSqlDatabaseServers(account: azdata.Account, su .join(', '); throw new Error(message); } - sortResourceArrayByName(response.response.body.value); - return response.response.body.value; + sortResourceArrayByName(response.response.data.value); + return response.response.data.value; } export async function getAvailableSqlDatabases(account: azdata.Account, subscription: Subscription, resourceGroupName: string, serverName: string): Promise { @@ -260,8 +260,8 @@ export async function getAvailableSqlDatabases(account: azdata.Account, subscrip .join(', '); throw new Error(message); } - sortResourceArrayByName(response.response.body.value); - return response.response.body.value; + sortResourceArrayByName(response.response.data.value); + return response.response.data.value; } export async function getAvailableSqlVMs(account: azdata.Account, subscription: Subscription): Promise { @@ -276,8 +276,8 @@ export async function getAvailableSqlVMs(account: azdata.Account, subscription: .join(', '); throw new Error(message); } - sortResourceArrayByName(response.response.body.value); - return response.response.body.value; + sortResourceArrayByName(response.response.data.value); + return response.response.data.value; } export async function getVMInstanceView(sqlVm: SqlVMServer, account: azdata.Account, subscription: Subscription): Promise { @@ -294,7 +294,7 @@ export async function getVMInstanceView(sqlVm: SqlVMServer, account: azdata.Acco } - return response.response.body; + return response.response.data; } export async function getAzureResourceGivenId(account: azdata.Account, subscription: Subscription, id: string, apiVersion: string): Promise { @@ -311,7 +311,7 @@ export async function getAzureResourceGivenId(account: azdata.Account, subscript } - return response.response.body; + return response.response.data; } export async function getComputeVM(sqlVm: SqlVMServer, account: azdata.Account, subscription: Subscription): Promise { @@ -367,8 +367,8 @@ export async function getSqlMigrationServiceById(account: azdata.Account, subscr .join(', '); throw new Error(message); } - response.response.body.properties.resourceGroup = getResourceGroupFromId(response.response.body.id); - return response.response.body; + response.response.data.properties.resourceGroup = getResourceGroupFromId(response.response.data.id); + return response.response.data; } export async function getSqlMigrationServicesByResourceGroup(account: azdata.Account, subscription: Subscription, resouceGroupName: string): Promise { @@ -382,11 +382,11 @@ export async function getSqlMigrationServicesByResourceGroup(account: azdata.Acc .join(', '); throw new Error(message); } - sortResourceArrayByName(response.response.body.value); - response.response.body.value.forEach((sms: SqlMigrationService) => { + sortResourceArrayByName(response.response.data.value); + response.response.data.value.forEach((sms: SqlMigrationService) => { sms.properties.resourceGroup = getResourceGroupFromId(sms.id); }); - return response.response.body.value; + return response.response.data.value; } export async function getSqlMigrationServices(account: azdata.Account, subscription: Subscription): Promise { @@ -400,11 +400,11 @@ export async function getSqlMigrationServices(account: azdata.Account, subscript .join(', '); throw new Error(message); } - sortResourceArrayByName(response.response.body.value); - response.response.body.value.forEach((sms: SqlMigrationService) => { + sortResourceArrayByName(response.response.data.value); + response.response.data.value.forEach((sms: SqlMigrationService) => { sms.properties.resourceGroup = getResourceGroupFromId(sms.id); }); - return response.response.body.value; + return response.response.data.value; } export async function createSqlMigrationService(account: azdata.Account, subscription: Subscription, resourceGroupName: string, regionName: string, sqlMigrationServiceName: string, sessionId: string): Promise { @@ -428,7 +428,7 @@ export async function createSqlMigrationService(account: azdata.Account, subscri let i = 0; for (i = 0; i < maxRetry; i++) { const asyncResponse = await api.makeAzureRestRequest(account, subscription, asyncPath, azurecore.HttpRequestMethod.GET, undefined, true, host); - const creationStatus = asyncResponse.response.body.status; + const creationStatus = asyncResponse.response.data.status; if (creationStatus === constants.ProvisioningState.Succeeded) { break; } else if (creationStatus === constants.ProvisioningState.Failed) { @@ -439,7 +439,7 @@ export async function createSqlMigrationService(account: azdata.Account, subscri if (i === maxRetry) { throw new Error(constants.DMS_PROVISIONING_FAILED); } - return response.response.body; + return response.response.data; } export async function getSqlMigrationServiceAuthKeys(account: azdata.Account, subscription: Subscription, resourceGroupName: string, regionName: string, sqlMigrationServiceName: string): Promise { @@ -454,8 +454,8 @@ export async function getSqlMigrationServiceAuthKeys(account: azdata.Account, su throw new Error(message); } return { - authKey1: response?.response?.body?.authKey1 ?? '', - authKey2: response?.response?.body?.authKey2 ?? '' + authKey1: response?.response?.data?.authKey1 ?? '', + authKey2: response?.response?.data?.authKey2 ?? '' }; } @@ -475,8 +475,8 @@ export async function regenerateSqlMigrationServiceAuthKey(account: azdata.Accou throw new Error(message); } return { - authKey1: response?.response?.body?.authKey1 ?? '', - authKey2: response?.response?.body?.authKey2 ?? '' + authKey1: response?.response?.data?.authKey1 ?? '', + authKey2: response?.response?.data?.authKey2 ?? '' }; } @@ -506,7 +506,7 @@ export async function getSqlMigrationServiceMonitoringData(account: azdata.Accou .join(', '); throw new Error(message); } - return response.response.body; + return response.response.data; } export async function startDatabaseMigration( @@ -532,7 +532,7 @@ export async function startDatabaseMigration( return { asyncUrl: asyncUrl, status: response.response.status, - databaseMigration: response.response.body + databaseMigration: response.response.data }; } @@ -552,7 +552,7 @@ export async function getMigrationDetails(account: azdata.Account, subscription: throw new Error(message); } - return response.response.body; + return response.response.data; } export async function getServiceMigrations(account: azdata.Account, subscription: Subscription, resourceId: string): Promise { @@ -567,7 +567,7 @@ export async function getServiceMigrations(account: azdata.Account, subscription throw new Error(message); } - return response.response.body.value; + return response.response.data.value; } export async function getMigrationTargetInstance(account: azdata.Account, subscription: Subscription, migration: DatabaseMigration): Promise { @@ -583,7 +583,7 @@ export async function getMigrationTargetInstance(account: azdata.Account, subscr throw new Error(message); } - return response.response.body; + return response.response.data; } export async function getMigrationAsyncOperationDetails(account: azdata.Account, subscription: Subscription, url: string): Promise { @@ -597,7 +597,7 @@ export async function getMigrationAsyncOperationDetails(account: azdata.Account, .join(', '); throw new Error(message); } - return response.response.body; + return response.response.data; } export async function startMigrationCutover(account: azdata.Account, subscription: Subscription, migration: DatabaseMigration): Promise { @@ -612,7 +612,7 @@ export async function startMigrationCutover(account: azdata.Account, subscriptio .join(', '); throw new Error(message); } - return response.response.body.value; + return response.response.data.value; } export async function stopMigration(account: azdata.Account, subscription: Subscription, migration: DatabaseMigration): Promise { @@ -718,7 +718,7 @@ export async function validateIrSqlDatabaseMigrationSettings( if (response.errors.length > 0) { throw new Error(response.errors.map(e => e.message).join(',')); } - return response.response.body; + return response.response.data; } export async function validateIrDatabaseMigrationSettings( @@ -785,7 +785,7 @@ export async function validateIrDatabaseMigrationSettings( if (response.errors.length > 0) { throw new Error(response.errors.map(e => e.message).join(',')); } - return response.response.body; + return response.response.data; } type SortableAzureResources = AzureProduct | azurecore.azureResource.FileShare | azurecore.azureResource.BlobContainer | azurecore.azureResource.Blob | azurecore.azureResource.AzureResourceSubscription | SqlMigrationService;