From ca347b882dc790d9ab8a8d63f5d9c65de7662a5e Mon Sep 17 00:00:00 2001 From: Vinod Kumar Date: Fri, 25 Jan 2019 17:20:23 +0530 Subject: [PATCH 1/6] Azure CLI Task: Added support for MSI based ARM service connections --- .../resources.resjson/en-US/resources.resjson | 2 +- Tasks/AzureCLIV1/azureclitask.ts | 67 ++++++++++--------- Tasks/AzureCLIV1/task.json | 4 +- Tasks/AzureCLIV1/task.loc.json | 3 +- 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson index 20b3170150d0..bb2ae136f6e7 100644 --- a/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson @@ -16,7 +16,7 @@ "loc.input.label.args": "Arguments", "loc.input.help.args": "Arguments passed to the script", "loc.input.label.addSpnToEnvironment": "Access service principal details in script", - "loc.input.help.addSpnToEnvironment": "Adds service principal id and key of the Azure endpoint you chose to the script's execution environment. You can use these variables: `$servicePrincipalId` and `$servicePrincipalKey` in your script", + "loc.input.help.addSpnToEnvironment": "Adds service principal id and key of the Azure endpoint you chose to the script's execution environment. You can use these variables: `$servicePrincipalId` and `$servicePrincipalKey` in your script.\n\nPS: Valid only with ARM Endpoint service connection with 'Service Principal' authentication scheme.", "loc.input.label.useGlobalConfig": "Use global Azure CLI configuration", "loc.input.help.useGlobalConfig": "If this is false, this task will use its own separate [Azure CLI configuration directory](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest#cli-configuration-file). This can be used to run Azure CLI tasks in *parallel* releases", "loc.input.label.cwd": "Working Directory", diff --git a/Tasks/AzureCLIV1/azureclitask.ts b/Tasks/AzureCLIV1/azureclitask.ts index afce6b9ee269..d378ff6b3600 100644 --- a/Tasks/AzureCLIV1/azureclitask.ts +++ b/Tasks/AzureCLIV1/azureclitask.ts @@ -1,4 +1,4 @@ -import { IExecSyncResult } from 'vsts-task-lib/toolrunner'; +import { IExecSyncResult, ToolRunner } from 'vsts-task-lib/toolrunner'; import path = require("path"); import tl = require("vsts-task-lib/task"); import fs = require("fs"); @@ -61,12 +61,13 @@ export class azureclitask { // set az cli config dir this.setConfigDirectory(); this.setAzureCloudBasedOnServiceEndpoint(); - this.loginAzure(); + var connectedService: string = tl.getInput("connectedServiceNameARM", true); + this.loginAzureRM(connectedService); tool.line(args); // additional args should always call line. line() parses quoted arg strings var addSpnToEnvironment = tl.getBoolInput("addSpnToEnvironment", false); - if (!!addSpnToEnvironment) { + if (!!addSpnToEnvironment && tl.getEndpointAuthorizationScheme(connectedService, true) == "ServicePrincipal") { await tool.exec({ failOnStdErr: failOnStdErr, env: { ...process.env, ...{ servicePrincipalId: this.servicePrincipalId, servicePrincipalKey: this.servicePrincipalKey } } @@ -116,39 +117,43 @@ export class azureclitask { private static servicePrincipalId: string = null; private static servicePrincipalKey: string = null; - private static loginAzure() { - var connectedService: string = tl.getInput("connectedServiceNameARM", true); - this.loginAzureRM(connectedService); - } - private static loginAzureRM(connectedService: string): void { - var servicePrincipalId: string = tl.getEndpointAuthorizationParameter(connectedService, "serviceprincipalid", false); - let authType: string = tl.getEndpointAuthorizationParameter(connectedService, 'authenticationType', true); - let cliPassword: string = null; - if (authType == "spnCertificate") { - tl.debug('certificate based endpoint'); - let certificateContent: string = tl.getEndpointAuthorizationParameter(connectedService, "servicePrincipalCertificate", false); - cliPassword = path.join(tl.getVariable('Agent.TempDirectory') || tl.getVariable('system.DefaultWorkingDirectory'), 'spnCert.pem'); - fs.writeFileSync(cliPassword, certificateContent); - this.cliPasswordPath = cliPassword; + var authScheme: string = tl.getEndpointAuthorizationScheme(connectedService, true); + var subscriptionID: string = tl.getEndpointDataParameter(connectedService, "SubscriptionID", true); - } - else { - tl.debug('key based endpoint'); - cliPassword = tl.getEndpointAuthorizationParameter(connectedService, "serviceprincipalkey", false); - this.servicePrincipalId = servicePrincipalId; - this.servicePrincipalKey = cliPassword; - } + if(authScheme == "ServicePrincipal") { + let authType: string = tl.getEndpointAuthorizationParameter(connectedService, 'authenticationType', true); + let cliPassword: string = null; + var servicePrincipalId: string = tl.getEndpointAuthorizationParameter(connectedService, "serviceprincipalid", false); + if (authType == "spnCertificate") { + tl.debug('certificate based endpoint'); + let certificateContent: string = tl.getEndpointAuthorizationParameter(connectedService, "servicePrincipalCertificate", false); + cliPassword = path.join(tl.getVariable('Agent.TempDirectory') || tl.getVariable('system.DefaultWorkingDirectory'), 'spnCert.pem'); + fs.writeFileSync(cliPassword, certificateContent); + this.cliPasswordPath = cliPassword; - var tenantId: string = tl.getEndpointAuthorizationParameter(connectedService, "tenantid", false); - var subscriptionID: string = tl.getEndpointDataParameter(connectedService, "SubscriptionID", true); + } + else { + tl.debug('key based endpoint'); + cliPassword = tl.getEndpointAuthorizationParameter(connectedService, "serviceprincipalkey", false); + this.servicePrincipalId = servicePrincipalId; + this.servicePrincipalKey = cliPassword; + } - //login using svn - this.throwIfError(tl.execSync("az", "login --service-principal -u \"" + servicePrincipalId + "\" -p \"" + cliPassword + "\" --tenant \"" + tenantId + "\""), tl.loc("LoginFailed")); - this.isLoggedIn = true; + var tenantId: string = tl.getEndpointAuthorizationParameter(connectedService, "tenantid", false); - //set the subscription imported to the current subscription - this.throwIfError(tl.execSync("az", "account set --subscription \"" + subscriptionID + "\""), tl.loc("ErrorInSettingUpSubscription")); + //login using svn + this.throwIfError(tl.execSync("az", "login --service-principal -u \"" + servicePrincipalId + "\" -p \"" + cliPassword + "\" --tenant \"" + tenantId + "\""), tl.loc("LoginFailed")); + this.isLoggedIn = true; + + //set the subscription imported to the current subscription + this.throwIfError(tl.execSync("az", "account set --subscription \"" + subscriptionID + "\""), tl.loc("ErrorInSettingUpSubscription")); + } + else if(authScheme == "ManagedServiceIdentity") { + //login using msi + this.throwIfError(tl.execSync("az", "login --identity"), tl.loc("LoginFailed")); + this.isLoggedIn = true; + } } private static setConfigDirectory(): void { diff --git a/Tasks/AzureCLIV1/task.json b/Tasks/AzureCLIV1/task.json index 0b283f54893b..e51ff8077842 100644 --- a/Tasks/AzureCLIV1/task.json +++ b/Tasks/AzureCLIV1/task.json @@ -19,7 +19,7 @@ "demands": [], "version": { "Major": 1, - "Minor": 144, + "Minor": 145, "Patch": 4 }, "minimumAgentVersion": "2.0.0", @@ -97,7 +97,7 @@ "label": "Access service principal details in script", "defaultValue": "false", "required": false, - "helpMarkDown": "Adds service principal id and key of the Azure endpoint you chose to the script's execution environment. You can use these variables: `$servicePrincipalId` and `$servicePrincipalKey` in your script", + "helpMarkDown": "Adds service principal id and key of the Azure endpoint you chose to the script's execution environment. You can use these variables: `$servicePrincipalId` and `$servicePrincipalKey` in your script.\n\nPS: Valid only with ARM Endpoint service connection with 'Service Principal' authentication scheme.", "groupName": "advanced" }, { diff --git a/Tasks/AzureCLIV1/task.loc.json b/Tasks/AzureCLIV1/task.loc.json index 01c371ab0bf2..5c7b03219b96 100644 --- a/Tasks/AzureCLIV1/task.loc.json +++ b/Tasks/AzureCLIV1/task.loc.json @@ -4,6 +4,7 @@ "friendlyName": "ms-resource:loc.friendlyName", "description": "ms-resource:loc.description", "author": "Microsoft Corporation", + "helpUrl": "http://go.microsoft.com/fwlink/?LinkID=827160", "helpMarkDown": "ms-resource:loc.helpMarkDown", "releaseNotes": "ms-resource:loc.releaseNotes", "category": "Deploy", @@ -18,7 +19,7 @@ "demands": [], "version": { "Major": 1, - "Minor": 144, + "Minor": 145, "Patch": 4 }, "minimumAgentVersion": "2.0.0", From 404b42a81ed5e668cf1622889c6cfcaa05df0d4e Mon Sep 17 00:00:00 2001 From: Vinod Kumar Date: Fri, 25 Jan 2019 17:23:49 +0530 Subject: [PATCH 2/6] typo --- Tasks/AzureCLIV1/azureclitask.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tasks/AzureCLIV1/azureclitask.ts b/Tasks/AzureCLIV1/azureclitask.ts index d378ff6b3600..03764ecffdf5 100644 --- a/Tasks/AzureCLIV1/azureclitask.ts +++ b/Tasks/AzureCLIV1/azureclitask.ts @@ -1,4 +1,4 @@ -import { IExecSyncResult, ToolRunner } from 'vsts-task-lib/toolrunner'; +import { IExecSyncResult } from 'vsts-task-lib/toolrunner'; import path = require("path"); import tl = require("vsts-task-lib/task"); import fs = require("fs"); From 381827ba78539b2b7a5f2733b56c9443cdd97bac Mon Sep 17 00:00:00 2001 From: Vinod Kumar Date: Mon, 28 Jan 2019 10:42:34 +0530 Subject: [PATCH 3/6] Addressed review comments --- .../Strings/resources.resjson/en-US/resources.resjson | 2 +- Tasks/AzureCLIV1/task.json | 4 ++-- Tasks/AzureCLIV1/task.loc.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson index bb2ae136f6e7..b4750fa884de 100644 --- a/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson @@ -16,7 +16,7 @@ "loc.input.label.args": "Arguments", "loc.input.help.args": "Arguments passed to the script", "loc.input.label.addSpnToEnvironment": "Access service principal details in script", - "loc.input.help.addSpnToEnvironment": "Adds service principal id and key of the Azure endpoint you chose to the script's execution environment. You can use these variables: `$servicePrincipalId` and `$servicePrincipalKey` in your script.\n\nPS: Valid only with ARM Endpoint service connection with 'Service Principal' authentication scheme.", + "loc.input.help.addSpnToEnvironment": "Adds service principal id and key of the Azure endpoint you chose to the script's execution environment. You can use these variables: `$servicePrincipalId` and `$servicePrincipalKey` in your script.\n\nThis is honored only when the Azure endpoint has Service Principal authentication scheme.", "loc.input.label.useGlobalConfig": "Use global Azure CLI configuration", "loc.input.help.useGlobalConfig": "If this is false, this task will use its own separate [Azure CLI configuration directory](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest#cli-configuration-file). This can be used to run Azure CLI tasks in *parallel* releases", "loc.input.label.cwd": "Working Directory", diff --git a/Tasks/AzureCLIV1/task.json b/Tasks/AzureCLIV1/task.json index e51ff8077842..5b9bbe6df0dc 100644 --- a/Tasks/AzureCLIV1/task.json +++ b/Tasks/AzureCLIV1/task.json @@ -19,7 +19,7 @@ "demands": [], "version": { "Major": 1, - "Minor": 145, + "Minor": 147, "Patch": 4 }, "minimumAgentVersion": "2.0.0", @@ -97,7 +97,7 @@ "label": "Access service principal details in script", "defaultValue": "false", "required": false, - "helpMarkDown": "Adds service principal id and key of the Azure endpoint you chose to the script's execution environment. You can use these variables: `$servicePrincipalId` and `$servicePrincipalKey` in your script.\n\nPS: Valid only with ARM Endpoint service connection with 'Service Principal' authentication scheme.", + "helpMarkDown": "Adds service principal id and key of the Azure endpoint you chose to the script's execution environment. You can use these variables: `$servicePrincipalId` and `$servicePrincipalKey` in your script.\n\nThis is honored only when the Azure endpoint has Service Principal authentication scheme.", "groupName": "advanced" }, { diff --git a/Tasks/AzureCLIV1/task.loc.json b/Tasks/AzureCLIV1/task.loc.json index 5c7b03219b96..fcf741afef13 100644 --- a/Tasks/AzureCLIV1/task.loc.json +++ b/Tasks/AzureCLIV1/task.loc.json @@ -19,7 +19,7 @@ "demands": [], "version": { "Major": 1, - "Minor": 145, + "Minor": 147, "Patch": 4 }, "minimumAgentVersion": "2.0.0", From 582198b1ba87f0dcadb11383739a94863595fe50 Mon Sep 17 00:00:00 2001 From: Vinod Kumar Date: Mon, 28 Jan 2019 11:04:14 +0530 Subject: [PATCH 4/6] Addressed review comments --- Tasks/AzureCLIV1/azureclitask.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tasks/AzureCLIV1/azureclitask.ts b/Tasks/AzureCLIV1/azureclitask.ts index 03764ecffdf5..00934b887bf7 100644 --- a/Tasks/AzureCLIV1/azureclitask.ts +++ b/Tasks/AzureCLIV1/azureclitask.ts @@ -153,6 +153,9 @@ export class azureclitask { //login using msi this.throwIfError(tl.execSync("az", "login --identity"), tl.loc("LoginFailed")); this.isLoggedIn = true; + + //set the subscription imported to the current subscription + this.throwIfError(tl.execSync("az", "account set --subscription \"" + subscriptionID + "\""), tl.loc("ErrorInSettingUpSubscription")); } } From 22f6c70ab43ca6c12ad9a4dce38ac7214d76b1c4 Mon Sep 17 00:00:00 2001 From: Vinod Kumar Date: Mon, 28 Jan 2019 16:10:54 +0530 Subject: [PATCH 5/6] Addressed review comments --- .../resources.resjson/en-US/resources.resjson | 1 + Tasks/AzureCLIV1/azureclitask.ts | 14 +++++--------- Tasks/AzureCLIV1/task.json | 3 ++- Tasks/AzureCLIV1/task.loc.json | 3 ++- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson index b4750fa884de..9a1ef3c67873 100644 --- a/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson @@ -29,6 +29,7 @@ "loc.messages.AzureSDKNotFound": "Azure CLI 2.x is not installed on this machine.", "loc.messages.FailedToLogout": "The following error occurred while logging out: %s", "loc.messages.LoginFailed": "Azure login failed", + "loc.messages.MSILoginFailed": "Azure login failed using Managed Service Identity", "loc.messages.ErrorInSettingUpSubscription": "Error in setting up subscription", "loc.messages.SettingAzureConfigDir": "Setting AZURE_CONFIG_DIR env variable to: %s", "loc.messages.SettingAzureCloud": "Setting active cloud to: %s", diff --git a/Tasks/AzureCLIV1/azureclitask.ts b/Tasks/AzureCLIV1/azureclitask.ts index 00934b887bf7..f9ebe25ff909 100644 --- a/Tasks/AzureCLIV1/azureclitask.ts +++ b/Tasks/AzureCLIV1/azureclitask.ts @@ -144,19 +144,15 @@ export class azureclitask { //login using svn this.throwIfError(tl.execSync("az", "login --service-principal -u \"" + servicePrincipalId + "\" -p \"" + cliPassword + "\" --tenant \"" + tenantId + "\""), tl.loc("LoginFailed")); - this.isLoggedIn = true; - - //set the subscription imported to the current subscription - this.throwIfError(tl.execSync("az", "account set --subscription \"" + subscriptionID + "\""), tl.loc("ErrorInSettingUpSubscription")); } else if(authScheme == "ManagedServiceIdentity") { //login using msi - this.throwIfError(tl.execSync("az", "login --identity"), tl.loc("LoginFailed")); - this.isLoggedIn = true; - - //set the subscription imported to the current subscription - this.throwIfError(tl.execSync("az", "account set --subscription \"" + subscriptionID + "\""), tl.loc("ErrorInSettingUpSubscription")); + this.throwIfError(tl.execSync("az", "login --identity"), tl.loc("MSILoginFailed")); } + + this.isLoggedIn = true; + //set the subscription imported to the current subscription + this.throwIfError(tl.execSync("az", "account set --subscription \"" + subscriptionID + "\""), tl.loc("ErrorInSettingUpSubscription")); } private static setConfigDirectory(): void { diff --git a/Tasks/AzureCLIV1/task.json b/Tasks/AzureCLIV1/task.json index 5b9bbe6df0dc..29a8792dba92 100644 --- a/Tasks/AzureCLIV1/task.json +++ b/Tasks/AzureCLIV1/task.json @@ -20,7 +20,7 @@ "version": { "Major": 1, "Minor": 147, - "Patch": 4 + "Patch": 0 }, "minimumAgentVersion": "2.0.0", "instanceNameFormat": "Azure CLI $(scriptPath)", @@ -144,6 +144,7 @@ "AzureSDKNotFound": "Azure CLI 2.x is not installed on this machine.", "FailedToLogout": "The following error occurred while logging out: %s", "LoginFailed": "Azure login failed", + "MSILoginFailed": "Azure login failed using Managed Service Identity", "ErrorInSettingUpSubscription": "Error in setting up subscription", "SettingAzureConfigDir": "Setting AZURE_CONFIG_DIR env variable to: %s", "SettingAzureCloud": "Setting active cloud to: %s", diff --git a/Tasks/AzureCLIV1/task.loc.json b/Tasks/AzureCLIV1/task.loc.json index fcf741afef13..e1c2b637877c 100644 --- a/Tasks/AzureCLIV1/task.loc.json +++ b/Tasks/AzureCLIV1/task.loc.json @@ -20,7 +20,7 @@ "version": { "Major": 1, "Minor": 147, - "Patch": 4 + "Patch": 0 }, "minimumAgentVersion": "2.0.0", "instanceNameFormat": "ms-resource:loc.instanceNameFormat", @@ -144,6 +144,7 @@ "AzureSDKNotFound": "ms-resource:loc.messages.AzureSDKNotFound", "FailedToLogout": "ms-resource:loc.messages.FailedToLogout", "LoginFailed": "ms-resource:loc.messages.LoginFailed", + "MSILoginFailed": "ms-resource:loc.messages.MSILoginFailed", "ErrorInSettingUpSubscription": "ms-resource:loc.messages.ErrorInSettingUpSubscription", "SettingAzureConfigDir": "ms-resource:loc.messages.SettingAzureConfigDir", "SettingAzureCloud": "ms-resource:loc.messages.SettingAzureCloud", From 9ee04e5999b524149811b0817a0ca20b8e026c79 Mon Sep 17 00:00:00 2001 From: Vinod Kumar Date: Tue, 29 Jan 2019 13:33:39 +0530 Subject: [PATCH 6/6] Addressed review comments --- .../Strings/resources.resjson/en-US/resources.resjson | 1 + Tasks/AzureCLIV1/azureclitask.ts | 7 +++++-- Tasks/AzureCLIV1/task.json | 1 + Tasks/AzureCLIV1/task.loc.json | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson index 9a1ef3c67873..a080b1ac4f3b 100644 --- a/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AzureCLIV1/Strings/resources.resjson/en-US/resources.resjson @@ -30,6 +30,7 @@ "loc.messages.FailedToLogout": "The following error occurred while logging out: %s", "loc.messages.LoginFailed": "Azure login failed", "loc.messages.MSILoginFailed": "Azure login failed using Managed Service Identity", + "loc.messages.AuthSchemeNotSupported": "Auth Scheme %s is not supported", "loc.messages.ErrorInSettingUpSubscription": "Error in setting up subscription", "loc.messages.SettingAzureConfigDir": "Setting AZURE_CONFIG_DIR env variable to: %s", "loc.messages.SettingAzureCloud": "Setting active cloud to: %s", diff --git a/Tasks/AzureCLIV1/azureclitask.ts b/Tasks/AzureCLIV1/azureclitask.ts index f9ebe25ff909..fe4385986115 100644 --- a/Tasks/AzureCLIV1/azureclitask.ts +++ b/Tasks/AzureCLIV1/azureclitask.ts @@ -121,7 +121,7 @@ export class azureclitask { var authScheme: string = tl.getEndpointAuthorizationScheme(connectedService, true); var subscriptionID: string = tl.getEndpointDataParameter(connectedService, "SubscriptionID", true); - if(authScheme == "ServicePrincipal") { + if(authScheme.toLowerCase() == "serviceprincipal") { let authType: string = tl.getEndpointAuthorizationParameter(connectedService, 'authenticationType', true); let cliPassword: string = null; var servicePrincipalId: string = tl.getEndpointAuthorizationParameter(connectedService, "serviceprincipalid", false); @@ -145,10 +145,13 @@ export class azureclitask { //login using svn this.throwIfError(tl.execSync("az", "login --service-principal -u \"" + servicePrincipalId + "\" -p \"" + cliPassword + "\" --tenant \"" + tenantId + "\""), tl.loc("LoginFailed")); } - else if(authScheme == "ManagedServiceIdentity") { + else if(authScheme.toLowerCase() == "managedserviceidentity") { //login using msi this.throwIfError(tl.execSync("az", "login --identity"), tl.loc("MSILoginFailed")); } + else{ + throw tl.loc('AuthSchemeNotSupported', authScheme); + } this.isLoggedIn = true; //set the subscription imported to the current subscription diff --git a/Tasks/AzureCLIV1/task.json b/Tasks/AzureCLIV1/task.json index 29a8792dba92..3c6cb7dc0074 100644 --- a/Tasks/AzureCLIV1/task.json +++ b/Tasks/AzureCLIV1/task.json @@ -145,6 +145,7 @@ "FailedToLogout": "The following error occurred while logging out: %s", "LoginFailed": "Azure login failed", "MSILoginFailed": "Azure login failed using Managed Service Identity", + "AuthSchemeNotSupported": "Auth Scheme %s is not supported", "ErrorInSettingUpSubscription": "Error in setting up subscription", "SettingAzureConfigDir": "Setting AZURE_CONFIG_DIR env variable to: %s", "SettingAzureCloud": "Setting active cloud to: %s", diff --git a/Tasks/AzureCLIV1/task.loc.json b/Tasks/AzureCLIV1/task.loc.json index e1c2b637877c..d41347d7d127 100644 --- a/Tasks/AzureCLIV1/task.loc.json +++ b/Tasks/AzureCLIV1/task.loc.json @@ -145,6 +145,7 @@ "FailedToLogout": "ms-resource:loc.messages.FailedToLogout", "LoginFailed": "ms-resource:loc.messages.LoginFailed", "MSILoginFailed": "ms-resource:loc.messages.MSILoginFailed", + "AuthSchemeNotSupported": "ms-resource:loc.messages.AuthSchemeNotSupported", "ErrorInSettingUpSubscription": "ms-resource:loc.messages.ErrorInSettingUpSubscription", "SettingAzureConfigDir": "ms-resource:loc.messages.SettingAzureConfigDir", "SettingAzureCloud": "ms-resource:loc.messages.SettingAzureCloud",