Skip to content
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

Users/ajya/nationalcloudclientsidechanges #3551

Merged
merged 13 commits into from
Feb 16, 2017
1 change: 1 addition & 0 deletions Tasks/AzureAppServiceManage/azureappservicemanage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ async function run() {
endPoint["servicePrincipalKey"] = tl.getEndpointAuthorizationParameter(connectedServiceName, 'serviceprincipalkey', true);
endPoint["tenantID"] = tl.getEndpointAuthorizationParameter(connectedServiceName, 'tenantid', true);
endPoint["subscriptionId"] = tl.getEndpointDataParameter(connectedServiceName, 'subscriptionid', true);
endPoint["envAuthUrl"] = tl.getEndpointDataParameter(connectedServiceName, 'environmentAuthorityUrl', true);
endPoint["url"] = tl.getEndpointUrl(connectedServiceName, true);

if(resourceGroupName === null) {
Expand Down
33 changes: 17 additions & 16 deletions Tasks/AzureNLBManagement/nlbazureutility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ var httpObj = new httpClient.HttpCallbackClient(tl.getVariable("AZURE_HTTP_USER_
var authUrl = 'https://login.windows.net/';
var azureApiVersion = '2016-09-01';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this API version work fine in other Cloud environment types. Do you see any issue with Azure deployments causing issues?


function getAccessToken(SPN, endpointUrl: string): Q.Promise<string> {
function getAccessToken(endpoint, endpointUrl: string): Q.Promise<string> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having the second parameter as enpointurl is confusing. There is already endpoint taken as input which has endpoint.url. I presume this is the resource for which you are requesting token. So should we just call it resource?


var deferred = Q.defer<string>();
var authorityUrl = authUrl + SPN.tenantID + "/oauth2/token/";
var envAuthUrl = endpoint.envAuthUrl;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if it is necessary to hard-code envAuthUrl if it is null.

var authorityUrl = envAuthUrl + endpoint.tenantID + "/oauth2/token/";

var post_data = querystring.stringify({
resource: endpointUrl,
client_id: SPN.servicePrincipalClientID,
client_id: endpoint.servicePrincipalClientID,
grant_type: "client_credentials",
client_secret: SPN.servicePrincipalKey
client_secret: endpoint.servicePrincipalKey
});

var requestHeader = {
Expand All @@ -40,11 +41,11 @@ function getAccessToken(SPN, endpointUrl: string): Q.Promise<string> {
return deferred.promise;
}

export async function getNetworkInterfacesInRG(SPN, endpointUrl: string, resourceGroupName: string) {
export async function getNetworkInterfacesInRG(endpoint, endpointUrl: string, resourceGroupName: string) {

var deferred = Q.defer<any>();
var restUrl = "https://management.azure.com/subscriptions/" + SPN.subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces?api-version=" + azureApiVersion;
var accessToken = await getAccessToken(SPN, endpointUrl);
var restUrl = endpoint.url + "subscriptions/" + endpoint.subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces?api-version=" + azureApiVersion;
var accessToken = await getAccessToken(endpoint, endpointUrl);

var requestHeader = {
Authorization: 'Bearer ' + accessToken
Expand All @@ -66,11 +67,11 @@ export async function getNetworkInterfacesInRG(SPN, endpointUrl: string, resourc
return deferred.promise;
}

export async function getLoadBalancer(SPN, endpointUrl: string, name: string, resourceGroupName: string) {
export async function getLoadBalancer(endpoint, endpointUrl: string, name: string, resourceGroupName: string) {

var deferred = Q.defer<any>();
var restUrl = "https://management.azure.com/subscriptions/" + SPN.subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/loadBalancers/" + name + "?api-version=" + azureApiVersion;
var accessToken = await getAccessToken(SPN, endpointUrl);
var restUrl = endpoint.url + "subscriptions/" + endpoint.subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/loadBalancers/" + name + "?api-version=" + azureApiVersion;
var accessToken = await getAccessToken(endpoint, endpointUrl);

var requestHeader = {
authorization: 'Bearer ' + accessToken
Expand All @@ -92,10 +93,10 @@ export async function getLoadBalancer(SPN, endpointUrl: string, name: string, re
return deferred.promise;
}

export async function getNetworkInterface(SPN, endpointUrl, name: string, resourceGroupName: string) {
export async function getNetworkInterface(endpoint, endpointUrl, name: string, resourceGroupName: string) {
var deferred = Q.defer<any>();
var restUrl = "https://management.azure.com/subscriptions/" + SPN.subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces/" + name + "?api-version=" + azureApiVersion;
var accessToken = await getAccessToken(SPN, endpointUrl);
var restUrl = endpoint.url + "subscriptions/" + endpoint.subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces/" + name + "?api-version=" + azureApiVersion;
var accessToken = await getAccessToken(endpoint, endpointUrl);

var requestHeader = {
authorization: 'Bearer ' + accessToken
Expand Down Expand Up @@ -136,11 +137,11 @@ async function checkProvisioningState(url: string, accessToken: string) {
return deferred.promise;
}

export async function setNetworkInterface(SPN, endpointUrl: string, nic, resourceGroupName: string){
export async function setNetworkInterface(endpoint, endpointUrl: string, nic, resourceGroupName: string){

var deferred = Q.defer();
var restUrl = "https://management.azure.com/subscriptions/" + SPN.subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces/" + nic.name + "?api-version=" + azureApiVersion;
var accessToken = await getAccessToken(SPN, endpointUrl);
var restUrl = endpoint.url + "subscriptions/" + endpoint.subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces/" + nic.name + "?api-version=" + azureApiVersion;
var accessToken = await getAccessToken(endpoint, endpointUrl);
var requestHeader = {
"Content-Type": "application/json; charset=utf-8",
"Authorization": 'Bearer ' + accessToken
Expand Down
1 change: 1 addition & 0 deletions Tasks/AzureNLBManagement/nlbtask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ async function run() {
SPN["servicePrincipalKey"] = endPointAuthCreds.parameters["serviceprincipalkey"];
SPN["tenantID"] = endPointAuthCreds.parameters["tenantid"];
SPN["subscriptionId"] = tl.getEndpointDataParameter(connectedServiceName, 'subscriptionid', true);
SPN["envAuthUrl"] = tl.getEndpointDataParameter(connectedServiceName, 'environmentAuthorityUrl', true);

var nicVm = await getNetworkInterface(SPN, endpointUrl, resourceGroupName);
tl.debug(`Network Interface - ${nicVm.name}'s configuration details fetched for the virtual machine ${process.env.COMPUTERNAME}`);
Expand Down
4 changes: 3 additions & 1 deletion Tasks/AzureResourceGroupDeployment/models/DeployAzureRG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ export class AzureRGTaskParameters {
var servicePrincipalId: string = endpointAuth.parameters["serviceprincipalid"];
var servicePrincipalKey: string = endpointAuth.parameters["serviceprincipalkey"];
var tenantId: string = endpointAuth.parameters["tenantid"];
var credentials = new msRestAzure.ApplicationTokenCredentials(servicePrincipalId, tenantId, servicePrincipalKey);
var armUrl: string = tl.getEndpointUrl(connectedService, true);
var envAuthUrl: string = tl.getEndpointDataParameter(connectedService, 'environmentAuthorityUrl', true);
var credentials = new msRestAzure.ApplicationTokenCredentials(servicePrincipalId, tenantId, servicePrincipalKey, armUrl, envAuthUrl);
return credentials;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class ServiceClient {

this.credentials = credentials;
this.subscriptionId = subscriptionId
this.baseUri = 'https://management.azure.com';
this.baseUri = this.credentials.armUrl;
this.longRunningOperationRetryTimeout = 60; // In minutes
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ export class ApplicationTokenCredentials {
private clientId: string;
private domain: string;
private secret: string;
public armUrl: string;
public authUrl: string;
private token_deferred: Q.Promise<string>;

constructor(clientId: string, domain: string, secret: string) {
constructor(clientId: string, domain: string, secret: string, armUrl: string, authUrl: string) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

authUrl is confusing since auth is mostly used for authentication. I would prefer full name authorityUrl

if (!Boolean(clientId) || typeof clientId.valueOf() !== 'string') {
throw new Error(tl.loc("ClientIdCannotBeEmpty"));
}
Expand All @@ -30,9 +32,19 @@ export class ApplicationTokenCredentials {
throw new Error(tl.loc("SecretCannotBeEmpty"));
}

if (!Boolean(armUrl) || typeof armUrl.valueOf() !== 'string') {
throw new Error(tl.loc("armUrlCannotBeEmpty"));
}

if (!Boolean(authUrl) || typeof authUrl.valueOf() !== 'string') {
throw new Error(tl.loc("authUrlCannotBeEmpty"));
}

this.clientId = clientId;
this.domain = domain;
this.secret = secret;
this.armUrl = armUrl;
this.authUrl = authUrl;
}

public getToken(force?: boolean): Q.Promise<string> {
Expand All @@ -45,9 +57,9 @@ export class ApplicationTokenCredentials {

private getAuthorizationToken(): Q.Promise<string> {
var deferred = Q.defer<string>();
var authorityUrl = authUrl + this.domain + "/oauth2/token/";
var authorityUrl = this.authUrl + this.domain + "/oauth2/token/";
var requestData = querystring.stringify({
resource: 'https://management.azure.com/',
resource: this.armUrl,
client_id: this.clientId,
grant_type: "client_credentials",
client_secret: this.secret
Expand Down
1 change: 1 addition & 0 deletions Tasks/AzureRmWebAppDeployment/azurermwebappdeployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ async function run() {
endPoint["servicePrincipalKey"] = tl.getEndpointAuthorizationParameter(connectedServiceName, 'serviceprincipalkey', true);
endPoint["tenantID"] = tl.getEndpointAuthorizationParameter(connectedServiceName, 'tenantid', true);
endPoint["subscriptionId"] = tl.getEndpointDataParameter(connectedServiceName, 'subscriptionid', true);
endPoint["envAuthUrl"] = tl.getEndpointDataParameter(connectedServiceName, 'environmentAuthorityUrl', true);
endPoint["url"] = tl.getEndpointUrl(connectedServiceName, true);

if(deployToSlotFlag) {
Expand Down
12 changes: 6 additions & 6 deletions Tasks/Common/VstsAzureHelpers_/InitializeFunctions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ function Initialize-AzureSubscription {

#Set UserAgent for Azure Calls
Set-UserAgent

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you ensure Azure PowerShell task is covered as part of your testing?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I have tested Azure Powershell Task

$environmentName = "AzureCloud"
if( $Endpoint.Data.Environment ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this does not validate if it contains an empty string with space. Please check if you want to trim it before it gets used

$environmentName = $Endpoint.Data.Environment
}

if ($Endpoint.Auth.Scheme -eq 'Certificate') {
# Certificate is only supported for the Azure module.
Expand All @@ -57,11 +62,6 @@ function Initialize-AzureSubscription {
$additional['CurrentStorageAccountName'] = $StorageAccount
}

$environmentName = "AzureCloud"
if( $Endpoint.Data.Environment ) {
$environmentName = $Endpoint.Data.Environment
}

# Set the subscription.
Write-Host "##[command]Set-AzureSubscription -SubscriptionName $($Endpoint.Data.SubscriptionName) -SubscriptionId $($Endpoint.Data.SubscriptionId) -Certificate ******** -Environment $environmentName $(Format-Splat $additional)"
Set-AzureSubscription -SubscriptionName $Endpoint.Data.SubscriptionName -SubscriptionId $Endpoint.Data.SubscriptionId -Certificate $certificate -Environment $environmentName @additional
Expand Down Expand Up @@ -127,7 +127,7 @@ function Initialize-AzureSubscription {
# Else, this is AzureRM.
try {
Write-Host "##[command]Add-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -Credential $psCredential"
$null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential
$null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -EnvironmentName $environmentName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to log $environmentName if it is within security rules

} catch {
# Provide an additional, custom, credentials-related error message.
Write-VstsTaskError -Message $_.Exception.Message
Expand Down
34 changes: 22 additions & 12 deletions Tasks/Common/VstsAzureRestHelpers_/VstsAzureRestHelpers_.psm1
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Private module-scope variables.
$script:jsonContentType = "application/json;charset=utf-8"
$script:formContentType = "application/x-www-form-urlencoded;charset=utf-8"
$script:azureRmUri = "https://management.azure.com"
$script:authUri = "https://login.microsoftonline.com/"
$script:defaultAuthUri = "https://login.microsoftonline.com/"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find this URL in the get-Environment output. What url does this map to?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

login.windows.net is legacy auth URL, login.microsoftonline.com is latest auth url. In environment property its showing only latest one. Since other URL is being used at many places in application so added it as another property.

$script:defaultEnvironmentAuthUri = "https://login.windows.net/"

# Connection Types
$certificateConnection = 'Certificate'
Expand Down Expand Up @@ -103,8 +103,13 @@ function Get-UsernamePasswordAccessToken {
# Well known Client-Id
$password = $endpoint.Auth.Parameters.Password
$username = $endpoint.Auth.Parameters.UserName
$authUrl = $script:defaultAuthUri
if($endpoint.Data.activeDirectoryAuthority)
{
$authUrl = $endpoint.Data.activeDirectoryAuthority
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is activeDirecotryAuthority and environment Auth Url used interchangeably?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the GetAccessToken in nlbUtility you were using the environment Auth url. Why?

}

$authUri = "$script:authUri/common/oauth2/token"
$authUri = "$authUrl/common/oauth2/token"
$body = @{
resource=$script:azureUri
client_id=$azurePsClientId
Expand Down Expand Up @@ -134,12 +139,17 @@ function Get-SpnAccessToken {
$principalId = $endpoint.Auth.Parameters.ServicePrincipalId
$tenantId = $endpoint.Auth.Parameters.TenantId
$principalKey = $endpoint.Auth.Parameters.ServicePrincipalKey
$envAuthUrl = $script:defaultEnvironmentAuthUri
if($endpoint.Data.environmentAuthorityUrl)
{
$envAuthUrl = $endpoint.Data.environmentAuthorityUrl
}

$azureUri = Get-AzureUri $endpoint

# Prepare contents for POST
$method = "POST"
$authUri = "https://login.windows.net/$tenantId/oauth2/token"
$authUri = "$envAuthUrl" + "$tenantId/oauth2/token"
$body = @{
resource=$azureUri+"/"
client_id=$principalId
Expand Down Expand Up @@ -240,7 +250,7 @@ function Get-AzRMStorageKeys
$resourceGroupId = $resourceGroupDetails.id

$method = "POST"
$uri = "$script:azureRmUri$resourceGroupId/providers/Microsoft.Storage/storageAccounts/$storageAccountName/listKeys" + '?api-version=2015-06-15'
$uri = "$($endpoint.Url)$resourceGroupId/providers/Microsoft.Storage/storageAccounts/$storageAccountName/listKeys" + '?api-version=2015-06-15'

$headers = @{"Authorization" = ("{0} {1}" -f $accessToken.token_type, $accessToken.access_token)}

Expand Down Expand Up @@ -281,7 +291,7 @@ function Get-AzRmVmCustomScriptExtension
$resourceGroupId = $resourceGroupDetails.id

$method="GET"
$uri = "$script:azureRmUri$resourceGroupId/providers/Microsoft.Compute/virtualMachines/$vmName/extensions/$Name" + '?api-version=2016-03-30'
$uri = "$($endpoint.Url)$resourceGroupId/providers/Microsoft.Compute/virtualMachines/$vmName/extensions/$Name" + '?api-version=2016-03-30'

$headers = @{"accept-language" = "en-US"}
$headers.Add("Authorization", ("{0} {1}" -f $accessToken.token_type, $accessToken.access_token))
Expand Down Expand Up @@ -323,7 +333,7 @@ function Remove-AzRmVmCustomScriptExtension
$resourceGroupId = $resourceGroupDetails.id

$method="DELETE"
$uri = "$script:azureRmUri$resourceGroupId/providers/Microsoft.Compute/virtualMachines/$vmName/extensions/$Name" + '?api-version=2016-03-30'
$uri = "$($endpoint.Url)$resourceGroupId/providers/Microsoft.Compute/virtualMachines/$vmName/extensions/$Name" + '?api-version=2016-03-30'

$headers = @{"accept-language" = "en-US"}
$headers.Add("Authorization", ("{0} {1}" -f $accessToken.token_type, $accessToken.access_token))
Expand Down Expand Up @@ -403,7 +413,7 @@ function Get-AzRmStorageAccount
$resourceGroupId = $resourceGroupDetails.id

$method="GET"
$uri = "$script:azureRmUri$resourceGroupId/providers/Microsoft.Storage/storageAccounts/$storageAccountName" + '?api-version=2016-01-01'
$uri = "$($endpoint.Url)$resourceGroupId/providers/Microsoft.Storage/storageAccounts/$storageAccountName" + '?api-version=2016-01-01'

$headers = @{"Authorization" = ("{0} {1}" -f $accessToken.token_type, $accessToken.access_token)}

Expand Down Expand Up @@ -457,7 +467,7 @@ function Get-AzRmResourceGroup
$subscriptionId = $endpoint.Data.SubscriptionId.ToLower()

$method="GET"
$uri = "$script:azureRmUri/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName" + '?api-version=2016-02-01'
$uri = "$($endpoint.Url)/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName" + '?api-version=2016-02-01'

$headers = @{"Authorization" = ("{0} {1}" -f $accessToken.token_type, $accessToken.access_token)}

Expand Down Expand Up @@ -497,7 +507,7 @@ function Get-AzureSqlDatabaseServerResourceId

Write-Verbose "[Azure Rest Call] Get Resource Groups"
$method = "GET"
$uri = "$script:azureRmUri/subscriptions/$subscriptionId/resources?api-version=$apiVersion"
$uri = "$($endpoint.Url)/subscriptions/$subscriptionId/resources?api-version=$apiVersion"
$headers = @{Authorization=("{0} {1}" -f $accessToken.token_type, $accessToken.access_token)}

do {
Expand Down Expand Up @@ -568,7 +578,7 @@ function Add-AzureRmSqlServerFirewall
# get azure sql server resource Id
$azureResourceId = Get-AzureSqlDatabaseServerResourceId -endpoint $endpoint -serverName $serverName -accessToken $accessToken

$uri = "$script:azureRmUri/$azureResourceId/firewallRules/$firewallRuleName\?api-version=$apiVersion"
$uri = "$($endpoint.Url)/$azureResourceId/firewallRules/$firewallRuleName\?api-version=$apiVersion"
$body = "{
'properties' : {
'startIpAddress':'$startIPAddress',
Expand Down Expand Up @@ -621,7 +631,7 @@ function Remove-AzureRmSqlServerFirewall
# Fetch Azure SQL server resource Id
$azureResourceId = Get-AzureSqlDatabaseServerResourceId -endpoint $endpoint -serverName $serverName -accessToken $accessToken

$uri = "$script:azureRmUri/$azureResourceId/firewallRules/$firewallRuleName\?api-version=$apiVersion"
$uri = "$($endpoint.Url)/$azureResourceId/firewallRules/$firewallRuleName\?api-version=$apiVersion"
$headers = @{Authorization=("{0} {1}" -f $accessToken.token_type, $accessToken.access_token)}

Invoke-RestMethod -Uri $uri -Method Delete -Headers $headers
Expand Down
Loading