Compare commits

..

2 Commits

Author SHA1 Message Date
aksm-ms
f001fbb0b9 Update main.js 2020-11-16 17:48:14 +05:30
aksm-ms
b4fcf5d07d adding az cli version debug logs (#76) 2020-11-03 17:17:50 +05:30
9 changed files with 54 additions and 235 deletions

View File

@@ -57,7 +57,7 @@ jobs:
steps: steps:
- name: Login via Az module - name: Login via Az module
uses: azure/login@v1 uses: azure/login@v1.1
with: with:
creds: ${{secrets.AZURE_CREDENTIALS}} creds: ${{secrets.AZURE_CREDENTIALS}}
enable-AzPSSession: true enable-AzPSSession: true

View File

@@ -5,7 +5,7 @@ jest.mock('../../src/PowerShell/Utilities/PowerShellToolRunner');
let spnlogin: ServicePrincipalLogin; let spnlogin: ServicePrincipalLogin;
beforeAll(() => { beforeAll(() => {
spnlogin = new ServicePrincipalLogin("servicePrincipalID", "servicePrinicipalkey", "tenantId", "subscriptionId", false, null, null); spnlogin = new ServicePrincipalLogin("servicePrincipalID", "servicePrinicipalkey", "tenantId", "subscriptionId", false);
}); });
afterEach(() => { afterEach(() => {

View File

@@ -9,10 +9,6 @@ inputs:
description: 'SetthisvaluetotruetoenableAzurePowerShellLogininadditiontoAzCLIlogin' description: 'SetthisvaluetotruetoenableAzurePowerShellLogininadditiontoAzCLIlogin'
required: false required: false
default: false default: false
environment:
description: 'Name of the environment. Supported values are azurecloud, azurestack, azureusgovernment, azurechinacloud, azuregermancloud. Default being azurecloud'
required: false
default: azurecloud
allow-no-subscriptions: allow-no-subscriptions:
description: 'Setthisvaluetotrueto enable support for accessing tenants without subscriptions' description: 'Setthisvaluetotrueto enable support for accessing tenants without subscriptions'
required: false required: false

View File

@@ -1,23 +1,4 @@
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) { return new (P || (P = Promise))(function (resolve, reject) {
@@ -27,24 +8,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next()); step((generator = generator.apply(thisArg, _arguments || [])).next());
}); });
}; };
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.ServicePrincipalLogin = void 0;
const core = __importStar(require("@actions/core")); const core = __importStar(require("@actions/core"));
const Utils_1 = __importDefault(require("./Utilities/Utils")); const Utils_1 = __importDefault(require("./Utilities/Utils"));
const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner")); const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner"));
const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder")); const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder"));
const Constants_1 = __importDefault(require("./Constants")); const Constants_1 = __importDefault(require("./Constants"));
class ServicePrincipalLogin { class ServicePrincipalLogin {
constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin, environment, resourceManagerEndpointUrl) { constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin) {
this.servicePrincipalId = servicePrincipalId; this.servicePrincipalId = servicePrincipalId;
this.servicePrincipalKey = servicePrincipalKey; this.servicePrincipalKey = servicePrincipalKey;
this.tenantId = tenantId; this.tenantId = tenantId;
this.subscriptionId = subscriptionId; this.subscriptionId = subscriptionId;
this.environment = environment;
this.resourceManagerEndpointUrl = resourceManagerEndpointUrl;
this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin; this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin;
} }
initialize() { initialize() {
@@ -69,22 +54,22 @@ class ServicePrincipalLogin {
servicePrincipalId: this.servicePrincipalId, servicePrincipalId: this.servicePrincipalId,
servicePrincipalKey: this.servicePrincipalKey, servicePrincipalKey: this.servicePrincipalKey,
subscriptionId: this.subscriptionId, subscriptionId: this.subscriptionId,
environment: this.environment, environment: ServicePrincipalLogin.environment,
scopeLevel: ServicePrincipalLogin.scopeLevel, scopeLevel: ServicePrincipalLogin.scopeLevel,
allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin, allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin
resourceManagerEndpointUrl: this.resourceManagerEndpointUrl
}; };
const script = new ScriptBuilder_1.default().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args); const script = new ScriptBuilder_1.default().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args);
yield PowerShellToolRunner_1.default.init(); yield PowerShellToolRunner_1.default.init();
// await PowerShellToolRunner.executePowerShellScriptBlock(script, options); yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(script, options);
// const result: any = JSON.parse(output.trim()); const result = JSON.parse(output.trim());
// if (!(Constants.Success in result)) { if (!(Constants_1.default.Success in result)) {
// throw new Error(`Azure PowerShell login failed with error: ${result[Constants.Error]}`); throw new Error(`Azure PowerShell login failed with error: ${result[Constants_1.default.Error]}`);
// } }
console.log(`Azure PowerShell session successfully initialized`); console.log(`Azure PowerShell session successfully initialized`);
}); });
} }
} }
exports.ServicePrincipalLogin = ServicePrincipalLogin; exports.ServicePrincipalLogin = ServicePrincipalLogin;
ServicePrincipalLogin.environment = Constants_1.default.AzureCloud;
ServicePrincipalLogin.scopeLevel = Constants_1.default.Subscription; ServicePrincipalLogin.scopeLevel = Constants_1.default.Subscription;
ServicePrincipalLogin.scheme = Constants_1.default.ServicePrincipal; ServicePrincipalLogin.scheme = Constants_1.default.ServicePrincipal;

