-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AzureRMWebAppTask migrated to nodejs #2506
Merged
Merged
Changes from all commits
Commits
Show all changes
65 commits
Select commit
Hold shift + click to select a range
5c87a1c
Migrating from Powershell to Node.js
vincent1173 fa03c87
Made Change to Friendly Name
vincent1173 28e9932
Additional Changes
vincent1173 8656196
Additional Changes
vincent1173 f704897
Made changes to RMUtil
vincent1173 b703fef
Merge branch 'master' of https://github.com/Microsoft/vsts-tasks into…
vincent1173 2aeb4cb
Made change to Rest Call
vincent1173 88bd1e0
Added Q
vincent1173 3f2fc9e
Added Q Library
vincent1173 2165c5c
Rearranged module headers
vincent1173 0a879a2
Made changes to task.json
vincent1173 9ad95f3
Redefining error message
vincent1173 6d5f42e
Removing PS Files
vincent1173 857b167
MSDEPloyexePath Function added
vincent1173 74c50bc
MSDEPloyexePath Function added
vincent1173 93f9a5e
Changed then with await, package.json updated
vincent1173 f5ca7e1
Removing .taskkey
vincent1173 a9f58b9
Run MSDeploycommand function updated
vincent1173 811338a
Async await changes
vincent1173 b835158
Handling files with spaces
vincent1173 b6f3080
CheckFile Function added
vincent1173 f28dd86
Fix for task not failing in case of error
vincent1173 8164962
Fixed review comments
vincent1173 6905985
Destination output url Fix
vincent1173 a435918
Publishing profile Fix
vincent1173 e7d9a4f
SetParamFile find Fix
vincent1173 66fb795
SetParam File Fix
vincent1173 f697987
File supplied Fix
vincent1173 9151d36
Fixing few formatting issues
mvvsubbu 2fc7486
Users/ajya/node js folder support to task (#2328)
dd227f2
PR Review Fix (MSDeploy return code Fix)
vincent1173 180d22f
Added WebDeploy Function
vincent1173 3f70859
Added Comments at Method Level
vincent1173 283fc8a
AzureRMUtil Update Deployment History Fix
vincent1173 90903b1
Fixing Formatting issues
vincent1173 58a5f6f
Destination URL Fix
vincent1173 07cf6d8
Migrating AzureRmWebApp from Powershell to Node.js (#2262)
vincent1173 2aeb121
common part moved to main
2e64fed
Deployment of webapplication using KUDU service
de54213
Indentation correction of deferred statement
d18690f
added messages that will be help for debugging.
bae8f21
Adding unit test for AzureRMWebAppDeployment Task (#2386)
asranja 6cfd9f0
Azure RM Upgrade scenario handling in task
mvvsubbu f7aee8d
Review comment fixes
mvvsubbu 8893cda
Merge pull request #2389 from Microsoft/users/ajya/devKuduSupportARMW…
mvvsubbu 051afc5
Changed Request to HttpClient
vincent1173 dd8efd8
Changes Reqyest to HttpClient
vincent1173 21e4d3d
Changed Error to defer(reject)
vincent1173 9aa3e20
Changed tl to defer(resolve)
vincent1173 ad36411
SetParamFile issue fix
vincent1173 af3d0cb
Merge pull request #2442 from Microsoft/users/vinca/AzureRestCall
vincent1173 fc2c47f
Merge pull request #2396 from Microsoft/users/subraman/azurermupgradefix
mvvsubbu db7590f
msDepoyBatchFIle Path FIx
vincent1173 8f8a430
Merge pull request #2452 from Microsoft/users/vinca/setParameterFix
vincent1173 d47e9f4
Conditional selection of deployment tool and check for param file on …
f9a492a
Added unit test (#2444)
asranja 2e08efa
resolving merge conflicts
af472f7
Task upgrade fix for not reading right inputs
mvvsubbu a9c9467
Merge pull request #2532 from Microsoft/users/subraman/upgradebugfixes
mvvsubbu d821050
Reverting compact changes handling in UI
mvvsubbu f7f416c
Path Issue & Bug Bash Fix (#2512)
vincent1173 27af6ce
Merge pull request #2542 from Microsoft/users/subraman/revertupgradef…
mvvsubbu 3a9d7e2
enabling appoffline feature by default (#2555)
38fc110
Parameter Content Fix (#2557)
vincent1173 d08a528
Help mark down corrected
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,272 @@ | ||
/// <reference path="../../definitions/node.d.ts" /> | ||
/// <reference path="../../definitions/q.d.ts" /> | ||
/// <reference path="../../definitions/vsts-task-lib.d.ts" /> | ||
/// <reference path="../../definitions/vso-node-api.d.ts" /> | ||
|
||
var adal = require ('adal-node'); | ||
var parseString = require('xml2js').parseString; | ||
|
||
import tl = require('vsts-task-lib/task'); | ||
import Q = require('q'); | ||
import httpClient = require('vso-node-api/HttpClient'); | ||
import restClient = require('vso-node-api/RestClient'); | ||
|
||
var httpObj = new httpClient.HttpClient(tl.getVariable("AZURE_HTTP_USER_AGENT")); | ||
var restObj = new restClient.RestClient(httpObj); | ||
|
||
var AuthenticationContext = adal.AuthenticationContext; | ||
var authUrl = 'https://login.windows.net/'; | ||
var armUrl = 'https://management.azure.com/'; | ||
var azureApiVersion = 'api-version=2015-08-01'; | ||
|
||
/** | ||
* updates the deployment status in kudu service | ||
* | ||
* @param publishingProfile Publish Profile details | ||
* @param isDeploymentSuccess Status of Deployment | ||
* | ||
* @returns promise with string | ||
*/ | ||
export function updateDeploymentStatus(publishingProfile, isDeploymentSuccess: boolean): Q.Promise<string> { | ||
var deferred = Q.defer<string>(); | ||
|
||
var webAppPublishKuduUrl = publishingProfile.publishUrl; | ||
if(webAppPublishKuduUrl) { | ||
var requestDetails = getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); | ||
var accessToken = 'Basic ' + (new Buffer(publishingProfile.userName + ':' + publishingProfile.userPWD).toString('base64')); | ||
var headers = { | ||
authorization: accessToken | ||
}; | ||
|
||
restObj.replace(requestDetails['requestUrl'], null, requestDetails['requestBody'], headers, null, | ||
(error, response, body) => { | ||
if(error) { | ||
deferred.reject(error); | ||
} | ||
else if(response === 200) { | ||
deferred.resolve(tl.loc("Successfullyupdateddeploymenthistory", body.url)); | ||
} | ||
else { | ||
tl.warning(body); | ||
deferred.reject(tl.loc("Failedtoupdatedeploymenthistory")); | ||
} | ||
}); | ||
} | ||
else { | ||
deferred.reject(tl.loc('WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite')); | ||
} | ||
|
||
return deferred.promise; | ||
} | ||
|
||
/** | ||
* Gets the Azure RM Web App Connections details from SPN | ||
* | ||
* @param SPN Service Principal Name | ||
* @param webAppName Name of the web App | ||
* @param resourceGroupName Resource Group Name | ||
* @param deployToSlotFlag Flag to check slot deployment | ||
* @param slotName Name of the slot | ||
* | ||
* @returns (JSON) | ||
*/ | ||
export async function getAzureRMWebAppPublishProfile(SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string) { | ||
if(!deployToSlotFlag) { | ||
var webAppID = await getAzureRMWebAppID(SPN, webAppName, 'Microsoft.Web/Sites'); | ||
// webAppID Format ==> /subscriptions/<subscriptionId>/resourceGroups/<resource_grp_name>/providers/Microsoft.Web/sites/<webAppName> | ||
resourceGroupName = webAppID.id.split ('/')[4]; | ||
} | ||
var publishProfile = await getWebAppPublishProfile(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName); | ||
return publishProfile; | ||
} | ||
|
||
function getAuthorizationToken(SPN): Q.Promise<string> { | ||
|
||
var deferred = Q.defer<string>(); | ||
var authorityUrl = authUrl + SPN.tenantID; | ||
|
||
var context = new AuthenticationContext(authorityUrl); | ||
context.acquireTokenWithClientCredentials(armUrl, SPN.servicePrincipalClientID, SPN.servicePrincipalKey, (error, tokenResponse) => { | ||
if(error) { | ||
deferred.reject(error); | ||
} | ||
else { | ||
deferred.resolve(tokenResponse.accessToken); | ||
} | ||
}); | ||
|
||
return deferred.promise; | ||
} | ||
|
||
function getDeploymentAuthor(): string { | ||
var author = tl.getVariable('build.sourceVersionAuthor'); | ||
|
||
if(author === undefined) { | ||
author = tl.getVariable('build.requestedfor'); | ||
} | ||
|
||
if(author === undefined) { | ||
author = tl.getVariable('release.requestedfor'); | ||
} | ||
|
||
if(author === undefined) { | ||
author = tl.getVariable('agent.name'); | ||
} | ||
|
||
return author; | ||
} | ||
|
||
function getUpdateHistoryRequest(webAppPublishKuduUrl: string, isDeploymentSuccess: boolean): any { | ||
|
||
var status = isDeploymentSuccess ? 4 : 3; | ||
var status_text = (status == 4) ? "success" : "failed"; | ||
var author = getDeploymentAuthor(); | ||
|
||
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 collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); | ||
var teamProject = tl.getVariable('system.teamProject'); | ||
|
||
var buildOrReleaseUrl = "" ; | ||
var deploymentId = ""; | ||
|
||
if(releaseUrl !== undefined) { | ||
deploymentId = releaseId + Date.now(); | ||
buildOrReleaseUrl = collectionUrl + teamProject + "/_apps/hub/ms.vss-releaseManagement-web.hub-explorer?releaseId=" + releaseId + "&_a=release-summary"; | ||
} | ||
else if(buildUrl !== undefined) { | ||
deploymentId = buildId + Date.now(); | ||
buildOrReleaseUrl = collectionUrl + teamProject + "/_build?buildId=" + buildId + "&_a=summary"; | ||
} | ||
else { | ||
throw new Error(tl.loc('CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved')); | ||
} | ||
|
||
var message = "Updating Deployment History For Deployment " + buildOrReleaseUrl; | ||
var requestBody = { | ||
status : status, | ||
status_text : status_text, | ||
message : message, | ||
author : author, | ||
deployer : 'VSTS', | ||
details : buildOrReleaseUrl | ||
}; | ||
|
||
var webAppHostUrl = webAppPublishKuduUrl.split(':')[0]; | ||
var requestUrl = "https://" + encodeURIComponent(webAppHostUrl) + "/deployments/" + encodeURIComponent(deploymentId); | ||
|
||
var requestDetails = new Array<string>(); | ||
requestDetails["requestBody"] = requestBody; | ||
requestDetails["requestUrl"] = requestUrl; | ||
return requestDetails; | ||
} | ||
|
||
async function getWebAppPublishProfile(SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string ) { | ||
|
||
var deferred = Q.defer(); | ||
var slotUrl = deployToSlotFlag ? "/slots/" + slotName : ""; | ||
var accessToken = await getAuthorizationToken(SPN); | ||
|
||
var url = armUrl + 'subscriptions/' + SPN.subscriptionId + '/resourceGroups/' + resourceGroupName + | ||
'/providers/Microsoft.Web/sites/' + webAppName + slotUrl + '/publishxml?' + azureApiVersion; | ||
var headers = { | ||
authorization: 'Bearer '+ accessToken | ||
|
||
}; | ||
|
||
httpObj.get('POST', url, headers, (error, response, body) => { | ||
if(error) { | ||
deferred.reject(error); | ||
} | ||
else if(response.statusCode === 200) { | ||
parseString(body, (error, result) => { | ||
for (var index in result.publishData.publishProfile) { | ||
if (result.publishData.publishProfile[index].$.publishMethod === "MSDeploy") | ||
deferred.resolve(result.publishData.publishProfile[index].$); | ||
} | ||
deferred.reject(tl.loc('ErrorNoSuchDeployingMethodExists')); | ||
}); | ||
} | ||
else { | ||
tl.error(response.statusMessage); | ||
deferred.reject(tl.loc('UnabletoretrieveconnectiondetailsforazureRMWebApp0StatusCode1', webAppName, response.statusCode)); | ||
} | ||
}); | ||
|
||
return deferred.promise; | ||
} | ||
|
||
async function getAzureRMWebAppID(SPN, webAppName: string, resourceType: string) { | ||
|
||
var deferred = Q.defer<any>(); | ||
var accessToken = await getAuthorizationToken(SPN); | ||
|
||
var url = armUrl + 'subscriptions/' + SPN.subscriptionId + '/resources?$filter=resourceType EQ \'' + resourceType + | ||
'\' AND name EQ \'' + webAppName + '\'&api-version=2016-07-01'; | ||
var headers = { | ||
authorization: 'Bearer '+ accessToken | ||
}; | ||
|
||
httpObj.get('GET', url, headers, (error, response, body) => { | ||
if(error) { | ||
deferred.reject(error); | ||
} | ||
else if(response.statusCode === 200) { | ||
var webAppIDDetails = JSON.parse(body); | ||
deferred.resolve(webAppIDDetails.value[0]); | ||
} | ||
else { | ||
tl.error(response.statusMessage); | ||
deferred.reject(tl.loc('UnabletoretrieveWebAppIDforazureRMWebApp0StatusCode1', webAppName, response.statusCode)); | ||
} | ||
}); | ||
|
||
return deferred.promise; | ||
} | ||
|
||
/** | ||
* REST request for azure webapp config details. Config details contains virtual application mappings. | ||
* | ||
* @param SPN Subscription details | ||
* @param webAppName Web application name | ||
* @param deployToSlotFlag Should deploy to slot | ||
* @param slotName Slot for deployment | ||
*/ | ||
export async function getAzureRMWebAppConfigDetails(SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string) { | ||
|
||
if(!deployToSlotFlag) { | ||
var webAppID = await getAzureRMWebAppID(SPN, webAppName, 'Microsoft.Web/Sites'); | ||
resourceGroupName = webAppID.id.split ('/')[4]; | ||
} | ||
|
||
var deferred = Q.defer<any>(); | ||
var accessToken = await getAuthorizationToken(SPN); | ||
var headers = { | ||
authorization: 'Bearer '+ accessToken | ||
}; | ||
|
||
var slotUrl = deployToSlotFlag ? "/slots/" + slotName : ""; | ||
var configUrl = armUrl + 'subscriptions/' + SPN.subscriptionId + '/resourceGroups/' + resourceGroupName + | ||
'/providers/Microsoft.Web/sites/' + webAppName + slotUrl + '/config/web?' + azureApiVersion; | ||
tl.debug(tl.loc("Requestingconfigdetails", configUrl)); | ||
|
||
httpObj.get('GET', configUrl, headers, (error, response, body) => { | ||
if( error ) { | ||
deferred.reject(error); | ||
} | ||
else if(response.statusCode === 200) { | ||
var obj = JSON.parse(body); | ||
deferred.resolve(obj); | ||
} | ||
else { | ||
tl.error(response.statusMessage); | ||
deferred.reject(tl.loc('ErrorOccurredStausCode0',response.statusCode)); | ||
} | ||
}); | ||
|
||
return deferred.promise; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not required to be separate function merge both functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done