diff --git a/Tasks/AzureFunctionAppV1/azure-arm-rest/azure-arm-app-service-kudu.ts b/Tasks/AzureFunctionAppV1/azure-arm-rest/azure-arm-app-service-kudu.ts deleted file mode 100644 index 74f9c6545129..000000000000 --- a/Tasks/AzureFunctionAppV1/azure-arm-rest/azure-arm-app-service-kudu.ts +++ /dev/null @@ -1,710 +0,0 @@ -import tl = require('azure-pipelines-task-lib/task'); -import fs = require('fs'); -import util = require('util'); -import webClient = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'); -import { WebJob, SiteExtension } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azureModels'; -import { KUDU_DEPLOYMENT_CONSTANTS } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/constants'; - -export class KuduServiceManagementClient { - private _scmUri; - private _accessToken: string; - private _cookie: string[]; - private _scmAccessCheck : boolean; - - constructor(scmUri: string, accessToken: string, scmAccessCheck: boolean) { - this._accessToken = accessToken; - this._scmUri = scmUri; - this._scmAccessCheck = scmAccessCheck; - } - - public async beginRequest(request: webClient.WebRequest, reqOptions?: webClient.WebRequestOptions, contentType?: string): Promise { - request.headers = request.headers || {}; - if(this._scmAccessCheck === false || this._scmAccessCheck == null) { - request.headers["Authorization"] = "Bearer " + this._accessToken; - tl.debug('Using Bearer Authentication'); - let authMethodtelemetry = '{"authMethod":"Bearer"}'; - console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureFunctionAppDeployment]" + authMethodtelemetry); - } - else{ - request.headers["Authorization"] = "Basic " + this._accessToken; - tl.debug('Using Basic Authentication'); - let authMethodtelemetry = '{"authMethod":"Basic"}'; - console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureFunctionAppDeployment]" + authMethodtelemetry); - } - - - request.headers['Content-Type'] = contentType || 'application/json; charset=utf-8'; - - if(!!this._cookie) { - tl.debug(`setting affinity cookie ${JSON.stringify(this._cookie)}`); - request.headers['Cookie'] = this._cookie; - } - - let retryCount = reqOptions && util.isNumber(reqOptions.retryCount) ? reqOptions.retryCount : 5; - - while(retryCount >= 0) { - try { - let httpResponse = await webClient.sendRequest(request, reqOptions); - if(httpResponse.headers['set-cookie'] && !this._cookie) { - this._cookie = httpResponse.headers['set-cookie']; - tl.debug(`loaded affinity cookie ${JSON.stringify(this._cookie)}`); - } - - return httpResponse; - } - catch(exception) { - let exceptionString: string = exception.toString(); - if(exceptionString.indexOf("Hostname/IP doesn't match certificates's altnames") != -1 - || exceptionString.indexOf("unable to verify the first certificate") != -1 - || exceptionString.indexOf("unable to get local issuer certificate") != -1) { - tl.warning(tl.loc('ASE_SSLIssueRecommendation')); - } - - if(retryCount > 0 && exceptionString.indexOf('Request timeout') != -1 && (!reqOptions || reqOptions.retryRequestTimedout)) { - tl.debug('encountered request timedout issue in Kudu. Retrying again'); - retryCount -= 1; - continue; - } - - throw new Error(exceptionString); - } - } - - } - - public getRequestUri(uriFormat: string, queryParameters?: Array) { - uriFormat = uriFormat[0] == "/" ? uriFormat : "/" + uriFormat; - - if(queryParameters && queryParameters.length > 0) { - uriFormat = uriFormat + '?' + queryParameters.join('&'); - } - - return this._scmUri + uriFormat; - } - - public getScmUri(): string { - return this._scmUri; - } -} - -export class Kudu { - private _client: KuduServiceManagementClient; - - constructor(scmUri: string, accessToken: string, scmPolicyCheck: boolean) { - this._client = new KuduServiceManagementClient(scmUri, accessToken, scmPolicyCheck); - } - - public async updateDeployment(requestBody: any): Promise { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(requestBody); - httpRequest.uri = this._client.getRequestUri(`/api/deployments/${requestBody.id}`); - - try { - let webRequestOptions: webClient.WebRequestOptions = {retriableErrorCodes: [], retriableStatusCodes: null, retryCount: 5, retryIntervalInSeconds: 5, retryRequestTimedout: true}; - var response = await this._client.beginRequest(httpRequest, webRequestOptions); - tl.debug(`updateDeployment. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - console.log(tl.loc("Successfullyupdateddeploymenthistory", response.body.url)); - return response.body.id; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('Failedtoupdatedeploymenthistory', this._getFormattedError(error))); - } - } - - - public async getContinuousJobs(): Promise> { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/continuouswebjobs`); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getContinuousJobs. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body as Array; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetContinuousWebJobs', this._getFormattedError(error))) - } - } - - public async startContinuousWebJob(jobName: string): Promise { - console.log(tl.loc('StartingWebJob', jobName)); - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/continuouswebjobs/${jobName}/start`); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`startContinuousWebJob. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - console.log(tl.loc('StartedWebJob', jobName)); - return response.body as WebJob; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToStartContinuousWebJob', jobName, this._getFormattedError(error))); - } - } - - public async stopContinuousWebJob(jobName: string): Promise { - console.log(tl.loc('StoppingWebJob', jobName)); - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/continuouswebjobs/${jobName}/stop`); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`stopContinuousWebJob. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - console.log(tl.loc('StoppedWebJob', jobName)); - return response.body as WebJob; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToStopContinuousWebJob', jobName, this._getFormattedError(error))); - } - } - - public async installSiteExtension(extensionID: string): Promise { - console.log(tl.loc("InstallingSiteExtension", extensionID)); - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.uri = this._client.getRequestUri(`/api/siteextensions/${extensionID}`); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`installSiteExtension. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - console.log(tl.loc("SiteExtensionInstalled", extensionID)); - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToInstallSiteExtension', extensionID, this._getFormattedError(error))) - } - } - - public async getSiteExtensions(): Promise> { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/siteextensions`, ['checkLatest=false']); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getSiteExtensions. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body as Array; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetSiteExtensions', this._getFormattedError(error))) - } - } - - public async getAllSiteExtensions(): Promise> { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/extensionfeed`); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getAllSiteExtensions. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body as Array; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetAllSiteExtensions', this._getFormattedError(error))) - } - } - - public async getProcess(processID: number): Promise { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/processes/${processID}`); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getProcess. status code: ${response.statusCode} - ${response.statusMessage}`); - if(response.statusCode == 200) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetProcess', this._getFormattedError(error))) - } - } - - public async killProcess(processID: number): Promise { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'DELETE'; - httpRequest.uri = this._client.getRequestUri(`/api/processes/${processID}`); - var reqOptions: webClient.WebRequestOptions = { - retriableErrorCodes: ["ETIMEDOUT"], - retriableStatusCodes: [503], - retryCount: 1, - retryIntervalInSeconds: 5, - retryRequestTimedout: true - }; - try { - var response = await this._client.beginRequest(httpRequest, reqOptions); - tl.debug(`killProcess. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 502) { - tl.debug(`Killed Process ${processID}`); - return; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToKillProcess', this._getFormattedError(error))) - } - } - - public async getAppSettings(): Promise> { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/settings`); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getAppSettings. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToFetchKuduAppSettings', this._getFormattedError(error))); - } - } - - public async listDir(physicalPath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`listFiles. Data: ${JSON.stringify(response)}`); - if([200, 201, 204].indexOf(response.statusCode) != -1) { - return response.body; - } - else if(response.statusCode === 404) { - return null; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('FailedToListPath', physicalPath, this._getFormattedError(error))); - } - } - - public async getFileContent(physicalPath: string, fileName: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/${fileName}`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getFileContent. Status code: ${response.statusCode} - ${response.statusMessage}`); - if([200, 201, 204].indexOf(response.statusCode) != -1) { - return response.body; - } - else if(response.statusCode === 404) { - return null; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('FailedToGetFileContent', physicalPath, fileName, this._getFormattedError(error))); - } - } - - public async uploadFile(physicalPath: string, fileName: string, filePath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - if(!tl.exist(filePath)) { - throw new Error(tl.loc('FilePathInvalid', filePath)); - } - - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/${fileName}`); - httpRequest.headers = { - 'If-Match': '*' - }; - httpRequest.body = fs.createReadStream(filePath); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`uploadFile. Data: ${JSON.stringify(response)}`); - if([200, 201, 204].indexOf(response.statusCode) != -1) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToUploadFile', physicalPath, fileName, this._getFormattedError(error))); - } - } - - public async createPath(physicalPath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`createPath. Data: ${JSON.stringify(response)}`); - if([200, 201, 204].indexOf(response.statusCode) != -1) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToCreatePath', physicalPath, this._getFormattedError(error))); - } - } - - public async runCommand(physicalPath: string, command: string): Promise { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/command`); - httpRequest.headers = { - 'Content-Type': 'multipart/form-data', - 'If-Match': '*' - }; - httpRequest.body = JSON.stringify({ - 'command': command, - 'dir': physicalPath - }); - - try { - tl.debug('Executing Script on Kudu. Command: ' + command); - let webRequestOptions: webClient.WebRequestOptions = {retriableErrorCodes: null, retriableStatusCodes: null, retryCount: 5, retryIntervalInSeconds: 5, retryRequestTimedout: false}; - var response = await this._client.beginRequest(httpRequest, webRequestOptions); - tl.debug(`runCommand. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return ; - } - else { - throw response; - } - } - catch(error) { - throw Error(error.toString()); - } - } - - public async extractZIP(webPackage: string, physicalPath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.uri = this._client.getRequestUri(`/api/zip/${physicalPath}/`); - httpRequest.headers = { - 'Content-Type': 'multipart/form-data', - 'If-Match': '*' - }; - httpRequest.body = fs.createReadStream(webPackage); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`extractZIP. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return ; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('Failedtodeploywebapppackageusingkuduservice', this._getFormattedError(error))); - } - } - - public getKuduStackTrace() { - let stackTraceUrl = this._client.getRequestUri(`/api/vfs/LogFiles/kudu/trace`); - return stackTraceUrl; - } - - public async zipDeploy(webPackage: string, queryParameters?: Array): Promise { - let httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/zipdeploy`, queryParameters); - httpRequest.body = fs.createReadStream(webPackage); - let requestOptions = new webClient.WebRequestOptions(); - //Bydefault webclient.sendRequest retries for [408, 409, 500, 502, 503, 504] as suggested by appservice team for zipdeploy api - //408 and 409 should not be retried as it will never turn into success - requestOptions.retriableStatusCodes = [500, 502, 503, 504]; - requestOptions.retryIntervalInSeconds = 5; - try { - let response = await this._client.beginRequest(httpRequest, requestOptions, 'application/octet-stream'); - tl.debug(`ZIP Deploy response: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - tl.debug('Deployment passed'); - return null; - } - else if(response.statusCode == 202) { - let pollableURL: string = response.headers.location; - if(!!pollableURL) { - tl.debug(`Polling for ZIP Deploy URL: ${pollableURL}`); - return await this._getDeploymentDetailsFromPollURL(pollableURL); - } - else { - tl.debug('zip deploy returned 202 without pollable URL.'); - return null; - } - } - else { - throw response; - } - } - catch(error) { - throw new Error(tl.loc('PackageDeploymentFailed', this._getFormattedError(error))); - } - } - - public async warDeploy(webPackage: string, queryParameters?: Array): Promise { - let httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/wardeploy`, queryParameters); - httpRequest.body = fs.createReadStream(webPackage); - - try { - let response = await this._client.beginRequest(httpRequest, null, 'application/octet-stream'); - tl.debug(`War Deploy response: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - tl.debug('Deployment passed'); - return null; - } - else if(response.statusCode == 202) { - let pollableURL: string = response.headers.location; - if(!!pollableURL) { - tl.debug(`Polling for War Deploy URL: ${pollableURL}`); - return await this._getDeploymentDetailsFromPollURL(pollableURL); - } - else { - tl.debug('war deploy returned 202 without pollable URL.'); - return null; - } - } - else { - throw response; - } - } - catch(error) { - throw new Error(tl.loc('PackageDeploymentFailed', this._getFormattedError(error))); - } - } - - - public async getDeploymentDetails(deploymentID: string): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/deployments/${deploymentID}`); ; - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getDeploymentDetails. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetDeploymentLogs', this._getFormattedError(error))) - } - } - - public async getDeploymentLogs(log_url: string): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = log_url; - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getDeploymentLogs. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetDeploymentLogs', this._getFormattedError(error))) - } - } - - public async deleteFile(physicalPath: string, fileName: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'DELETE'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/${fileName}`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`deleteFile. Data: ${JSON.stringify(response)}`); - if([200, 201, 204, 404].indexOf(response.statusCode) != -1) { - return ; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('FailedToDeleteFile', physicalPath, fileName, this._getFormattedError(error))); - } - } - - public async deleteFolder(physicalPath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'DELETE'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`deleteFolder. Data: ${JSON.stringify(response)}`); - if([200, 201, 204, 404].indexOf(response.statusCode) != -1) { - return ; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('FailedToDeleteFolder', physicalPath, this._getFormattedError(error))); - } - } - - private async _getDeploymentDetailsFromPollURL(pollURL: string):Promise { - let httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = pollURL; - httpRequest.headers = {}; - - while(true) { - let response = await this._client.beginRequest(httpRequest); - if(response.statusCode == 200 || response.statusCode == 202) { - var result = response.body; - tl.debug(`POLL URL RESULT: ${JSON.stringify(response)}`); - if(result.status == KUDU_DEPLOYMENT_CONSTANTS.SUCCESS || result.status == KUDU_DEPLOYMENT_CONSTANTS.FAILED) { - return result; - } - else { - tl.debug(`Deployment status: ${result.status} '${result.status_text}'. retry after 5 seconds`); - await webClient.sleepFor(5); - continue; - } - } - else { - throw response; - } - } - } - - private _getFormattedError(error: any) { - if(error && error.message) { - if(error.statusCode) { - error.message = `${typeof error.message.valueOf() == 'string' ? error.message : error.message.Code + " - " + error.message.Message } (CODE: ${error.statusCode})` - } - - return error.message; - } - if(error && error.statusCode) { - return `${error.statusMessage} (CODE: ${error.statusCode})`; - } - return error; - } - - public async validateZipDeploy(webPackage: string, queryParameters?: Array): Promise { - try { - var stats = fs.statSync(webPackage); - var fileSizeInBytes = stats.size; - let httpRequest: webClient.WebRequest = { - method: 'POST', - uri: this._client.getRequestUri(`/api/zipdeploy/validate`, queryParameters), - body: fs.createReadStream(webPackage), - headers: { - 'Content-Length': fileSizeInBytes - }, - }; - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retriableStatusCodes = [500, 502, 503, 504]; - requestOptions.retryIntervalInSeconds = 5; - - let response = await this._client.beginRequest(httpRequest, requestOptions, 'application/octet-stream'); - if(response.statusCode == 200) { - tl.debug(`Validation passed response: ${JSON.stringify(response)}`); - if (response.body && response.body.result){ - tl.warning(`${JSON.stringify(response.body.result)}`); - } - return null; - } - else if(response.statusCode == 400) { - tl.debug(`Validation failed response: ${JSON.stringify(response)}`); - throw response; - } - else { - tl.debug(`Skipping validation with status: ${response.statusCode}`); - return null; - } - } - catch(error) { - if (error && error.body && error.body.result && typeof error.body.result.valueOf() == 'string' && error.body.result.includes('ZipDeploy Validation ERROR')) { - throw Error(JSON.stringify(error.body.result)); - } - else { - tl.debug(`Skipping validation with error: ${error}`); - return null; - } - } - } -} diff --git a/Tasks/AzureFunctionAppV1/azure-arm-rest/azure-arm-app-service.ts b/Tasks/AzureFunctionAppV1/azure-arm-rest/azure-arm-app-service.ts deleted file mode 100644 index a0df5706f08d..000000000000 --- a/Tasks/AzureFunctionAppV1/azure-arm-rest/azure-arm-app-service.ts +++ /dev/null @@ -1,824 +0,0 @@ -import tl = require('azure-pipelines-task-lib/task'); -import webClient = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'); -import { - AzureEndpoint, - AzureAppServiceConfigurationDetails -} from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azureModels'; - -import { - ServiceClient, - ToError -} from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/AzureServiceClient'; -import constants = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/constants'); -const CorrelationIdInResponse = "x-ms-correlation-request-id"; - -export class ServiceClient_1 extends ServiceClient{ - public async beginRequest(request: webClient.WebRequest, reqOptions?: webClient.WebRequestOptions): Promise { - var token = await this.getCredentials().getToken(); - - request.headers = request.headers || {}; - request.headers["Authorization"] = "Bearer " + token; - if (this.acceptLanguage) { - request.headers['accept-language'] = this.acceptLanguage; - } - request.headers['Content-Type'] = 'application/json; charset=utf-8'; - - var httpResponse = null; - - try - { - httpResponse = await webClient.sendRequest(request, reqOptions); - if (httpResponse.statusCode === 401 && httpResponse.body && httpResponse.body.error && httpResponse.body.error.code === "ExpiredAuthenticationToken") { - // The access token might have expire. Re-issue the request after refreshing the token. - token = await this.getCredentials().getToken(true); - request.headers["Authorization"] = "Bearer " + token; - httpResponse = await webClient.sendRequest(request, reqOptions); - } - - if(!!httpResponse.headers[CorrelationIdInResponse]) { - tl.debug(`Correlation ID from ARM api call response : ${httpResponse.headers[CorrelationIdInResponse]}`); - } - } catch(exception) { - let exceptionString: string = exception.toString(); - if(exceptionString.indexOf("Hostname/IP doesn't match certificates's altnames") != -1 - || exceptionString.indexOf("unable to verify the first certificate") != -1 - || exceptionString.indexOf("unable to get local issuer certificate") != -1) { - tl.warning(tl.loc('ASE_SSLIssueRecommendation')); - } - - throw exception; - } - - return httpResponse; - } -} - -export class AzureAppService { - private _resourceGroup: string; - private _name: string; - private _slot: string; - private _appKind: string; - private _isConsumptionApp: boolean; - public _client: ServiceClient_1; - private _appServiceConfigurationDetails: AzureAppServiceConfigurationDetails; - private _appServicePublishingProfile: any; - private _appServiceApplicationSetings: AzureAppServiceConfigurationDetails; - private _appServiceConfigurationSettings: AzureAppServiceConfigurationDetails; - private _appServiceConnectionString: AzureAppServiceConfigurationDetails; - - constructor(endpoint: AzureEndpoint, resourceGroup: string, name: string, slot?: string, appKind?: string, isConsumptionApp?: boolean) { - this._client = new ServiceClient_1(endpoint.applicationTokenCredentials, endpoint.subscriptionID, 30); - this._resourceGroup = resourceGroup; - this._name = name; - this._slot = (slot && slot.toLowerCase() == constants.productionSlot) ? null : slot; - this._appKind = appKind; - this._isConsumptionApp = isConsumptionApp; - } - - public async start(): Promise { - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/start`, { - '{ResourceGroupName}': this._resourceGroup, - '{name}': this._name - }, null, '2016-08-01'); - - console.log(tl.loc('StartingAppService', this._getFormattedName())); - var response = await this._client.beginRequest(webRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - console.log(tl.loc('StartedAppService', this._getFormattedName())); - } - catch(error) { - throw Error(tl.loc('FailedToStartAppService', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async stop(): Promise { - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/stop`, { - '{ResourceGroupName}': this._resourceGroup, - '{name}': this._name - }, null, '2016-08-01'); - - console.log(tl.loc('StoppingAppService', this._getFormattedName())); - var response = await this._client.beginRequest(webRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - console.log(tl.loc('StoppedAppService', this._getFormattedName())); - } - catch(error) { - throw Error(tl.loc('FailedToStopAppService', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async restart(): Promise { - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/restart`, { - '{ResourceGroupName}': this._resourceGroup, - '{name}': this._name - }, null, '2016-08-01'); - - console.log(tl.loc('RestartingAppService', this._getFormattedName())); - var response = await this._client.beginRequest(webRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - console.log(tl.loc('RestartedAppService', this._getFormattedName())); - } - catch(error) { - throw Error(tl.loc('FailedToRestartAppService', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async swap(slotName: string, preserveVNet?: boolean): Promise { - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'POST'; - webRequest.body = JSON.stringify({ - targetSlot: slotName, - preserveVnet: preserveVNet - }); - - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/slotsswap`, { - '{ResourceGroupName}': this._resourceGroup, - '{name}': this._name, - '{slotUrl}': slotUrl - }, null, '2016-08-01'); - - console.log(tl.loc('SwappingAppServiceSlotSlots', this._name, this.getSlot(), slotName)); - var response = await this._client.beginRequest(webRequest); - if(response.statusCode == 202) { - response= await this._client.getLongRunningOperationResult(response); - } - - if(response.statusCode != 200) { - throw ToError(response); - } - - console.log(tl.loc('SwappedAppServiceSlotSlots', this._name, this.getSlot(), slotName)); - } - catch(error) { - throw Error(tl.loc('FailedToSwapAppServiceSlotSlots', this._name, this.getSlot(), slotName, this._client.getFormattedError(error))); - } - } - - public async get(force?: boolean): Promise { - if(force || !this._appServiceConfigurationDetails) { - this._appServiceConfigurationDetails = await this._get(); - } - - return this._appServiceConfigurationDetails; - } - - public async getPublishingProfileWithSecrets(force?: boolean): Promise{ - if(force || !this._appServicePublishingProfile) { - this._appServicePublishingProfile = await this._getPublishingProfileWithSecrets(); - } - - return this._appServicePublishingProfile; - } - - public async getPublishingCredentials(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/publishingcredentials/list`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServicePublishingCredentials', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async getApplicationSettings(force?: boolean): Promise { - if(force || !this._appServiceApplicationSetings) { - this._appServiceApplicationSetings = await this._getApplicationSettings(); - } - - return this._appServiceApplicationSetings; - } - - public async updateApplicationSettings(applicationSettings): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(applicationSettings); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/appsettings`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceApplicationSettings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async patchApplicationSettings(addProperties: any, deleteProperties?: any, formatJSON?: boolean): Promise { - var applicationSettings = await this.getApplicationSettings(); - var isNewValueUpdated: boolean = false; - for(var key in addProperties) { - if(formatJSON) { - if(JSON.stringify(applicationSettings.properties[key]) != JSON.stringify(addProperties[key])) { - tl.debug(`Value of ${key} has been changed to ${JSON.stringify(addProperties[key])}`); - isNewValueUpdated = true; - } - else { - tl.debug(`${key} is already present.`); - } - } - else { - if(applicationSettings.properties[key] != addProperties[key]) { - tl.debug(`Value of ${key} has been changed to ${addProperties[key]}`); - isNewValueUpdated = true; - } - else { - tl.debug(`${key} is already present.`); - } - } - - applicationSettings.properties[key] = addProperties[key]; - } - for(var key in deleteProperties) { - if(key in applicationSettings.properties) { - delete applicationSettings.properties[key]; - tl.debug(`Removing app setting : ${key}`); - isNewValueUpdated = true; - } - } - - if(isNewValueUpdated) { - applicationSettings.properties[constants.WebsiteEnableSyncUpdateSiteKey] = this._isConsumptionApp ? 'false' : 'true'; - await this.updateApplicationSettings(applicationSettings); - } - - return isNewValueUpdated; - } - - public async patchApplicationSettingsSlot(addProperties: any): Promise { - var appSettingsSlotSettings = await this.getSlotConfigurationNames(); - let appSettingNames = appSettingsSlotSettings.properties.appSettingNames; - var isNewValueUpdated: boolean = false; - for(var key in addProperties) { - if(!appSettingNames) { - appSettingsSlotSettings.properties.appSettingNames = []; - appSettingNames = appSettingsSlotSettings.properties.appSettingNames; - } - if(addProperties[key].slotSetting == true) { - if((appSettingNames.length == 0) || (!appSettingNames.includes(addProperties[key].name))) { - appSettingNames.push(addProperties[key].name); - } - tl.debug(`Slot setting updated for key : ${addProperties[key].name}`); - isNewValueUpdated = true; - } - else if ((addProperties[key].slotSetting == false || (addProperties[key].slotSetting == null)) && appSettingNames != null ) { - const index = appSettingNames.indexOf(addProperties[key].name, 0); - if (index > -1) { - appSettingNames.splice(index, 1); - } - isNewValueUpdated = true; - } - } - - if(isNewValueUpdated) { - await this.updateSlotConfigSettings(appSettingsSlotSettings); - } - - } - - public async syncFunctionTriggers(): Promise { - try { - let i = 0; - let retryCount = 5; - let retryIntervalInSeconds = 2; - let timeToWait: number = retryIntervalInSeconds; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/syncfunctiontriggers`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - while(true) { - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode == 200) { - return response.body; - } - else if(response.statusCode == 400) { - if (++i < retryCount) { - await webClient.sleepFor(timeToWait); - timeToWait = timeToWait * retryIntervalInSeconds + retryIntervalInSeconds; - continue; - } - else { - throw ToError(response); - } - } - else { - throw ToError(response); - } - } - } - catch(error) { - throw Error(tl.loc('FailedToSyncTriggers', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async getConfiguration(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/web`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2018-02-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceConfiguration', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async updateConfiguration(applicationSettings): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(applicationSettings); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/web`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2018-02-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceConfiguration', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async patchConfiguration(properties: any): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PATCH'; - httpRequest.body = JSON.stringify(properties); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/web`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2018-02-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToPatchAppServiceConfiguration', this._getFormattedName(), this._client.getFormattedError(error))); - } - - } - - public async getConnectionStrings(force?: boolean): Promise { - if(force || !this._appServiceConnectionString) { - this._appServiceConnectionString = await this._getConnectionStrings(); - } - - return this._appServiceConnectionString; - } - - public async getSlotConfigurationNames(force?: boolean): Promise { - if(force || !this._appServiceConfigurationSettings) { - this._appServiceConfigurationSettings = await this._getSlotConfigurationNames(); - } - - return this._appServiceConfigurationSettings; - } - - public async patchConnectionString(addProperties: any): Promise { - var connectionStringSettings = await this.getConnectionStrings(); - var isNewValueUpdated: boolean = false; - for(var key in addProperties) { - if(JSON.stringify(connectionStringSettings.properties[key]) != JSON.stringify(addProperties[key])) { - tl.debug(`Value of ${key} has been changed to ${JSON.stringify(addProperties[key])}`); - isNewValueUpdated = true; - } - else { - tl.debug(`${key} is already present.`); - } - connectionStringSettings.properties[key] = addProperties[key]; - } - - if(isNewValueUpdated) { - await this.updateConnectionStrings(connectionStringSettings); - } - } - - public async updateConnectionStrings(connectionStringSettings: any): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(connectionStringSettings); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/connectionstrings`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceConnectionStrings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async patchConnectionStringSlot(addProperties: any): Promise { - var connectionStringSlotSettings = await this.getSlotConfigurationNames(); - let connectionStringNames = connectionStringSlotSettings.properties.connectionStringNames; - var isNewValueUpdated: boolean = false; - for(var key in addProperties) { - if(!connectionStringNames) { - connectionStringSlotSettings.properties.connectionStringNames = []; - connectionStringNames = connectionStringSlotSettings.properties.connectionStringNames; - } - if(addProperties[key].slotSetting == true) { - if((connectionStringNames.length == 0) || (!connectionStringNames.includes(key))) { - connectionStringNames.push(key); - } - tl.debug(`Slot setting updated for key : ${key}`); - isNewValueUpdated = true; - } - } - - if(isNewValueUpdated) { - await this.updateSlotConfigSettings(connectionStringSlotSettings); - } - } - - public async updateSlotConfigSettings(SlotConfigSettings: any): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(SlotConfigSettings); - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/slotConfigNames`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceConfigSlotSettings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async getMetadata(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/metadata/list`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceMetadata', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async updateMetadata(applicationSettings): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(applicationSettings); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/metadata`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceMetadata', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async patchMetadata(properties): Promise { - var applicationSettings = await this.getMetadata(); - for(var key in properties) { - applicationSettings.properties[key] = properties[key]; - } - - await this.updateMetadata(applicationSettings); - } - - public getSlot(): string { - return this._slot ? this._slot : "production"; - } - - private async _getPublishingProfileWithSecrets(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/publishxml`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - var publishingProfile = response.body; - return publishingProfile; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServicePublishingProfile', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private async _getApplicationSettings(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/appsettings/list`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceApplicationSettings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private async _getConnectionStrings(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/connectionstrings/list`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceConnectionStrings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private async _getSlotConfigurationNames(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/slotConfigNames`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceSlotConfigurationNames', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private async _get(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - var appDetails = response.body; - return appDetails as AzureAppServiceConfigurationDetails; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceDetails', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private _getFormattedName(): string { - return this._slot ? `${this._name}-${this._slot}` : this._name; - } - - public getName(): string { - return this._name; - } - - public async getSitePublishingCredentialPolicies(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/basicPublishingCredentialsPolicies/scm`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2022-03-01'); - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retryCount = 1; - - var response = await this._client.beginRequest(httpRequest, requestOptions); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(`Failed to get SitePublishingCredentialPolicies. Error: ${this._client.getFormattedError(error)}`); - } - } - - public async getSiteVirtualNetworkConnections(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/virtualNetworkConnections`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2022-03-01'); - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retryCount = 1; - - var response = await this._client.beginRequest(httpRequest, requestOptions); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(`Failed to get Virtual Network Connections. Error: ${this._client.getFormattedError(error)}`); - } - } - - public async getSitePrivateEndpointConnections(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/privateEndpointConnections`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2022-03-01'); - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retryCount = 1; - - var response = await this._client.beginRequest(httpRequest, requestOptions); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(`Failed to get Private Endpoint Connections. Error: ${this._client.getFormattedError(error)}`); - } - } - - public async getConnectionStringValidation(connectionDetails): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.body = JSON.stringify(connectionDetails); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/extensions/DaaS/api/connectionstringvalidation/validate/`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2022-03-01'); - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retryCount = 1; - - var response = await this._client.beginRequest(httpRequest, requestOptions); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(`Failed to get Connection String Validation. Error: ${this._client.getFormattedError(error)}`); - } - } - } \ No newline at end of file diff --git a/Tasks/AzureFunctionAppV1/azurermwebappdeployment.ts b/Tasks/AzureFunctionAppV1/azurermwebappdeployment.ts index 767c93e8c89d..49b076a49ee6 100644 --- a/Tasks/AzureFunctionAppV1/azurermwebappdeployment.ts +++ b/Tasks/AzureFunctionAppV1/azurermwebappdeployment.ts @@ -1,15 +1,15 @@ import tl = require('azure-pipelines-task-lib/task'); import path = require('path'); +import * as Endpoint from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-endpoint'; import { TaskParameters, TaskParametersUtility } from './taskparameters'; import { DeploymentFactory } from './deploymentProvider/DeploymentFactory'; -import * as Endpoint from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azure-arm-endpoint'; async function main() { let isDeploymentSuccess: boolean = true; try { tl.setResourcePath(path.join( __dirname, 'task.json')); - tl.setResourcePath(path.join( __dirname, 'node_modules/azure-pipelines-tasks-azurermdeploycommon/module.json')); + tl.setResourcePath(path.join( __dirname, 'node_modules/azure-pipelines-tasks-azure-arm-rest-v2/module.json')); var taskParams: TaskParameters = await TaskParametersUtility.getParameters(); var deploymentFactory: DeploymentFactory = new DeploymentFactory(taskParams); var deploymentProvider = await deploymentFactory.GetDeploymentProvider(); diff --git a/Tasks/AzureFunctionAppV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts b/Tasks/AzureFunctionAppV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts index 2e0649121c88..be725b360f07 100644 --- a/Tasks/AzureFunctionAppV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts +++ b/Tasks/AzureFunctionAppV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts @@ -1,20 +1,22 @@ -import { IWebAppDeploymentProvider } from './IWebAppDeploymentProvider'; +import tl = require('azure-pipelines-task-lib/task'); +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; +import { Kudu } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service-kudu'; +import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azure-arm-rest-v2/constants'; +import { AzureAppServiceUtility } from 'azure-pipelines-tasks-azure-arm-rest-v2/azureAppServiceUtility'; +import { PackageUtility } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility' import { TaskParameters } from '../taskparameters'; +import { AzureAppServiceUtilityExt } from '../operations/AzureAppServiceUtilityExt'; import { KuduServiceUtility } from '../operations/KuduServiceUtility'; -import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; -import { Kudu } from '../azure-arm-rest/azure-arm-app-service-kudu'; -import { AzureAppServiceUtility } from '../operations/AzureAppServiceUtility'; -import tl = require('azure-pipelines-task-lib/task'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility' import { addReleaseAnnotation } from '../operations/ReleaseAnnotationUtility'; -import { PackageUtility } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; -import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azurermdeploycommon/Constants'; +import { IWebAppDeploymentProvider } from './IWebAppDeploymentProvider'; export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvider { protected taskParams:TaskParameters; protected appService: AzureAppService; protected kuduService: Kudu; protected appServiceUtility: AzureAppServiceUtility; + protected appServiceUtilityExt: AzureAppServiceUtilityExt; protected kuduServiceUtility: KuduServiceUtility; protected virtualApplicationPath: string = ""; protected activeDeploymentID; @@ -26,14 +28,15 @@ export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvide } public async PreDeploymentStep() { - this.appService = new AzureAppService(this.taskParams.azureEndpoint, this.taskParams.ResourceGroupName, this.taskParams.WebAppName, + this.appService = new AzureAppService(this.taskParams.azureEndpoint, this.taskParams.ResourceGroupName, this.taskParams.WebAppName, this.taskParams.SlotName, this.taskParams.WebAppKind); this.appServiceUtility = new AzureAppServiceUtility(this.appService); + this.appServiceUtilityExt = new AzureAppServiceUtilityExt(this.appService); this.kuduService = await this.appServiceUtility.getKuduService(); this.kuduServiceUtility = new KuduServiceUtility(this.kuduService); - await this.appServiceUtility.getFuntionAppNetworkingCheck(this.taskParams.isLinuxApp); + await this.appServiceUtilityExt.getFuntionAppNetworkingCheck(this.taskParams.isLinuxApp); } public async DeployWebAppStep() {} @@ -58,9 +61,9 @@ export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvide if(this.taskParams.ConfigurationSettings) { var customApplicationSettings = ParameterParser.parse(this.taskParams.ConfigurationSettings); - await this.appServiceUtility.updateConfigurationSettings(customApplicationSettings); + await this.appService.updateConfigurationSettings(customApplicationSettings); } - await this.appServiceUtility.updateScmTypeAndConfigurationDetails(); + await this.appServiceUtilityExt.updateScmTypeAndConfigurationDetails(); } } \ No newline at end of file diff --git a/Tasks/AzureFunctionAppV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts b/Tasks/AzureFunctionAppV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts index bd0aa7c467bf..011630349229 100644 --- a/Tasks/AzureFunctionAppV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts +++ b/Tasks/AzureFunctionAppV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts @@ -1,11 +1,10 @@ -import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; import tl = require('azure-pipelines-task-lib/task'); -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; import path = require('path'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility' - -var webCommonUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); +var webCommonUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility' +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; const linuxFunctionStorageSetting: string = '-WEBSITES_ENABLE_APP_SERVICE_STORAGE true'; const linuxFunctionRuntimeSettingName: string = '-FUNCTIONS_WORKER_RUNTIME '; diff --git a/Tasks/AzureFunctionAppV1/deploymentProvider/ConsumptionWebAppDeploymentProvider.ts b/Tasks/AzureFunctionAppV1/deploymentProvider/ConsumptionWebAppDeploymentProvider.ts index ecc553bd8641..b2ceeeccf51e 100644 --- a/Tasks/AzureFunctionAppV1/deploymentProvider/ConsumptionWebAppDeploymentProvider.ts +++ b/Tasks/AzureFunctionAppV1/deploymentProvider/ConsumptionWebAppDeploymentProvider.ts @@ -1,23 +1,23 @@ -import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; import tl = require('azure-pipelines-task-lib/task'); -import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; -import { AzureAppServiceUtility } from '../operations/AzureAppServiceUtility'; -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; -import { sleepFor } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'; import Q = require('q'); -var webCommonUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); +var webCommonUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); var azureStorage = require('azure-storage'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility'; +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; +import { sleepFor } from 'azure-pipelines-tasks-azure-arm-rest-v2/webClient'; +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility'; +import { AzureAppServiceUtilityExt } from '../operations/AzureAppServiceUtilityExt'; +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; export class ConsumptionWebAppDeploymentProvider extends AzureRmWebAppDeploymentProvider { public async PreDeploymentStep() { - this.appService = new AzureAppService(this.taskParams.azureEndpoint, this.taskParams.ResourceGroupName, this.taskParams.WebAppName, + this.appService = new AzureAppService(this.taskParams.azureEndpoint, this.taskParams.ResourceGroupName, this.taskParams.WebAppName, this.taskParams.SlotName, this.taskParams.WebAppKind, true); - this.appServiceUtility = new AzureAppServiceUtility(this.appService); + this.appServiceUtilityExt = new AzureAppServiceUtilityExt(this.appService); } - + public async DeployWebAppStep() { let storageDetails = await this.findStorageAccount(); let sasUrl = await this.uploadPackage(storageDetails, this.taskParams.Package); @@ -128,10 +128,10 @@ export class ConsumptionWebAppDeploymentProvider extends AzureRmWebAppDeployment protected async PostDeploymentStep() { if(this.taskParams.ConfigurationSettings) { var customApplicationSettings = ParameterParser.parse(this.taskParams.ConfigurationSettings); - await this.appServiceUtility.updateConfigurationSettings(customApplicationSettings); + await this.appService.updateConfigurationSettings(customApplicationSettings); } - await this.appServiceUtility.updateScmTypeAndConfigurationDetails(); + await this.appServiceUtilityExt.updateScmTypeAndConfigurationDetails(); } private _getUserDefinedAppSettings() { diff --git a/Tasks/AzureFunctionAppV1/deploymentProvider/DeploymentFactory.ts b/Tasks/AzureFunctionAppV1/deploymentProvider/DeploymentFactory.ts index 12e67405466b..fa8160607436 100644 --- a/Tasks/AzureFunctionAppV1/deploymentProvider/DeploymentFactory.ts +++ b/Tasks/AzureFunctionAppV1/deploymentProvider/DeploymentFactory.ts @@ -1,11 +1,11 @@ +import tl = require('azure-pipelines-task-lib/task'); +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; import { TaskParameters, DeploymentType } from '../taskparameters'; import { BuiltInLinuxWebAppDeploymentProvider } from './BuiltInLinuxWebAppDeploymentProvider'; +import { ConsumptionWebAppDeploymentProvider } from './ConsumptionWebAppDeploymentProvider'; import { IWebAppDeploymentProvider } from './IWebAppDeploymentProvider'; import { WindowsWebAppZipDeployProvider } from './WindowsWebAppZipDeployProvider'; import { WindowsWebAppRunFromZipProvider } from './WindowsWebAppRunFromZipProvider'; -import { ConsumptionWebAppDeploymentProvider } from './ConsumptionWebAppDeploymentProvider'; -import tl = require('azure-pipelines-task-lib/task'); -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; import { WindowsWebAppWarDeployProvider } from './WindowsWebAppWarDeployProvider'; export class DeploymentFactory { diff --git a/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts b/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts index b1f0bab76414..4e09e4609390 100644 --- a/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts +++ b/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts @@ -1,17 +1,18 @@ -import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; import tl = require('azure-pipelines-task-lib/task'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility' +var deployUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility' import { DeploymentType } from '../taskparameters'; -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; +import { FileTransformsUtility } from '../operations/FileTransformsUtility'; import { addReleaseAnnotation } from '../operations/ReleaseAnnotationUtility'; -import { FileTransformsUtility } from 'azure-pipelines-tasks-azurermdeploycommon/operations/FileTransformsUtility.js'; +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; + const oldRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP'; const runFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 1'; -var deployUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); export class WindowsWebAppRunFromZipProvider extends AzureRmWebAppDeploymentProvider { - + public async DeployWebAppStep() { let deploymentMethodtelemetry = '{"deploymentMethod":"Run from Package"}'; console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureWebAppDeployment]" + deploymentMethodtelemetry); diff --git a/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts b/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts index 875df08dc2b2..6f0196606728 100644 --- a/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts +++ b/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts @@ -1,29 +1,28 @@ -import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; import tl = require('azure-pipelines-task-lib/task'); -var webCommonUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); - +var webCommonUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; export class WindowsWebAppWarDeployProvider extends AzureRmWebAppDeploymentProvider { - + private zipDeploymentID: string; public async DeployWebAppStep() { tl.debug("Initiated deployment via kudu service for webapp war package : "+ this.taskParams.Package.getPath()); - + let deploymentMethodtelemetry = '{"deploymentMethod":"War Deploy"}'; console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureWebAppDeployment]" + deploymentMethodtelemetry); await this.kuduServiceUtility.warmpUp(); - + var warName = webCommonUtility.getFileNameFromPath(this.taskParams.Package.getPath(), ".war"); - this.zipDeploymentID = await this.kuduServiceUtility.deployUsingWarDeploy(this.taskParams.Package.getPath(), + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingWarDeploy(this.taskParams.Package.getPath(), { slotName: this.appService.getSlot() }, warName); await this.PostDeploymentStep(); } - + public async UpdateDeploymentStatus(isDeploymentSuccess: boolean) { if(this.kuduServiceUtility) { await super.UpdateDeploymentStatus(isDeploymentSuccess); diff --git a/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts b/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts index b16e28d21778..761cb875b1e0 100644 --- a/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts +++ b/Tasks/AzureFunctionAppV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts @@ -1,21 +1,22 @@ -import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; import tl = require('azure-pipelines-task-lib/task'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility' +var deployUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility' import { DeploymentType } from '../taskparameters'; -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; -import { FileTransformsUtility } from 'azure-pipelines-tasks-azurermdeploycommon/operations/FileTransformsUtility.js'; +import { FileTransformsUtility } from '../operations/FileTransformsUtility'; +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; + const removeRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP -WEBSITE_RUN_FROM_PACKAGE'; -var deployUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvider { - + private zipDeploymentID: string; - + public async DeployWebAppStep() { let deploymentMethodtelemetry = '{"deploymentMethod":"Zip Deploy"}'; console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureWebAppDeployment]" + deploymentMethodtelemetry); - + var webPackage = await FileTransformsUtility.applyTransformations(this.taskParams.Package.getPath(), this.taskParams.WebConfigParameters, this.taskParams.Package.getPackageType()); if(this.taskParams.DeploymentType === DeploymentType.zipDeploy) { diff --git a/Tasks/AzureFunctionAppV1/make.json b/Tasks/AzureFunctionAppV1/make.json index 65aef0088694..8733fe153102 100644 --- a/Tasks/AzureFunctionAppV1/make.json +++ b/Tasks/AzureFunctionAppV1/make.json @@ -1,4 +1,12 @@ { + "rm": [ + { + "items": [ + "node_modules/azure-pipelines-tasks-azure-arm-rest-v2/node_modules/azure-pipelines-task-lib" + ], + "options": "-Rf" + } + ], "externals": { "archivePackages": [ { diff --git a/Tasks/AzureFunctionAppV1/operations/AzureAppServiceUtility.ts b/Tasks/AzureFunctionAppV1/operations/AzureAppServiceUtilityExt.ts similarity index 56% rename from Tasks/AzureFunctionAppV1/operations/AzureAppServiceUtility.ts rename to Tasks/AzureFunctionAppV1/operations/AzureAppServiceUtilityExt.ts index 6b027f5522b0..6c1cda775605 100644 --- a/Tasks/AzureFunctionAppV1/operations/AzureAppServiceUtility.ts +++ b/Tasks/AzureFunctionAppV1/operations/AzureAppServiceUtilityExt.ts @@ -1,14 +1,10 @@ import tl = require('azure-pipelines-task-lib/task'); -import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; -import webClient = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'); -var parseString = require('xml2js').parseString; -import Q = require('q'); -import { Kudu } from '../azure-arm-rest/azure-arm-app-service-kudu'; -import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azurermdeploycommon/Constants'; -import * as os from "os"; var glob = require("glob"); +import * as os from "os"; +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; +import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azure-arm-rest-v2/constants'; -export class AzureAppServiceUtility { +export class AzureAppServiceUtilityExt { private _appService: AzureAppService; constructor(appService: AzureAppService) { this._appService = appService; @@ -61,169 +57,6 @@ export class AzureAppServiceUtility { } } - public async getWebDeployPublishingProfile(): Promise { - var publishingProfile = await this._appService.getPublishingProfileWithSecrets(); - var defer = Q.defer(); - parseString(publishingProfile, (error, result) => { - if(!!error) { - defer.reject(error); - } - var publishProfile = result && result.publishData && result.publishData.publishProfile ? result.publishData.publishProfile : null; - if(publishProfile) { - for (var index in publishProfile) { - if (publishProfile[index].$ && publishProfile[index].$.publishMethod === "MSDeploy") { - defer.resolve(result.publishData.publishProfile[index].$); - } - } - } - - defer.reject(tl.loc('ErrorNoSuchDeployingMethodExists')); - }); - - return defer.promise; - } - - public async getApplicationURL(virtualApplication?: string): Promise { - let webDeployProfile: any = await this.getWebDeployPublishingProfile(); - return await webDeployProfile.destinationAppUrl + ( virtualApplication ? "/" + virtualApplication : "" ); - } - - public async pingApplication(): Promise { - try { - var applicationUrl: string = await this.getApplicationURL(); - - if(!applicationUrl) { - tl.debug("Application Url not found."); - return; - } - await AzureAppServiceUtility.pingApplication(applicationUrl); - } catch(error) { - tl.debug("Unable to ping App Service. Error: ${error}"); - } - } - - public static async pingApplication(applicationUrl: string) { - if(!applicationUrl) { - tl.debug('Application Url empty.'); - return; - } - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'GET'; - webRequest.uri = applicationUrl; - let webRequestOptions: webClient.WebRequestOptions = {retriableErrorCodes: [], retriableStatusCodes: [], retryCount: 1, retryIntervalInSeconds: 5, retryRequestTimedout: true}; - var response = await webClient.sendRequest(webRequest, webRequestOptions); - tl.debug(`App Service status Code: '${response.statusCode}'. Status Message: '${response.statusMessage}'`); - } - catch(error) { - tl.debug(`Unable to ping App Service. Error: ${error}`); - } - } - - public async getKuduService(): Promise { - var publishingCredentials = await this._appService.getPublishingCredentials(); - var scmPolicyCheck = await this.isSitePublishingCredentialsEnabled(); - - - if(publishingCredentials.properties["scmUri"]) { - if(scmPolicyCheck === false) { - tl.debug('Gettting Bearer token'); - var accessToken = await this._appService._client.getCredentials().getToken(); - } - else{ - tl.setVariable(`AZURE_APP_SERVICE_KUDU_${this._appService.getSlot()}_PASSWORD`, publishingCredentials.properties["publishingPassword"], true); - var accessToken = (new Buffer(publishingCredentials.properties["publishingUserName"] + ':' + publishingCredentials.properties["publishingPassword"]).toString('base64')); - } - return new Kudu(publishingCredentials.properties["scmUri"], accessToken, scmPolicyCheck); - } - - throw Error(tl.loc('KuduSCMDetailsAreEmpty')); - } - - public async getPhysicalPath(virtualApplication: string): Promise { - - if(!virtualApplication) { - return '/site/wwwroot'; - } - - virtualApplication = (virtualApplication.startsWith("/")) ? virtualApplication.substr(1) : virtualApplication; - - var physicalToVirtualPathMap = await this._getPhysicalToVirtualPathMap(virtualApplication); - - if(!physicalToVirtualPathMap) { - throw Error(tl.loc("VirtualApplicationDoesNotExist", virtualApplication)); - } - - tl.debug(`Virtual Application Map: Physical path: '${physicalToVirtualPathMap.physicalPath}'. Virtual path: '${physicalToVirtualPathMap.virtualPath}'.`); - return physicalToVirtualPathMap.physicalPath; - } - - public async updateConfigurationSettings(properties: any, formatJSON?: boolean) : Promise { - if(formatJSON) { - var configurationSettingsProperties = properties[0]; - console.log(tl.loc('UpdatingAppServiceConfigurationSettings', JSON.stringify(configurationSettingsProperties))); - await this._appService.patchConfiguration({'properties': configurationSettingsProperties}); - } - else - { - for(var property in properties) { - if(!!properties[property] && properties[property].value !== undefined) { - properties[property] = properties[property].value; - } - } - - console.log(tl.loc('UpdatingAppServiceConfigurationSettings', JSON.stringify(properties))); - await this._appService.patchConfiguration({'properties': properties}); - } - console.log(tl.loc('UpdatedAppServiceConfigurationSettings')); - } - - public async updateAndMonitorAppSettings(addProperties?: any, deleteProperties?: any, formatJSON?: boolean): Promise { - if(formatJSON) { - var appSettingsProperties = {}; - for(var property in addProperties) { - appSettingsProperties[addProperties[property].name] = addProperties[property].value; - } - - if(!!addProperties) { - console.log(tl.loc('UpdatingAppServiceApplicationSettings', JSON.stringify(appSettingsProperties))); - } - - if(!!deleteProperties) { - console.log(tl.loc('DeletingAppServiceApplicationSettings', JSON.stringify(Object.keys(deleteProperties)))); - } - - var isNewValueUpdated: boolean = await this._appService.patchApplicationSettings(appSettingsProperties, deleteProperties, true); - } - else { - for(var property in addProperties) { - if(!!addProperties[property] && addProperties[property].value !== undefined) { - addProperties[property] = addProperties[property].value; - } - } - - if(!!addProperties) { - console.log(tl.loc('UpdatingAppServiceApplicationSettings', JSON.stringify(addProperties))); - } - - if(!!deleteProperties) { - console.log(tl.loc('DeletingAppServiceApplicationSettings', JSON.stringify(Object.keys(deleteProperties)))); - } - - var isNewValueUpdated: boolean = await this._appService.patchApplicationSettings(addProperties, deleteProperties); - } - - if(!!isNewValueUpdated) { - console.log(tl.loc('UpdatedAppServiceApplicationSettings')); - } - else { - console.log(tl.loc('AppServiceApplicationSettingsAlreadyPresent')); - } - - await this._appService.patchApplicationSettingsSlot(addProperties); - return isNewValueUpdated; - } - public async updateConnectionStrings(addProperties: any): Promise { var connectionStringProperties = {}; for(var property in addProperties) { @@ -251,69 +84,13 @@ export class AzureAppServiceUtility { return isNewValueUpdated; } - public async enableRenameLockedFiles(): Promise { - try { - var webAppSettings = await this._appService.getApplicationSettings(); - if(webAppSettings && webAppSettings.properties) { - if(webAppSettings.properties.MSDEPLOY_RENAME_LOCKED_FILES !== '1') { - tl.debug(`Rename locked files value found to be ${webAppSettings.properties.MSDEPLOY_RENAME_LOCKED_FILES}. Updating the value to 1`); - await this.updateAndMonitorAppSettings({ 'MSDEPLOY_RENAME_LOCKED_FILES' : '1' }); - console.log(tl.loc('RenameLockedFilesEnabled')); - } - else { - tl.debug('Rename locked files is already enabled in App Service'); - } - } - } - catch(error) { - throw new Error(tl.loc('FailedToEnableRenameLockedFiles', error)); - } - } - - public async updateStartupCommandAndRuntimeStack(runtimeStack: string, startupCommand?: string): Promise { - var configDetails = await this._appService.getConfiguration(); - var appCommandLine: string = configDetails.properties.appCommandLine; - startupCommand = (!!startupCommand) ? startupCommand : appCommandLine; - var linuxFxVersion: string = configDetails.properties.linuxFxVersion; - runtimeStack = (!!runtimeStack) ? runtimeStack : linuxFxVersion; - - if (startupCommand != appCommandLine || runtimeStack != linuxFxVersion) { - await this.updateConfigurationSettings({linuxFxVersion: runtimeStack, appCommandLine: startupCommand}); - } - else { - tl.debug(`Skipped updating the values. linuxFxVersion: ${linuxFxVersion} : appCommandLine: ${appCommandLine}`) - } - } - - private async _getPhysicalToVirtualPathMap(virtualApplication: string): Promise { - // construct URL depending on virtualApplication or root of webapplication - var physicalPath = null; - var virtualPath = "/" + virtualApplication; - var appConfigSettings = await this._appService.getConfiguration(); - var virtualApplicationMappings = appConfigSettings.properties && appConfigSettings.properties.virtualApplications; - - if(virtualApplicationMappings) { - for( var mapping of virtualApplicationMappings ) { - if(mapping.virtualPath.toLowerCase() == virtualPath.toLowerCase()) { - physicalPath = mapping.physicalPath; - break; - } - } - } - - return physicalPath ? { - 'virtualPath': virtualPath, - 'physicalPath': physicalPath - }: null; - } - private _getNewMetadata(): any { var collectionUri = tl.getVariable("system.teamfoundationCollectionUri"); var projectId = tl.getVariable("system.teamprojectId"); var releaseDefinitionId = tl.getVariable("release.definitionId"); // Log metadata properties based on whether task is running in build OR release. - + let newProperties = { VSTSRM_ProjectId: projectId, VSTSRM_AccountId: tl.getVariable("system.collectionId") @@ -323,7 +100,7 @@ export class AzureAppServiceUtility { // Task is running in Release var artifactAlias = tl.getVariable(AzureDeployPackageArtifactAlias); tl.debug("Artifact Source Alias is: "+ artifactAlias); - + let buildDefinitionUrl = ""; let buildDefintionId = ""; @@ -345,7 +122,7 @@ export class AzureAppServiceUtility { buildDefinitionUrl = collectionUri + buildProjectId + "/_build?_a=simple-process&definitionId=" + buildDefintionId; } } - + newProperties["VSTSRM_BuildDefinitionId"] = buildDefintionId; newProperties["VSTSRM_ReleaseDefinitionId"] = releaseDefinitionId; newProperties["VSTSRM_BuildDefinitionWebAccessUrl"] = buildDefinitionUrl; @@ -367,27 +144,27 @@ export class AzureAppServiceUtility { try{ let isFuncPrivate = await this.isFuncWithPrivateEndpoint(); let isMicrosoftHostedAgent = await this.isMicrosoftHostedAgent(); - + if (isFuncPrivate == "true" && isMicrosoftHostedAgent == "true"){ //will NOT be able to reach kudu site if isFuncPrivate and isMicrosoftHostedAgent tl.warning("ERROR: Function app has private endpoint(s). But you are not running this pipeline from a self-hosted agent that has access to the Functions App. Relevant documentation: " + "https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser#install"); } - else if (isFuncPrivate == "true"){ + else if (isFuncPrivate == "true"){ //just FYI console.log("NOTE: Function app has private endpoint(s). Therefore, make sure that you are running this pipeline from a self-hosted agent that has access to the Functions App."); } - + let isFuncVNet = await this.isFuncVnetIntegrated(); if (isFuncVNet == "true"){ //just FYI console.log("NOTE: Function app is VNet integrated."); } - + //network validation only avaliable for Windows (NOT Linux) if (!isLinuxApp) { let errormessage = await this.isAzureWebJobsStorageAccessible(); - + if (errormessage){ //AzureWebJobsStorage connection string is NOT accessible from Kudu tl.warning(`ERROR: ${errormessage}`); @@ -396,12 +173,12 @@ export class AzureAppServiceUtility { if (isFuncVNet == "false"){ console.log("NOTE: Function app is NOT VNet integrated."); } - } - } + } + } } catch(error){ tl.debug(`Skipping networking check with error: ${error}`); - } + } } public async isFuncWithPrivateEndpoint(): Promise{ @@ -412,7 +189,7 @@ export class AzureAppServiceUtility { tl.debug("Function app has Private Endpoints."); return "true"; } - else { + else { tl.debug("Function app has NO Private Endpoints."); return "false"; } @@ -420,47 +197,28 @@ export class AzureAppServiceUtility { catch(error){ tl.debug(`Skipping private endpoint check: ${error}`); return null; - } + } } public async isFuncVnetIntegrated(): Promise{ try{ let vnet: any = await this._appService.getSiteVirtualNetworkConnections(); tl.debug(`VNET check: ${JSON.stringify(vnet)}`); - if (vnet && vnet.length && vnet.length > 0){ + if (vnet && vnet.length && vnet.length > 0){ tl.debug("Function app is VNet integrated."); return "true"; } - else { + else { tl.debug("Function app is NOT VNet integrated."); return "false"; - } + } } catch(error){ tl.debug(`Skipping VNET check: ${error}`); return null; - } - } - - public async isSitePublishingCredentialsEnabled(): Promise{ - try{ - let scmAuthPolicy: any = await this._appService.getSitePublishingCredentialPolicies(); - tl.debug(`Site Publishing Policy check: ${JSON.stringify(scmAuthPolicy)}`); - if(scmAuthPolicy && scmAuthPolicy.properties.allow) { - tl.debug("Function App does allow SCM access"); - return true; - } - else { - tl.debug("Function App does not allow SCM Access"); - return false; - } - } - catch(error){ - tl.debug(`Call to get SCM Policy check failed: ${error}`); - return false; } } - + public async isMicrosoftHostedAgent(): Promise{ try{ let agentos = os.type(); @@ -468,10 +226,10 @@ export class AzureAppServiceUtility { if (agentos.match(/^Window/)){ tl.debug(`Windows Agent`); - dir = "C:\\agents\\*\\.setup_info"; + dir = "C:\\agents\\*\\.setup_info"; } - else if (agentos.match(/^Linux/)){ - tl.debug(`Linux Agent`); + else if (agentos.match(/^Linux/)){ + tl.debug(`Linux Agent`); dir = `${process.env.HOME}/agents/*/.setup_info`; } else if (agentos.match(/^Darwin/)){ @@ -479,7 +237,7 @@ export class AzureAppServiceUtility { dir = `${process.env.HOME}/runners/*/.setup_info`; } - var files = glob.sync(dir); + var files = glob.sync(dir); if (files && files.length && files.length > 0) { tl.debug(`Running on Microsoft-hosted agent.`); return "true"; @@ -492,16 +250,16 @@ export class AzureAppServiceUtility { } } - public async isAzureWebJobsStorageAccessible(): Promise{ + public async isAzureWebJobsStorageAccessible(): Promise{ let errormessage = ""; let propertyName = "AzureWebJobsStorage"; let appSettings = await this._appService.getApplicationSettings(); if(appSettings && appSettings.properties && appSettings.properties.AzureWebJobsStorage) { let connectionDetails = {}; - connectionDetails['ConnectionString'] = appSettings.properties.AzureWebJobsStorage; + connectionDetails['ConnectionString'] = appSettings.properties.AzureWebJobsStorage; connectionDetails['Type'] = 'StorageAccount'; - + if(connectionDetails['ConnectionString'].includes('@Microsoft.KeyVault')){ console.log("NOTE: Skipping AzureWebJobsStorage connection string validation since Key Vault reference is used."); } @@ -523,7 +281,7 @@ export class AzureAppServiceUtility { * MalformedConnectionString, * UnknownError */ - if (validation && validation.StatusText && validation.StatusText != "Success"){ + if (validation && validation.StatusText && validation.StatusText != "Success"){ switch (validation.StatusText) { case "MalformedConnectionString": @@ -540,8 +298,8 @@ export class AzureAppServiceUtility { break; case "Forbidden": // Some authentication failures come through as Forbidden so check the exception data - if(validation.Exception != undefined && - validation.Exception.RequestInformation != undefined && + if(validation.Exception != undefined && + validation.Exception.RequestInformation != undefined && JSON.stringify(validation.Exception.RequestInformation).includes("AuthenticationFailed")) { errormessage = `Authentication failure - The credentials in the "${propertyName}" connection string are either invalid or expired. Please update the app setting "${propertyName}" with a valid connection string.`; } else { @@ -555,9 +313,9 @@ export class AzureAppServiceUtility { } // Show the exception message as it contains useful information to fix the issue. Don't show it unless its accompanied with other explanations. errormessage += (errormessage != "" && validation.Exception ? `\r\n\r\nException encountered while connecting: ${validation.Exception.Message}` : undefined); - } + } } - } - return errormessage; + } + return errormessage; } } \ No newline at end of file diff --git a/Tasks/AzureFunctionAppV1/operations/FileTransformsUtility.ts b/Tasks/AzureFunctionAppV1/operations/FileTransformsUtility.ts new file mode 100644 index 000000000000..fdf1fef18a03 --- /dev/null +++ b/Tasks/AzureFunctionAppV1/operations/FileTransformsUtility.ts @@ -0,0 +1,29 @@ +import tl = require('azure-pipelines-task-lib/task'); +var deployUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var generateWebConfigUtil = require('azure-pipelines-tasks-webdeployment-common/webconfigutil'); +import { parse } from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility'; +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; + +export class FileTransformsUtility { + private static rootDirectoryPath: string = "D:\\home\\site\\wwwroot"; + public static async applyTransformations(webPackage: string, parameters: string, packageType: PackageType): Promise { + tl.debug("WebConfigParameters is "+ parameters); + if (parameters) { + var isFolderBasedDeployment: boolean = tl.stats(webPackage).isDirectory(); + var folderPath = await deployUtility.generateTemporaryFolderForDeployment(isFolderBasedDeployment, webPackage, packageType); + if (parameters) { + tl.debug('parsing web.config parameters'); + var webConfigParameters = parse(parameters); + generateWebConfigUtil.addWebConfigFile(folderPath, webConfigParameters, this.rootDirectoryPath); + } + + var output = await deployUtility.archiveFolderForDeployment(isFolderBasedDeployment, folderPath); + webPackage = output.webDeployPkg; + } + else { + tl.debug('File Tranformation not enabled'); + } + + return webPackage; + } +} \ No newline at end of file diff --git a/Tasks/AzureFunctionAppV1/operations/KuduServiceUtility.ts b/Tasks/AzureFunctionAppV1/operations/KuduServiceUtility.ts index b6a165a4a2e9..c2b9d790c135 100644 --- a/Tasks/AzureFunctionAppV1/operations/KuduServiceUtility.ts +++ b/Tasks/AzureFunctionAppV1/operations/KuduServiceUtility.ts @@ -1,15 +1,11 @@ import tl = require('azure-pipelines-task-lib/task'); -import Q = require('q'); import path = require('path'); +import webClient = require('azure-pipelines-tasks-azure-arm-rest-v2/webClient'); +var deployUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); +import { Kudu } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service-kudu'; +import { AzureDeployPackageArtifactAlias, KUDU_DEPLOYMENT_CONSTANTS } from 'azure-pipelines-tasks-azure-arm-rest-v2/constants'; -import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azurermdeploycommon/Constants'; -import { KUDU_DEPLOYMENT_CONSTANTS } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/constants'; -import { Kudu } from '../azure-arm-rest/azure-arm-app-service-kudu'; - -import webClient = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'); - -var deployUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); const physicalRootPath: string = '/site/wwwroot'; const deploymentFolder: string = 'site/deployments'; const manifestFileName: string = 'manifest'; @@ -18,7 +14,6 @@ const VSTS_DEPLOY: string = 'VSTS_FUNCTIONS_V1'; export class KuduServiceUtility { private _appServiceKuduService: Kudu; - private _deploymentID: string; constructor(kuduService: Kudu) { this._appServiceKuduService = kuduService; @@ -42,27 +37,8 @@ export class KuduServiceUtility { } public getDeploymentID(): string { - if(this._deploymentID) { - return this._deploymentID; - } - - var buildUrl = tl.getVariable('build.buildUri'); - var releaseUrl = tl.getVariable('release.releaseUri'); - var buildId = tl.getVariable('build.buildId'); var releaseId = tl.getVariable('release.releaseId'); - - var buildNumber = tl.getVariable('build.buildNumber'); - var releaseName = tl.getVariable('release.releaseName'); - - var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); - var teamProject = tl.getVariable('system.teamProjectId'); - - var commitId = tl.getVariable('build.sourceVersion'); - var repoName = tl.getVariable('build.repository.name'); - var repoProvider = tl.getVariable('build.repository.provider'); - - var buildOrReleaseUrl = "" ; var deploymentID: string = (releaseId ? releaseId : buildId) + Date.now().toString(); return deploymentID; } @@ -113,7 +89,7 @@ export class KuduServiceUtility { return deploymentDetails.id; } catch(error) { - let stackTraceUrl:string = this._appServiceKuduService.getKuduStackTrace(); + let stackTraceUrl:string = this._appServiceKuduService.getKuduStackTraceUrl(); tl.error(tl.loc('PackageDeploymentFailed')); tl.error(tl.loc('KuduStackTraceURL', stackTraceUrl)); throw Error(error); @@ -136,7 +112,7 @@ export class KuduServiceUtility { console.log("NOTE: Run From Package makes wwwroot read-only, so you will receive an error when writing files to this directory."); } catch(error) { - let stackTraceUrl:string = this._appServiceKuduService.getKuduStackTrace(); + let stackTraceUrl:string = this._appServiceKuduService.getKuduStackTraceUrl(); tl.error(tl.loc('PackageDeploymentFailed')); tl.error(tl.loc('KuduStackTraceURL', stackTraceUrl)); throw Error(error); @@ -232,81 +208,6 @@ export class KuduServiceUtility { } } - private async _printPostDeploymentLogs(physicalPath: string) : Promise { - var stdoutLog = await this._appServiceKuduService.getFileContent(physicalPath, 'stdout.txt'); - var stderrLog = await this._appServiceKuduService.getFileContent(physicalPath, 'stderr.txt'); - var scriptReturnCode = await this._appServiceKuduService.getFileContent(physicalPath, 'script_result.txt'); - - if(scriptReturnCode == null) { - throw new Error('File not found in Kudu Service. ' + 'script_result.txt'); - } - - if(stdoutLog) { - console.log(tl.loc('stdoutFromScript')); - console.log(stdoutLog); - } - if(stderrLog) { - console.log(tl.loc('stderrFromScript')); - if(scriptReturnCode != '0') { - tl.error(stderrLog); - throw Error(tl.loc('ScriptExecutionOnKuduFailed', scriptReturnCode, stderrLog)); - } - else { - console.log(stderrLog); - } - } - } - - private async runCommand(physicalPath: string, command: string, timeOutInMinutes?: number, pollFolderPath?: string, pollFile?: string): Promise { - try { - await this._appServiceKuduService.runCommand(physicalPath, command); - } - catch(error) { - if(!!pollFolderPath && !!pollFile && timeOutInMinutes > 0 && error.toString().indexOf('Request timeout: /api/command') != -1) { - tl.debug('Request timeout occurs. Trying to poll for file: ' + pollFile); - await this._pollForFile(pollFolderPath, pollFile, timeOutInMinutes); - } - else { - if(typeof error.valueOf() == 'string') { - throw error; - } - - throw `${error.statusCode} - ${error.statusMessage}`; - } - } - } - - private _getPostDeploymentScript(scriptType, inlineScript, scriptPath, isLinux): any { - if(scriptType === 'Inline Script') { - tl.debug('creating kuduPostDeploymentScript_local file'); - var scriptFilePath = path.join(tl.getVariable('AGENT.TEMPDIRECTORY'), isLinux ? 'kuduPostDeploymentScript_local.sh' : 'kuduPostDeploymentScript_local.cmd'); - tl.writeFile(scriptFilePath, inlineScript); - tl.debug('Created temporary script file : ' + scriptFilePath); - return { - "filePath": scriptFilePath, - "isCreated": true - }; - } - if(!tl.exist(scriptPath)) { - throw Error(tl.loc('ScriptFileNotFound', scriptPath)); - } - var scriptExtension = path.extname(scriptPath); - if(isLinux){ - if(scriptExtension != '.sh'){ - throw Error(tl.loc('InvalidScriptFile', scriptPath)); - } - } else { - if(scriptExtension != '.bat' && scriptExtension != '.cmd') { - throw Error(tl.loc('InvalidScriptFile', scriptPath)); - } - } - tl.debug('postDeployment script path to execute : ' + scriptPath); - return { - filePath: scriptPath, - isCreated: false - } - } - private async _warFileDeployment(packagePath: string, physicalPath: string, virtualPath?: string): Promise { tl.debug('WAR: webAppPackage = ' + packagePath); let warFile = path.basename(packagePath.slice(0, packagePath.length - '.war'.length)); @@ -317,7 +218,6 @@ export class KuduServiceUtility { physicalPath = physicalPath + "/webapps/" + warFile; await this.createPathIfRequired(physicalPath); return physicalPath; - } private async _appOfflineKuduService(physicalPath: string, enableFeature: boolean): Promise { @@ -335,44 +235,13 @@ export class KuduServiceUtility { } } - private async _pollForFile(physicalPath: string, fileName: string, timeOutInMinutes: number): Promise { - var attempts: number = 0; - const retryInterval: number = 10; - if(tl.getVariable('appservicedeploy.retrytimeout')) { - timeOutInMinutes = Number(tl.getVariable('appservicedeploy.retrytimeout')); - tl.debug('Retry timeout in minutes provided by user: ' + timeOutInMinutes); - } - - var timeOutInSeconds = timeOutInMinutes * 60; - var noOfRetry = timeOutInSeconds / retryInterval; - - tl.debug(`Polling started for file: ${fileName} with retry count: ${noOfRetry}`); - - while (attempts < noOfRetry) { - attempts += 1; - var fileContent: string = await this._appServiceKuduService.getFileContent(physicalPath, fileName); - if(fileContent == null) { - tl.debug('File: ' + fileName + ' not found. retry after 5 seconds. Attempt: ' + attempts); - await webClient.sleepFor(5); - } - else { - tl.debug('Found file: ' + fileName); - return ; - } - } - - if(attempts == noOfRetry) { - throw new Error(tl.loc('PollingForFileTimeOut')); - } - } - private _getUpdateHistoryRequest(isDeploymentSuccess: boolean, deploymentID?: string, customMessage?: any): any { - + var artifactAlias = tl.getVariable(AzureDeployPackageArtifactAlias); var status = isDeploymentSuccess ? KUDU_DEPLOYMENT_CONSTANTS.SUCCESS : KUDU_DEPLOYMENT_CONSTANTS.FAILED; var releaseId = tl.getVariable('release.releaseId'); var releaseName = tl.getVariable('release.releaseName'); - var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); + var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); var teamProject = tl.getVariable('system.teamProjectId'); let buildId = '', buildNumber = '', buildProject = '', commitId = '', repoProvider = '', repoName = '', branch = '', repositoryUrl = '', author = ''; diff --git a/Tasks/AzureFunctionAppV1/operations/ReleaseAnnotationUtility.ts b/Tasks/AzureFunctionAppV1/operations/ReleaseAnnotationUtility.ts index 569ee785128a..56998219c1ad 100644 --- a/Tasks/AzureFunctionAppV1/operations/ReleaseAnnotationUtility.ts +++ b/Tasks/AzureFunctionAppV1/operations/ReleaseAnnotationUtility.ts @@ -1,7 +1,7 @@ import tl = require('azure-pipelines-task-lib/task'); -import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; -import { AzureApplicationInsights, ApplicationInsightsResources} from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azure-arm-appinsights'; -import { AzureEndpoint } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azureModels'; +import { AzureApplicationInsights, ApplicationInsightsResources} from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-appinsights'; +import { AzureEndpoint } from 'azure-pipelines-tasks-azure-arm-rest-v2/azureModels'; +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; var uuidV4 = require("uuid/v4"); diff --git a/Tasks/AzureFunctionAppV1/package-lock.json b/Tasks/AzureFunctionAppV1/package-lock.json index 5144d378a324..42888965e5fc 100644 --- a/Tasks/AzureFunctionAppV1/package-lock.json +++ b/Tasks/AzureFunctionAppV1/package-lock.json @@ -4,6 +4,28 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@azure/msal-common": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-9.1.1.tgz", + "integrity": "sha512-we9xR8lvu47fF0h+J8KyXoRy9+G/fPzm3QEa2TrdR3jaVS3LKAyE2qyMuUkNdbVkvzl8Zr9f7l+IUSP22HeqXw==" + }, + "@azure/msal-node": { + "version": "1.14.5", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.5.tgz", + "integrity": "sha512-NcVdMfn8Z3ogN+9RjOSF7uwf2Gki5DEJl0BdDSL83KUAgVAobtkZi5W8EqxbJLrTO/ET0jv5DregrcR5qg2pEA==", + "requires": { + "@azure/msal-common": "^9.0.1", + "jsonwebtoken": "^8.5.1", + "uuid": "^8.3.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, "@types/concat-stream": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", @@ -15,7 +37,15 @@ "@types/form-data": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "requires": { + "@types/node": "*" + } + }, + "@types/jsonwebtoken": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", + "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", "requires": { "@types/node": "*" } @@ -40,11 +70,20 @@ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, + "@xmldom/xmldom": { + "version": "git+https://github.com/xmldom/xmldom.git#238b1ea8431fae8817812c68d55b4933248af07e", + "from": "git+https://github.com/xmldom/xmldom.git#0.8.6" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -56,25 +95,10 @@ "uri-js": "^4.2.2" } }, - "archiver": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz", - "integrity": "sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=", - "requires": { - "archiver-utils": "^1.3.0", - "async": "^2.0.0", - "buffer-crc32": "^0.2.1", - "glob": "^7.0.0", - "lodash": "^4.8.0", - "readable-stream": "^2.0.0", - "tar-stream": "^1.5.0", - "zip-stream": "^1.2.0" - } - }, "archiver-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", - "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "integrity": "sha512-h+hTREBXcW5e1L9RihGXdH4PHHdGipG/jE2sMZrqIH6BmZAxeGU5IWjVsKhokdCSWX7km6Kkh406zZNEElHFPQ==", "requires": { "glob": "^7.0.0", "graceful-fs": "^4.1.0", @@ -87,7 +111,7 @@ "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "asn1": { "version": "0.2.6", @@ -110,6 +134,14 @@ "lodash": "^4.17.14" } }, + "async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", + "requires": { + "tslib": "^2.4.0" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -125,16 +157,25 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, + "azure-devops-node-api": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz", + "integrity": "sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA==", + "requires": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, "azure-pipelines-task-lib": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.1.10.tgz", - "integrity": "sha512-S5iH1mD9G7boOV0kjVsFkqlz/6FOZjQAajshj3ajzQK9Wr3XRq9JK9+grJP4ityG6of28X2XWpieFdJLhnWLoA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.4.0.tgz", + "integrity": "sha512-3eC4OTFw+7xD7A2aUhxR/j+jRlTI+vVfS0CGxt1pCLs4c/KmY0tQWgbqjD3157kmiucWxELBvgZHaD2gCBe9fg==", "requires": { - "minimatch": "3.0.4", - "mockery": "^1.7.0", + "minimatch": "3.0.5", + "mockery": "^2.1.0", "q": "^1.5.1", "semver": "^5.1.0", - "shelljs": "^0.8.4", + "shelljs": "^0.8.5", "sync-request": "6.1.0", "uuid": "^3.0.1" }, @@ -142,34 +183,144 @@ "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" } } }, - "azure-pipelines-tasks-azurermdeploycommon": { - "version": "3.207.0", - "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-azurermdeploycommon/-/azure-pipelines-tasks-azurermdeploycommon-3.207.0.tgz", - "integrity": "sha512-eGq/1x0yOkMw6bAZxJSN+PaIjmJgJbnEySljXdQsyQ8oBU5u442EGAC6PNa7tHCYcNf5el5cm2rhyhKeY2AQFQ==", + "azure-pipelines-tasks-azure-arm-rest-v2": { + "version": "3.221.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-azure-arm-rest-v2/-/azure-pipelines-tasks-azure-arm-rest-v2-3.221.1.tgz", + "integrity": "sha512-ku1bb4n9+udPPUQj+xRCmEiVsq4ZY96KH99gPJE36WPtjWsUH38ZwPbby2juKN2H6SLuPfCMtIby7WEjGsNRDQ==", "requires": { + "@azure/msal-node": "1.14.5", + "@types/jsonwebtoken": "^8.5.8", "@types/mocha": "^5.2.7", "@types/node": "^10.17.0", - "@types/q": "1.0.7", - "archiver": "2.1.1", - "azure-pipelines-task-lib": "^3.1.0", - "decompress-zip": "^0.3.3", - "jsonwebtoken": "7.3.0", - "ltx": "2.6.2", - "node-stream-zip": "1.7.0", + "@types/q": "1.5.4", + "async-mutex": "^0.4.0", + "azure-devops-node-api": "^12.0.0", + "azure-pipelines-task-lib": "^3.4.0", + "https-proxy-agent": "^4.0.0", + "jsonwebtoken": "^8.5.1", + "node-fetch": "^2.6.7", "q": "1.5.1", - "typed-rest-client": "^1.8.4", - "winreg": "1.2.2", + "typed-rest-client": "1.8.4", "xml2js": "0.4.13" }, "dependencies": { + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" + }, + "azure-devops-node-api": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.0.0.tgz", + "integrity": "sha512-S6Il++7dQeMlZDokBDWw7YVoPeb90tWF10pYxnoauRMnkuL91jq9M7SOYRVhtO3FUC5URPkB/qzGa7jTLft0Xw==", + "requires": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "azure-pipelines-task-lib": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.4.0.tgz", + "integrity": "sha512-3eC4OTFw+7xD7A2aUhxR/j+jRlTI+vVfS0CGxt1pCLs4c/KmY0tQWgbqjD3157kmiucWxELBvgZHaD2gCBe9fg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + } + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz", + "integrity": "sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "typed-rest-client": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.4.tgz", + "integrity": "sha512-MyfKKYzk3I6/QQp6e1T50py4qg+c+9BzOEl2rBmQIpStwNUoqQ73An+Tkfy9YuV7O+o2mpVVJpe+fH//POZkbg==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + } + } + }, + "azure-pipelines-tasks-webdeployment-common": { + "version": "4.219.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-webdeployment-common/-/azure-pipelines-tasks-webdeployment-common-4.219.1.tgz", + "integrity": "sha512-Uf9b0u33Wwff2EBBxFcvPaL8LetSBT2q8l28SVTOVcDgnQVMKJPR7pMK+DBzLiDlLe164MOcGrlOK+Oi/0+5LA==", + "requires": { + "@types/mocha": "^5.2.7", + "@types/node": "^10.17.0", + "@xmldom/xmldom": "git+https://github.com/xmldom/xmldom.git#0.8.6", + "archiver": "1.2.0", + "azure-pipelines-task-lib": "^4.2.0", + "decompress-zip": "^0.3.3", + "ltx": "2.8.0", + "q": "1.4.1", + "winreg": "1.2.2", + "xml2js": "0.4.13" + }, + "dependencies": { + "archiver": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.2.0.tgz", + "integrity": "sha512-5GQRAgpHGPwWIiMzL9lthd+t75fLi8BpRBYtflomSYv2i6+EO9trtwWAm2+zGjIuwKmVmBRknAZFFBSqxYxiJw==", + "requires": { + "archiver-utils": "^1.3.0", + "async": "^2.0.0", + "buffer-crc32": "^0.2.1", + "glob": "^7.0.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0", + "tar-stream": "^1.5.0", + "zip-stream": "^1.1.0" + } + }, + "azure-pipelines-task-lib": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.3.1.tgz", + "integrity": "sha512-AEwz0+Sofv80UviCYsS6fzyX5zzsLapmNCMNUoaRePZQVN+oQBStix1DGg4fdZf9zJ6acNd9xEBZQWbWuZu5Zg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + } + } + }, + "ltx": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/ltx/-/ltx-2.8.0.tgz", + "integrity": "sha512-SJJUrmDgXP0gkUzgErfkaeD+pugM8GYxerTALQa1gTUb5W1wrC4k07GZU+QNZd7MpFqJSYWXTQSUy8Ps03hx5Q==", + "requires": { + "inherits": "^2.0.1" + } } } }, @@ -233,7 +384,7 @@ "binary": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", "requires": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" @@ -288,17 +439,17 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" }, "buffer-from": { "version": "1.1.2", @@ -308,7 +459,7 @@ "buffers": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==" }, "call-bind": { "version": "1.0.2", @@ -327,7 +478,7 @@ "chainsaw": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", "requires": { "traverse": ">=0.3.0 <0.4" } @@ -343,7 +494,7 @@ "compress-commons": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", - "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "integrity": "sha512-SLTU8iWWmcORfUN+4351Z2aZXKJe1tr0jSilPMCZlLPzpdTXnkBW1LevW/MfuANBKJek8Xu9ggqrtVmQrChLtg==", "requires": { "buffer-crc32": "^0.2.1", "crc32-stream": "^2.0.0", @@ -354,7 +505,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "concat-stream": { "version": "1.6.2", @@ -383,7 +534,7 @@ "crc32-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", - "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "integrity": "sha512-UjZSqFCbn+jZUHJIh6Y3vMF7EJLcJWNm4tKDf2peJRwlZKHvkkvOMTvAei6zjU9gO1xONVr3rRFw0gixm2eUng==", "requires": { "crc": "^3.4.4", "readable-stream": "^2.0.0" @@ -397,6 +548,21 @@ "assert-plus": "^1.0.0" } }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "decompress-zip": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.3.tgz", @@ -502,7 +668,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "function-bind": { "version": "1.1.1", @@ -510,19 +676,19 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" } }, "get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" }, "getpass": { "version": "0.1.7", @@ -533,16 +699,26 @@ } }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "graceful-fs": { @@ -573,9 +749,9 @@ } }, "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "hash-base": { "version": "3.1.0", @@ -617,11 +793,6 @@ } } }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" - }, "http-basic": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", @@ -651,6 +822,15 @@ "sshpk": "^1.7.0" } }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + } + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -659,7 +839,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -676,9 +856,9 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" }, "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "requires": { "has": "^1.0.3" } @@ -693,27 +873,11 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "isemail": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz", - "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=" - }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, - "joi": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz", - "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=", - "requires": { - "hoek": "2.x.x", - "isemail": "1.x.x", - "moment": "2.x.x", - "topo": "1.x.x" - } - }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -748,15 +912,20 @@ "integrity": "sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70=" }, "jsonwebtoken": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.3.0.tgz", - "integrity": "sha1-hRGNanDj/M3xQ4n056HD+cip+7o=", - "requires": { - "joi": "^6.10.1", - "jws": "^3.1.4", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", - "ms": "^0.7.1", - "xtend": "^4.0.1" + "ms": "^2.1.1", + "semver": "^5.6.0" } }, "jsprim": { @@ -802,18 +971,40 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "ltx": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/ltx/-/ltx-2.6.2.tgz", - "integrity": "sha1-cD5EN9XjlNJsAxT9j9Xevtjgmdk=", - "requires": { - "inherits": "^2.0.1" - } + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "md5.js": { "version": "1.3.5", @@ -839,9 +1030,9 @@ } }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", "requires": { "brace-expansion": "^1.1.7" } @@ -849,12 +1040,12 @@ "mkpath": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", - "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=" + "integrity": "sha512-bauHShmaxVQiEvlrAPWxSPn8spSL8gDVRl11r8vLT4r/KdnknLqtqwQbToZ2Oa8sJkExYY1z6/d+X7pNiqo4yg==" }, "mockery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", - "integrity": "sha1-9O3g2HUMHJcnwnLqLGBiniyaHE8=" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-2.1.0.tgz", + "integrity": "sha512-9VkOmxKlWXoDO/h1jDZaS4lH33aWfRiJiNT/tKj+8OGzrcFDLo8d0syGdbsc3Bc4GvRXPb+NMMvojotmuGJTvA==" }, "moment": { "version": "2.29.4", @@ -862,19 +1053,22 @@ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "ms": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", - "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node-stream-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.7.0.tgz", - "integrity": "sha512-kYVtF3lK++53Bg6hZNplYVMrR7Lt0IYdLWehgoHUJLJcSwg/xd2Rm2Z7kJ5W8ZA7pdeg/DiUQDatbYwL3C7qSw==" + "node-fetch": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "requires": { + "whatwg-url": "^5.0.0" + } }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", "requires": { "abbrev": "1" } @@ -882,7 +1076,7 @@ "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "requires": { "remove-trailing-separator": "^1.0.1" } @@ -893,14 +1087,14 @@ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -908,12 +1102,12 @@ "parse-cache-control": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=" + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-parse": { "version": "1.0.7", @@ -926,9 +1120,9 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", "requires": { "asap": "~2.0.6" } @@ -985,7 +1179,7 @@ "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "requires": { "resolve": "^1.1.6" } @@ -993,7 +1187,7 @@ "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" }, "request": { "version": "2.88.2", @@ -1030,11 +1224,11 @@ } }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -1098,7 +1292,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, "supports-preserve-symlinks-flag": { "version": "1.0.0", @@ -1159,24 +1353,6 @@ "version": "8.10.66", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "requires": { - "side-channel": "^1.0.4" - } } } }, @@ -1185,18 +1361,10 @@ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" }, - "topo": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", - "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=", - "requires": { - "hoek": "2.x.x" - } - }, "touch": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", - "integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=", + "integrity": "sha512-/LQ54KM9rPf3rGXGo2UPQWx3ol242Zg6Whq27H5DEmZhCJo+pm9N5BzRGepO9vTVhYxpXJdcc1+3uaYt9NyeKg==", "requires": { "nopt": "~1.0.10" }, @@ -1204,7 +1372,7 @@ "nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", "requires": { "abbrev": "1" } @@ -1220,10 +1388,20 @@ "punycode": "^2.1.1" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "traverse": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==" + }, + "tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "tunnel": { "version": "0.0.6", @@ -1259,6 +1437,18 @@ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", "requires": { "side-channel": "^1.0.4" + }, + "dependencies": { + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + } } } } @@ -1266,7 +1456,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "typescript": { "version": "4.0.2", @@ -1312,15 +1502,29 @@ "extsprintf": "^1.2.0" } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "winreg": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.2.tgz", - "integrity": "sha1-hQmvo7ccW70RCm18YkfsZ3NsWY8=" + "integrity": "sha512-I1mQ2HDZbOXm3XctfGPNzm9p/md7FAxHtACVFeBNrnOE4p4b3a0baqNObx1OqHE8DEx25l5CaCDipxFM5FSYOg==" }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "xml2js": { "version": "0.4.13", @@ -1344,7 +1548,7 @@ "zip-stream": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", - "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "integrity": "sha512-2olrDUuPM4NvRIgGPhvrp84f7/HmWR6RiQrgwFF2VctmnssFiogtYL3DcA8Vl2bsSmju79sVXe38TsII7JleUg==", "requires": { "archiver-utils": "^1.3.0", "compress-commons": "^1.2.0", diff --git a/Tasks/AzureFunctionAppV1/package.json b/Tasks/AzureFunctionAppV1/package.json index 6514f36b6962..16f891b7521b 100644 --- a/Tasks/AzureFunctionAppV1/package.json +++ b/Tasks/AzureFunctionAppV1/package.json @@ -20,7 +20,10 @@ "@types/mocha": "^5.2.7", "@types/node": "^10.17.0", "@types/q": "1.0.7", - "azure-pipelines-tasks-azurermdeploycommon": "3.207.0", + "azure-devops-node-api": "11.2.0", + "azure-pipelines-task-lib": "^3.4.0", + "azure-pipelines-tasks-azure-arm-rest-v2": "^3.221.1", + "azure-pipelines-tasks-webdeployment-common": "^4.219.1", "azure-storage": "2.10.7", "moment": "^2.29.3", "q": "1.4.1", diff --git a/Tasks/AzureFunctionAppV1/task.json b/Tasks/AzureFunctionAppV1/task.json index 8626fdac7918..c222ff824b03 100644 --- a/Tasks/AzureFunctionAppV1/task.json +++ b/Tasks/AzureFunctionAppV1/task.json @@ -18,7 +18,7 @@ "version": { "Major": 1, "Minor": 221, - "Patch": 101 + "Patch": 102 }, "minimumAgentVersion": "2.104.1", "groups": [ diff --git a/Tasks/AzureFunctionAppV1/task.loc.json b/Tasks/AzureFunctionAppV1/task.loc.json index 1c314dcfe3a6..3091540d6ed7 100644 --- a/Tasks/AzureFunctionAppV1/task.loc.json +++ b/Tasks/AzureFunctionAppV1/task.loc.json @@ -18,7 +18,7 @@ "version": { "Major": 1, "Minor": 221, - "Patch": 101 + "Patch": 102 }, "minimumAgentVersion": "2.104.1", "groups": [ diff --git a/Tasks/AzureFunctionAppV1/taskparameters.ts b/Tasks/AzureFunctionAppV1/taskparameters.ts index 53b892489514..62c4f4528fc5 100644 --- a/Tasks/AzureFunctionAppV1/taskparameters.ts +++ b/Tasks/AzureFunctionAppV1/taskparameters.ts @@ -1,10 +1,11 @@ -import { AzureEndpoint } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azureModels'; import tl = require('azure-pipelines-task-lib/task'); -import { Package, PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; -var webCommonUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -import { AzureRMEndpoint } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azure-arm-endpoint'; -import { AzureResourceFilterUtility } from 'azure-pipelines-tasks-azurermdeploycommon/operations/AzureResourceFilterUtility'; -import { AzureAppService } from './azure-arm-rest/azure-arm-app-service'; +var webCommonUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; +import { AzureRMEndpoint } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-endpoint'; +import { Resources } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-resource'; +import { AzureEndpoint } from 'azure-pipelines-tasks-azure-arm-rest-v2/azureModels'; +import { Package, PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; + const skuDynamicValue: string = 'dynamic'; const skuElasticPremiumValue: string = 'elasticpremium'; @@ -69,7 +70,8 @@ export class TaskParametersUtility { var kind = taskParameters.WebAppKind; var sku; if (!resourceGroupName) { - var appDetails = await AzureResourceFilterUtility.getAppDetails(taskParameters.azureEndpoint, taskParameters.WebAppName); + var azureResources: Resources = new Resources(taskParameters.azureEndpoint); + var appDetails = await azureResources.getAppDetails(taskParameters.WebAppName); resourceGroupName = appDetails["resourceGroupName"]; if(!kind) { kind = webAppKindMap.get(appDetails["kind"]) ? webAppKindMap.get(appDetails["kind"]) : appDetails["kind"]; diff --git a/Tasks/AzureFunctionAppV2/azure-arm-rest/azure-arm-app-service-kudu.ts b/Tasks/AzureFunctionAppV2/azure-arm-rest/azure-arm-app-service-kudu.ts deleted file mode 100644 index 74f0dc58c6e6..000000000000 --- a/Tasks/AzureFunctionAppV2/azure-arm-rest/azure-arm-app-service-kudu.ts +++ /dev/null @@ -1,712 +0,0 @@ -import tl = require('azure-pipelines-task-lib/task'); -import fs = require('fs'); -import util = require('util'); -import webClient = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'); -import { WebJob, SiteExtension } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azureModels'; -import { KUDU_DEPLOYMENT_CONSTANTS } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/constants'; - - -export class KuduServiceManagementClient{ - private _scmUri; - private _cookie: string[]; - private _accessToken; - private _scmAccessCheck : boolean; - - - constructor(scmUri: string , accessToken: string , scmAccessCheck: boolean) { - this._accessToken = accessToken; - this._scmUri = scmUri; - this._scmAccessCheck = scmAccessCheck; - } - - public async beginRequest(request: webClient.WebRequest, reqOptions?: webClient.WebRequestOptions, contentType?: string): Promise { - request.headers = request.headers || {}; - if(this._scmAccessCheck === false || this._scmAccessCheck == null) { - request.headers["Authorization"] = "Bearer " + this._accessToken; - tl.debug('Using Bearer Authentication'); - let authMethodtelemetry = '{"authMethod":"Bearer"}'; - console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureFunctionAppDeployment]" + authMethodtelemetry); - } - else{ - request.headers["Authorization"] = "Basic " + this._accessToken; - tl.debug('Using Basic Authentication'); - let authMethodtelemetry = '{"authMethod":"Basic"}'; - console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureFunctionAppDeployment]" + authMethodtelemetry); - } - - request.headers['Content-Type'] = contentType || 'application/json; charset=utf-8'; - - - if(!!this._cookie) { - tl.debug(`setting affinity cookie ${JSON.stringify(this._cookie)}`); - request.headers['Cookie'] = this._cookie; - } - - let retryCount = reqOptions && util.isNumber(reqOptions.retryCount) ? reqOptions.retryCount : 5; - - while(retryCount >= 0) { - try { - let httpResponse = await webClient.sendRequest(request, reqOptions); - if(httpResponse.headers['set-cookie'] && !this._cookie) { - this._cookie = httpResponse.headers['set-cookie']; - tl.debug(`loaded affinity cookie ${JSON.stringify(this._cookie)}`); - } - - return httpResponse; - } - catch(exception) { - let exceptionString: string = exception.toString(); - if(exceptionString.indexOf("Hostname/IP doesn't match certificates's altnames") != -1 - || exceptionString.indexOf("unable to verify the first certificate") != -1 - || exceptionString.indexOf("unable to get local issuer certificate") != -1) { - tl.warning(tl.loc('ASE_SSLIssueRecommendation')); - } - - if(retryCount > 0 && exceptionString.indexOf('Request timeout') != -1 && (!reqOptions || reqOptions.retryRequestTimedout)) { - tl.debug('encountered request timedout issue in Kudu. Retrying again'); - retryCount -= 1; - continue; - } - - throw new Error(exceptionString); - } - } - - } - - public getRequestUri(uriFormat: string, queryParameters?: Array) { - uriFormat = uriFormat[0] == "/" ? uriFormat : "/" + uriFormat; - - if(queryParameters && queryParameters.length > 0) { - uriFormat = uriFormat + '?' + queryParameters.join('&'); - } - - return this._scmUri + uriFormat; - } - - public getScmUri(): string { - return this._scmUri; - } -} - -export class Kudu { - private _client: KuduServiceManagementClient; - - constructor(scmUri: string, accessToken: string, scmPolicyCheck: boolean) { - this._client = new KuduServiceManagementClient(scmUri, accessToken, scmPolicyCheck); - } - - public async updateDeployment(requestBody: any): Promise { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(requestBody); - httpRequest.uri = this._client.getRequestUri(`/api/deployments/${requestBody.id}`); - - try { - let webRequestOptions: webClient.WebRequestOptions = {retriableErrorCodes: [], retriableStatusCodes: null, retryCount: 5, retryIntervalInSeconds: 5, retryRequestTimedout: true}; - var response = await this._client.beginRequest(httpRequest, webRequestOptions); - tl.debug(`updateDeployment. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - console.log(tl.loc("Successfullyupdateddeploymenthistory", response.body.url)); - return response.body.id; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('Failedtoupdatedeploymenthistory', this._getFormattedError(error))); - } - } - - - public async getContinuousJobs(): Promise> { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/continuouswebjobs`); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getContinuousJobs. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body as Array; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetContinuousWebJobs', this._getFormattedError(error))) - } - } - - public async startContinuousWebJob(jobName: string): Promise { - console.log(tl.loc('StartingWebJob', jobName)); - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/continuouswebjobs/${jobName}/start`); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`startContinuousWebJob. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - console.log(tl.loc('StartedWebJob', jobName)); - return response.body as WebJob; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToStartContinuousWebJob', jobName, this._getFormattedError(error))); - } - } - - public async stopContinuousWebJob(jobName: string): Promise { - console.log(tl.loc('StoppingWebJob', jobName)); - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/continuouswebjobs/${jobName}/stop`); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`stopContinuousWebJob. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - console.log(tl.loc('StoppedWebJob', jobName)); - return response.body as WebJob; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToStopContinuousWebJob', jobName, this._getFormattedError(error))); - } - } - - public async installSiteExtension(extensionID: string): Promise { - console.log(tl.loc("InstallingSiteExtension", extensionID)); - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.uri = this._client.getRequestUri(`/api/siteextensions/${extensionID}`); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`installSiteExtension. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - console.log(tl.loc("SiteExtensionInstalled", extensionID)); - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToInstallSiteExtension', extensionID, this._getFormattedError(error))) - } - } - - public async getSiteExtensions(): Promise> { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/siteextensions`, ['checkLatest=false']); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getSiteExtensions. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body as Array; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetSiteExtensions', this._getFormattedError(error))) - } - } - - public async getAllSiteExtensions(): Promise> { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/extensionfeed`); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getAllSiteExtensions. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body as Array; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetAllSiteExtensions', this._getFormattedError(error))) - } - } - - public async getProcess(processID: number): Promise { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/processes/${processID}`); - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getProcess. status code: ${response.statusCode} - ${response.statusMessage}`); - if(response.statusCode == 200) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetProcess', this._getFormattedError(error))) - } - } - - public async killProcess(processID: number): Promise { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'DELETE'; - httpRequest.uri = this._client.getRequestUri(`/api/processes/${processID}`); - var reqOptions: webClient.WebRequestOptions = { - retriableErrorCodes: ["ETIMEDOUT"], - retriableStatusCodes: [503], - retryCount: 1, - retryIntervalInSeconds: 5, - retryRequestTimedout: true - }; - try { - var response = await this._client.beginRequest(httpRequest, reqOptions); - tl.debug(`killProcess. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 502) { - tl.debug(`Killed Process ${processID}`); - return; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToKillProcess', this._getFormattedError(error))) - } - } - - public async getAppSettings(): Promise> { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/settings`); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getAppSettings. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToFetchKuduAppSettings', this._getFormattedError(error))); - } - } - - public async listDir(physicalPath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`listFiles. Data: ${JSON.stringify(response)}`); - if([200, 201, 204].indexOf(response.statusCode) != -1) { - return response.body; - } - else if(response.statusCode === 404) { - return null; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('FailedToListPath', physicalPath, this._getFormattedError(error))); - } - } - - public async getFileContent(physicalPath: string, fileName: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/${fileName}`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getFileContent. Status code: ${response.statusCode} - ${response.statusMessage}`); - if([200, 201, 204].indexOf(response.statusCode) != -1) { - return response.body; - } - else if(response.statusCode === 404) { - return null; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('FailedToGetFileContent', physicalPath, fileName, this._getFormattedError(error))); - } - } - - public async uploadFile(physicalPath: string, fileName: string, filePath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - if(!tl.exist(filePath)) { - throw new Error(tl.loc('FilePathInvalid', filePath)); - } - - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/${fileName}`); - httpRequest.headers = { - 'If-Match': '*' - }; - httpRequest.body = fs.createReadStream(filePath); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`uploadFile. Data: ${JSON.stringify(response)}`); - if([200, 201, 204].indexOf(response.statusCode) != -1) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToUploadFile', physicalPath, fileName, this._getFormattedError(error))); - } - } - - public async createPath(physicalPath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`createPath. Data: ${JSON.stringify(response)}`); - if([200, 201, 204].indexOf(response.statusCode) != -1) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToCreatePath', physicalPath, this._getFormattedError(error))); - } - } - - public async runCommand(physicalPath: string, command: string): Promise { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/command`); - httpRequest.headers = { - 'Content-Type': 'multipart/form-data', - 'If-Match': '*' - }; - httpRequest.body = JSON.stringify({ - 'command': command, - 'dir': physicalPath - }); - - try { - tl.debug('Executing Script on Kudu. Command: ' + command); - let webRequestOptions: webClient.WebRequestOptions = {retriableErrorCodes: null, retriableStatusCodes: null, retryCount: 5, retryIntervalInSeconds: 5, retryRequestTimedout: false}; - var response = await this._client.beginRequest(httpRequest, webRequestOptions); - tl.debug(`runCommand. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return ; - } - else { - throw response; - } - } - catch(error) { - throw Error(error.toString()); - } - } - - public async extractZIP(webPackage: string, physicalPath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.uri = this._client.getRequestUri(`/api/zip/${physicalPath}/`); - httpRequest.headers = { - 'Content-Type': 'multipart/form-data', - 'If-Match': '*' - }; - httpRequest.body = fs.createReadStream(webPackage); - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`extractZIP. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return ; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('Failedtodeploywebapppackageusingkuduservice', this._getFormattedError(error))); - } - } - - public getKuduStackTrace() { - let stackTraceUrl = this._client.getRequestUri(`/api/vfs/LogFiles/kudu/trace`); - return stackTraceUrl; - } - - public async zipDeploy(webPackage: string, queryParameters?: Array): Promise { - let httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/zipdeploy`, queryParameters); - httpRequest.body = fs.createReadStream(webPackage); - let requestOptions = new webClient.WebRequestOptions(); - //Bydefault webclient.sendRequest retries for [408, 409, 500, 502, 503, 504] as suggested by appservice team for zipdeploy api - //408 and 409 should not be retried as it will never turn into success - requestOptions.retriableStatusCodes = [500, 502, 503, 504]; - requestOptions.retryIntervalInSeconds = 5; - try { - let response = await this._client.beginRequest(httpRequest, requestOptions, 'application/octet-stream'); - tl.debug(`ZIP Deploy response: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - tl.debug('Deployment passed'); - return null; - } - else if(response.statusCode == 202) { - let pollableURL: string = response.headers.location; - if(!!pollableURL) { - tl.debug(`Polling for ZIP Deploy URL: ${pollableURL}`); - return await this._getDeploymentDetailsFromPollURL(pollableURL); - } - else { - tl.debug('zip deploy returned 202 without pollable URL.'); - return null; - } - } - else { - throw response; - } - } - catch(error) { - throw new Error(tl.loc('PackageDeploymentFailed', this._getFormattedError(error))); - } - } - - public async warDeploy(webPackage: string, queryParameters?: Array): Promise { - let httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.uri = this._client.getRequestUri(`/api/wardeploy`, queryParameters); - httpRequest.body = fs.createReadStream(webPackage); - - try { - let response = await this._client.beginRequest(httpRequest, null, 'application/octet-stream'); - tl.debug(`War Deploy response: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - tl.debug('Deployment passed'); - return null; - } - else if(response.statusCode == 202) { - let pollableURL: string = response.headers.location; - if(!!pollableURL) { - tl.debug(`Polling for War Deploy URL: ${pollableURL}`); - return await this._getDeploymentDetailsFromPollURL(pollableURL); - } - else { - tl.debug('war deploy returned 202 without pollable URL.'); - return null; - } - } - else { - throw response; - } - } - catch(error) { - throw new Error(tl.loc('PackageDeploymentFailed', this._getFormattedError(error))); - } - } - - - public async getDeploymentDetails(deploymentID: string): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`/api/deployments/${deploymentID}`); ; - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getDeploymentDetails. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetDeploymentLogs', this._getFormattedError(error))) - } - } - - public async getDeploymentLogs(log_url: string): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = log_url; - var response = await this._client.beginRequest(httpRequest); - tl.debug(`getDeploymentLogs. Data: ${JSON.stringify(response)}`); - if(response.statusCode == 200) { - return response.body; - } - - throw response; - } - catch(error) { - throw Error(tl.loc('FailedToGetDeploymentLogs', this._getFormattedError(error))) - } - } - - public async deleteFile(physicalPath: string, fileName: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'DELETE'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/${fileName}`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`deleteFile. Data: ${JSON.stringify(response)}`); - if([200, 201, 204, 404].indexOf(response.statusCode) != -1) { - return ; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('FailedToDeleteFile', physicalPath, fileName, this._getFormattedError(error))); - } - } - - public async deleteFolder(physicalPath: string): Promise { - physicalPath = physicalPath.replace(/[\\]/g, "/"); - physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'DELETE'; - httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}`); - httpRequest.headers = { - 'If-Match': '*' - }; - - try { - var response = await this._client.beginRequest(httpRequest); - tl.debug(`deleteFolder. Data: ${JSON.stringify(response)}`); - if([200, 201, 204, 404].indexOf(response.statusCode) != -1) { - return ; - } - else { - throw response; - } - } - catch(error) { - throw Error(tl.loc('FailedToDeleteFolder', physicalPath, this._getFormattedError(error))); - } - } - - private async _getDeploymentDetailsFromPollURL(pollURL: string):Promise { - let httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = pollURL; - httpRequest.headers = {}; - - while(true) { - let response = await this._client.beginRequest(httpRequest); - if(response.statusCode == 200 || response.statusCode == 202) { - var result = response.body; - tl.debug(`POLL URL RESULT: ${JSON.stringify(response)}`); - if(result.status == KUDU_DEPLOYMENT_CONSTANTS.SUCCESS || result.status == KUDU_DEPLOYMENT_CONSTANTS.FAILED) { - return result; - } - else { - tl.debug(`Deployment status: ${result.status} '${result.status_text}'. retry after 5 seconds`); - await webClient.sleepFor(5); - continue; - } - } - else { - throw response; - } - } - } - - private _getFormattedError(error: any) { - if(error && error.message) { - if(error.statusCode) { - error.message = `${typeof error.message.valueOf() == 'string' ? error.message : error.message.Code + " - " + error.message.Message } (CODE: ${error.statusCode})` - } - - return error.message; - } - if(error && error.statusCode) { - return `${error.statusMessage} (CODE: ${error.statusCode})`; - } - return error; - } - - public async validateZipDeploy(webPackage: string, queryParameters?: Array): Promise { - try { - var stats = fs.statSync(webPackage); - var fileSizeInBytes = stats.size; - let httpRequest: webClient.WebRequest = { - method: 'POST', - uri: this._client.getRequestUri(`/api/zipdeploy/validate`, queryParameters), - body: fs.createReadStream(webPackage), - headers: { - 'Content-Length': fileSizeInBytes - }, - }; - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retriableStatusCodes = [500, 502, 503, 504]; - requestOptions.retryIntervalInSeconds = 5; - - let response = await this._client.beginRequest(httpRequest, requestOptions, 'application/octet-stream'); - if(response.statusCode == 200) { - tl.debug(`Validation passed response: ${JSON.stringify(response)}`); - if (response.body && response.body.result){ - tl.warning(`${JSON.stringify(response.body.result)}`); - } - return null; - } - else if(response.statusCode == 400) { - tl.debug(`Validation failed response: ${JSON.stringify(response)}`); - throw response; - } - else { - tl.debug(`Skipping validation with status: ${response.statusCode}`); - return null; - } - } - catch(error) { - if (error && error.body && error.body.result && typeof error.body.result.valueOf() == 'string' && error.body.result.includes('ZipDeploy Validation ERROR')) { - throw Error(JSON.stringify(error.body.result)); - } - else { - tl.debug(`Skipping validation with error: ${error}`); - return null; - } - } - } -} diff --git a/Tasks/AzureFunctionAppV2/azure-arm-rest/azure-arm-app-service.ts b/Tasks/AzureFunctionAppV2/azure-arm-rest/azure-arm-app-service.ts deleted file mode 100644 index 883e4f488982..000000000000 --- a/Tasks/AzureFunctionAppV2/azure-arm-rest/azure-arm-app-service.ts +++ /dev/null @@ -1,824 +0,0 @@ -import tl = require('azure-pipelines-task-lib/task'); -import webClient = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'); -import { - AzureEndpoint, - AzureAppServiceConfigurationDetails -} from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azureModels'; - -import { - ServiceClient, - ToError -} from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/AzureServiceClient'; -import constants = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/constants'); -const CorrelationIdInResponse = "x-ms-correlation-request-id"; - -export class ServiceClient_1 extends ServiceClient{ - public async beginRequest(request: webClient.WebRequest, reqOptions?: webClient.WebRequestOptions): Promise { - var token = await this.getCredentials().getToken(); - - request.headers = request.headers || {}; - request.headers["Authorization"] = "Bearer " + token; - if (this.acceptLanguage) { - request.headers['accept-language'] = this.acceptLanguage; - } - request.headers['Content-Type'] = 'application/json; charset=utf-8'; - - var httpResponse = null; - - try - { - httpResponse = await webClient.sendRequest(request, reqOptions); - if (httpResponse.statusCode === 401 && httpResponse.body && httpResponse.body.error && httpResponse.body.error.code === "ExpiredAuthenticationToken") { - // The access token might have expire. Re-issue the request after refreshing the token. - token = await this.getCredentials().getToken(true); - request.headers["Authorization"] = "Bearer " + token; - httpResponse = await webClient.sendRequest(request, reqOptions); - } - - if(!!httpResponse.headers[CorrelationIdInResponse]) { - tl.debug(`Correlation ID from ARM api call response : ${httpResponse.headers[CorrelationIdInResponse]}`); - } - } catch(exception) { - let exceptionString: string = exception.toString(); - if(exceptionString.indexOf("Hostname/IP doesn't match certificates's altnames") != -1 - || exceptionString.indexOf("unable to verify the first certificate") != -1 - || exceptionString.indexOf("unable to get local issuer certificate") != -1) { - tl.warning(tl.loc('ASE_SSLIssueRecommendation')); - } - - throw exception; - } - - return httpResponse; - } -} - -export class AzureAppService { - private _resourceGroup: string; - private _name: string; - private _slot: string; - private _appKind: string; - private _isConsumptionApp: boolean; - public _client: ServiceClient_1; - private _appServiceConfigurationDetails: AzureAppServiceConfigurationDetails; - private _appServicePublishingProfile: any; - private _appServiceApplicationSetings: AzureAppServiceConfigurationDetails; - private _appServiceConfigurationSettings: AzureAppServiceConfigurationDetails; - private _appServiceConnectionString: AzureAppServiceConfigurationDetails; - - constructor(endpoint: AzureEndpoint, resourceGroup: string, name: string, slot?: string, appKind?: string, isConsumptionApp?: boolean) { - this._client = new ServiceClient_1(endpoint.applicationTokenCredentials, endpoint.subscriptionID, 30); - this._resourceGroup = resourceGroup; - this._name = name; - this._slot = (slot && slot.toLowerCase() == constants.productionSlot) ? null : slot; - this._appKind = appKind; - this._isConsumptionApp = isConsumptionApp; - } - - public async start(): Promise { - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/start`, { - '{ResourceGroupName}': this._resourceGroup, - '{name}': this._name - }, null, '2016-08-01'); - - console.log(tl.loc('StartingAppService', this._getFormattedName())); - var response = await this._client.beginRequest(webRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - console.log(tl.loc('StartedAppService', this._getFormattedName())); - } - catch(error) { - throw Error(tl.loc('FailedToStartAppService', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async stop(): Promise { - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/stop`, { - '{ResourceGroupName}': this._resourceGroup, - '{name}': this._name - }, null, '2016-08-01'); - - console.log(tl.loc('StoppingAppService', this._getFormattedName())); - var response = await this._client.beginRequest(webRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - console.log(tl.loc('StoppedAppService', this._getFormattedName())); - } - catch(error) { - throw Error(tl.loc('FailedToStopAppService', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async restart(): Promise { - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/restart`, { - '{ResourceGroupName}': this._resourceGroup, - '{name}': this._name - }, null, '2016-08-01'); - - console.log(tl.loc('RestartingAppService', this._getFormattedName())); - var response = await this._client.beginRequest(webRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - console.log(tl.loc('RestartedAppService', this._getFormattedName())); - } - catch(error) { - throw Error(tl.loc('FailedToRestartAppService', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async swap(slotName: string, preserveVNet?: boolean): Promise { - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'POST'; - webRequest.body = JSON.stringify({ - targetSlot: slotName, - preserveVnet: preserveVNet - }); - - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/slotsswap`, { - '{ResourceGroupName}': this._resourceGroup, - '{name}': this._name, - '{slotUrl}': slotUrl - }, null, '2016-08-01'); - - console.log(tl.loc('SwappingAppServiceSlotSlots', this._name, this.getSlot(), slotName)); - var response = await this._client.beginRequest(webRequest); - if(response.statusCode == 202) { - response= await this._client.getLongRunningOperationResult(response); - } - - if(response.statusCode != 200) { - throw ToError(response); - } - - console.log(tl.loc('SwappedAppServiceSlotSlots', this._name, this.getSlot(), slotName)); - } - catch(error) { - throw Error(tl.loc('FailedToSwapAppServiceSlotSlots', this._name, this.getSlot(), slotName, this._client.getFormattedError(error))); - } - } - - public async get(force?: boolean): Promise { - if(force || !this._appServiceConfigurationDetails) { - this._appServiceConfigurationDetails = await this._get(); - } - - return this._appServiceConfigurationDetails; - } - - public async getPublishingProfileWithSecrets(force?: boolean): Promise{ - if(force || !this._appServicePublishingProfile) { - this._appServicePublishingProfile = await this._getPublishingProfileWithSecrets(); - } - - return this._appServicePublishingProfile; - } - - public async getPublishingCredentials(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/publishingcredentials/list`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServicePublishingCredentials', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async getApplicationSettings(force?: boolean): Promise { - if(force || !this._appServiceApplicationSetings) { - this._appServiceApplicationSetings = await this._getApplicationSettings(); - } - - return this._appServiceApplicationSetings; - } - - public async updateApplicationSettings(applicationSettings): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(applicationSettings); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/appsettings`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceApplicationSettings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async patchApplicationSettings(addProperties: any, deleteProperties?: any, formatJSON?: boolean): Promise { - var applicationSettings = await this.getApplicationSettings(); - var isNewValueUpdated: boolean = false; - for(var key in addProperties) { - if(formatJSON) { - if(JSON.stringify(applicationSettings.properties[key]) != JSON.stringify(addProperties[key])) { - tl.debug(`Value of ${key} has been changed to ${JSON.stringify(addProperties[key])}`); - isNewValueUpdated = true; - } - else { - tl.debug(`${key} is already present.`); - } - } - else { - if(applicationSettings.properties[key] != addProperties[key]) { - tl.debug(`Value of ${key} has been changed to ${addProperties[key]}`); - isNewValueUpdated = true; - } - else { - tl.debug(`${key} is already present.`); - } - } - - applicationSettings.properties[key] = addProperties[key]; - } - for(var key in deleteProperties) { - if(key in applicationSettings.properties) { - delete applicationSettings.properties[key]; - tl.debug(`Removing app setting : ${key}`); - isNewValueUpdated = true; - } - } - - if(isNewValueUpdated) { - applicationSettings.properties[constants.WebsiteEnableSyncUpdateSiteKey] = this._isConsumptionApp ? 'false' : 'true'; - await this.updateApplicationSettings(applicationSettings); - } - - return isNewValueUpdated; - } - - public async patchApplicationSettingsSlot(addProperties: any): Promise { - var appSettingsSlotSettings = await this.getSlotConfigurationNames(); - let appSettingNames = appSettingsSlotSettings.properties.appSettingNames; - var isNewValueUpdated: boolean = false; - for(var key in addProperties) { - if(!appSettingNames) { - appSettingsSlotSettings.properties.appSettingNames = []; - appSettingNames = appSettingsSlotSettings.properties.appSettingNames; - } - if(addProperties[key].slotSetting == true) { - if((appSettingNames.length == 0) || (!appSettingNames.includes(addProperties[key].name))) { - appSettingNames.push(addProperties[key].name); - } - tl.debug(`Slot setting updated for key : ${addProperties[key].name}`); - isNewValueUpdated = true; - } - else if ((addProperties[key].slotSetting == false || (addProperties[key].slotSetting == null)) && appSettingNames != null ) { - const index = appSettingNames.indexOf(addProperties[key].name, 0); - if (index > -1) { - appSettingNames.splice(index, 1); - } - isNewValueUpdated = true; - } - } - - if(isNewValueUpdated) { - await this.updateSlotConfigSettings(appSettingsSlotSettings); - } - - } - - public async syncFunctionTriggers(): Promise { - try { - let i = 0; - let retryCount = 5; - let retryIntervalInSeconds = 2; - let timeToWait: number = retryIntervalInSeconds; - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/syncfunctiontriggers`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - while(true) { - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode == 200) { - return response.body; - } - else if(response.statusCode == 400) { - if (++i < retryCount) { - await webClient.sleepFor(timeToWait); - timeToWait = timeToWait * retryIntervalInSeconds + retryIntervalInSeconds; - continue; - } - else { - throw ToError(response); - } - } - else { - throw ToError(response); - } - } - } - catch(error) { - throw Error(tl.loc('FailedToSyncTriggers', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async getConfiguration(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/web`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2018-02-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceConfiguration', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async updateConfiguration(applicationSettings): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(applicationSettings); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/web`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2018-02-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceConfiguration', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async patchConfiguration(properties: any): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PATCH'; - httpRequest.body = JSON.stringify(properties); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/web`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2018-02-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToPatchAppServiceConfiguration', this._getFormattedName(), this._client.getFormattedError(error))); - } - - } - - public async getConnectionStrings(force?: boolean): Promise { - if(force || !this._appServiceConnectionString) { - this._appServiceConnectionString = await this._getConnectionStrings(); - } - - return this._appServiceConnectionString; - } - - public async getSlotConfigurationNames(force?: boolean): Promise { - if(force || !this._appServiceConfigurationSettings) { - this._appServiceConfigurationSettings = await this._getSlotConfigurationNames(); - } - - return this._appServiceConfigurationSettings; - } - - public async patchConnectionString(addProperties: any): Promise { - var connectionStringSettings = await this.getConnectionStrings(); - var isNewValueUpdated: boolean = false; - for(var key in addProperties) { - if(JSON.stringify(connectionStringSettings.properties[key]) != JSON.stringify(addProperties[key])) { - tl.debug(`Value of ${key} has been changed to ${JSON.stringify(addProperties[key])}`); - isNewValueUpdated = true; - } - else { - tl.debug(`${key} is already present.`); - } - connectionStringSettings.properties[key] = addProperties[key]; - } - - if(isNewValueUpdated) { - await this.updateConnectionStrings(connectionStringSettings); - } - } - - public async updateConnectionStrings(connectionStringSettings: any): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(connectionStringSettings); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/connectionstrings`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceConnectionStrings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async patchConnectionStringSlot(addProperties: any): Promise { - var connectionStringSlotSettings = await this.getSlotConfigurationNames(); - let connectionStringNames = connectionStringSlotSettings.properties.connectionStringNames; - var isNewValueUpdated: boolean = false; - for(var key in addProperties) { - if(!connectionStringNames) { - connectionStringSlotSettings.properties.connectionStringNames = []; - connectionStringNames = connectionStringSlotSettings.properties.connectionStringNames; - } - if(addProperties[key].slotSetting == true) { - if((connectionStringNames.length == 0) || (!connectionStringNames.includes(key))) { - connectionStringNames.push(key); - } - tl.debug(`Slot setting updated for key : ${key}`); - isNewValueUpdated = true; - } - } - - if(isNewValueUpdated) { - await this.updateSlotConfigSettings(connectionStringSlotSettings); - } - } - - public async updateSlotConfigSettings(SlotConfigSettings: any): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(SlotConfigSettings); - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/slotConfigNames`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceConfigSlotSettings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async getMetadata(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/metadata/list`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceMetadata', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async updateMetadata(applicationSettings): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'PUT'; - httpRequest.body = JSON.stringify(applicationSettings); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/metadata`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToUpdateAppServiceMetadata', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - public async patchMetadata(properties): Promise { - var applicationSettings = await this.getMetadata(); - for(var key in properties) { - applicationSettings.properties[key] = properties[key]; - } - - await this.updateMetadata(applicationSettings); - } - - public getSlot(): string { - return this._slot ? this._slot : "production"; - } - - private async _getPublishingProfileWithSecrets(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/publishxml`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - var publishingProfile = response.body; - return publishingProfile; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServicePublishingProfile', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private async _getApplicationSettings(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/appsettings/list`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceApplicationSettings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private async _getConnectionStrings(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/connectionstrings/list`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceConnectionStrings', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private async _getSlotConfigurationNames(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/slotConfigNames`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceSlotConfigurationNames', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private async _get(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2016-08-01'); - - var response = await this._client.beginRequest(httpRequest); - if(response.statusCode != 200) { - throw ToError(response); - } - - var appDetails = response.body; - return appDetails as AzureAppServiceConfigurationDetails; - } - catch(error) { - throw Error(tl.loc('FailedToGetAppServiceDetails', this._getFormattedName(), this._client.getFormattedError(error))); - } - } - - private _getFormattedName(): string { - return this._slot ? `${this._name}-${this._slot}` : this._name; - } - - public getName(): string { - return this._name; - } - - public async getSitePublishingCredentialPolicies(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/basicPublishingCredentialsPolicies/scm`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2022-03-01'); - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retryCount = 1; - - var response = await this._client.beginRequest(httpRequest, requestOptions); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(`Failed to get SitePublishingCredentialPolicies. Error: ${this._client.getFormattedError(error)}`); - } - } - - public async getSiteVirtualNetworkConnections(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/virtualNetworkConnections`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2022-03-01'); - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retryCount = 1; - - var response = await this._client.beginRequest(httpRequest, requestOptions); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(`Failed to get Virtual Network Connections. Error: ${this._client.getFormattedError(error)}`); - } - } - - public async getSitePrivateEndpointConnections(): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/privateEndpointConnections`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2022-03-01'); - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retryCount = 1; - - var response = await this._client.beginRequest(httpRequest, requestOptions); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(`Failed to get Private Endpoint Connections. Error: ${this._client.getFormattedError(error)}`); - } - } - - public async getConnectionStringValidation(connectionDetails): Promise { - try { - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'POST'; - httpRequest.body = JSON.stringify(connectionDetails); - var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; - httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/extensions/DaaS/api/connectionstringvalidation/validate/`, - { - '{resourceGroupName}': this._resourceGroup, - '{name}': this._name, - }, null, '2022-03-01'); - let requestOptions = new webClient.WebRequestOptions(); - requestOptions.retryCount = 1; - - var response = await this._client.beginRequest(httpRequest, requestOptions); - if(response.statusCode != 200) { - throw ToError(response); - } - - return response.body; - } - catch(error) { - throw Error(`Failed to get Connection String Validation. Error: ${this._client.getFormattedError(error)}`); - } - } - } \ No newline at end of file diff --git a/Tasks/AzureFunctionAppV2/azurermwebappdeployment.ts b/Tasks/AzureFunctionAppV2/azurermwebappdeployment.ts index 3994da6e824f..e4f11d2c0053 100644 --- a/Tasks/AzureFunctionAppV2/azurermwebappdeployment.ts +++ b/Tasks/AzureFunctionAppV2/azurermwebappdeployment.ts @@ -1,15 +1,15 @@ import tl = require('azure-pipelines-task-lib/task'); import path = require('path'); +import * as Endpoint from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-endpoint'; import { TaskParameters, TaskParametersUtility } from './taskparameters'; import { DeploymentFactory } from './deploymentProvider/DeploymentFactory'; -import * as Endpoint from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azure-arm-endpoint'; async function main() { let isDeploymentSuccess: boolean = true; try { tl.setResourcePath(path.join( __dirname, 'task.json')); - tl.setResourcePath(path.join( __dirname, 'node_modules/azure-pipelines-tasks-azurermdeploycommon/module.json')); + tl.setResourcePath(path.join( __dirname, 'node_modules/azure-pipelines-tasks-azure-arm-rest-v2/module.json')); var taskParams: TaskParameters = await TaskParametersUtility.getParameters(); var deploymentFactory: DeploymentFactory = new DeploymentFactory(taskParams); var deploymentProvider = await deploymentFactory.GetDeploymentProvider(); @@ -29,10 +29,9 @@ async function main() { if(deploymentProvider != null) { await deploymentProvider.UpdateDeploymentStatus(isDeploymentSuccess); } - + Endpoint.dispose(); tl.debug(isDeploymentSuccess ? "Deployment Succeeded" : "Deployment failed"); - } } diff --git a/Tasks/AzureFunctionAppV2/deploymentProvider/AzureRmWebAppDeploymentProvider.ts b/Tasks/AzureFunctionAppV2/deploymentProvider/AzureRmWebAppDeploymentProvider.ts index 30595b5b0640..b1f9686e19f6 100644 --- a/Tasks/AzureFunctionAppV2/deploymentProvider/AzureRmWebAppDeploymentProvider.ts +++ b/Tasks/AzureFunctionAppV2/deploymentProvider/AzureRmWebAppDeploymentProvider.ts @@ -1,20 +1,22 @@ -import { IWebAppDeploymentProvider } from './IWebAppDeploymentProvider'; +import tl = require('azure-pipelines-task-lib/task'); +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; +import { Kudu } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service-kudu'; +import { AzureAppServiceUtility } from 'azure-pipelines-tasks-azure-arm-rest-v2/azureAppServiceUtility'; +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility' +import { PackageUtility } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; +import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azure-arm-rest-v2/constants'; import { TaskParameters } from '../taskparameters'; +import { AzureAppServiceUtilityExt } from '../operations/AzureAppServiceUtilityExt'; import { KuduServiceUtility } from '../operations/KuduServiceUtility'; -import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; -import { Kudu } from '../azure-arm-rest/azure-arm-app-service-kudu'; -import { AzureAppServiceUtility } from '../operations/AzureAppServiceUtility'; -import tl = require('azure-pipelines-task-lib/task'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility' import { addReleaseAnnotation } from '../operations/ReleaseAnnotationUtility'; -import { PackageUtility } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; -import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azurermdeploycommon/Constants'; +import { IWebAppDeploymentProvider } from './IWebAppDeploymentProvider'; export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvider { protected taskParams:TaskParameters; protected appService: AzureAppService; protected kuduService: Kudu; protected appServiceUtility: AzureAppServiceUtility; + protected appServiceUtilityExt: AzureAppServiceUtilityExt; protected kuduServiceUtility: KuduServiceUtility; protected virtualApplicationPath: string = ""; protected activeDeploymentID; @@ -26,14 +28,15 @@ export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvide } public async PreDeploymentStep() { - this.appService = new AzureAppService(this.taskParams.azureEndpoint, this.taskParams.ResourceGroupName, this.taskParams.WebAppName, + this.appService = new AzureAppService(this.taskParams.azureEndpoint, this.taskParams.ResourceGroupName, this.taskParams.WebAppName, this.taskParams.SlotName, this.taskParams.WebAppKind); this.appServiceUtility = new AzureAppServiceUtility(this.appService); + this.appServiceUtilityExt = new AzureAppServiceUtilityExt(this.appService); this.kuduService = await this.appServiceUtility.getKuduService(); this.kuduServiceUtility = new KuduServiceUtility(this.kuduService); - - await this.appServiceUtility.getFuntionAppNetworkingCheck(this.taskParams.isLinuxApp); + + await this.appServiceUtilityExt.getFuntionAppNetworkingCheck(this.taskParams.isLinuxApp); } public async DeployWebAppStep() {} @@ -56,6 +59,6 @@ export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvide await this.appServiceUtility.updateAndMonitorAppSettings(customApplicationSettings); } - await this.appServiceUtility.updateScmTypeAndConfigurationDetails(); - } + await this.appServiceUtilityExt.updateScmTypeAndConfigurationDetails(); + } } \ No newline at end of file diff --git a/Tasks/AzureFunctionAppV2/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts b/Tasks/AzureFunctionAppV2/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts index d36096795781..6f6dfec78390 100644 --- a/Tasks/AzureFunctionAppV2/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts +++ b/Tasks/AzureFunctionAppV2/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts @@ -1,12 +1,11 @@ -import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; import tl = require('azure-pipelines-task-lib/task'); -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; import path = require('path'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility' +var webCommonUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility' import { TaskParameters, DeploymentType } from '../taskparameters'; - -var webCommonUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; const linuxFunctionStorageSetting: string = '-WEBSITES_ENABLE_APP_SERVICE_STORAGE true'; const linuxFunctionRuntimeSettingName: string = '-FUNCTIONS_WORKER_RUNTIME '; diff --git a/Tasks/AzureFunctionAppV2/deploymentProvider/ConsumptionWebAppDeploymentProvider.ts b/Tasks/AzureFunctionAppV2/deploymentProvider/ConsumptionWebAppDeploymentProvider.ts index 73407912bd81..e7f44655eb4f 100644 --- a/Tasks/AzureFunctionAppV2/deploymentProvider/ConsumptionWebAppDeploymentProvider.ts +++ b/Tasks/AzureFunctionAppV2/deploymentProvider/ConsumptionWebAppDeploymentProvider.ts @@ -1,24 +1,23 @@ -import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; import tl = require('azure-pipelines-task-lib/task'); -import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; -import { AzureAppServiceUtility } from '../operations/AzureAppServiceUtility'; -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; -import { sleepFor } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'; import Q = require('q'); -var webCommonUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); +var webCommonUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); var azureStorage = require('azure-storage'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility'; -import { TaskParameters, DeploymentType } from '../taskparameters'; +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; +import { sleepFor } from 'azure-pipelines-tasks-azure-arm-rest-v2/webClient'; +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility'; +import { AzureAppServiceUtilityExt } from '../operations/AzureAppServiceUtilityExt'; +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; export class ConsumptionWebAppDeploymentProvider extends AzureRmWebAppDeploymentProvider { public async PreDeploymentStep() { - this.appService = new AzureAppService(this.taskParams.azureEndpoint, this.taskParams.ResourceGroupName, this.taskParams.WebAppName, + this.appService = new AzureAppService(this.taskParams.azureEndpoint, this.taskParams.ResourceGroupName, this.taskParams.WebAppName, this.taskParams.SlotName, this.taskParams.WebAppKind, true); - this.appServiceUtility = new AzureAppServiceUtility(this.appService); + this.appServiceUtilityExt = new AzureAppServiceUtilityExt(this.appService); } - + public async DeployWebAppStep() { let deploymentMethodtelemetry = '{"deploymentMethod":"RunFromPackage to URL for Linux"}'; console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureFunctionAppDeployment]" + deploymentMethodtelemetry); @@ -135,10 +134,10 @@ export class ConsumptionWebAppDeploymentProvider extends AzureRmWebAppDeployment protected async PostDeploymentStep() { if(this.taskParams.ConfigurationSettings) { var customApplicationSettings = ParameterParser.parse(this.taskParams.ConfigurationSettings); - await this.appServiceUtility.updateConfigurationSettings(customApplicationSettings); + await this.appService.updateConfigurationSettings(customApplicationSettings); } - await this.appServiceUtility.updateScmTypeAndConfigurationDetails(); + await this.appServiceUtilityExt.updateScmTypeAndConfigurationDetails(); } private _getUserDefinedAppSettings() { diff --git a/Tasks/AzureFunctionAppV2/deploymentProvider/DeploymentFactory.ts b/Tasks/AzureFunctionAppV2/deploymentProvider/DeploymentFactory.ts index abbf402fbdde..7711ee67393e 100644 --- a/Tasks/AzureFunctionAppV2/deploymentProvider/DeploymentFactory.ts +++ b/Tasks/AzureFunctionAppV2/deploymentProvider/DeploymentFactory.ts @@ -1,11 +1,11 @@ +import tl = require('azure-pipelines-task-lib/task'); +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; import { TaskParameters, DeploymentType } from '../taskparameters'; import { BuiltInLinuxWebAppDeploymentProvider } from './BuiltInLinuxWebAppDeploymentProvider'; import { IWebAppDeploymentProvider } from './IWebAppDeploymentProvider'; import { WindowsWebAppZipDeployProvider } from './WindowsWebAppZipDeployProvider'; import { WindowsWebAppRunFromZipProvider } from './WindowsWebAppRunFromZipProvider'; import { ConsumptionWebAppDeploymentProvider } from './ConsumptionWebAppDeploymentProvider'; -import tl = require('azure-pipelines-task-lib/task'); -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; export class DeploymentFactory { diff --git a/Tasks/AzureFunctionAppV2/deploymentProvider/WindowsWebAppRunFromZipProvider.ts b/Tasks/AzureFunctionAppV2/deploymentProvider/WindowsWebAppRunFromZipProvider.ts index 7b679a428669..df9bb547e8d0 100644 --- a/Tasks/AzureFunctionAppV2/deploymentProvider/WindowsWebAppRunFromZipProvider.ts +++ b/Tasks/AzureFunctionAppV2/deploymentProvider/WindowsWebAppRunFromZipProvider.ts @@ -1,17 +1,18 @@ -import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; import tl = require('azure-pipelines-task-lib/task'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility' +var deployUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility' +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; import { DeploymentType } from '../taskparameters'; -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; +import { FileTransformsUtility } from '../operations/FileTransformsUtility'; import { addReleaseAnnotation } from '../operations/ReleaseAnnotationUtility'; -import { FileTransformsUtility } from 'azure-pipelines-tasks-azurermdeploycommon/operations/FileTransformsUtility.js'; +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; + const oldRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP'; const runFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 1'; -var deployUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); export class WindowsWebAppRunFromZipProvider extends AzureRmWebAppDeploymentProvider { - + public async DeployWebAppStep() { let deploymentMethodtelemetry = '{"deploymentMethod":"Run from Package for Windows"}'; console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureFunctionAppDeployment]" + deploymentMethodtelemetry); diff --git a/Tasks/AzureFunctionAppV2/deploymentProvider/WindowsWebAppZipDeployProvider.ts b/Tasks/AzureFunctionAppV2/deploymentProvider/WindowsWebAppZipDeployProvider.ts index 9b030cc7ff83..9201fefe6a25 100644 --- a/Tasks/AzureFunctionAppV2/deploymentProvider/WindowsWebAppZipDeployProvider.ts +++ b/Tasks/AzureFunctionAppV2/deploymentProvider/WindowsWebAppZipDeployProvider.ts @@ -1,21 +1,22 @@ -import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; import tl = require('azure-pipelines-task-lib/task'); -import * as ParameterParser from 'azure-pipelines-tasks-azurermdeploycommon/operations/ParameterParserUtility' +var deployUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); +import * as ParameterParser from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility' +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; import { DeploymentType } from '../taskparameters'; -import { PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; -import { FileTransformsUtility } from 'azure-pipelines-tasks-azurermdeploycommon/operations/FileTransformsUtility.js'; +import { FileTransformsUtility } from '../operations/FileTransformsUtility'; +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; + const removeRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP -WEBSITE_RUN_FROM_PACKAGE'; -var deployUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvider { - + private zipDeploymentID: string; - + public async DeployWebAppStep() { let deploymentMethodtelemetry = '{"deploymentMethod":"Zip Deploy for Windows"}'; console.log("##vso[telemetry.publish area=TaskDeploymentMethod;feature=AzureFunctionAppDeployment]" + deploymentMethodtelemetry); - + var webPackage = await FileTransformsUtility.applyTransformations(this.taskParams.Package.getPath(), this.taskParams.WebConfigParameters, this.taskParams.Package.getPackageType()); if(this.taskParams.DeploymentType === DeploymentType.zipDeploy) { diff --git a/Tasks/AzureFunctionAppV2/make.json b/Tasks/AzureFunctionAppV2/make.json index 65aef0088694..8733fe153102 100644 --- a/Tasks/AzureFunctionAppV2/make.json +++ b/Tasks/AzureFunctionAppV2/make.json @@ -1,4 +1,12 @@ { + "rm": [ + { + "items": [ + "node_modules/azure-pipelines-tasks-azure-arm-rest-v2/node_modules/azure-pipelines-task-lib" + ], + "options": "-Rf" + } + ], "externals": { "archivePackages": [ { diff --git a/Tasks/AzureFunctionAppV2/operations/AzureAppServiceUtility.ts b/Tasks/AzureFunctionAppV2/operations/AzureAppServiceUtilityExt.ts similarity index 55% rename from Tasks/AzureFunctionAppV2/operations/AzureAppServiceUtility.ts rename to Tasks/AzureFunctionAppV2/operations/AzureAppServiceUtilityExt.ts index 8402ce108aa1..4235502d30a0 100644 --- a/Tasks/AzureFunctionAppV2/operations/AzureAppServiceUtility.ts +++ b/Tasks/AzureFunctionAppV2/operations/AzureAppServiceUtilityExt.ts @@ -1,14 +1,10 @@ import tl = require('azure-pipelines-task-lib/task'); -import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; -import webClient = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'); -var parseString = require('xml2js').parseString; -import Q = require('q'); -import { Kudu } from '../azure-arm-rest/azure-arm-app-service-kudu'; -import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azurermdeploycommon/Constants'; -import * as os from "os"; var glob = require("glob"); +import * as os from "os"; +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; +import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azure-arm-rest-v2/constants'; -export class AzureAppServiceUtility { +export class AzureAppServiceUtilityExt { private _appService: AzureAppService; constructor(appService: AzureAppService) { this._appService = appService; @@ -61,169 +57,6 @@ export class AzureAppServiceUtility { } } - public async getWebDeployPublishingProfile(): Promise { - var publishingProfile = await this._appService.getPublishingProfileWithSecrets(); - var defer = Q.defer(); - parseString(publishingProfile, (error, result) => { - if(!!error) { - defer.reject(error); - } - var publishProfile = result && result.publishData && result.publishData.publishProfile ? result.publishData.publishProfile : null; - if(publishProfile) { - for (var index in publishProfile) { - if (publishProfile[index].$ && publishProfile[index].$.publishMethod === "MSDeploy") { - defer.resolve(result.publishData.publishProfile[index].$); - } - } - } - - defer.reject(tl.loc('ErrorNoSuchDeployingMethodExists')); - }); - - return defer.promise; - } - - public async getApplicationURL(virtualApplication?: string): Promise { - let webDeployProfile: any = await this.getWebDeployPublishingProfile(); - return await webDeployProfile.destinationAppUrl + ( virtualApplication ? "/" + virtualApplication : "" ); - } - - public async pingApplication(): Promise { - try { - var applicationUrl: string = await this.getApplicationURL(); - - if(!applicationUrl) { - tl.debug("Application Url not found."); - return; - } - await AzureAppServiceUtility.pingApplication(applicationUrl); - } catch(error) { - tl.debug("Unable to ping App Service. Error: ${error}"); - } - } - - public static async pingApplication(applicationUrl: string) { - if(!applicationUrl) { - tl.debug('Application Url empty.'); - return; - } - try { - var webRequest = new webClient.WebRequest(); - webRequest.method = 'GET'; - webRequest.uri = applicationUrl; - let webRequestOptions: webClient.WebRequestOptions = {retriableErrorCodes: [], retriableStatusCodes: [], retryCount: 1, retryIntervalInSeconds: 5, retryRequestTimedout: true}; - var response = await webClient.sendRequest(webRequest, webRequestOptions); - tl.debug(`App Service status Code: '${response.statusCode}'. Status Message: '${response.statusMessage}'`); - } - catch(error) { - tl.debug(`Unable to ping App Service. Error: ${error}`); - } - } - - public async getKuduService(): Promise { - - var publishingCredentials = await this._appService.getPublishingCredentials(); - var scmPolicyCheck = await this.isSitePublishingCredentialsEnabled(); - - if(publishingCredentials.properties["scmUri"]) { - if(scmPolicyCheck === false) { - tl.debug('Gettting Bearer token'); - var accessToken = await this._appService._client.getCredentials().getToken(); - } - else{ - tl.setVariable(`AZURE_APP_SERVICE_KUDU_${this._appService.getSlot()}_PASSWORD`, publishingCredentials.properties["publishingPassword"], true); - var accessToken = (new Buffer(publishingCredentials.properties["publishingUserName"] + ':' + publishingCredentials.properties["publishingPassword"]).toString('base64')); - } - return new Kudu(publishingCredentials.properties["scmUri"], accessToken, scmPolicyCheck); - } - - throw Error(tl.loc('KuduSCMDetailsAreEmpty')); - } - - public async getPhysicalPath(virtualApplication: string): Promise { - - if(!virtualApplication) { - return '/site/wwwroot'; - } - - virtualApplication = (virtualApplication.startsWith("/")) ? virtualApplication.substr(1) : virtualApplication; - - var physicalToVirtualPathMap = await this._getPhysicalToVirtualPathMap(virtualApplication); - - if(!physicalToVirtualPathMap) { - throw Error(tl.loc("VirtualApplicationDoesNotExist", virtualApplication)); - } - - tl.debug(`Virtual Application Map: Physical path: '${physicalToVirtualPathMap.physicalPath}'. Virtual path: '${physicalToVirtualPathMap.virtualPath}'.`); - return physicalToVirtualPathMap.physicalPath; - } - - public async updateConfigurationSettings(properties: any, formatJSON?: boolean) : Promise { - if(formatJSON) { - var configurationSettingsProperties = properties[0]; - console.log(tl.loc('UpdatingAppServiceConfigurationSettings', JSON.stringify(configurationSettingsProperties))); - await this._appService.patchConfiguration({'properties': configurationSettingsProperties}); - } - else - { - for(var property in properties) { - if(!!properties[property] && properties[property].value !== undefined) { - properties[property] = properties[property].value; - } - } - - console.log(tl.loc('UpdatingAppServiceConfigurationSettings', JSON.stringify(properties))); - await this._appService.patchConfiguration({'properties': properties}); - } - console.log(tl.loc('UpdatedAppServiceConfigurationSettings')); - } - - public async updateAndMonitorAppSettings(addProperties?: any, deleteProperties?: any, formatJSON?: boolean): Promise { - if(formatJSON) { - var appSettingsProperties = {}; - for(var property in addProperties) { - appSettingsProperties[addProperties[property].name] = addProperties[property].value; - } - - if(!!addProperties) { - console.log(tl.loc('UpdatingAppServiceApplicationSettings', JSON.stringify(appSettingsProperties))); - } - - if(!!deleteProperties) { - console.log(tl.loc('DeletingAppServiceApplicationSettings', JSON.stringify(Object.keys(deleteProperties)))); - } - - var isNewValueUpdated: boolean = await this._appService.patchApplicationSettings(appSettingsProperties, deleteProperties, true); - } - else { - for(var property in addProperties) { - if(!!addProperties[property] && addProperties[property].value !== undefined) { - addProperties[property] = addProperties[property].value; - } - } - - if(!!addProperties) { - console.log(tl.loc('UpdatingAppServiceApplicationSettings', JSON.stringify(addProperties))); - } - - if(!!deleteProperties) { - console.log(tl.loc('DeletingAppServiceApplicationSettings', JSON.stringify(Object.keys(deleteProperties)))); - } - - var isNewValueUpdated: boolean = await this._appService.patchApplicationSettings(addProperties, deleteProperties); - } - - if(!!isNewValueUpdated) { - console.log(tl.loc('UpdatedAppServiceApplicationSettings')); - } - else { - console.log(tl.loc('AppServiceApplicationSettingsAlreadyPresent')); - } - - await this._appService.patchApplicationSettingsSlot(addProperties); - return isNewValueUpdated; - } - public async updateConnectionStrings(addProperties: any): Promise { var connectionStringProperties = {}; for(var property in addProperties) { @@ -251,69 +84,13 @@ export class AzureAppServiceUtility { return isNewValueUpdated; } - public async enableRenameLockedFiles(): Promise { - try { - var webAppSettings = await this._appService.getApplicationSettings(); - if(webAppSettings && webAppSettings.properties) { - if(webAppSettings.properties.MSDEPLOY_RENAME_LOCKED_FILES !== '1') { - tl.debug(`Rename locked files value found to be ${webAppSettings.properties.MSDEPLOY_RENAME_LOCKED_FILES}. Updating the value to 1`); - await this.updateAndMonitorAppSettings({ 'MSDEPLOY_RENAME_LOCKED_FILES' : '1' }); - console.log(tl.loc('RenameLockedFilesEnabled')); - } - else { - tl.debug('Rename locked files is already enabled in App Service'); - } - } - } - catch(error) { - throw new Error(tl.loc('FailedToEnableRenameLockedFiles', error)); - } - } - - public async updateStartupCommandAndRuntimeStack(runtimeStack: string, startupCommand?: string): Promise { - var configDetails = await this._appService.getConfiguration(); - var appCommandLine: string = configDetails.properties.appCommandLine; - startupCommand = (!!startupCommand) ? startupCommand : appCommandLine; - var linuxFxVersion: string = configDetails.properties.linuxFxVersion; - runtimeStack = (!!runtimeStack) ? runtimeStack : linuxFxVersion; - - if (startupCommand != appCommandLine || runtimeStack != linuxFxVersion) { - await this.updateConfigurationSettings({linuxFxVersion: runtimeStack, appCommandLine: startupCommand}); - } - else { - tl.debug(`Skipped updating the values. linuxFxVersion: ${linuxFxVersion} : appCommandLine: ${appCommandLine}`) - } - } - - private async _getPhysicalToVirtualPathMap(virtualApplication: string): Promise { - // construct URL depending on virtualApplication or root of webapplication - var physicalPath = null; - var virtualPath = "/" + virtualApplication; - var appConfigSettings = await this._appService.getConfiguration(); - var virtualApplicationMappings = appConfigSettings.properties && appConfigSettings.properties.virtualApplications; - - if(virtualApplicationMappings) { - for( var mapping of virtualApplicationMappings ) { - if(mapping.virtualPath.toLowerCase() == virtualPath.toLowerCase()) { - physicalPath = mapping.physicalPath; - break; - } - } - } - - return physicalPath ? { - 'virtualPath': virtualPath, - 'physicalPath': physicalPath - }: null; - } - private _getNewMetadata(): any { var collectionUri = tl.getVariable("system.teamfoundationCollectionUri"); var projectId = tl.getVariable("system.teamprojectId"); var releaseDefinitionId = tl.getVariable("release.definitionId"); // Log metadata properties based on whether task is running in build OR release. - + let newProperties = { VSTSRM_ProjectId: projectId, VSTSRM_AccountId: tl.getVariable("system.collectionId") @@ -323,7 +100,7 @@ export class AzureAppServiceUtility { // Task is running in Release var artifactAlias = tl.getVariable(AzureDeployPackageArtifactAlias); tl.debug("Artifact Source Alias is: "+ artifactAlias); - + let buildDefinitionUrl = ""; let buildDefintionId = ""; @@ -345,7 +122,7 @@ export class AzureAppServiceUtility { buildDefinitionUrl = collectionUri + buildProjectId + "/_build?_a=simple-process&definitionId=" + buildDefintionId; } } - + newProperties["VSTSRM_BuildDefinitionId"] = buildDefintionId; newProperties["VSTSRM_ReleaseDefinitionId"] = releaseDefinitionId; newProperties["VSTSRM_BuildDefinitionWebAccessUrl"] = buildDefinitionUrl; @@ -365,32 +142,32 @@ export class AzureAppServiceUtility { public async getFuntionAppNetworkingCheck(isLinuxApp): Promise { let success = true; - + try{ let isFuncPrivate = await this.isFuncWithPrivateEndpoint(); let isMicrosoftHostedAgent = await this.isMicrosoftHostedAgent(); - + if (isFuncPrivate == "true" && isMicrosoftHostedAgent == "true"){ //will NOT be able to reach kudu site if isFuncPrivate and isMicrosoftHostedAgent tl.error("Function app has private endpoint(s). But you are not running this pipeline from a self-hosted agent that has access to the Functions App. Relevant documentation: " + "https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser#install"); success = false; } - else if (isFuncPrivate == "true"){ + else if (isFuncPrivate == "true"){ //just FYI console.log("NOTE: Function app has private endpoint(s). Therefore, make sure that you are running this pipeline from a self-hosted agent that has access to the Functions App."); } - + let isFuncVNet = await this.isFuncVnetIntegrated(); if (isFuncVNet == "true"){ //just FYI console.log("NOTE: Function app is VNet integrated."); } - + //network validation only avaliable for Windows (NOT Linux) if (!isLinuxApp) { let errormessage = await this.isAzureWebJobsStorageAccessible(); - + if (errormessage){ //AzureWebJobsStorage connection string is NOT accessible from Kudu tl.error(errormessage); @@ -400,13 +177,13 @@ export class AzureAppServiceUtility { if (isFuncVNet == "false"){ console.log("NOTE: Function app is NOT VNet integrated."); } - } - } + } + } } catch(error){ tl.debug(`Skipping networking check with error: ${error}`); - } - + } + if (!success){ throw Error("Networking validation for the Function app and Storage account has failed. Please review all error messages."); } @@ -419,58 +196,35 @@ export class AzureAppServiceUtility { if (pe && pe.value && pe.value.length && pe.value.length > 0){ tl.debug("Function app has Private Endpoints."); return "true"; - } - else { - tl.debug("Function app has NO Private Endpoints."); - return "false"; - } - } - catch(error){ - tl.debug(`Skipping private endpoint check: ${error}`); - return null; - - } - - } - - - public async isSitePublishingCredentialsEnabled(): Promise{ - try{ - let scmAuthPolicy: any = await this._appService.getSitePublishingCredentialPolicies(); - tl.debug(`Site Publishing Policy check: ${JSON.stringify(scmAuthPolicy)}`); - if(scmAuthPolicy && scmAuthPolicy.properties.allow) { - tl.debug("Function App does allow SCM access"); - return true; } else { - tl.debug("Function App does not allow SCM Access"); - return false; + tl.debug("Function app has NO Private Endpoints."); + return "false"; } } catch(error){ - tl.debug(`Call to get SCM Policy check failed: ${error}`); - return false; + tl.debug(`Skipping private endpoint check: ${error}`); + return null; } } - - + public async isFuncVnetIntegrated(): Promise{ try{ let vnet: any = await this._appService.getSiteVirtualNetworkConnections(); tl.debug(`VNET check: ${JSON.stringify(vnet)}`); - if (vnet && vnet.length && vnet.length > 0){ + if (vnet && vnet.length && vnet.length > 0){ tl.debug("Function app is VNet integrated."); return "true"; } - else { + else { tl.debug("Function app is NOT VNet integrated."); return "false"; - } + } } catch(error){ tl.debug(`Skipping VNET check: ${error}`); return null; - } + } } public async isMicrosoftHostedAgent(): Promise{ @@ -480,10 +234,10 @@ export class AzureAppServiceUtility { if (agentos.match(/^Window/)){ tl.debug(`Windows Agent`); - dir = "C:\\agents\\*\\.setup_info"; + dir = "C:\\agents\\*\\.setup_info"; } - else if (agentos.match(/^Linux/)){ - tl.debug(`Linux Agent`); + else if (agentos.match(/^Linux/)){ + tl.debug(`Linux Agent`); dir = `${process.env.HOME}/agents/*/.setup_info`; } else if (agentos.match(/^Darwin/)){ @@ -491,7 +245,7 @@ export class AzureAppServiceUtility { dir = `${process.env.HOME}/runners/*/.setup_info`; } - var files = glob.sync(dir); + var files = glob.sync(dir); if (files && files.length && files.length > 0) { tl.debug(`Running on Microsoft-hosted agent.`); return "true"; @@ -504,14 +258,14 @@ export class AzureAppServiceUtility { } } - public async isAzureWebJobsStorageAccessible(): Promise{ + public async isAzureWebJobsStorageAccessible(): Promise{ let errormessage = ""; let propertyName = "AzureWebJobsStorage"; let appSettings = await this._appService.getApplicationSettings(); if(appSettings && appSettings.properties && appSettings.properties.AzureWebJobsStorage) { let connectionDetails = {}; - connectionDetails['ConnectionString'] = appSettings.properties.AzureWebJobsStorage; + connectionDetails['ConnectionString'] = appSettings.properties.AzureWebJobsStorage; connectionDetails['Type'] = 'StorageAccount'; if(connectionDetails['ConnectionString'].includes('@Microsoft.KeyVault')){ @@ -535,7 +289,7 @@ export class AzureAppServiceUtility { * MalformedConnectionString, * UnknownError */ - if (validation && validation.StatusText && validation.StatusText != "Success"){ + if (validation && validation.StatusText && validation.StatusText != "Success"){ switch (validation.StatusText) { case "MalformedConnectionString": @@ -552,8 +306,8 @@ export class AzureAppServiceUtility { break; case "Forbidden": // Some authentication failures come through as Forbidden so check the exception data - if(validation.Exception != undefined && - validation.Exception.RequestInformation != undefined && + if(validation.Exception != undefined && + validation.Exception.RequestInformation != undefined && JSON.stringify(validation.Exception.RequestInformation).includes("AuthenticationFailed")) { errormessage = `Authentication failure - The credentials in the "${propertyName}" connection string are either invalid or expired. Please update the app setting "${propertyName}" with a valid connection string.`; } else { @@ -568,8 +322,8 @@ export class AzureAppServiceUtility { // Show the exception message as it contains useful information to fix the issue. Don't show it unless its accompanied with other explanations. errormessage += (errormessage != "" && validation.Exception ? `\r\n\r\nException encountered while connecting: ${validation.Exception.Message}` : undefined); } - } - } - return errormessage; + } + } + return errormessage; } } \ No newline at end of file diff --git a/Tasks/AzureFunctionAppV2/operations/FileTransformsUtility.ts b/Tasks/AzureFunctionAppV2/operations/FileTransformsUtility.ts new file mode 100644 index 000000000000..fdf1fef18a03 --- /dev/null +++ b/Tasks/AzureFunctionAppV2/operations/FileTransformsUtility.ts @@ -0,0 +1,29 @@ +import tl = require('azure-pipelines-task-lib/task'); +var deployUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var generateWebConfigUtil = require('azure-pipelines-tasks-webdeployment-common/webconfigutil'); +import { parse } from 'azure-pipelines-tasks-webdeployment-common/ParameterParserUtility'; +import { PackageType } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; + +export class FileTransformsUtility { + private static rootDirectoryPath: string = "D:\\home\\site\\wwwroot"; + public static async applyTransformations(webPackage: string, parameters: string, packageType: PackageType): Promise { + tl.debug("WebConfigParameters is "+ parameters); + if (parameters) { + var isFolderBasedDeployment: boolean = tl.stats(webPackage).isDirectory(); + var folderPath = await deployUtility.generateTemporaryFolderForDeployment(isFolderBasedDeployment, webPackage, packageType); + if (parameters) { + tl.debug('parsing web.config parameters'); + var webConfigParameters = parse(parameters); + generateWebConfigUtil.addWebConfigFile(folderPath, webConfigParameters, this.rootDirectoryPath); + } + + var output = await deployUtility.archiveFolderForDeployment(isFolderBasedDeployment, folderPath); + webPackage = output.webDeployPkg; + } + else { + tl.debug('File Tranformation not enabled'); + } + + return webPackage; + } +} \ No newline at end of file diff --git a/Tasks/AzureFunctionAppV2/operations/KuduServiceUtility.ts b/Tasks/AzureFunctionAppV2/operations/KuduServiceUtility.ts index 026bc3ed1024..e1236eec2cda 100644 --- a/Tasks/AzureFunctionAppV2/operations/KuduServiceUtility.ts +++ b/Tasks/AzureFunctionAppV2/operations/KuduServiceUtility.ts @@ -1,15 +1,11 @@ import tl = require('azure-pipelines-task-lib/task'); -import Q = require('q'); import path = require('path'); +var deployUtility = require('azure-pipelines-tasks-webdeployment-common/utility'); +var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility'); +import { Kudu } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service-kudu'; +import { AzureDeployPackageArtifactAlias, KUDU_DEPLOYMENT_CONSTANTS } from 'azure-pipelines-tasks-azure-arm-rest-v2/constants'; +import webClient = require('azure-pipelines-tasks-azure-arm-rest-v2/webClient'); -import { AzureDeployPackageArtifactAlias } from 'azure-pipelines-tasks-azurermdeploycommon/Constants'; -import { KUDU_DEPLOYMENT_CONSTANTS } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/constants'; -import { Kudu } from '../azure-arm-rest/azure-arm-app-service-kudu'; - -import webClient = require('azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/webClient'); - -var deployUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -var zipUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/ziputility.js'); const physicalRootPath: string = '/site/wwwroot'; const deploymentFolder: string = 'site/deployments'; const manifestFileName: string = 'manifest'; @@ -18,7 +14,6 @@ const VSTS_DEPLOY: string = 'VSTS_FUNCTIONS_V2'; export class KuduServiceUtility { private _appServiceKuduService: Kudu; - private _deploymentID: string; constructor(kuduService: Kudu) { this._appServiceKuduService = kuduService; @@ -42,27 +37,9 @@ export class KuduServiceUtility { } public getDeploymentID(): string { - if(this._deploymentID) { - return this._deploymentID; - } - - var buildUrl = tl.getVariable('build.buildUri'); - var releaseUrl = tl.getVariable('release.releaseUri'); - var buildId = tl.getVariable('build.buildId'); var releaseId = tl.getVariable('release.releaseId'); - - var buildNumber = tl.getVariable('build.buildNumber'); - var releaseName = tl.getVariable('release.releaseName'); - - var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); - var teamProject = tl.getVariable('system.teamProjectId'); - - var commitId = tl.getVariable('build.sourceVersion'); - var repoName = tl.getVariable('build.repository.name'); - var repoProvider = tl.getVariable('build.repository.provider'); - - var buildOrReleaseUrl = "" ; + var deploymentID: string = (releaseId ? releaseId : buildId) + Date.now().toString(); return deploymentID; } @@ -113,7 +90,7 @@ export class KuduServiceUtility { return deploymentDetails.id; } catch(error) { - let stackTraceUrl:string = this._appServiceKuduService.getKuduStackTrace(); + let stackTraceUrl:string = this._appServiceKuduService.getKuduStackTraceUrl(); tl.error(tl.loc('PackageDeploymentFailed')); tl.error(tl.loc('KuduStackTraceURL', stackTraceUrl)); throw Error(error); @@ -136,7 +113,7 @@ export class KuduServiceUtility { console.log("NOTE: Run From Package makes wwwroot read-only, so you will receive an error when writing files to this directory."); } catch(error) { - let stackTraceUrl:string = this._appServiceKuduService.getKuduStackTrace(); + let stackTraceUrl:string = this._appServiceKuduService.getKuduStackTraceUrl(); tl.error(tl.loc('PackageDeploymentFailed')); tl.error(tl.loc('KuduStackTraceURL', stackTraceUrl)); throw Error(error); @@ -232,81 +209,6 @@ export class KuduServiceUtility { } } - private async _printPostDeploymentLogs(physicalPath: string) : Promise { - var stdoutLog = await this._appServiceKuduService.getFileContent(physicalPath, 'stdout.txt'); - var stderrLog = await this._appServiceKuduService.getFileContent(physicalPath, 'stderr.txt'); - var scriptReturnCode = await this._appServiceKuduService.getFileContent(physicalPath, 'script_result.txt'); - - if(scriptReturnCode == null) { - throw new Error('File not found in Kudu Service. ' + 'script_result.txt'); - } - - if(stdoutLog) { - console.log(tl.loc('stdoutFromScript')); - console.log(stdoutLog); - } - if(stderrLog) { - console.log(tl.loc('stderrFromScript')); - if(scriptReturnCode != '0') { - tl.error(stderrLog); - throw Error(tl.loc('ScriptExecutionOnKuduFailed', scriptReturnCode, stderrLog)); - } - else { - console.log(stderrLog); - } - } - } - - private async runCommand(physicalPath: string, command: string, timeOutInMinutes?: number, pollFolderPath?: string, pollFile?: string): Promise { - try { - await this._appServiceKuduService.runCommand(physicalPath, command); - } - catch(error) { - if(!!pollFolderPath && !!pollFile && timeOutInMinutes > 0 && error.toString().indexOf('Request timeout: /api/command') != -1) { - tl.debug('Request timeout occurs. Trying to poll for file: ' + pollFile); - await this._pollForFile(pollFolderPath, pollFile, timeOutInMinutes); - } - else { - if(typeof error.valueOf() == 'string') { - throw error; - } - - throw `${error.statusCode} - ${error.statusMessage}`; - } - } - } - - private _getPostDeploymentScript(scriptType, inlineScript, scriptPath, isLinux): any { - if(scriptType === 'Inline Script') { - tl.debug('creating kuduPostDeploymentScript_local file'); - var scriptFilePath = path.join(tl.getVariable('AGENT.TEMPDIRECTORY'), isLinux ? 'kuduPostDeploymentScript_local.sh' : 'kuduPostDeploymentScript_local.cmd'); - tl.writeFile(scriptFilePath, inlineScript); - tl.debug('Created temporary script file : ' + scriptFilePath); - return { - "filePath": scriptFilePath, - "isCreated": true - }; - } - if(!tl.exist(scriptPath)) { - throw Error(tl.loc('ScriptFileNotFound', scriptPath)); - } - var scriptExtension = path.extname(scriptPath); - if(isLinux){ - if(scriptExtension != '.sh'){ - throw Error(tl.loc('InvalidScriptFile', scriptPath)); - } - } else { - if(scriptExtension != '.bat' && scriptExtension != '.cmd') { - throw Error(tl.loc('InvalidScriptFile', scriptPath)); - } - } - tl.debug('postDeployment script path to execute : ' + scriptPath); - return { - filePath: scriptPath, - isCreated: false - } - } - private async _warFileDeployment(packagePath: string, physicalPath: string, virtualPath?: string): Promise { tl.debug('WAR: webAppPackage = ' + packagePath); let warFile = path.basename(packagePath.slice(0, packagePath.length - '.war'.length)); @@ -317,7 +219,6 @@ export class KuduServiceUtility { physicalPath = physicalPath + "/webapps/" + warFile; await this.createPathIfRequired(physicalPath); return physicalPath; - } private async _appOfflineKuduService(physicalPath: string, enableFeature: boolean): Promise { @@ -335,44 +236,13 @@ export class KuduServiceUtility { } } - private async _pollForFile(physicalPath: string, fileName: string, timeOutInMinutes: number): Promise { - var attempts: number = 0; - const retryInterval: number = 10; - if(tl.getVariable('appservicedeploy.retrytimeout')) { - timeOutInMinutes = Number(tl.getVariable('appservicedeploy.retrytimeout')); - tl.debug('Retry timeout in minutes provided by user: ' + timeOutInMinutes); - } - - var timeOutInSeconds = timeOutInMinutes * 60; - var noOfRetry = timeOutInSeconds / retryInterval; - - tl.debug(`Polling started for file: ${fileName} with retry count: ${noOfRetry}`); - - while (attempts < noOfRetry) { - attempts += 1; - var fileContent: string = await this._appServiceKuduService.getFileContent(physicalPath, fileName); - if(fileContent == null) { - tl.debug('File: ' + fileName + ' not found. retry after 5 seconds. Attempt: ' + attempts); - await webClient.sleepFor(5); - } - else { - tl.debug('Found file: ' + fileName); - return ; - } - } - - if(attempts == noOfRetry) { - throw new Error(tl.loc('PollingForFileTimeOut')); - } - } - private _getUpdateHistoryRequest(isDeploymentSuccess: boolean, deploymentID?: string, customMessage?: any): any { - + var artifactAlias = tl.getVariable(AzureDeployPackageArtifactAlias); var status = isDeploymentSuccess ? KUDU_DEPLOYMENT_CONSTANTS.SUCCESS : KUDU_DEPLOYMENT_CONSTANTS.FAILED; var releaseId = tl.getVariable('release.releaseId'); var releaseName = tl.getVariable('release.releaseName'); - var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); + var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); var teamProject = tl.getVariable('system.teamProjectId'); let buildId = '', buildNumber = '', buildProject = '', commitId = '', repoProvider = '', repoName = '', branch = '', repositoryUrl = '', author = ''; diff --git a/Tasks/AzureFunctionAppV2/operations/ReleaseAnnotationUtility.ts b/Tasks/AzureFunctionAppV2/operations/ReleaseAnnotationUtility.ts index 569ee785128a..db004fa4389b 100644 --- a/Tasks/AzureFunctionAppV2/operations/ReleaseAnnotationUtility.ts +++ b/Tasks/AzureFunctionAppV2/operations/ReleaseAnnotationUtility.ts @@ -1,7 +1,7 @@ import tl = require('azure-pipelines-task-lib/task'); -import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; -import { AzureApplicationInsights, ApplicationInsightsResources} from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azure-arm-appinsights'; -import { AzureEndpoint } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azureModels'; +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; +import { AzureApplicationInsights, ApplicationInsightsResources} from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-appinsights'; +import { AzureEndpoint } from 'azure-pipelines-tasks-azure-arm-rest-v2/azureModels'; var uuidV4 = require("uuid/v4"); diff --git a/Tasks/AzureFunctionAppV2/package-lock.json b/Tasks/AzureFunctionAppV2/package-lock.json index 04a9dd12da61..c86817cc55da 100644 --- a/Tasks/AzureFunctionAppV2/package-lock.json +++ b/Tasks/AzureFunctionAppV2/package-lock.json @@ -4,6 +4,28 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@azure/msal-common": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-9.1.1.tgz", + "integrity": "sha512-we9xR8lvu47fF0h+J8KyXoRy9+G/fPzm3QEa2TrdR3jaVS3LKAyE2qyMuUkNdbVkvzl8Zr9f7l+IUSP22HeqXw==" + }, + "@azure/msal-node": { + "version": "1.14.5", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.5.tgz", + "integrity": "sha512-NcVdMfn8Z3ogN+9RjOSF7uwf2Gki5DEJl0BdDSL83KUAgVAobtkZi5W8EqxbJLrTO/ET0jv5DregrcR5qg2pEA==", + "requires": { + "@azure/msal-common": "^9.0.1", + "jsonwebtoken": "^8.5.1", + "uuid": "^8.3.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, "@types/concat-stream": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", @@ -20,6 +42,14 @@ "@types/node": "*" } }, + "@types/jsonwebtoken": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", + "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", + "requires": { + "@types/node": "*" + } + }, "@types/mocha": { "version": "5.2.7", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", @@ -40,11 +70,20 @@ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, + "@xmldom/xmldom": { + "version": "git+https://github.com/xmldom/xmldom.git#238b1ea8431fae8817812c68d55b4933248af07e", + "from": "git+https://github.com/xmldom/xmldom.git#0.8.6" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -56,21 +95,6 @@ "uri-js": "^4.2.2" } }, - "archiver": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz", - "integrity": "sha512-01psM0DMD3YItvhnAXZODfsViaeDidrJwfne3lsoVrbyYa/xFQwTbVjY+2WlEBm7qH1fCsyxAA1SgNr/XenTlQ==", - "requires": { - "archiver-utils": "^1.3.0", - "async": "^2.0.0", - "buffer-crc32": "^0.2.1", - "glob": "^7.0.0", - "lodash": "^4.8.0", - "readable-stream": "^2.0.0", - "tar-stream": "^1.5.0", - "zip-stream": "^1.2.0" - } - }, "archiver-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", @@ -110,6 +134,14 @@ "lodash": "^4.17.14" } }, + "async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", + "requires": { + "tslib": "^2.4.0" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -125,6 +157,15 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, + "azure-devops-node-api": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz", + "integrity": "sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA==", + "requires": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, "azure-pipelines-task-lib": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.4.0.tgz", @@ -139,14 +180,6 @@ "uuid": "^3.0.1" }, "dependencies": { - "minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -154,30 +187,140 @@ } } }, - "azure-pipelines-tasks-azurermdeploycommon": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-azurermdeploycommon/-/azure-pipelines-tasks-azurermdeploycommon-3.208.0.tgz", - "integrity": "sha512-fnC+/CXdBlA6wuXLFiBcDhyfbIGeGYEePArwJl0UFesKrLLc1f6ddBz7E6esz6USdu2MFy6lWBwl9oDnurg+Rg==", + "azure-pipelines-tasks-azure-arm-rest-v2": { + "version": "3.221.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-azure-arm-rest-v2/-/azure-pipelines-tasks-azure-arm-rest-v2-3.221.1.tgz", + "integrity": "sha512-ku1bb4n9+udPPUQj+xRCmEiVsq4ZY96KH99gPJE36WPtjWsUH38ZwPbby2juKN2H6SLuPfCMtIby7WEjGsNRDQ==", "requires": { + "@azure/msal-node": "1.14.5", + "@types/jsonwebtoken": "^8.5.8", "@types/mocha": "^5.2.7", "@types/node": "^10.17.0", - "@types/q": "1.0.7", - "archiver": "2.1.1", - "azure-pipelines-task-lib": "^3.1.0", - "decompress-zip": "^0.3.3", - "jsonwebtoken": "8.5.1", - "ltx": "2.6.2", - "node-stream-zip": "1.7.0", + "@types/q": "1.5.4", + "async-mutex": "^0.4.0", + "azure-devops-node-api": "^12.0.0", + "azure-pipelines-task-lib": "^3.4.0", + "https-proxy-agent": "^4.0.0", + "jsonwebtoken": "^8.5.1", + "node-fetch": "^2.6.7", "q": "1.5.1", - "typed-rest-client": "^1.8.4", - "winreg": "1.2.2", + "typed-rest-client": "1.8.4", "xml2js": "0.4.13" }, "dependencies": { + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" + }, + "azure-devops-node-api": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.0.0.tgz", + "integrity": "sha512-S6Il++7dQeMlZDokBDWw7YVoPeb90tWF10pYxnoauRMnkuL91jq9M7SOYRVhtO3FUC5URPkB/qzGa7jTLft0Xw==", + "requires": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "azure-pipelines-task-lib": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.4.0.tgz", + "integrity": "sha512-3eC4OTFw+7xD7A2aUhxR/j+jRlTI+vVfS0CGxt1pCLs4c/KmY0tQWgbqjD3157kmiucWxELBvgZHaD2gCBe9fg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + } + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz", + "integrity": "sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "typed-rest-client": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.4.tgz", + "integrity": "sha512-MyfKKYzk3I6/QQp6e1T50py4qg+c+9BzOEl2rBmQIpStwNUoqQ73An+Tkfy9YuV7O+o2mpVVJpe+fH//POZkbg==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + } + } + }, + "azure-pipelines-tasks-webdeployment-common": { + "version": "4.219.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-webdeployment-common/-/azure-pipelines-tasks-webdeployment-common-4.219.1.tgz", + "integrity": "sha512-Uf9b0u33Wwff2EBBxFcvPaL8LetSBT2q8l28SVTOVcDgnQVMKJPR7pMK+DBzLiDlLe164MOcGrlOK+Oi/0+5LA==", + "requires": { + "@types/mocha": "^5.2.7", + "@types/node": "^10.17.0", + "@xmldom/xmldom": "git+https://github.com/xmldom/xmldom.git#0.8.6", + "archiver": "1.2.0", + "azure-pipelines-task-lib": "^4.2.0", + "decompress-zip": "^0.3.3", + "ltx": "2.8.0", + "q": "1.4.1", + "winreg": "1.2.2", + "xml2js": "0.4.13" + }, + "dependencies": { + "archiver": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.2.0.tgz", + "integrity": "sha512-5GQRAgpHGPwWIiMzL9lthd+t75fLi8BpRBYtflomSYv2i6+EO9trtwWAm2+zGjIuwKmVmBRknAZFFBSqxYxiJw==", + "requires": { + "archiver-utils": "^1.3.0", + "async": "^2.0.0", + "buffer-crc32": "^0.2.1", + "glob": "^7.0.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0", + "tar-stream": "^1.5.0", + "zip-stream": "^1.1.0" + } + }, + "azure-pipelines-task-lib": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.3.1.tgz", + "integrity": "sha512-AEwz0+Sofv80UviCYsS6fzyX5zzsLapmNCMNUoaRePZQVN+oQBStix1DGg4fdZf9zJ6acNd9xEBZQWbWuZu5Zg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + } + } + }, + "ltx": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/ltx/-/ltx-2.8.0.tgz", + "integrity": "sha512-SJJUrmDgXP0gkUzgErfkaeD+pugM8GYxerTALQa1gTUb5W1wrC4k07GZU+QNZd7MpFqJSYWXTQSUy8Ps03hx5Q==", + "requires": { + "inherits": "^2.0.1" + } } } }, @@ -405,6 +548,21 @@ "assert-plus": "^1.0.0" } }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "decompress-zip": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.3.tgz", @@ -551,6 +709,16 @@ "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "graceful-fs": { @@ -654,6 +822,15 @@ "sshpk": "^1.7.0" } }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + } + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -829,14 +1006,6 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, - "ltx": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/ltx/-/ltx-2.6.2.tgz", - "integrity": "sha512-xg03AeMzTVozL1K/fuzxkzvnvx+yjY6/uJHN6dmQYP8Jm26GJjEr5EV3Sj5Yi/XYDJ1k9xVPZWvdQzJG7o+C5w==", - "requires": { - "inherits": "^2.0.1" - } - }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -861,9 +1030,9 @@ } }, "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", "requires": { "brace-expansion": "^1.1.7" } @@ -888,10 +1057,13 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node-stream-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.7.0.tgz", - "integrity": "sha512-kYVtF3lK++53Bg6hZNplYVMrR7Lt0IYdLWehgoHUJLJcSwg/xd2Rm2Z7kJ5W8ZA7pdeg/DiUQDatbYwL3C7qSw==" + "node-fetch": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "requires": { + "whatwg-url": "^5.0.0" + } }, "nopt": { "version": "3.0.6", @@ -1216,11 +1388,21 @@ "punycode": "^2.1.1" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "traverse": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==" }, + "tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, "tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", @@ -1308,6 +1490,20 @@ "extsprintf": "^1.2.0" } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "winreg": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.2.tgz", diff --git a/Tasks/AzureFunctionAppV2/package.json b/Tasks/AzureFunctionAppV2/package.json index 5537730c6f29..43723cc893c4 100644 --- a/Tasks/AzureFunctionAppV2/package.json +++ b/Tasks/AzureFunctionAppV2/package.json @@ -20,7 +20,10 @@ "@types/mocha": "^5.2.7", "@types/node": "^10.17.0", "@types/q": "1.0.7", - "azure-pipelines-tasks-azurermdeploycommon": "^3.208.0", + "azure-devops-node-api": "11.2.0", + "azure-pipelines-task-lib": "^3.4.0", + "azure-pipelines-tasks-azure-arm-rest-v2": "^3.221.1", + "azure-pipelines-tasks-webdeployment-common": "^4.219.1", "azure-storage": "2.10.7", "moment": "^2.29.4", "q": "1.4.1", diff --git a/Tasks/AzureFunctionAppV2/task.json b/Tasks/AzureFunctionAppV2/task.json index 55367fad613e..f4c7c6b8fe87 100644 --- a/Tasks/AzureFunctionAppV2/task.json +++ b/Tasks/AzureFunctionAppV2/task.json @@ -18,7 +18,7 @@ "version": { "Major": 2, "Minor": 221, - "Patch": 101 + "Patch": 102 }, "releaseNotes": "What's new in version 2.*
Removed WAR Deploy Support, setting Web.Config options, and the option for the Startup command for Linux Azure Function Apps.", "minimumAgentVersion": "2.104.1", diff --git a/Tasks/AzureFunctionAppV2/task.loc.json b/Tasks/AzureFunctionAppV2/task.loc.json index c4742cbb4413..84a31169ec9f 100644 --- a/Tasks/AzureFunctionAppV2/task.loc.json +++ b/Tasks/AzureFunctionAppV2/task.loc.json @@ -18,7 +18,7 @@ "version": { "Major": 2, "Minor": 221, - "Patch": 101 + "Patch": 102 }, "releaseNotes": "ms-resource:loc.releaseNotes", "minimumAgentVersion": "2.104.1", diff --git a/Tasks/AzureFunctionAppV2/taskparameters.ts b/Tasks/AzureFunctionAppV2/taskparameters.ts index b86390f0aebe..5f3355e9540b 100644 --- a/Tasks/AzureFunctionAppV2/taskparameters.ts +++ b/Tasks/AzureFunctionAppV2/taskparameters.ts @@ -1,10 +1,10 @@ -import { AzureEndpoint } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azureModels'; import tl = require('azure-pipelines-task-lib/task'); -import { Package, PackageType } from 'azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/packageUtility'; -var webCommonUtility = require('azure-pipelines-tasks-azurermdeploycommon/webdeployment-common/utility.js'); -import { AzureRMEndpoint } from 'azure-pipelines-tasks-azurermdeploycommon/azure-arm-rest/azure-arm-endpoint'; -import { AzureResourceFilterUtility } from 'azure-pipelines-tasks-azurermdeploycommon/operations/AzureResourceFilterUtility'; -import { AzureAppService } from './azure-arm-rest/azure-arm-app-service'; +import { AzureEndpoint } from 'azure-pipelines-tasks-azure-arm-rest-v2/azureModels'; +import { AzureRMEndpoint } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-endpoint'; +import { AzureAppService } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-app-service'; +import { Resources } from 'azure-pipelines-tasks-azure-arm-rest-v2/azure-arm-resource'; +import { Package } from 'azure-pipelines-tasks-webdeployment-common/packageUtility'; + const skuDynamicValue: string = 'dynamic'; const skuElasticPremiumValue: string = 'elasticpremium'; @@ -66,7 +66,8 @@ export class TaskParametersUtility { var kind = taskParameters.WebAppKind; var sku; if (!resourceGroupName) { - var appDetails = await AzureResourceFilterUtility.getAppDetails(taskParameters.azureEndpoint, taskParameters.WebAppName); + var azureResources: Resources = new Resources(taskParameters.azureEndpoint); + var appDetails = await azureResources.getAppDetails(taskParameters.WebAppName); resourceGroupName = appDetails["resourceGroupName"]; if(!kind) { kind = webAppKindMap.get(appDetails["kind"]) ? webAppKindMap.get(appDetails["kind"]) : appDetails["kind"];