View File

@@ -20,9 +20,6 @@ class ScriptBuilder {
let command = `Clear-AzContext -Scope Process; let command = `Clear-AzContext -Scope Process;
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`;
if (scheme === Constants_1.default.ServicePrincipal) { if (scheme === Constants_1.default.ServicePrincipal) {
if (args.environment.toLowerCase() == "azurestack") {
command += `Add-AzEnvironment -Name ${args.environment} -ARMEndpoint ${args.resourceManagerEndpointUrl} | out-null;`;
}
command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \ command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \ (New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \
-Environment '${args.environment}' | out-null;`; -Environment '${args.environment}' | out-null;`;

View File

@@ -36,104 +36,46 @@ function main() {
core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString); core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv); core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
azPath = yield io.which("az", true); azPath = yield io.which("az", true);
let azureSupportedCloudName = new Set([
"azureusgovernment",
"azurechinacloud",
"azuregermancloud",
"azurecloud",
"azurestack"
]);
let output = ""; let output = "";
const execOptions = { const options = {
listeners: { listeners: {
stdout: (data) => { stdout: (data) => {
output += data.toString(); output += data.toString();
} }
} }
}; };
yield executeAzCliCommand("--version", true, execOptions); yield executeAzCliCommand("--version", true, options);
core.debug(`az cli version used:\n${output}`); core.debug(`az cli version used:\n${output}`);
let creds = core.getInput('creds', { required: true }); let creds = core.getInput('creds', { required: true });
let secrets = new actions_secret_parser_1.SecretParser(creds, actions_secret_parser_1.FormatType.JSON); let secrets = new actions_secret_parser_1.SecretParser(creds, actions_secret_parser_1.FormatType.JSON);
let servicePrincipalId = secrets.getSecret("$.clientId", false); let servicePrincipalId = secrets.getSecret("$.clientId", false);
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true); let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
let tenantId = secrets.getSecret("$.tenantId", false); let tenantId = secrets.getSecret("$.tenantId", false);
let subscriptionId = secrets.getSecret("$.subscriptionId", false); let subscriptionId = secrets.getSecret("$.subscriptionId", false);
let resourceManagerEndpointUrl = secrets.getSecret("$.resourceManagerEndpointUrl", false);
let environment = core.getInput("environment").toLowerCase();
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true"; const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true"; const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true";
if (!servicePrincipalId || !servicePrincipalKey || !tenantId) { if (!servicePrincipalId || !servicePrincipalKey || !tenantId) {
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied."); throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied.");
} }
if (!subscriptionId && !allowNoSubscriptionsLogin) { if (!subscriptionId && !allowNoSubscriptionsLogin) {
throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied."); throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied.");
} }
if (!azureSupportedCloudName.has(environment)) {
throw new Error("Unsupported value for environment is passed.The list of supported values for environment are azureusgovernment', azurechinacloud, azuregermancloud, azurecloud or azurestack");
}
// TODO: refactor this into an Azure stack specific utility.
// Attempting Az cli login
if (environment == "azurestack") {
if (!resourceManagerEndpointUrl) {
throw new Error("resourceManagerEndpointUrl is a required parameter when environment is defined.");
}
console.log(`Unregistering cloud: "${environment}" first if it exists`);
try {
yield executeAzCliCommand(`cloud set -n AzureCloud`, true);
yield executeAzCliCommand(`cloud unregister -n "${environment}"`, false);
}
catch (error) {
console.log(`Ignore cloud not registered error: "${error}"`);
}
console.log(`Registering cloud: "${environment}" with ARM endpoint: "${resourceManagerEndpointUrl}"`);
try {
let baseUri = resourceManagerEndpointUrl;
if (baseUri.endsWith('/')) {
baseUri = baseUri.substring(0, baseUri.length - 1); // need to remove trailing / from resourceManagerEndpointUrl to correctly derive suffixes below
}
let suffixKeyvault = ".vault" + baseUri.substring(baseUri.indexOf('.')); // keyvault suffix starts with .
let suffixStorage = baseUri.substring(baseUri.indexOf('.') + 1); // storage suffix starts without .
let profileVersion = "2019-03-01-hybrid";
yield executeAzCliCommand(`cloud register -n "${environment}" --endpoint-resource-manager "${resourceManagerEndpointUrl}" --suffix-keyvault-dns "${suffixKeyvault}" --suffix-storage-endpoint "${suffixStorage}" --profile "${profileVersion}"`, false);
}
catch (error) {
core.error(`Error while trying to register cloud "${environment}": "${error}"`);
}
console.log(`Done registering cloud: "${environment}"`);
}
yield executeAzCliCommand(`cloud set -n "${environment}"`, false);
console.log(`Done setting cloud: "${environment}"`);
// Attempting Az cli login // Attempting Az cli login
console.log(`ak - clientId: ${servicePrincipalId}`);
if (allowNoSubscriptionsLogin) { if (allowNoSubscriptionsLogin) {
let args = [ yield executeAzCliCommand(`login --allow-no-subscriptions --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
"--allow-no-subscriptions",
"--service-principal",
"-u", servicePrincipalId,
"-p", servicePrincipalKey,
"--tenant", tenantId
];
yield executeAzCliCommand(`login`, true, {}, args);
} }
else { else {
let args = [ yield executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
"--service-principal", yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`, true);
"-u", servicePrincipalId,
"-p", servicePrincipalKey,
"--tenant", tenantId
];
yield executeAzCliCommand(`login`, true, {}, args);
args = [
"--subscription",
subscriptionId
];
yield executeAzCliCommand(`account set`, true, {}, args);
} }
isAzCLISuccess = true; isAzCLISuccess = true;
if (enableAzPSSession) { if (enableAzPSSession) {
// Attempting Az PS login // Attempting Az PS login
console.log(`Running Azure PS Login`); console.log(`Running Azure PS Login`);
const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin, environment, resourceManagerEndpointUrl); const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin);
yield spnlogin.initialize(); yield spnlogin.initialize();
yield spnlogin.login(); yield spnlogin.login();
} }
@@ -155,11 +97,12 @@ function main() {
} }
}); });
} }
function executeAzCliCommand(command, silent, execOptions = {}, args = []) {
function executeAzCliCommand(command, silent, options = {}) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
execOptions.silent = !!silent; options.silent = !!silent;
try { try {
yield exec.exec(`"${azPath}" ${command}`, args, execOptions); yield exec.exec(`"${azPath}" ${command}`, [], options);
} }
catch (error) { catch (error) {
throw new Error(error); throw new Error(error);

View File

@@ -6,30 +6,24 @@ import ScriptBuilder from './Utilities/ScriptBuilder';
import Constants from './Constants'; import Constants from './Constants';
export class ServicePrincipalLogin implements IAzurePowerShellSession { export class ServicePrincipalLogin implements IAzurePowerShellSession {
static readonly environment: string = Constants.AzureCloud;
static readonly scopeLevel: string = Constants.Subscription; static readonly scopeLevel: string = Constants.Subscription;
static readonly scheme: string = Constants.ServicePrincipal; static readonly scheme: string = Constants.ServicePrincipal;
environment: string;
servicePrincipalId: string; servicePrincipalId: string;
servicePrincipalKey: string; servicePrincipalKey: string;
tenantId: string; tenantId: string;
subscriptionId: string; subscriptionId: string;
resourceManagerEndpointUrl: string;
allowNoSubscriptionsLogin: boolean; allowNoSubscriptionsLogin: boolean;
constructor(servicePrincipalId: string, constructor(servicePrincipalId: string,
servicePrincipalKey: string, servicePrincipalKey: string,
tenantId: string, tenantId: string,
subscriptionId: string, subscriptionId: string,
allowNoSubscriptionsLogin: boolean, allowNoSubscriptionsLogin: boolean) {
environment: string,
resourceManagerEndpointUrl: string) {
this.servicePrincipalId = servicePrincipalId; this.servicePrincipalId = servicePrincipalId;
this.servicePrincipalKey = servicePrincipalKey; this.servicePrincipalKey = servicePrincipalKey;
this.tenantId = tenantId; this.tenantId = tenantId;
this.subscriptionId = subscriptionId; this.subscriptionId = subscriptionId;
this.environment = environment;
this.resourceManagerEndpointUrl = resourceManagerEndpointUrl;
this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin; this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin;
} }
@@ -53,18 +47,17 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession {
servicePrincipalId: this.servicePrincipalId, servicePrincipalId: this.servicePrincipalId,
servicePrincipalKey: this.servicePrincipalKey, servicePrincipalKey: this.servicePrincipalKey,
subscriptionId: this.subscriptionId, subscriptionId: this.subscriptionId,
environment: this.environment, environment: ServicePrincipalLogin.environment,
scopeLevel: ServicePrincipalLogin.scopeLevel, scopeLevel: ServicePrincipalLogin.scopeLevel,
allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin, allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin
resourceManagerEndpointUrl: this.resourceManagerEndpointUrl
} }
const script: string = new ScriptBuilder().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args); const script: string = new ScriptBuilder().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args);
await PowerShellToolRunner.init(); await PowerShellToolRunner.init();
// await PowerShellToolRunner.executePowerShellScriptBlock(script, options); await PowerShellToolRunner.executePowerShellScriptBlock(script, options);
// const result: any = JSON.parse(output.trim()); const result: any = JSON.parse(output.trim());
// if (!(Constants.Success in result)) { if (!(Constants.Success in result)) {
// throw new Error(`Azure PowerShell login failed with error: ${result[Constants.Error]}`); throw new Error(`Azure PowerShell login failed with error: ${result[Constants.Error]}`);
// } }
console.log(`Azure PowerShell session successfully initialized`); console.log(`Azure PowerShell session successfully initialized`);
} }

View File

@@ -8,22 +8,14 @@ export default class ScriptBuilder {
getAzPSLoginScript(scheme: string, tenantId: string, args: any): string { getAzPSLoginScript(scheme: string, tenantId: string, args: any): string {
let command = `Clear-AzContext -Scope Process; let command = `Clear-AzContext -Scope Process;
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`;
if (scheme === Constants.ServicePrincipal) { if (scheme === Constants.ServicePrincipal) {
if (args.environment.toLowerCase() == "azurestack") {
command += `Add-AzEnvironment -Name ${args.environment} -ARMEndpoint ${args.resourceManagerEndpointUrl} | out-null;`;
}
command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \ command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \ (New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \
-Environment '${args.environment}' | out-null;`; -Environment '${args.environment}' | out-null;`;
if (args.scopeLevel === Constants.Subscription && !args.allowNoSubscriptionsLogin) { if (args.scopeLevel === Constants.Subscription && !args.allowNoSubscriptionsLogin) {
command += `Set-AzContext -SubscriptionId '${args.subscriptionId}' -TenantId '${tenantId}' | out-null;`; command += `Set-AzContext -SubscriptionId '${args.subscriptionId}' -TenantId '${tenantId}' | out-null;`;
} }
} }
this.script += `try { this.script += `try {
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
$WarningPreference = "SilentlyContinue" $WarningPreference = "SilentlyContinue"
@@ -35,7 +27,6 @@ export default class ScriptBuilder {
$output['${Constants.Error}'] = $_.exception.Message $output['${Constants.Error}'] = $_.exception.Message
} }
return ConvertTo-Json $output`; return ConvertTo-Json $output`;
core.debug(`Azure PowerShell Login Script: ${this.script}`); core.debug(`Azure PowerShell Login Script: ${this.script}`);
return this.script; return this.script;
} }

View File

@@ -1,6 +1,7 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import * as io from '@actions/io'; import * as io from '@actions/io';
import { FormatType, SecretParser } from 'actions-secret-parser'; import { FormatType, SecretParser } from 'actions-secret-parser';
import { ServicePrincipalLogin } from './PowerShell/ServicePrincipalLogin'; import { ServicePrincipalLogin } from './PowerShell/ServicePrincipalLogin';
@@ -20,23 +21,15 @@ async function main() {
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv); core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
azPath = await io.which("az", true); azPath = await io.which("az", true);
let azureSupportedCloudName = new Set([
"azureusgovernment",
"azurechinacloud",
"azuregermancloud",
"azurecloud",
"azurestack"]);
let output: string = ""; let output: string = "";
const execOptions: any = { const options: any = {
listeners: { listeners: {
stdout: (data: Buffer) => { stdout: (data: Buffer) => {
output += data.toString(); output += data.toString();
} }
} }
}; };
await executeAzCliCommand("--version", true, execOptions); await executeAzCliCommand("--version", true, options);
core.debug(`az cli version used:\n${output}`); core.debug(`az cli version used:\n${output}`);
let creds = core.getInput('creds', { required: true }); let creds = core.getInput('creds', { required: true });
@@ -45,11 +38,8 @@ async function main() {
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true); let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
let tenantId = secrets.getSecret("$.tenantId", false); let tenantId = secrets.getSecret("$.tenantId", false);
let subscriptionId = secrets.getSecret("$.subscriptionId", false); let subscriptionId = secrets.getSecret("$.subscriptionId", false);
let resourceManagerEndpointUrl = secrets.getSecret("$.resourceManagerEndpointUrl", false);
let environment = core.getInput("environment").toLowerCase();
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true"; const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true"; const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true";
if (!servicePrincipalId || !servicePrincipalKey || !tenantId) { if (!servicePrincipalId || !servicePrincipalKey || !tenantId) {
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied."); throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied.");
} }
@@ -58,119 +48,43 @@ async function main() {
throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied."); throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied.");
} }
if (!azureSupportedCloudName.has(environment)){
throw new Error("Unsupported value for environment is passed.The list of supported values for environment are azureusgovernment', azurechinacloud, azuregermancloud, azurecloud or azurestack");
}
// TODO: refactor this into an Azure stack specific utility.
// Attempting Az cli login
if (environment == "azurestack") {
if (!resourceManagerEndpointUrl) {
throw new Error("resourceManagerEndpointUrl is a required parameter when environment is defined.");
}
console.log(`Unregistering cloud: "${environment}" first if it exists`);
try {
await executeAzCliCommand(`cloud set -n AzureCloud`, true);
await executeAzCliCommand(`cloud unregister -n "${environment}"`, false);
}
catch (error) {
console.log(`Ignore cloud not registered error: "${error}"`);
}
console.log(`Registering cloud: "${environment}" with ARM endpoint: "${resourceManagerEndpointUrl}"`);
try {
let baseUri = resourceManagerEndpointUrl;
if (baseUri.endsWith('/')) {
baseUri = baseUri.substring(0, baseUri.length-1); // need to remove trailing / from resourceManagerEndpointUrl to correctly derive suffixes below
}
let suffixKeyvault = ".vault" + baseUri.substring(baseUri.indexOf('.')); // keyvault suffix starts with .
let suffixStorage = baseUri.substring(baseUri.indexOf('.')+1); // storage suffix starts without .
let profileVersion = "2019-03-01-hybrid";
await executeAzCliCommand(`cloud register -n "${environment}" --endpoint-resource-manager "${resourceManagerEndpointUrl}" --suffix-keyvault-dns "${suffixKeyvault}" --suffix-storage-endpoint "${suffixStorage}" --profile "${profileVersion}"`, false);
}
catch (error) {
core.error(`Error while trying to register cloud "${environment}": "${error}"`);
}
console.log(`Done registering cloud: "${environment}"`)
}
await executeAzCliCommand(`cloud set -n "${environment}"`, false);
console.log(`Done setting cloud: "${environment}"`);
// Attempting Az cli login // Attempting Az cli login
if (allowNoSubscriptionsLogin) { if (allowNoSubscriptionsLogin) {
let args = [ await executeAzCliCommand(`login --allow-no-subscriptions --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
"--allow-no-subscriptions",
"--service-principal",
"-u", servicePrincipalId,
"-p", servicePrincipalKey,
"--tenant", tenantId
];
await executeAzCliCommand(`login`, true, {}, args);
} }
else { else {
let args = [ await executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
"--service-principal", await executeAzCliCommand(`account set --subscription "${subscriptionId}"`, true);
"-u", servicePrincipalId,
"-p", servicePrincipalKey,
"--tenant", tenantId
];
await executeAzCliCommand(`login`, true, {}, args);
args = [
"--subscription",
subscriptionId
];
await executeAzCliCommand(`account set`, true, {}, args);
} }
isAzCLISuccess = true; isAzCLISuccess = true;
if (enableAzPSSession) { if (enableAzPSSession) {
// Attempting Az PS login // Attempting Az PS login
console.log(`Running Azure PS Login`); console.log(`Running Azure PS Login`);
const spnlogin: ServicePrincipalLogin = new ServicePrincipalLogin( const spnlogin: ServicePrincipalLogin = new ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin);
servicePrincipalId,
servicePrincipalKey,
tenantId,
subscriptionId,
allowNoSubscriptionsLogin,
environment,
resourceManagerEndpointUrl);
await spnlogin.initialize(); await spnlogin.initialize();
await spnlogin.login(); await spnlogin.login();
} }
console.log("Login successful."); console.log("Login successful.");
} } catch (error) {
catch (error) {
if (!isAzCLISuccess) { if (!isAzCLISuccess) {
core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"); core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows");
} } else {
else {
core.error(`Azure PowerShell Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"`); core.error(`Azure PowerShell Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"`);
} }
core.setFailed(error); core.setFailed(error);
} } finally {
finally {
// Reset AZURE_HTTP_USER_AGENT // Reset AZURE_HTTP_USER_AGENT
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix); core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv); core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
} }
} }
async function executeAzCliCommand( async function executeAzCliCommand(command: string, silent?: boolean, options: any = {}) {
command: string, options.silent = !!silent;
silent?: boolean,
execOptions: any = {},
args: any = []) {
execOptions.silent = !!silent;
try { try {
await exec.exec(`"${azPath}" ${command}`, args, execOptions); await exec.exec(`"${azPath}" ${command}`, [], options);
} }
catch (error) { catch(error) {
throw new Error(error); throw new Error(error);
} }
} }