From 739c3386a1914a441a051586cdb61430dd5de547 Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Wed, 4 Mar 2020 17:44:34 +0530 Subject: [PATCH 01/27] Added changes for azure powershell login --- lib/loginAzurePowerShell.js | 66 +++++++++++++++++++++++++++++++++++++ lib/main.js | 4 ++- src/loginAzurePowerShell.ts | 48 +++++++++++++++++++++++++++ src/main.ts | 12 +++---- 4 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 lib/loginAzurePowerShell.js create mode 100644 src/loginAzurePowerShell.ts diff --git a/lib/loginAzurePowerShell.js b/lib/loginAzurePowerShell.js new file mode 100644 index 00000000..f275a99a --- /dev/null +++ b/lib/loginAzurePowerShell.js @@ -0,0 +1,66 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + 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; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const exec = __importStar(require("@actions/exec")); +const io = __importStar(require("@actions/io")); +var psPath; +exports.initializeAz = (servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) => __awaiter(void 0, void 0, void 0, function* () { + psPath = yield io.which("pwsh", true); + setPSModulePath(); + yield loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); +}); +function setPSModulePath() { + // TODO: get latest module/setup action + let azPSVersion = "2.6.0"; + let modulePath = ""; + const runner = JSON.parse(process.env.RUNNER_CONTEXT); + switch (runner.os) { + case "Linux": + modulePath = `/usr/share/az_${azPSVersion}:`; + break; + case "Windows": + modulePath = `C:\\Modules\\az_${azPSVersion};`; + break; + case "macOS": + // TODO: add modulepath + break; + } + process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; +} +function loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) { + return __awaiter(this, void 0, void 0, function* () { + const environment = "AzureCloud"; + yield executePowerShellCommand(`Clear-AzContext -Scope Process`); + yield executePowerShellCommand(`Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue`); + yield executePowerShellCommand(`Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ + (New-Object System.Management.Automation.PSCredential('${servicePrincipalId}',(ConvertTo-SecureString ${servicePrincipalKey} -AsPlainText -Force))) \ + -Environment ${environment}`); + yield executePowerShellCommand(`Set-AzContext -SubscriptionId ${subscriptionId} -TenantId ${tenantId}`); + yield executePowerShellCommand(`Get-AzContext`); + }); +} +function executePowerShellCommand(command) { + return __awaiter(this, void 0, void 0, function* () { + try { + yield exec.exec(`"${psPath}" -Command "${command}"`, [], {}); + } + catch (error) { + throw new Error(error); + } + }); +} diff --git a/lib/main.js b/lib/main.js index 0a1efa97..226622d4 100644 --- a/lib/main.js +++ b/lib/main.js @@ -21,12 +21,13 @@ const crypto = __importStar(require("crypto")); const exec = __importStar(require("@actions/exec")); const io = __importStar(require("@actions/io")); const actions_secret_parser_1 = require("actions-secret-parser"); +const loginAzurePowerShell_1 = require("./loginAzurePowerShell"); var azPath; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; function main() { return __awaiter(this, void 0, void 0, function* () { try { - // Set user agent varable + // Set user agent variable let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); let actionName = 'AzureLogin'; let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS_${actionName}_${usrAgentRepo}`; @@ -44,6 +45,7 @@ function main() { } yield executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`); yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`); + yield loginAzurePowerShell_1.initializeAz(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); console.log("Login successful."); } catch (error) { diff --git a/src/loginAzurePowerShell.ts b/src/loginAzurePowerShell.ts new file mode 100644 index 00000000..afd51bdd --- /dev/null +++ b/src/loginAzurePowerShell.ts @@ -0,0 +1,48 @@ +import * as exec from '@actions/exec'; +import * as io from '@actions/io'; + +var psPath: string; + +export const initializeAz = async (servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) => { + psPath = await io.which("pwsh", true); + setPSModulePath(); + await loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); +} + +function setPSModulePath() { + // TODO: get latest module/setup action + let azPSVersion: string = "2.6.0"; + let modulePath: string = ""; + const runner = JSON.parse(process.env.RUNNER_CONTEXT); + switch (runner.os) { + case "Linux": + modulePath = `/usr/share/az_${azPSVersion}:`; + break; + case "Windows": + modulePath = `C:\\Modules\\az_${azPSVersion};`; + break; + case "macOS": + // TODO: add modulepath + break; + } + process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; +} + +async function loginToAzure(servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) { + const environment: string = "AzureCloud"; + await executePowerShellCommand(`Clear-AzContext -Scope Process`); + await executePowerShellCommand(`Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue`); + await executePowerShellCommand(`Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ + (New-Object System.Management.Automation.PSCredential('${servicePrincipalId}',(ConvertTo-SecureString ${servicePrincipalKey} -AsPlainText -Force))) \ + -Environment ${environment}`); + await executePowerShellCommand(`Set-AzContext -SubscriptionId ${subscriptionId} -TenantId ${tenantId}`); + await executePowerShellCommand(`Get-AzContext`); +} + +async function executePowerShellCommand(command: string) { + try { + await exec.exec(`"${psPath}" -Command "${command}"`, [], {}) + } catch (error) { + throw new Error(error); + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index a3a32fd5..b73f50bb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,13 +4,14 @@ import * as exec from '@actions/exec'; import * as io from '@actions/io'; import { FormatType, SecretParser } from 'actions-secret-parser'; +import { initializeAz } from './loginAzurePowerShell'; var azPath: string; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; async function main() { - try{ - // Set user agent varable + try { + // Set user agent variable let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); let actionName = 'AzureLogin'; let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS_${actionName}_${usrAgentRepo}`; @@ -28,10 +29,10 @@ async function main() { if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) { throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied."); } - await executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`); await executeAzCliCommand(`account set --subscription "${subscriptionId}"`); - console.log("Login successful."); + await initializeAz(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); + console.log("Login successful."); } catch (error) { core.error("Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"); core.setFailed(error); @@ -43,12 +44,11 @@ async function main() { async function executeAzCliCommand(command: string) { try { - await exec.exec(`"${azPath}" ${command}`, [], {}); + await exec.exec(`"${azPath}" ${command}`, [], {}); } catch(error) { throw new Error(error); } } - main(); \ No newline at end of file From 5260ae1262c0df21570b156d211ffc2dc146592b Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Thu, 5 Mar 2020 00:58:14 +0530 Subject: [PATCH 02/27] Changes in loginAzurePowerShell.ts --- lib/loginAzurePowerShell.js | 3 +-- src/loginAzurePowerShell.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/loginAzurePowerShell.js b/lib/loginAzurePowerShell.js index f275a99a..31cdc151 100644 --- a/lib/loginAzurePowerShell.js +++ b/lib/loginAzurePowerShell.js @@ -28,8 +28,7 @@ function setPSModulePath() { // TODO: get latest module/setup action let azPSVersion = "2.6.0"; let modulePath = ""; - const runner = JSON.parse(process.env.RUNNER_CONTEXT); - switch (runner.os) { + switch (process.env.RUNNER_OS) { case "Linux": modulePath = `/usr/share/az_${azPSVersion}:`; break; diff --git a/src/loginAzurePowerShell.ts b/src/loginAzurePowerShell.ts index afd51bdd..eb15a343 100644 --- a/src/loginAzurePowerShell.ts +++ b/src/loginAzurePowerShell.ts @@ -13,8 +13,7 @@ function setPSModulePath() { // TODO: get latest module/setup action let azPSVersion: string = "2.6.0"; let modulePath: string = ""; - const runner = JSON.parse(process.env.RUNNER_CONTEXT); - switch (runner.os) { + switch (process.env.RUNNER_OS) { case "Linux": modulePath = `/usr/share/az_${azPSVersion}:`; break; From 7882b87bc3b79d38ae17977c0a411dd890b6baf5 Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Thu, 5 Mar 2020 16:11:15 +0530 Subject: [PATCH 03/27] using latest version --- lib/loginAzurePowerShell.js | 2 +- src/loginAzurePowerShell.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/loginAzurePowerShell.js b/lib/loginAzurePowerShell.js index 31cdc151..b3771399 100644 --- a/lib/loginAzurePowerShell.js +++ b/lib/loginAzurePowerShell.js @@ -26,7 +26,7 @@ exports.initializeAz = (servicePrincipalId, servicePrincipalKey, tenantId, subsc }); function setPSModulePath() { // TODO: get latest module/setup action - let azPSVersion = "2.6.0"; + let azPSVersion = "3.5.0"; let modulePath = ""; switch (process.env.RUNNER_OS) { case "Linux": diff --git a/src/loginAzurePowerShell.ts b/src/loginAzurePowerShell.ts index eb15a343..fa4af8ee 100644 --- a/src/loginAzurePowerShell.ts +++ b/src/loginAzurePowerShell.ts @@ -11,7 +11,7 @@ export const initializeAz = async (servicePrincipalId: string, servicePrincipalK function setPSModulePath() { // TODO: get latest module/setup action - let azPSVersion: string = "2.6.0"; + let azPSVersion: string = "3.5.0"; let modulePath: string = ""; switch (process.env.RUNNER_OS) { case "Linux": From 12e896239faac8cbc478449e3bbd4810ddc86f2b Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Fri, 6 Mar 2020 12:26:11 +0530 Subject: [PATCH 04/27] Added getlatestazmodule version --- lib/loginAzurePowerShell.js | 34 +++++++++++++++++++++++++++------- src/loginAzurePowerShell.ts | 33 ++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/lib/loginAzurePowerShell.js b/lib/loginAzurePowerShell.js index b3771399..fe93acd8 100644 --- a/lib/loginAzurePowerShell.js +++ b/lib/loginAzurePowerShell.js @@ -16,24 +16,24 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(require("@actions/core")); const exec = __importStar(require("@actions/exec")); const io = __importStar(require("@actions/io")); var psPath; exports.initializeAz = (servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) => __awaiter(void 0, void 0, void 0, function* () { psPath = yield io.which("pwsh", true); setPSModulePath(); + setPSModulePath(yield getLatestAzModule()); yield loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); }); -function setPSModulePath() { - // TODO: get latest module/setup action - let azPSVersion = "3.5.0"; +function setPSModulePath(azPSVersion = "") { let modulePath = ""; switch (process.env.RUNNER_OS) { case "Linux": - modulePath = `/usr/share/az_${azPSVersion}:`; + modulePath = `/usr/share/${azPSVersion}:`; break; case "Windows": - modulePath = `C:\\Modules\\az_${azPSVersion};`; + modulePath = `C:\\Modules\\${azPSVersion};`; break; case "macOS": // TODO: add modulepath @@ -41,6 +41,26 @@ function setPSModulePath() { } process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } +function getLatestAzModule() { + return __awaiter(this, void 0, void 0, function* () { + const moduleName = "Az.Accounts"; + let output = ""; + let error = ""; + let options = { + listeners: { + stdout: (data) => { + output += data.toString(); + }, + stderr: (data) => { + error += data.toString(); + } + } + }; + yield executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); + core.debug(`Az Module version used: ${output}`); + return `az_${output}`; + }); +} function loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) { return __awaiter(this, void 0, void 0, function* () { const environment = "AzureCloud"; @@ -53,10 +73,10 @@ function loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscri yield executePowerShellCommand(`Get-AzContext`); }); } -function executePowerShellCommand(command) { +function executePowerShellCommand(command, options = {}) { return __awaiter(this, void 0, void 0, function* () { try { - yield exec.exec(`"${psPath}" -Command "${command}"`, [], {}); + yield exec.exec(`"${psPath}" -Command "${command}"`, [], options); } catch (error) { throw new Error(error); diff --git a/src/loginAzurePowerShell.ts b/src/loginAzurePowerShell.ts index fa4af8ee..11d62d66 100644 --- a/src/loginAzurePowerShell.ts +++ b/src/loginAzurePowerShell.ts @@ -1,3 +1,4 @@ +import * as core from '@actions/core'; import * as exec from '@actions/exec'; import * as io from '@actions/io'; @@ -6,19 +7,18 @@ var psPath: string; export const initializeAz = async (servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) => { psPath = await io.which("pwsh", true); setPSModulePath(); + setPSModulePath(await getLatestAzModule()); await loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); } -function setPSModulePath() { - // TODO: get latest module/setup action - let azPSVersion: string = "3.5.0"; +function setPSModulePath(azPSVersion = "") { let modulePath: string = ""; switch (process.env.RUNNER_OS) { case "Linux": - modulePath = `/usr/share/az_${azPSVersion}:`; + modulePath = `/usr/share/${azPSVersion}:`; break; case "Windows": - modulePath = `C:\\Modules\\az_${azPSVersion};`; + modulePath = `C:\\Modules\\${azPSVersion};`; break; case "macOS": // TODO: add modulepath @@ -27,6 +27,25 @@ function setPSModulePath() { process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } +async function getLatestAzModule() { + const moduleName = "Az.Accounts"; + let output: string = ""; + let error: string = ""; + let options: any = { + listeners: { + stdout: (data: Buffer) => { + output += data.toString(); + }, + stderr: (data: Buffer) => { + error += data.toString(); + } + } + }; + await executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); + core.debug(`Az Module version used: ${output}`); + return `az_${output}`; +} + async function loginToAzure(servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) { const environment: string = "AzureCloud"; await executePowerShellCommand(`Clear-AzContext -Scope Process`); @@ -38,9 +57,9 @@ async function loginToAzure(servicePrincipalId: string, servicePrincipalKey: str await executePowerShellCommand(`Get-AzContext`); } -async function executePowerShellCommand(command: string) { +async function executePowerShellCommand(command: string, options: any = {}) { try { - await exec.exec(`"${psPath}" -Command "${command}"`, [], {}) + await exec.exec(`"${psPath}" -Command "${command}"`, [], options); } catch (error) { throw new Error(error); } From a68f90e22a903ed31c2581a17338ed6fc0086d4d Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Mon, 9 Mar 2020 14:00:22 +0530 Subject: [PATCH 05/27] changes in runner info --- lib/loginAzurePowerShell.js | 10 +++++++--- src/loginAzurePowerShell.ts | 15 ++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/loginAzurePowerShell.js b/lib/loginAzurePowerShell.js index fe93acd8..b1bac9a3 100644 --- a/lib/loginAzurePowerShell.js +++ b/lib/loginAzurePowerShell.js @@ -16,6 +16,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); +const os = __importStar(require("os")); const core = __importStar(require("@actions/core")); const exec = __importStar(require("@actions/exec")); const io = __importStar(require("@actions/io")); @@ -23,25 +24,28 @@ var psPath; exports.initializeAz = (servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) => __awaiter(void 0, void 0, void 0, function* () { psPath = yield io.which("pwsh", true); setPSModulePath(); - setPSModulePath(yield getLatestAzModule()); + setPSModulePath(yield getLatestModule()); yield loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); }); function setPSModulePath(azPSVersion = "") { let modulePath = ""; - switch (process.env.RUNNER_OS) { + const RUNNER = process.env.RUNNER_OS || os.type(); + switch (RUNNER) { case "Linux": modulePath = `/usr/share/${azPSVersion}:`; break; case "Windows": + case "Windows_NT": modulePath = `C:\\Modules\\${azPSVersion};`; break; case "macOS": + case "Darwin": // TODO: add modulepath break; } process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } -function getLatestAzModule() { +function getLatestModule() { return __awaiter(this, void 0, void 0, function* () { const moduleName = "Az.Accounts"; let output = ""; diff --git a/src/loginAzurePowerShell.ts b/src/loginAzurePowerShell.ts index 11d62d66..db2d00c2 100644 --- a/src/loginAzurePowerShell.ts +++ b/src/loginAzurePowerShell.ts @@ -1,34 +1,39 @@ +import * as os from 'os'; import * as core from '@actions/core'; import * as exec from '@actions/exec'; import * as io from '@actions/io'; +import { defaultCoreCipherList } from 'constants'; var psPath: string; export const initializeAz = async (servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) => { psPath = await io.which("pwsh", true); setPSModulePath(); - setPSModulePath(await getLatestAzModule()); + setPSModulePath(await getLatestModule()); await loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); } -function setPSModulePath(azPSVersion = "") { +function setPSModulePath(azPSVersion: string = "") { let modulePath: string = ""; - switch (process.env.RUNNER_OS) { + const RUNNER: string = process.env.RUNNER_OS || os.type(); + switch (RUNNER) { case "Linux": modulePath = `/usr/share/${azPSVersion}:`; break; case "Windows": + case "Windows_NT": modulePath = `C:\\Modules\\${azPSVersion};`; break; case "macOS": + case "Darwin": // TODO: add modulepath break; } process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } -async function getLatestAzModule() { - const moduleName = "Az.Accounts"; +async function getLatestModule() { + const moduleName: string = "Az.Accounts"; let output: string = ""; let error: string = ""; let options: any = { From f805ead5d49ae568d528cbfb9be66966ae9dc8dd Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Mon, 9 Mar 2020 17:27:58 +0530 Subject: [PATCH 06/27] code refactor --- lib/loginAzurePowerShell.js | 15 ++++++--------- src/loginAzurePowerShell.ts | 17 +++++++---------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/lib/loginAzurePowerShell.js b/lib/loginAzurePowerShell.js index b1bac9a3..48ede152 100644 --- a/lib/loginAzurePowerShell.js +++ b/lib/loginAzurePowerShell.js @@ -23,8 +23,10 @@ const io = __importStar(require("@actions/io")); var psPath; exports.initializeAz = (servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) => __awaiter(void 0, void 0, void 0, function* () { psPath = yield io.which("pwsh", true); + const prefix = "az_"; setPSModulePath(); - setPSModulePath(yield getLatestModule()); + const azLatestVersion = yield getLatestAzModule(); + setPSModulePath(`${prefix}${azLatestVersion}`); yield loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); }); function setPSModulePath(azPSVersion = "") { @@ -45,7 +47,7 @@ function setPSModulePath(azPSVersion = "") { } process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } -function getLatestModule() { +function getLatestAzModule() { return __awaiter(this, void 0, void 0, function* () { const moduleName = "Az.Accounts"; let output = ""; @@ -62,7 +64,7 @@ function getLatestModule() { }; yield executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); core.debug(`Az Module version used: ${output}`); - return `az_${output}`; + return output; }); } function loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) { @@ -79,11 +81,6 @@ function loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscri } function executePowerShellCommand(command, options = {}) { return __awaiter(this, void 0, void 0, function* () { - try { - yield exec.exec(`"${psPath}" -Command "${command}"`, [], options); - } - catch (error) { - throw new Error(error); - } + yield exec.exec(`"${psPath}" -Command "${command}"`, [], options); }); } diff --git a/src/loginAzurePowerShell.ts b/src/loginAzurePowerShell.ts index db2d00c2..90eee6e5 100644 --- a/src/loginAzurePowerShell.ts +++ b/src/loginAzurePowerShell.ts @@ -2,14 +2,15 @@ import * as os from 'os'; import * as core from '@actions/core'; import * as exec from '@actions/exec'; import * as io from '@actions/io'; -import { defaultCoreCipherList } from 'constants'; var psPath: string; export const initializeAz = async (servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) => { psPath = await io.which("pwsh", true); + const prefix = "az_"; setPSModulePath(); - setPSModulePath(await getLatestModule()); + const azLatestVersion: string = await getLatestAzModule(); + setPSModulePath(`${prefix}${azLatestVersion}`); await loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); } @@ -32,7 +33,7 @@ function setPSModulePath(azPSVersion: string = "") { process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } -async function getLatestModule() { +async function getLatestAzModule() { const moduleName: string = "Az.Accounts"; let output: string = ""; let error: string = ""; @@ -48,7 +49,7 @@ async function getLatestModule() { }; await executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); core.debug(`Az Module version used: ${output}`); - return `az_${output}`; + return output; } async function loginToAzure(servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) { @@ -63,9 +64,5 @@ async function loginToAzure(servicePrincipalId: string, servicePrincipalKey: str } async function executePowerShellCommand(command: string, options: any = {}) { - try { - await exec.exec(`"${psPath}" -Command "${command}"`, [], options); - } catch (error) { - throw new Error(error); - } -} \ No newline at end of file + await exec.exec(`"${psPath}" -Command "${command}"`, [], options); +} From 1c9bfa52b45a022a8bcee33dcd05fcc1aa6ec57c Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Mon, 9 Mar 2020 17:40:48 +0530 Subject: [PATCH 07/27] changes in loginAzurePowerShell --- lib/loginAzurePowerShell.js | 7 ++++++- src/loginAzurePowerShell.ts | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/loginAzurePowerShell.js b/lib/loginAzurePowerShell.js index 48ede152..206e861b 100644 --- a/lib/loginAzurePowerShell.js +++ b/lib/loginAzurePowerShell.js @@ -81,6 +81,11 @@ function loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscri } function executePowerShellCommand(command, options = {}) { return __awaiter(this, void 0, void 0, function* () { - yield exec.exec(`"${psPath}" -Command "${command}"`, [], options); + try { + yield exec.exec(`"${psPath}" -Command "${command}"`, [], options); + } + catch (error) { + throw new Error(error); + } }); } diff --git a/src/loginAzurePowerShell.ts b/src/loginAzurePowerShell.ts index 90eee6e5..423539fa 100644 --- a/src/loginAzurePowerShell.ts +++ b/src/loginAzurePowerShell.ts @@ -64,5 +64,9 @@ async function loginToAzure(servicePrincipalId: string, servicePrincipalKey: str } async function executePowerShellCommand(command: string, options: any = {}) { - await exec.exec(`"${psPath}" -Command "${command}"`, [], options); + try { + await exec.exec(`"${psPath}" -Command "${command}"`, [], options); + } catch (error) { + throw new Error(error); + } } From 1c43646e3aed0878cb910d6ec6d6ce9a29e36a3d Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Tue, 10 Mar 2020 10:18:25 +0530 Subject: [PATCH 08/27] code refactor --- lib/loginAzurePowerShell.js | 21 +++++++++++++-------- src/loginAzurePowerShell.ts | 22 +++++++++++++--------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/lib/loginAzurePowerShell.js b/lib/loginAzurePowerShell.js index 206e861b..abe1ea05 100644 --- a/lib/loginAzurePowerShell.js +++ b/lib/loginAzurePowerShell.js @@ -23,12 +23,19 @@ const io = __importStar(require("@actions/io")); var psPath; exports.initializeAz = (servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) => __awaiter(void 0, void 0, void 0, function* () { psPath = yield io.which("pwsh", true); - const prefix = "az_"; - setPSModulePath(); - const azLatestVersion = yield getLatestAzModule(); - setPSModulePath(`${prefix}${azLatestVersion}`); + yield importModule(); yield loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); }); +function importModule() { + return __awaiter(this, void 0, void 0, function* () { + setPSModulePath(); + const prefix = "az_"; + const moduleName = "Az.Accounts"; + const azLatestVersion = yield getLatestModule(moduleName); + core.debug(`Az Module version used: ${azLatestVersion}`); + setPSModulePath(`${prefix}${azLatestVersion}`); + }); +} function setPSModulePath(azPSVersion = "") { let modulePath = ""; const RUNNER = process.env.RUNNER_OS || os.type(); @@ -47,9 +54,8 @@ function setPSModulePath(azPSVersion = "") { } process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } -function getLatestAzModule() { +function getLatestModule(moduleName) { return __awaiter(this, void 0, void 0, function* () { - const moduleName = "Az.Accounts"; let output = ""; let error = ""; let options = { @@ -63,8 +69,7 @@ function getLatestAzModule() { } }; yield executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); - core.debug(`Az Module version used: ${output}`); - return output; + return output.trim(); }); } function loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) { diff --git a/src/loginAzurePowerShell.ts b/src/loginAzurePowerShell.ts index 423539fa..37997003 100644 --- a/src/loginAzurePowerShell.ts +++ b/src/loginAzurePowerShell.ts @@ -7,13 +7,19 @@ var psPath: string; export const initializeAz = async (servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) => { psPath = await io.which("pwsh", true); - const prefix = "az_"; - setPSModulePath(); - const azLatestVersion: string = await getLatestAzModule(); - setPSModulePath(`${prefix}${azLatestVersion}`); + await importModule(); await loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); } +async function importModule() { + setPSModulePath(); + const prefix = "az_"; + const moduleName: string = "Az.Accounts"; + const azLatestVersion: string = await getLatestModule(moduleName); + core.debug(`Az Module version used: ${azLatestVersion}`); + setPSModulePath(`${prefix}${azLatestVersion}`); +} + function setPSModulePath(azPSVersion: string = "") { let modulePath: string = ""; const RUNNER: string = process.env.RUNNER_OS || os.type(); @@ -33,8 +39,7 @@ function setPSModulePath(azPSVersion: string = "") { process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } -async function getLatestAzModule() { - const moduleName: string = "Az.Accounts"; +async function getLatestModule(moduleName: string) { let output: string = ""; let error: string = ""; let options: any = { @@ -48,8 +53,7 @@ async function getLatestAzModule() { } }; await executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); - core.debug(`Az Module version used: ${output}`); - return output; + return output.trim(); } async function loginToAzure(servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) { @@ -66,7 +70,7 @@ async function loginToAzure(servicePrincipalId: string, servicePrincipalKey: str async function executePowerShellCommand(command: string, options: any = {}) { try { await exec.exec(`"${psPath}" -Command "${command}"`, [], options); - } catch (error) { + } catch(error) { throw new Error(error); } } From 3e94d97948e4736610c9056debaef65b8958f00c Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Mon, 16 Mar 2020 15:15:59 +0530 Subject: [PATCH 09/27] Code refactor --- src/PowerShell/Constants.ts | 9 +++ src/PowerShell/IAzurePowerShellSession.ts | 4 + src/PowerShell/ServicePrincipalLogin.ts | 39 ++++++++++ .../Utilities/PowerShellToolRunner.ts | 20 +++++ src/PowerShell/Utilities/ScriptBuilder.ts | 16 ++++ src/PowerShell/Utilities/Utils.ts | 55 ++++++++++++++ src/loginAzurePowerShell.ts | 76 ------------------- src/main.ts | 10 ++- 8 files changed, 151 insertions(+), 78 deletions(-) create mode 100644 src/PowerShell/Constants.ts create mode 100644 src/PowerShell/IAzurePowerShellSession.ts create mode 100644 src/PowerShell/ServicePrincipalLogin.ts create mode 100644 src/PowerShell/Utilities/PowerShellToolRunner.ts create mode 100644 src/PowerShell/Utilities/ScriptBuilder.ts create mode 100644 src/PowerShell/Utilities/Utils.ts delete mode 100644 src/loginAzurePowerShell.ts diff --git a/src/PowerShell/Constants.ts b/src/PowerShell/Constants.ts new file mode 100644 index 00000000..f8f6036a --- /dev/null +++ b/src/PowerShell/Constants.ts @@ -0,0 +1,9 @@ +export class Constants { + static readonly prefix: string = "az_"; + static readonly moduleName: string = "Az.Accounts"; + static readonly versionPattern = /[0-9]\.[0-9]\.[0-9]/; + + static readonly environment: string = "AzureCloud"; + static readonly scopeLevel: string = "Subscription"; + static readonly scheme: string = "ServicePrincipal"; +} \ No newline at end of file diff --git a/src/PowerShell/IAzurePowerShellSession.ts b/src/PowerShell/IAzurePowerShellSession.ts new file mode 100644 index 00000000..544369d5 --- /dev/null +++ b/src/PowerShell/IAzurePowerShellSession.ts @@ -0,0 +1,4 @@ +interface IAzurePowerShellSession { + initialize(); + login(); +} \ No newline at end of file diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts new file mode 100644 index 00000000..b7f00a90 --- /dev/null +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -0,0 +1,39 @@ +import * as core from '@actions/core'; + +import Utils from './Utils'; +import PowerShellToolRunner from './PowerShellToolRunner'; +import ScriptBuilder from './ScriptBuilder'; +import { Constants } from './Constants'; + +export class ServicePrincipalLogin implements IAzurePowerShellSession { + static readonly environment: string = Constants.environment; + static readonly scopeLevel: string = Constants.scopeLevel; + static readonly scheme: string = Constants.scheme; + servicePrincipalId: string; + servicePrincipalKey: string; + tenantId: string; + subscriptionId: string; + + constructor(servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) { + this.servicePrincipalId = servicePrincipalId; + this.servicePrincipalKey = servicePrincipalKey; + this.tenantId = tenantId; + this.subscriptionId = subscriptionId; + } + + async initialize() { + Utils.setPSModulePath(); + const azLatestVersion: string = await Utils.getLatestModule(Constants.moduleName); + core.debug(`Az Module version used: ${azLatestVersion}`); + Utils.setPSModulePath(`${Constants.prefix}${azLatestVersion}`); + } + + async login() { + PowerShellToolRunner.init(); + const scriptBuilder: ScriptBuilder = new ScriptBuilder(); + const script: string = scriptBuilder.getScript(ServicePrincipalLogin.scheme, this.tenantId, this.servicePrincipalId, this.servicePrincipalKey, + this.subscriptionId, ServicePrincipalLogin.environment, ServicePrincipalLogin.scopeLevel); + PowerShellToolRunner.executePowerShellCommand(script); + } + +} \ No newline at end of file diff --git a/src/PowerShell/Utilities/PowerShellToolRunner.ts b/src/PowerShell/Utilities/PowerShellToolRunner.ts new file mode 100644 index 00000000..57eb5783 --- /dev/null +++ b/src/PowerShell/Utilities/PowerShellToolRunner.ts @@ -0,0 +1,20 @@ +import * as io from '@actions/io'; +import * as exec from '@actions/exec'; + +export default class PowerShellToolRunner { + static psPath: string; + + static async init() { + if(!PowerShellToolRunner.psPath) { + PowerShellToolRunner.psPath = await io.which("pwsh", true); + } + } + + static async executePowerShellCommand(command: string, options: any = {}) { + try { + await exec.exec(`"${PowerShellToolRunner.psPath}" -Command "${command}"`, [], options); + } catch(error) { + throw new Error(error); + } + } +} \ No newline at end of file diff --git a/src/PowerShell/Utilities/ScriptBuilder.ts b/src/PowerShell/Utilities/ScriptBuilder.ts new file mode 100644 index 00000000..eaba02ea --- /dev/null +++ b/src/PowerShell/Utilities/ScriptBuilder.ts @@ -0,0 +1,16 @@ +export default class ScriptBuilder { + script: string; + getScript(scheme: string, tenantId: string, servicePrincipalId: string, servicePrincipalKey: string, subscriptionId: string, environment: string, scopeLevel: string): string { + this.script += `Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; + if (scheme === "ServicePrincipal") { + this.script += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ + (New-Object System.Management.Automation.PSCredential('${servicePrincipalId}',(ConvertTo-SecureString ${servicePrincipalKey} -AsPlainText -Force))) \ + -Environment ${environment};`; + if (scopeLevel === "Subscription") { + this.script += `Set-AzContext -SubscriptionId ${subscriptionId} -TenantId ${tenantId};`; + } + } + this.script += `Get-AzContext`; + return this.script; + } +} \ No newline at end of file diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts new file mode 100644 index 00000000..f7ebcadc --- /dev/null +++ b/src/PowerShell/Utilities/Utils.ts @@ -0,0 +1,55 @@ +import * as os from 'os'; +import * as exec from '@actions/exec'; +import * as io from '@actions/io'; + +import { Constants } from './Constants'; +import PowerShellToolRunner from './PowerShellToolRunner'; + +export default class Utils { + static async getLatestModule(moduleName: string): Promise { + let output: string = ""; + let error: string = ""; + const options: any = { + listeners: { + stdout: (data: Buffer) => { + output += data.toString(); + }, + stderr: (data: Buffer) => { + error += data.toString(); + } + } + }; + PowerShellToolRunner.init(); + await PowerShellToolRunner.executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); + if(!Utils.isValidVersion(output.trim())) { + return ""; + } + return output.trim(); + } + + private static isValidVersion(version: string): boolean { + return !!version.match(Constants.versionPattern); + } + + static setPSModulePath(azPSVersion: string = "") { + let modulePath: string = ""; + const RUNNER: string = process.env.RUNNER_OS || os.type(); + switch (RUNNER) { + case "Linux": + modulePath = `/usr/share/${azPSVersion}:`; + break; + case "Windows": + case "Windows_NT": + modulePath = `C:\\Modules\\${azPSVersion};`; + break; + case "macOS": + case "Darwin": + // TODO: add modulepath + break; + default: + throw new Error("Unknown os"); + } + process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; + } +} + diff --git a/src/loginAzurePowerShell.ts b/src/loginAzurePowerShell.ts deleted file mode 100644 index 37997003..00000000 --- a/src/loginAzurePowerShell.ts +++ /dev/null @@ -1,76 +0,0 @@ -import * as os from 'os'; -import * as core from '@actions/core'; -import * as exec from '@actions/exec'; -import * as io from '@actions/io'; - -var psPath: string; - -export const initializeAz = async (servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) => { - psPath = await io.which("pwsh", true); - await importModule(); - await loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); -} - -async function importModule() { - setPSModulePath(); - const prefix = "az_"; - const moduleName: string = "Az.Accounts"; - const azLatestVersion: string = await getLatestModule(moduleName); - core.debug(`Az Module version used: ${azLatestVersion}`); - setPSModulePath(`${prefix}${azLatestVersion}`); -} - -function setPSModulePath(azPSVersion: string = "") { - let modulePath: string = ""; - const RUNNER: string = process.env.RUNNER_OS || os.type(); - switch (RUNNER) { - case "Linux": - modulePath = `/usr/share/${azPSVersion}:`; - break; - case "Windows": - case "Windows_NT": - modulePath = `C:\\Modules\\${azPSVersion};`; - break; - case "macOS": - case "Darwin": - // TODO: add modulepath - break; - } - process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; -} - -async function getLatestModule(moduleName: string) { - let output: string = ""; - let error: string = ""; - let options: any = { - listeners: { - stdout: (data: Buffer) => { - output += data.toString(); - }, - stderr: (data: Buffer) => { - error += data.toString(); - } - } - }; - await executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); - return output.trim(); -} - -async function loginToAzure(servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) { - const environment: string = "AzureCloud"; - await executePowerShellCommand(`Clear-AzContext -Scope Process`); - await executePowerShellCommand(`Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue`); - await executePowerShellCommand(`Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ - (New-Object System.Management.Automation.PSCredential('${servicePrincipalId}',(ConvertTo-SecureString ${servicePrincipalKey} -AsPlainText -Force))) \ - -Environment ${environment}`); - await executePowerShellCommand(`Set-AzContext -SubscriptionId ${subscriptionId} -TenantId ${tenantId}`); - await executePowerShellCommand(`Get-AzContext`); -} - -async function executePowerShellCommand(command: string, options: any = {}) { - try { - await exec.exec(`"${psPath}" -Command "${command}"`, [], options); - } catch(error) { - throw new Error(error); - } -} diff --git a/src/main.ts b/src/main.ts index b73f50bb..949f7879 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import * as exec from '@actions/exec'; import * as io from '@actions/io'; import { FormatType, SecretParser } from 'actions-secret-parser'; -import { initializeAz } from './loginAzurePowerShell'; +import { ServicePrincipalLogin } from './ServicePrincipalLogin'; var azPath: string; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; @@ -26,12 +26,18 @@ async function main() { let servicePrincipalKey = secrets.getSecret("$.clientSecret", true); let tenantId = secrets.getSecret("$.tenantId", false); let subscriptionId = secrets.getSecret("$.subscriptionId", false); + const enablePSSession = !!core.getInput('enable-PSSession'); if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) { throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied."); } await executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`); await executeAzCliCommand(`account set --subscription "${subscriptionId}"`); - await initializeAz(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); + if (enablePSSession) { + console.log(`Running Azure PS Login`); + const spnlogin: ServicePrincipalLogin = new ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); + spnlogin.initialize(); + spnlogin.login(); + } console.log("Login successful."); } catch (error) { core.error("Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"); From 7fc98cfa3dfb7e5546b31e7c725cea3f0bd9ba70 Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Mon, 16 Mar 2020 17:01:10 +0530 Subject: [PATCH 10/27] Code refactor --- lib/PowerShell/Constants.js | 11 +++ lib/PowerShell/IAzurePowerShellSession.js | 0 lib/PowerShell/ServicePrincipalLogin.js | 54 ++++++++++++++ .../Utilities/PowerShellToolRunner.js | 35 +++++++++ lib/PowerShell/Utilities/ScriptBuilder.js | 18 +++++ lib/PowerShell/Utilities/Utils.js | 72 +++++++++++++++++++ lib/main.js | 10 ++- src/PowerShell/ServicePrincipalLogin.ts | 6 +- .../Utilities/PowerShellToolRunner.ts | 6 +- src/PowerShell/Utilities/Utils.ts | 2 +- src/main.ts | 2 +- 11 files changed, 204 insertions(+), 12 deletions(-) create mode 100644 lib/PowerShell/Constants.js create mode 100644 lib/PowerShell/IAzurePowerShellSession.js create mode 100644 lib/PowerShell/ServicePrincipalLogin.js create mode 100644 lib/PowerShell/Utilities/PowerShellToolRunner.js create mode 100644 lib/PowerShell/Utilities/ScriptBuilder.js create mode 100644 lib/PowerShell/Utilities/Utils.js diff --git a/lib/PowerShell/Constants.js b/lib/PowerShell/Constants.js new file mode 100644 index 00000000..49ab99a7 --- /dev/null +++ b/lib/PowerShell/Constants.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class Constants { +} +exports.Constants = Constants; +Constants.prefix = "az_"; +Constants.moduleName = "Az.Accounts"; +Constants.versionPattern = /[0-9]\.[0-9]\.[0-9]/; +Constants.environment = "AzureCloud"; +Constants.scopeLevel = "Subscription"; +Constants.scheme = "ServicePrincipal"; diff --git a/lib/PowerShell/IAzurePowerShellSession.js b/lib/PowerShell/IAzurePowerShellSession.js new file mode 100644 index 00000000..e69de29b diff --git a/lib/PowerShell/ServicePrincipalLogin.js b/lib/PowerShell/ServicePrincipalLogin.js new file mode 100644 index 00000000..ef4e60e6 --- /dev/null +++ b/lib/PowerShell/ServicePrincipalLogin.js @@ -0,0 +1,54 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + 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) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(require("@actions/core")); +const Utils_1 = __importDefault(require("./Utilities/Utils")); +const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner")); +const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder")); +const Constants_1 = require("./Constants"); +class ServicePrincipalLogin { + constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) { + this.servicePrincipalId = servicePrincipalId; + this.servicePrincipalKey = servicePrincipalKey; + this.tenantId = tenantId; + this.subscriptionId = subscriptionId; + } + initialize() { + return __awaiter(this, void 0, void 0, function* () { + Utils_1.default.setPSModulePath(); + const azLatestVersion = yield Utils_1.default.getLatestModule(Constants_1.Constants.moduleName); + core.debug(`Az Module version used: ${azLatestVersion}`); + Utils_1.default.setPSModulePath(`${Constants_1.Constants.prefix}${azLatestVersion}`); + }); + } + login() { + return __awaiter(this, void 0, void 0, function* () { + PowerShellToolRunner_1.default.init(); + const scriptBuilder = new ScriptBuilder_1.default(); + const script = scriptBuilder.getScript(ServicePrincipalLogin.scheme, this.tenantId, this.servicePrincipalId, this.servicePrincipalKey, this.subscriptionId, ServicePrincipalLogin.environment, ServicePrincipalLogin.scopeLevel); + PowerShellToolRunner_1.default.executePowerShellCommand(script); + }); + } +} +exports.ServicePrincipalLogin = ServicePrincipalLogin; +ServicePrincipalLogin.environment = Constants_1.Constants.environment; +ServicePrincipalLogin.scopeLevel = Constants_1.Constants.scopeLevel; +ServicePrincipalLogin.scheme = Constants_1.Constants.scheme; diff --git a/lib/PowerShell/Utilities/PowerShellToolRunner.js b/lib/PowerShell/Utilities/PowerShellToolRunner.js new file mode 100644 index 00000000..7205551b --- /dev/null +++ b/lib/PowerShell/Utilities/PowerShellToolRunner.js @@ -0,0 +1,35 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + 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; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const io = __importStar(require("@actions/io")); +const exec = __importStar(require("@actions/exec")); +class PowerShellToolRunner { + static init() { + return __awaiter(this, void 0, void 0, function* () { + if (!PowerShellToolRunner.psPath) { + PowerShellToolRunner.psPath = yield io.which("pwsh", true); + } + }); + } + static executePowerShellCommand(command, options = {}) { + return __awaiter(this, void 0, void 0, function* () { + yield exec.exec(`"${PowerShellToolRunner.psPath}" -Command "${command}"`, [], options); + }); + } +} +exports.default = PowerShellToolRunner; diff --git a/lib/PowerShell/Utilities/ScriptBuilder.js b/lib/PowerShell/Utilities/ScriptBuilder.js new file mode 100644 index 00000000..68bc01f1 --- /dev/null +++ b/lib/PowerShell/Utilities/ScriptBuilder.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class ScriptBuilder { + getScript(scheme, tenantId, servicePrincipalId, servicePrincipalKey, subscriptionId, environment, scopeLevel) { + this.script += `Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; + if (scheme === "ServicePrincipal") { + this.script += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ + (New-Object System.Management.Automation.PSCredential('${servicePrincipalId}',(ConvertTo-SecureString ${servicePrincipalKey} -AsPlainText -Force))) \ + -Environment ${environment};`; + if (scopeLevel === "Subscription") { + this.script += `Set-AzContext -SubscriptionId ${subscriptionId} -TenantId ${tenantId};`; + } + } + this.script += `Get-AzContext`; + return this.script; + } +} +exports.default = ScriptBuilder; diff --git a/lib/PowerShell/Utilities/Utils.js b/lib/PowerShell/Utilities/Utils.js new file mode 100644 index 00000000..d23b998e --- /dev/null +++ b/lib/PowerShell/Utilities/Utils.js @@ -0,0 +1,72 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + 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) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const os = __importStar(require("os")); +const Constants_1 = require("../Constants"); +const PowerShellToolRunner_1 = __importDefault(require("./PowerShellToolRunner")); +class Utils { + static getLatestModule(moduleName) { + return __awaiter(this, void 0, void 0, function* () { + let output = ""; + let error = ""; + const options = { + listeners: { + stdout: (data) => { + output += data.toString(); + }, + stderr: (data) => { + error += data.toString(); + } + } + }; + PowerShellToolRunner_1.default.init(); + yield PowerShellToolRunner_1.default.executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); + if (!Utils.isValidVersion(output.trim())) { + return ""; + } + return output.trim(); + }); + } + static isValidVersion(version) { + return !!version.match(Constants_1.Constants.versionPattern); + } + static setPSModulePath(azPSVersion = "") { + let modulePath = ""; + const RUNNER = process.env.RUNNER_OS || os.type(); + switch (RUNNER) { + case "Linux": + modulePath = `/usr/share/${azPSVersion}:`; + break; + case "Windows": + case "Windows_NT": + modulePath = `C:\\Modules\\${azPSVersion};`; + break; + case "macOS": + case "Darwin": + // TODO: add modulepath + break; + default: + throw new Error("Unknown os"); + } + process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; + } +} +exports.default = Utils; diff --git a/lib/main.js b/lib/main.js index 226622d4..ba89d83d 100644 --- a/lib/main.js +++ b/lib/main.js @@ -21,7 +21,7 @@ const crypto = __importStar(require("crypto")); const exec = __importStar(require("@actions/exec")); const io = __importStar(require("@actions/io")); const actions_secret_parser_1 = require("actions-secret-parser"); -const loginAzurePowerShell_1 = require("./loginAzurePowerShell"); +const ServicePrincipalLogin_1 = require("./PowerShell/ServicePrincipalLogin"); var azPath; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; function main() { @@ -40,12 +40,18 @@ function main() { let servicePrincipalKey = secrets.getSecret("$.clientSecret", true); let tenantId = secrets.getSecret("$.tenantId", false); let subscriptionId = secrets.getSecret("$.subscriptionId", false); + const enablePSSession = !!core.getInput('enable-PSSession'); if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) { throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied."); } yield executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`); yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`); - yield loginAzurePowerShell_1.initializeAz(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); + if (enablePSSession) { + console.log(`Running Azure PS Login`); + const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); + spnlogin.initialize(); + spnlogin.login(); + } console.log("Login successful."); } catch (error) { diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts index b7f00a90..5b291c0a 100644 --- a/src/PowerShell/ServicePrincipalLogin.ts +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -1,8 +1,8 @@ import * as core from '@actions/core'; -import Utils from './Utils'; -import PowerShellToolRunner from './PowerShellToolRunner'; -import ScriptBuilder from './ScriptBuilder'; +import Utils from './Utilities/Utils'; +import PowerShellToolRunner from './Utilities/PowerShellToolRunner'; +import ScriptBuilder from './Utilities/ScriptBuilder'; import { Constants } from './Constants'; export class ServicePrincipalLogin implements IAzurePowerShellSession { diff --git a/src/PowerShell/Utilities/PowerShellToolRunner.ts b/src/PowerShell/Utilities/PowerShellToolRunner.ts index 57eb5783..86014d79 100644 --- a/src/PowerShell/Utilities/PowerShellToolRunner.ts +++ b/src/PowerShell/Utilities/PowerShellToolRunner.ts @@ -11,10 +11,6 @@ export default class PowerShellToolRunner { } static async executePowerShellCommand(command: string, options: any = {}) { - try { - await exec.exec(`"${PowerShellToolRunner.psPath}" -Command "${command}"`, [], options); - } catch(error) { - throw new Error(error); - } + await exec.exec(`"${PowerShellToolRunner.psPath}" -Command "${command}"`, [], options); } } \ No newline at end of file diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts index f7ebcadc..a3e62590 100644 --- a/src/PowerShell/Utilities/Utils.ts +++ b/src/PowerShell/Utilities/Utils.ts @@ -2,7 +2,7 @@ import * as os from 'os'; import * as exec from '@actions/exec'; import * as io from '@actions/io'; -import { Constants } from './Constants'; +import { Constants } from '../Constants'; import PowerShellToolRunner from './PowerShellToolRunner'; export default class Utils { diff --git a/src/main.ts b/src/main.ts index 949f7879..f81f26d7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import * as exec from '@actions/exec'; import * as io from '@actions/io'; import { FormatType, SecretParser } from 'actions-secret-parser'; -import { ServicePrincipalLogin } from './ServicePrincipalLogin'; +import { ServicePrincipalLogin } from './PowerShell/ServicePrincipalLogin'; var azPath: string; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; From c909df33380e4394912cd71d495db9d187ec5efd Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Mon, 16 Mar 2020 17:07:31 +0530 Subject: [PATCH 11/27] added review comments --- lib/PowerShell/Constants.js | 2 +- lib/PowerShell/ServicePrincipalLogin.js | 14 +++++++------- lib/PowerShell/Utilities/Utils.js | 6 +++--- src/PowerShell/Constants.ts | 2 +- src/PowerShell/ServicePrincipalLogin.ts | 4 ++-- src/PowerShell/Utilities/Utils.ts | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/PowerShell/Constants.js b/lib/PowerShell/Constants.js index 49ab99a7..e47bba72 100644 --- a/lib/PowerShell/Constants.js +++ b/lib/PowerShell/Constants.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); class Constants { } -exports.Constants = Constants; +exports.default = Constants; Constants.prefix = "az_"; Constants.moduleName = "Az.Accounts"; Constants.versionPattern = /[0-9]\.[0-9]\.[0-9]/; diff --git a/lib/PowerShell/ServicePrincipalLogin.js b/lib/PowerShell/ServicePrincipalLogin.js index ef4e60e6..9dadd9e3 100644 --- a/lib/PowerShell/ServicePrincipalLogin.js +++ b/lib/PowerShell/ServicePrincipalLogin.js @@ -23,7 +23,7 @@ const core = __importStar(require("@actions/core")); const Utils_1 = __importDefault(require("./Utilities/Utils")); const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner")); const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder")); -const Constants_1 = require("./Constants"); +const Constants_1 = __importDefault(require("./Constants")); class ServicePrincipalLogin { constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) { this.servicePrincipalId = servicePrincipalId; @@ -34,14 +34,14 @@ class ServicePrincipalLogin { initialize() { return __awaiter(this, void 0, void 0, function* () { Utils_1.default.setPSModulePath(); - const azLatestVersion = yield Utils_1.default.getLatestModule(Constants_1.Constants.moduleName); + const azLatestVersion = yield Utils_1.default.getLatestModule(Constants_1.default.moduleName); core.debug(`Az Module version used: ${azLatestVersion}`); - Utils_1.default.setPSModulePath(`${Constants_1.Constants.prefix}${azLatestVersion}`); + Utils_1.default.setPSModulePath(`${Constants_1.default.prefix}${azLatestVersion}`); }); } login() { return __awaiter(this, void 0, void 0, function* () { - PowerShellToolRunner_1.default.init(); + yield PowerShellToolRunner_1.default.init(); const scriptBuilder = new ScriptBuilder_1.default(); const script = scriptBuilder.getScript(ServicePrincipalLogin.scheme, this.tenantId, this.servicePrincipalId, this.servicePrincipalKey, this.subscriptionId, ServicePrincipalLogin.environment, ServicePrincipalLogin.scopeLevel); PowerShellToolRunner_1.default.executePowerShellCommand(script); @@ -49,6 +49,6 @@ class ServicePrincipalLogin { } } exports.ServicePrincipalLogin = ServicePrincipalLogin; -ServicePrincipalLogin.environment = Constants_1.Constants.environment; -ServicePrincipalLogin.scopeLevel = Constants_1.Constants.scopeLevel; -ServicePrincipalLogin.scheme = Constants_1.Constants.scheme; +ServicePrincipalLogin.environment = Constants_1.default.environment; +ServicePrincipalLogin.scopeLevel = Constants_1.default.scopeLevel; +ServicePrincipalLogin.scheme = Constants_1.default.scheme; diff --git a/lib/PowerShell/Utilities/Utils.js b/lib/PowerShell/Utilities/Utils.js index d23b998e..70dba97b 100644 --- a/lib/PowerShell/Utilities/Utils.js +++ b/lib/PowerShell/Utilities/Utils.js @@ -20,7 +20,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); const os = __importStar(require("os")); -const Constants_1 = require("../Constants"); +const Constants_1 = __importDefault(require("../Constants")); const PowerShellToolRunner_1 = __importDefault(require("./PowerShellToolRunner")); class Utils { static getLatestModule(moduleName) { @@ -37,7 +37,7 @@ class Utils { } } }; - PowerShellToolRunner_1.default.init(); + yield PowerShellToolRunner_1.default.init(); yield PowerShellToolRunner_1.default.executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); if (!Utils.isValidVersion(output.trim())) { return ""; @@ -46,7 +46,7 @@ class Utils { }); } static isValidVersion(version) { - return !!version.match(Constants_1.Constants.versionPattern); + return !!version.match(Constants_1.default.versionPattern); } static setPSModulePath(azPSVersion = "") { let modulePath = ""; diff --git a/src/PowerShell/Constants.ts b/src/PowerShell/Constants.ts index f8f6036a..2e85a96e 100644 --- a/src/PowerShell/Constants.ts +++ b/src/PowerShell/Constants.ts @@ -1,4 +1,4 @@ -export class Constants { +export default class Constants { static readonly prefix: string = "az_"; static readonly moduleName: string = "Az.Accounts"; static readonly versionPattern = /[0-9]\.[0-9]\.[0-9]/; diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts index 5b291c0a..7760e97c 100644 --- a/src/PowerShell/ServicePrincipalLogin.ts +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -3,7 +3,7 @@ import * as core from '@actions/core'; import Utils from './Utilities/Utils'; import PowerShellToolRunner from './Utilities/PowerShellToolRunner'; import ScriptBuilder from './Utilities/ScriptBuilder'; -import { Constants } from './Constants'; +import Constants from './Constants'; export class ServicePrincipalLogin implements IAzurePowerShellSession { static readonly environment: string = Constants.environment; @@ -29,7 +29,7 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession { } async login() { - PowerShellToolRunner.init(); + await PowerShellToolRunner.init(); const scriptBuilder: ScriptBuilder = new ScriptBuilder(); const script: string = scriptBuilder.getScript(ServicePrincipalLogin.scheme, this.tenantId, this.servicePrincipalId, this.servicePrincipalKey, this.subscriptionId, ServicePrincipalLogin.environment, ServicePrincipalLogin.scopeLevel); diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts index a3e62590..9d0efca3 100644 --- a/src/PowerShell/Utilities/Utils.ts +++ b/src/PowerShell/Utilities/Utils.ts @@ -2,7 +2,7 @@ import * as os from 'os'; import * as exec from '@actions/exec'; import * as io from '@actions/io'; -import { Constants } from '../Constants'; +import Constants from '../Constants'; import PowerShellToolRunner from './PowerShellToolRunner'; export default class Utils { @@ -19,7 +19,7 @@ export default class Utils { } } }; - PowerShellToolRunner.init(); + await PowerShellToolRunner.init(); await PowerShellToolRunner.executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); if(!Utils.isValidVersion(output.trim())) { return ""; From 04bdab0c41036de0d839d557b10fe51e118e9828 Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Mon, 16 Mar 2020 17:10:02 +0530 Subject: [PATCH 12/27] changes in scriptbuilder --- lib/PowerShell/Utilities/ScriptBuilder.js | 3 +++ src/PowerShell/Utilities/ScriptBuilder.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/PowerShell/Utilities/ScriptBuilder.js b/lib/PowerShell/Utilities/ScriptBuilder.js index 68bc01f1..68fd9c1e 100644 --- a/lib/PowerShell/Utilities/ScriptBuilder.js +++ b/lib/PowerShell/Utilities/ScriptBuilder.js @@ -1,6 +1,9 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class ScriptBuilder { + constructor() { + this.script = ""; + } getScript(scheme, tenantId, servicePrincipalId, servicePrincipalKey, subscriptionId, environment, scopeLevel) { this.script += `Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; if (scheme === "ServicePrincipal") { diff --git a/src/PowerShell/Utilities/ScriptBuilder.ts b/src/PowerShell/Utilities/ScriptBuilder.ts index eaba02ea..8895d227 100644 --- a/src/PowerShell/Utilities/ScriptBuilder.ts +++ b/src/PowerShell/Utilities/ScriptBuilder.ts @@ -1,5 +1,5 @@ export default class ScriptBuilder { - script: string; + script: string = ""; getScript(scheme: string, tenantId: string, servicePrincipalId: string, servicePrincipalKey: string, subscriptionId: string, environment: string, scopeLevel: string): string { this.script += `Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; if (scheme === "ServicePrincipal") { From 09ec3faf97f1105c1a74c87d2f2a4981fa5bb023 Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Tue, 17 Mar 2020 09:46:10 +0530 Subject: [PATCH 13/27] changes in setmodulepath --- lib/PowerShell/Utilities/Utils.js | 14 +++++++------- src/PowerShell/Utilities/Utils.ts | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/PowerShell/Utilities/Utils.js b/lib/PowerShell/Utilities/Utils.js index 70dba97b..e32d79ae 100644 --- a/lib/PowerShell/Utilities/Utils.js +++ b/lib/PowerShell/Utilities/Utils.js @@ -50,17 +50,17 @@ class Utils { } static setPSModulePath(azPSVersion = "") { let modulePath = ""; - const RUNNER = process.env.RUNNER_OS || os.type(); - switch (RUNNER) { - case "Linux": + const runner = process.env.RUNNER_OS || os.type(); + switch (runner.toLowerCase()) { + case "linux": modulePath = `/usr/share/${azPSVersion}:`; break; - case "Windows": - case "Windows_NT": + case "windows": + case "windows_nt": modulePath = `C:\\Modules\\${azPSVersion};`; break; - case "macOS": - case "Darwin": + case "macos": + case "darwin": // TODO: add modulepath break; default: diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts index 9d0efca3..9a25a72b 100644 --- a/src/PowerShell/Utilities/Utils.ts +++ b/src/PowerShell/Utilities/Utils.ts @@ -33,17 +33,17 @@ export default class Utils { static setPSModulePath(azPSVersion: string = "") { let modulePath: string = ""; - const RUNNER: string = process.env.RUNNER_OS || os.type(); - switch (RUNNER) { - case "Linux": + const runner: string = process.env.RUNNER_OS || os.type(); + switch (runner.toLowerCase()) { + case "linux": modulePath = `/usr/share/${azPSVersion}:`; break; - case "Windows": - case "Windows_NT": + case "windows": + case "windows_nt": modulePath = `C:\\Modules\\${azPSVersion};`; break; - case "macOS": - case "Darwin": + case "macos": + case "darwin": // TODO: add modulepath break; default: From cb2f4176bfc1e6603b6f7b2c4122f9327c913786 Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Tue, 17 Mar 2020 15:34:44 +0530 Subject: [PATCH 14/27] added paths in tsconfig.json --- lib/PowerShell/ServicePrincipalLogin.js | 10 +++++----- lib/PowerShell/Utilities/Utils.js | 4 ++-- lib/main.js | 7 +++++-- src/PowerShell/ServicePrincipalLogin.ts | 10 +++++----- src/PowerShell/Utilities/Utils.ts | 6 ++---- src/main.ts | 2 +- tsconfig.json | 7 +++++-- 7 files changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/PowerShell/ServicePrincipalLogin.js b/lib/PowerShell/ServicePrincipalLogin.js index 9dadd9e3..3f473425 100644 --- a/lib/PowerShell/ServicePrincipalLogin.js +++ b/lib/PowerShell/ServicePrincipalLogin.js @@ -20,10 +20,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); const core = __importStar(require("@actions/core")); -const Utils_1 = __importDefault(require("./Utilities/Utils")); -const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner")); -const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder")); -const Constants_1 = __importDefault(require("./Constants")); +const Utils_1 = __importDefault(require("PowerShell/Utilities/Utils")); +const PowerShellToolRunner_1 = __importDefault(require("PowerShell/Utilities/PowerShellToolRunner")); +const ScriptBuilder_1 = __importDefault(require("PowerShell/Utilities/ScriptBuilder")); +const Constants_1 = __importDefault(require("PowerShell/Constants")); class ServicePrincipalLogin { constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) { this.servicePrincipalId = servicePrincipalId; @@ -48,7 +48,7 @@ class ServicePrincipalLogin { }); } } -exports.ServicePrincipalLogin = ServicePrincipalLogin; +exports.default = ServicePrincipalLogin; ServicePrincipalLogin.environment = Constants_1.default.environment; ServicePrincipalLogin.scopeLevel = Constants_1.default.scopeLevel; ServicePrincipalLogin.scheme = Constants_1.default.scheme; diff --git a/lib/PowerShell/Utilities/Utils.js b/lib/PowerShell/Utilities/Utils.js index e32d79ae..f5b6b69a 100644 --- a/lib/PowerShell/Utilities/Utils.js +++ b/lib/PowerShell/Utilities/Utils.js @@ -20,8 +20,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); const os = __importStar(require("os")); -const Constants_1 = __importDefault(require("../Constants")); -const PowerShellToolRunner_1 = __importDefault(require("./PowerShellToolRunner")); +const Constants_1 = __importDefault(require("PowerShell/Constants")); +const PowerShellToolRunner_1 = __importDefault(require("PowerShell/Utilities/PowerShellToolRunner")); class Utils { static getLatestModule(moduleName) { return __awaiter(this, void 0, void 0, function* () { diff --git a/lib/main.js b/lib/main.js index ba89d83d..47da445d 100644 --- a/lib/main.js +++ b/lib/main.js @@ -15,13 +15,16 @@ var __importStar = (this && this.__importStar) || function (mod) { result["default"] = mod; return result; }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); const core = __importStar(require("@actions/core")); const crypto = __importStar(require("crypto")); const exec = __importStar(require("@actions/exec")); const io = __importStar(require("@actions/io")); const actions_secret_parser_1 = require("actions-secret-parser"); -const ServicePrincipalLogin_1 = require("./PowerShell/ServicePrincipalLogin"); +const ServicePrincipalLogin_1 = __importDefault(require("PowerShell/ServicePrincipalLogin")); var azPath; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; function main() { @@ -48,7 +51,7 @@ function main() { yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`); if (enablePSSession) { console.log(`Running Azure PS Login`); - const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); + const spnlogin = new ServicePrincipalLogin_1.default(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); spnlogin.initialize(); spnlogin.login(); } diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts index 7760e97c..288e343e 100644 --- a/src/PowerShell/ServicePrincipalLogin.ts +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -1,11 +1,11 @@ import * as core from '@actions/core'; -import Utils from './Utilities/Utils'; -import PowerShellToolRunner from './Utilities/PowerShellToolRunner'; -import ScriptBuilder from './Utilities/ScriptBuilder'; -import Constants from './Constants'; +import Utils from 'PowerShell/Utilities/Utils'; +import PowerShellToolRunner from 'PowerShell/Utilities/PowerShellToolRunner'; +import ScriptBuilder from 'PowerShell/Utilities/ScriptBuilder'; +import Constants from 'PowerShell/Constants'; -export class ServicePrincipalLogin implements IAzurePowerShellSession { +export default class ServicePrincipalLogin implements IAzurePowerShellSession { static readonly environment: string = Constants.environment; static readonly scopeLevel: string = Constants.scopeLevel; static readonly scheme: string = Constants.scheme; diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts index 9a25a72b..c990d6c4 100644 --- a/src/PowerShell/Utilities/Utils.ts +++ b/src/PowerShell/Utilities/Utils.ts @@ -1,9 +1,7 @@ import * as os from 'os'; -import * as exec from '@actions/exec'; -import * as io from '@actions/io'; -import Constants from '../Constants'; -import PowerShellToolRunner from './PowerShellToolRunner'; +import Constants from 'PowerShell/Constants'; +import PowerShellToolRunner from 'PowerShell/Utilities/PowerShellToolRunner'; export default class Utils { static async getLatestModule(moduleName: string): Promise { diff --git a/src/main.ts b/src/main.ts index f81f26d7..68a41d1e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import * as exec from '@actions/exec'; import * as io from '@actions/io'; import { FormatType, SecretParser } from 'actions-secret-parser'; -import { ServicePrincipalLogin } from './PowerShell/ServicePrincipalLogin'; +import ServicePrincipalLogin from 'PowerShell/ServicePrincipalLogin'; var azPath: string; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; diff --git a/tsconfig.json b/tsconfig.json index 7a865ad1..bbf65293 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -38,8 +38,11 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + "baseUrl": "src", /* Base directory to resolve non-absolute module names. */ + "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + "PowerShell/*": ["PowerShell/*"], + "PowerShell/Utilities/*": [ "PowerShell/Utilities/*"] + }, // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ From 860e5ace464e898dbc62db0a2281b26250c076d8 Mon Sep 17 00:00:00 2001 From: aksm-ms <58936966+aksm-ms@users.noreply.github.com> Date: Tue, 17 Mar 2020 17:26:39 +0530 Subject: [PATCH 15/27] Revert "added paths in tsconfig.json" This reverts commit cb2f4176bfc1e6603b6f7b2c4122f9327c913786. --- lib/PowerShell/ServicePrincipalLogin.js | 10 +++++----- lib/PowerShell/Utilities/Utils.js | 4 ++-- lib/main.js | 7 ++----- src/PowerShell/ServicePrincipalLogin.ts | 10 +++++----- src/PowerShell/Utilities/Utils.ts | 6 ++++-- src/main.ts | 2 +- tsconfig.json | 7 ++----- 7 files changed, 21 insertions(+), 25 deletions(-) diff --git a/lib/PowerShell/ServicePrincipalLogin.js b/lib/PowerShell/ServicePrincipalLogin.js index 3f473425..9dadd9e3 100644 --- a/lib/PowerShell/ServicePrincipalLogin.js +++ b/lib/PowerShell/ServicePrincipalLogin.js @@ -20,10 +20,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); const core = __importStar(require("@actions/core")); -const Utils_1 = __importDefault(require("PowerShell/Utilities/Utils")); -const PowerShellToolRunner_1 = __importDefault(require("PowerShell/Utilities/PowerShellToolRunner")); -const ScriptBuilder_1 = __importDefault(require("PowerShell/Utilities/ScriptBuilder")); -const Constants_1 = __importDefault(require("PowerShell/Constants")); +const Utils_1 = __importDefault(require("./Utilities/Utils")); +const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner")); +const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder")); +const Constants_1 = __importDefault(require("./Constants")); class ServicePrincipalLogin { constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) { this.servicePrincipalId = servicePrincipalId; @@ -48,7 +48,7 @@ class ServicePrincipalLogin { }); } } -exports.default = ServicePrincipalLogin; +exports.ServicePrincipalLogin = ServicePrincipalLogin; ServicePrincipalLogin.environment = Constants_1.default.environment; ServicePrincipalLogin.scopeLevel = Constants_1.default.scopeLevel; ServicePrincipalLogin.scheme = Constants_1.default.scheme; diff --git a/lib/PowerShell/Utilities/Utils.js b/lib/PowerShell/Utilities/Utils.js index f5b6b69a..e32d79ae 100644 --- a/lib/PowerShell/Utilities/Utils.js +++ b/lib/PowerShell/Utilities/Utils.js @@ -20,8 +20,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); const os = __importStar(require("os")); -const Constants_1 = __importDefault(require("PowerShell/Constants")); -const PowerShellToolRunner_1 = __importDefault(require("PowerShell/Utilities/PowerShellToolRunner")); +const Constants_1 = __importDefault(require("../Constants")); +const PowerShellToolRunner_1 = __importDefault(require("./PowerShellToolRunner")); class Utils { static getLatestModule(moduleName) { return __awaiter(this, void 0, void 0, function* () { diff --git a/lib/main.js b/lib/main.js index 47da445d..ba89d83d 100644 --- a/lib/main.js +++ b/lib/main.js @@ -15,16 +15,13 @@ var __importStar = (this && this.__importStar) || function (mod) { result["default"] = mod; return result; }; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", { value: true }); const core = __importStar(require("@actions/core")); const crypto = __importStar(require("crypto")); const exec = __importStar(require("@actions/exec")); const io = __importStar(require("@actions/io")); const actions_secret_parser_1 = require("actions-secret-parser"); -const ServicePrincipalLogin_1 = __importDefault(require("PowerShell/ServicePrincipalLogin")); +const ServicePrincipalLogin_1 = require("./PowerShell/ServicePrincipalLogin"); var azPath; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; function main() { @@ -51,7 +48,7 @@ function main() { yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`); if (enablePSSession) { console.log(`Running Azure PS Login`); - const spnlogin = new ServicePrincipalLogin_1.default(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); + const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); spnlogin.initialize(); spnlogin.login(); } diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts index 288e343e..7760e97c 100644 --- a/src/PowerShell/ServicePrincipalLogin.ts +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -1,11 +1,11 @@ import * as core from '@actions/core'; -import Utils from 'PowerShell/Utilities/Utils'; -import PowerShellToolRunner from 'PowerShell/Utilities/PowerShellToolRunner'; -import ScriptBuilder from 'PowerShell/Utilities/ScriptBuilder'; -import Constants from 'PowerShell/Constants'; +import Utils from './Utilities/Utils'; +import PowerShellToolRunner from './Utilities/PowerShellToolRunner'; +import ScriptBuilder from './Utilities/ScriptBuilder'; +import Constants from './Constants'; -export default class ServicePrincipalLogin implements IAzurePowerShellSession { +export class ServicePrincipalLogin implements IAzurePowerShellSession { static readonly environment: string = Constants.environment; static readonly scopeLevel: string = Constants.scopeLevel; static readonly scheme: string = Constants.scheme; diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts index c990d6c4..9a25a72b 100644 --- a/src/PowerShell/Utilities/Utils.ts +++ b/src/PowerShell/Utilities/Utils.ts @@ -1,7 +1,9 @@ import * as os from 'os'; +import * as exec from '@actions/exec'; +import * as io from '@actions/io'; -import Constants from 'PowerShell/Constants'; -import PowerShellToolRunner from 'PowerShell/Utilities/PowerShellToolRunner'; +import Constants from '../Constants'; +import PowerShellToolRunner from './PowerShellToolRunner'; export default class Utils { static async getLatestModule(moduleName: string): Promise { diff --git a/src/main.ts b/src/main.ts index 68a41d1e..f81f26d7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import * as exec from '@actions/exec'; import * as io from '@actions/io'; import { FormatType, SecretParser } from 'actions-secret-parser'; -import ServicePrincipalLogin from 'PowerShell/ServicePrincipalLogin'; +import { ServicePrincipalLogin } from './PowerShell/ServicePrincipalLogin'; var azPath: string; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; diff --git a/tsconfig.json b/tsconfig.json index bbf65293..7a865ad1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -38,11 +38,8 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - "baseUrl": "src", /* Base directory to resolve non-absolute module names. */ - "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - "PowerShell/*": ["PowerShell/*"], - "PowerShell/Utilities/*": [ "PowerShell/Utilities/*"] - }, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ From 13aa761aaa45323873644cede724db8b372bd40c Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Thu, 19 Mar 2020 11:08:42 +0530 Subject: [PATCH 16/27] changes in action.yml --- action.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/action.yml b/action.yml index 146130e0..1e6373c6 100644 --- a/action.yml +++ b/action.yml @@ -5,6 +5,10 @@ inputs: creds: description: 'Paste output of `az ad sp create-for-rbac` as value of secret variable: AZURE_CREDENTIALS' required: true + enable-PSSession: + description: 'Set this value to true to enable Azure PowerShell Login in addition to Az CLI login' + required: false + default: false branding: icon: 'login.svg' color: 'blue' From 7e72509c6bfe9cf4893df1076c52ff8b4ca6a2cc Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Thu, 19 Mar 2020 11:38:04 +0530 Subject: [PATCH 17/27] changes in main --- lib/main.js | 2 +- src/main.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/main.js b/lib/main.js index ba89d83d..4948a2a9 100644 --- a/lib/main.js +++ b/lib/main.js @@ -40,7 +40,7 @@ function main() { let servicePrincipalKey = secrets.getSecret("$.clientSecret", true); let tenantId = secrets.getSecret("$.tenantId", false); let subscriptionId = secrets.getSecret("$.subscriptionId", false); - const enablePSSession = !!core.getInput('enable-PSSession'); + const enablePSSession = core.getInput('enable-PSSession').toLowerCase() === "true"; if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) { throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied."); } diff --git a/src/main.ts b/src/main.ts index f81f26d7..86b0ad00 100644 --- a/src/main.ts +++ b/src/main.ts @@ -26,7 +26,7 @@ async function main() { let servicePrincipalKey = secrets.getSecret("$.clientSecret", true); let tenantId = secrets.getSecret("$.tenantId", false); let subscriptionId = secrets.getSecret("$.subscriptionId", false); - const enablePSSession = !!core.getInput('enable-PSSession'); + const enablePSSession = core.getInput('enable-PSSession').toLowerCase() === "true"; if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) { throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied."); } From a2be320a3e528434fbe9e9ae74a6fc7196b4c911 Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Thu, 19 Mar 2020 19:27:30 +0530 Subject: [PATCH 18/27] added review comments --- lib/PowerShell/Constants.js | 9 +- lib/PowerShell/ServicePrincipalLogin.js | 52 ++++- lib/PowerShell/Utilities/ScriptBuilder.js | 58 ++++- lib/PowerShell/Utilities/Utils.js | 40 +--- lib/main.js | 6 +- package-lock.json | 257 ++++++++++++++++++++++ package.json | 3 +- src/PowerShell/Constants.ts | 10 +- src/PowerShell/ServicePrincipalLogin.ts | 54 ++++- src/PowerShell/Utilities/ScriptBuilder.ts | 54 ++++- src/PowerShell/Utilities/Utils.ts | 33 +-- src/main.ts | 6 +- 12 files changed, 472 insertions(+), 110 deletions(-) diff --git a/lib/PowerShell/Constants.js b/lib/PowerShell/Constants.js index e47bba72..98f75ccf 100644 --- a/lib/PowerShell/Constants.js +++ b/lib/PowerShell/Constants.js @@ -6,6 +6,9 @@ exports.default = Constants; Constants.prefix = "az_"; Constants.moduleName = "Az.Accounts"; Constants.versionPattern = /[0-9]\.[0-9]\.[0-9]/; -Constants.environment = "AzureCloud"; -Constants.scopeLevel = "Subscription"; -Constants.scheme = "ServicePrincipal"; +Constants.AzureCloud = "AzureCloud"; +Constants.Subscription = "Subscription"; +Constants.ServicePrincipal = "ServicePrincipal"; +Constants.Success = "Success"; +Constants.Error = "Error"; +Constants.AzVersion = "AzVersion"; diff --git a/lib/PowerShell/ServicePrincipalLogin.js b/lib/PowerShell/ServicePrincipalLogin.js index 9dadd9e3..59900bd4 100644 --- a/lib/PowerShell/ServicePrincipalLogin.js +++ b/lib/PowerShell/ServicePrincipalLogin.js @@ -34,21 +34,59 @@ class ServicePrincipalLogin { initialize() { return __awaiter(this, void 0, void 0, function* () { Utils_1.default.setPSModulePath(); - const azLatestVersion = yield Utils_1.default.getLatestModule(Constants_1.default.moduleName); + const script = new ScriptBuilder_1.default().getLatestModuleScript(Constants_1.default.moduleName); + const outputJson = yield this.getLatestModule(script); + const azLatestVersion = outputJson.Constants.AzPSVersion; + if (!(Constants_1.default.Success in outputJson) || !Utils_1.default.isValidVersion(azLatestVersion)) { + throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); + } core.debug(`Az Module version used: ${azLatestVersion}`); Utils_1.default.setPSModulePath(`${Constants_1.default.prefix}${azLatestVersion}`); }); } + getLatestModule(script) { + return __awaiter(this, void 0, void 0, function* () { + let output = ""; + const options = { + listeners: { + stdout: (data) => { + output += data.toString(); + } + } + }; + yield PowerShellToolRunner_1.default.init(); + yield PowerShellToolRunner_1.default.executePowerShellCommand(script, options); + return JSON.parse(output.trim()); + }); + } login() { return __awaiter(this, void 0, void 0, function* () { + let output = ""; + const options = { + listeners: { + stdout: (data) => { + output += data.toString(); + } + } + }; + const args = { + servicePrincipalId: this.servicePrincipalId, + servicePrincipalKey: this.servicePrincipalKey, + subscriptionId: this.subscriptionId, + environment: ServicePrincipalLogin.environment, + scopeLevel: ServicePrincipalLogin.scopeLevel + }; + const script = new ScriptBuilder_1.default().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args); yield PowerShellToolRunner_1.default.init(); - const scriptBuilder = new ScriptBuilder_1.default(); - const script = scriptBuilder.getScript(ServicePrincipalLogin.scheme, this.tenantId, this.servicePrincipalId, this.servicePrincipalKey, this.subscriptionId, ServicePrincipalLogin.environment, ServicePrincipalLogin.scopeLevel); - PowerShellToolRunner_1.default.executePowerShellCommand(script); + yield PowerShellToolRunner_1.default.executePowerShellCommand(script, options); + const outputJson = JSON.parse(output.trim()); + if (!(Constants_1.default.Success in outputJson)) { + throw new Error(`Azure PowerShell login failed with error: ${outputJson.Constants.Error}`); + } }); } } exports.ServicePrincipalLogin = ServicePrincipalLogin; -ServicePrincipalLogin.environment = Constants_1.default.environment; -ServicePrincipalLogin.scopeLevel = Constants_1.default.scopeLevel; -ServicePrincipalLogin.scheme = Constants_1.default.scheme; +ServicePrincipalLogin.environment = Constants_1.default.AzureCloud; +ServicePrincipalLogin.scopeLevel = Constants_1.default.Subscription; +ServicePrincipalLogin.scheme = Constants_1.default.ServicePrincipal; diff --git a/lib/PowerShell/Utilities/ScriptBuilder.js b/lib/PowerShell/Utilities/ScriptBuilder.js index 68fd9c1e..0308a0bd 100644 --- a/lib/PowerShell/Utilities/ScriptBuilder.js +++ b/lib/PowerShell/Utilities/ScriptBuilder.js @@ -1,20 +1,60 @@ "use strict"; +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) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(require("@actions/core")); +const Constants_1 = __importDefault(require("../Constants")); class ScriptBuilder { constructor() { this.script = ""; } - getScript(scheme, tenantId, servicePrincipalId, servicePrincipalKey, subscriptionId, environment, scopeLevel) { - this.script += `Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; - if (scheme === "ServicePrincipal") { - this.script += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ - (New-Object System.Management.Automation.PSCredential('${servicePrincipalId}',(ConvertTo-SecureString ${servicePrincipalKey} -AsPlainText -Force))) \ - -Environment ${environment};`; - if (scopeLevel === "Subscription") { - this.script += `Set-AzContext -SubscriptionId ${subscriptionId} -TenantId ${tenantId};`; + getAzPSLoginScript(scheme, tenantId, args) { + let command = `Clear-AzContext -Scope Process; + Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; + if (scheme === Constants_1.default.ServicePrincipal) { + command += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ + (New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString ${args.servicePrincipalKey} -AsPlainText -Force))) \ + -Environment ${args.environment};`; + if (args.scopeLevel === Constants_1.default.Subscription) { + command += `Set-AzContext -SubscriptionId ${args.subscriptionId} -TenantId ${tenantId};`; } } - this.script += `Get-AzContext`; + command += `Get-AzContext`; + this.script += `try { + $$ErrorActionPreference = "Stop"; + $$output = @{}; + ${command} + $$output['${Constants_1.default.Success}'] = "true"; + } + catch { + $$output['${Constants_1.default.Error}'] = $$_.exception.Message; + } + return ConvertTo-Json $$a`; + core.debug(`Azure PowerShell Login Script: ${this.script}`); + return this.script; + } + getLatestModuleScript(moduleName) { + const command = `Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1`; + this.script += `try { + $$ErrorActionPreference = "Stop"; + $$output = @{}; + $$data = ${command}; + $$output['${Constants_1.default.AzVersion}'] = $$data.Version.ToString(); + $$output['${Constants_1.default.Success}'] = "true"; + } + catch { + $$output['${Constants_1.default.Error}'] = $$_.exception.Message; + } + return ConvertTo-Json $$a`; + core.debug(`GetLatestModuleScript: ${this.script}`); return this.script; } } diff --git a/lib/PowerShell/Utilities/Utils.js b/lib/PowerShell/Utilities/Utils.js index e32d79ae..e0d6f284 100644 --- a/lib/PowerShell/Utilities/Utils.js +++ b/lib/PowerShell/Utilities/Utils.js @@ -1,13 +1,4 @@ "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; @@ -21,33 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { Object.defineProperty(exports, "__esModule", { value: true }); const os = __importStar(require("os")); const Constants_1 = __importDefault(require("../Constants")); -const PowerShellToolRunner_1 = __importDefault(require("./PowerShellToolRunner")); class Utils { - static getLatestModule(moduleName) { - return __awaiter(this, void 0, void 0, function* () { - let output = ""; - let error = ""; - const options = { - listeners: { - stdout: (data) => { - output += data.toString(); - }, - stderr: (data) => { - error += data.toString(); - } - } - }; - yield PowerShellToolRunner_1.default.init(); - yield PowerShellToolRunner_1.default.executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); - if (!Utils.isValidVersion(output.trim())) { - return ""; - } - return output.trim(); - }); - } - static isValidVersion(version) { - return !!version.match(Constants_1.default.versionPattern); - } static setPSModulePath(azPSVersion = "") { let modulePath = ""; const runner = process.env.RUNNER_OS || os.type(); @@ -64,9 +29,12 @@ class Utils { // TODO: add modulepath break; default: - throw new Error("Unknown os"); + throw new Error(`Unknown os: ${runner.toLowerCase()}`); } process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } + static isValidVersion(version) { + return !!version.match(Constants_1.default.versionPattern); + } } exports.default = Utils; diff --git a/lib/main.js b/lib/main.js index 4948a2a9..ca968e8b 100644 --- a/lib/main.js +++ b/lib/main.js @@ -44,13 +44,15 @@ function main() { if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) { throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied."); } + // Attempting Az cli login yield executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`); yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`); if (enablePSSession) { + // Attempting Az PS login console.log(`Running Azure PS Login`); const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); - spnlogin.initialize(); - spnlogin.login(); + yield spnlogin.initialize(); + yield spnlogin.login(); } console.log("Login successful."); } diff --git a/package-lock.json b/package-lock.json index c3e3c9b5..e8b32c12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,24 @@ "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.1.tgz", "integrity": "sha512-rhq+tfZukbtaus7xyUtwKfuiCRXd1hWSfmJNEpFgBQJ4woqPEpsBw04awicjwz9tyG2/MVhAEMfVn664Cri5zA==" }, + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, "@types/node": { "version": "12.7.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.11.tgz", @@ -36,11 +54,89 @@ "xpath": "0.0.27" } }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, "escodegen": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", @@ -80,6 +176,64 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + } + } + }, "jsonpath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.2.tgz", @@ -99,6 +253,35 @@ "type-check": "~0.3.2" } }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", + "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", + "requires": { + "minimist": "^1.2.5" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -112,17 +295,45 @@ "word-wrap": "~1.2.3" } }, + "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=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "optional": true }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, "static-eval": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", @@ -131,6 +342,47 @@ "escodegen": "^1.8.1" } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "tslib": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" + }, + "tslint": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.0.tgz", + "integrity": "sha512-fXjYd/61vU6da04E505OZQGb2VCN2Mq3doeWcOIryuG+eqdmFUXTYVwdhnbEu2k46LNLgUYt9bI5icQze/j0bQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.10.0", + "tsutils": "^2.29.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "requires": { + "tslib": "^1.8.1" + } + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -155,6 +407,11 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, "xmldom": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", diff --git a/package.json b/package.json index b0b60823..26e25c46 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@actions/core": "^1.1.3", "@actions/exec": "^1.0.1", "@actions/io": "^1.0.1", - "actions-secret-parser": "^1.0.2" + "actions-secret-parser": "^1.0.2", + "tslint": "^6.1.0" } } diff --git a/src/PowerShell/Constants.ts b/src/PowerShell/Constants.ts index 2e85a96e..9613db1d 100644 --- a/src/PowerShell/Constants.ts +++ b/src/PowerShell/Constants.ts @@ -3,7 +3,11 @@ export default class Constants { static readonly moduleName: string = "Az.Accounts"; static readonly versionPattern = /[0-9]\.[0-9]\.[0-9]/; - static readonly environment: string = "AzureCloud"; - static readonly scopeLevel: string = "Subscription"; - static readonly scheme: string = "ServicePrincipal"; + static readonly AzureCloud: string = "AzureCloud"; + static readonly Subscription: string = "Subscription"; + static readonly ServicePrincipal: string = "ServicePrincipal"; + + static readonly Success: string = "Success"; + static readonly Error: string = "Error"; + static readonly AzVersion: string = "AzVersion"; } \ No newline at end of file diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts index 7760e97c..f4ac6d0c 100644 --- a/src/PowerShell/ServicePrincipalLogin.ts +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -6,9 +6,9 @@ import ScriptBuilder from './Utilities/ScriptBuilder'; import Constants from './Constants'; export class ServicePrincipalLogin implements IAzurePowerShellSession { - static readonly environment: string = Constants.environment; - static readonly scopeLevel: string = Constants.scopeLevel; - static readonly scheme: string = Constants.scheme; + static readonly environment: string = Constants.AzureCloud; + static readonly scopeLevel: string = Constants.Subscription; + static readonly scheme: string = Constants.ServicePrincipal; servicePrincipalId: string; servicePrincipalKey: string; tenantId: string; @@ -23,17 +23,53 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession { async initialize() { Utils.setPSModulePath(); - const azLatestVersion: string = await Utils.getLatestModule(Constants.moduleName); + const script: string = new ScriptBuilder().getLatestModuleScript(Constants.moduleName); + const outputJson = await this.getLatestModule(script); + const azLatestVersion: string = outputJson.Constants.AzPSVersion; + if (!(Constants.Success in outputJson) || !Utils.isValidVersion(azLatestVersion)) { + throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); + } core.debug(`Az Module version used: ${azLatestVersion}`); Utils.setPSModulePath(`${Constants.prefix}${azLatestVersion}`); } - async login() { + private async getLatestModule(script: string): Promise { + let output: string = ""; + const options: any = { + listeners: { + stdout: (data: Buffer) => { + output += data.toString(); + } + } + }; await PowerShellToolRunner.init(); - const scriptBuilder: ScriptBuilder = new ScriptBuilder(); - const script: string = scriptBuilder.getScript(ServicePrincipalLogin.scheme, this.tenantId, this.servicePrincipalId, this.servicePrincipalKey, - this.subscriptionId, ServicePrincipalLogin.environment, ServicePrincipalLogin.scopeLevel); - PowerShellToolRunner.executePowerShellCommand(script); + await PowerShellToolRunner.executePowerShellCommand(script, options); + return JSON.parse(output.trim()); + } + + async login() { + let output: string = ""; + const options: any = { + listeners: { + stdout: (data: Buffer) => { + output += data.toString(); + } + } + }; + const args: any = { + servicePrincipalId: this.servicePrincipalId, + servicePrincipalKey: this.servicePrincipalKey, + subscriptionId: this.subscriptionId, + environment: ServicePrincipalLogin.environment, + scopeLevel: ServicePrincipalLogin.scopeLevel + } + const script: string = new ScriptBuilder().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args); + await PowerShellToolRunner.init(); + await PowerShellToolRunner.executePowerShellCommand(script, options); + const outputJson: any = JSON.parse(output.trim()); + if (!(Constants.Success in outputJson)) { + throw new Error(`Azure PowerShell login failed with error: ${outputJson.Constants.Error}`); + } } } \ No newline at end of file diff --git a/src/PowerShell/Utilities/ScriptBuilder.ts b/src/PowerShell/Utilities/ScriptBuilder.ts index 8895d227..43b33b85 100644 --- a/src/PowerShell/Utilities/ScriptBuilder.ts +++ b/src/PowerShell/Utilities/ScriptBuilder.ts @@ -1,16 +1,50 @@ +import * as core from '@actions/core'; + +import Constants from "../Constants"; + export default class ScriptBuilder { script: string = ""; - getScript(scheme: string, tenantId: string, servicePrincipalId: string, servicePrincipalKey: string, subscriptionId: string, environment: string, scopeLevel: string): string { - this.script += `Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; - if (scheme === "ServicePrincipal") { - this.script += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ - (New-Object System.Management.Automation.PSCredential('${servicePrincipalId}',(ConvertTo-SecureString ${servicePrincipalKey} -AsPlainText -Force))) \ - -Environment ${environment};`; - if (scopeLevel === "Subscription") { - this.script += `Set-AzContext -SubscriptionId ${subscriptionId} -TenantId ${tenantId};`; + + getAzPSLoginScript(scheme: string, tenantId: string, args: any): string { + let command = `Clear-AzContext -Scope Process; + Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`; + if (scheme === Constants.ServicePrincipal) { + command += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ + (New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString ${args.servicePrincipalKey} -AsPlainText -Force))) \ + -Environment ${args.environment};`; + if (args.scopeLevel === Constants.Subscription) { + command += `Set-AzContext -SubscriptionId ${args.subscriptionId} -TenantId ${tenantId};`; } } - this.script += `Get-AzContext`; + command += `Get-AzContext`; + this.script += `try { + $$ErrorActionPreference = "Stop"; + $$output = @{}; + ${command} + $$output['${Constants.Success}'] = "true"; + } + catch { + $$output['${Constants.Error}'] = $$_.exception.Message; + } + return ConvertTo-Json $$a`; + core.debug(`Azure PowerShell Login Script: ${this.script}`); return this.script; } -} \ No newline at end of file + + getLatestModuleScript(moduleName: string): string { + const command: string = `Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1`; + this.script += `try { + $$ErrorActionPreference = "Stop"; + $$output = @{}; + $$data = ${command}; + $$output['${Constants.AzVersion}'] = $$data.Version.ToString(); + $$output['${Constants.Success}'] = "true"; + } + catch { + $$output['${Constants.Error}'] = $$_.exception.Message; + } + return ConvertTo-Json $$a`; + core.debug(`GetLatestModuleScript: ${this.script}`); + return this.script; + } +} diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts index 9a25a72b..1428c6ef 100644 --- a/src/PowerShell/Utilities/Utils.ts +++ b/src/PowerShell/Utilities/Utils.ts @@ -1,36 +1,9 @@ import * as os from 'os'; -import * as exec from '@actions/exec'; -import * as io from '@actions/io'; import Constants from '../Constants'; import PowerShellToolRunner from './PowerShellToolRunner'; export default class Utils { - static async getLatestModule(moduleName: string): Promise { - let output: string = ""; - let error: string = ""; - const options: any = { - listeners: { - stdout: (data: Buffer) => { - output += data.toString(); - }, - stderr: (data: Buffer) => { - error += data.toString(); - } - } - }; - await PowerShellToolRunner.init(); - await PowerShellToolRunner.executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); - if(!Utils.isValidVersion(output.trim())) { - return ""; - } - return output.trim(); - } - - private static isValidVersion(version: string): boolean { - return !!version.match(Constants.versionPattern); - } - static setPSModulePath(azPSVersion: string = "") { let modulePath: string = ""; const runner: string = process.env.RUNNER_OS || os.type(); @@ -47,9 +20,13 @@ export default class Utils { // TODO: add modulepath break; default: - throw new Error("Unknown os"); + throw new Error(`Unknown os: ${runner.toLowerCase()}`); } process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } + + static isValidVersion(version: string): boolean { + return !!version.match(Constants.versionPattern); + } } diff --git a/src/main.ts b/src/main.ts index 86b0ad00..a9e7f461 100644 --- a/src/main.ts +++ b/src/main.ts @@ -30,13 +30,15 @@ async function main() { if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) { throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied."); } + // Attempting Az cli login await executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`); await executeAzCliCommand(`account set --subscription "${subscriptionId}"`); if (enablePSSession) { + // Attempting Az PS login console.log(`Running Azure PS Login`); const spnlogin: ServicePrincipalLogin = new ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); - spnlogin.initialize(); - spnlogin.login(); + await spnlogin.initialize(); + await spnlogin.login(); } console.log("Login successful."); } catch (error) { From ad3250b83a0b50a6e0f5bd5fc79214371d5677a5 Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Fri, 20 Mar 2020 16:00:28 +0530 Subject: [PATCH 19/27] Added changes for review comments --- lib/PowerShell/ServicePrincipalLogin.js | 8 +- .../Utilities/PowerShellToolRunner.js | 5 + lib/PowerShell/Utilities/ScriptBuilder.js | 31 +++--- lib/PowerShell/Utilities/Utils.js | 3 +- lib/loginAzurePowerShell.js | 96 ------------------- src/PowerShell/ServicePrincipalLogin.ts | 8 +- .../Utilities/PowerShellToolRunner.ts | 4 + src/PowerShell/Utilities/ScriptBuilder.ts | 31 +++--- src/PowerShell/Utilities/Utils.ts | 4 +- 9 files changed, 51 insertions(+), 139 deletions(-) delete mode 100644 lib/loginAzurePowerShell.js diff --git a/lib/PowerShell/ServicePrincipalLogin.js b/lib/PowerShell/ServicePrincipalLogin.js index 59900bd4..babeb9da 100644 --- a/lib/PowerShell/ServicePrincipalLogin.js +++ b/lib/PowerShell/ServicePrincipalLogin.js @@ -36,7 +36,7 @@ class ServicePrincipalLogin { Utils_1.default.setPSModulePath(); const script = new ScriptBuilder_1.default().getLatestModuleScript(Constants_1.default.moduleName); const outputJson = yield this.getLatestModule(script); - const azLatestVersion = outputJson.Constants.AzPSVersion; + const azLatestVersion = outputJson[Constants_1.default.AzVersion]; if (!(Constants_1.default.Success in outputJson) || !Utils_1.default.isValidVersion(azLatestVersion)) { throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); } @@ -55,7 +55,7 @@ class ServicePrincipalLogin { } }; yield PowerShellToolRunner_1.default.init(); - yield PowerShellToolRunner_1.default.executePowerShellCommand(script, options); + yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(script, options); return JSON.parse(output.trim()); }); } @@ -78,10 +78,10 @@ class ServicePrincipalLogin { }; const script = new ScriptBuilder_1.default().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args); yield PowerShellToolRunner_1.default.init(); - yield PowerShellToolRunner_1.default.executePowerShellCommand(script, options); + yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(script, options); const outputJson = JSON.parse(output.trim()); if (!(Constants_1.default.Success in outputJson)) { - throw new Error(`Azure PowerShell login failed with error: ${outputJson.Constants.Error}`); + throw new Error(`Azure PowerShell login failed with error: ${outputJson[Constants_1.default.Error]}`); } }); } diff --git a/lib/PowerShell/Utilities/PowerShellToolRunner.js b/lib/PowerShell/Utilities/PowerShellToolRunner.js index 7205551b..8a313bcf 100644 --- a/lib/PowerShell/Utilities/PowerShellToolRunner.js +++ b/lib/PowerShell/Utilities/PowerShellToolRunner.js @@ -26,6 +26,11 @@ class PowerShellToolRunner { } }); } + static executePowerShellScriptBlock(scriptBlock, options = {}) { + return __awaiter(this, void 0, void 0, function* () { + yield exec.exec(`${PowerShellToolRunner.psPath} -Command`, [scriptBlock], options); + }); + } static executePowerShellCommand(command, options = {}) { return __awaiter(this, void 0, void 0, function* () { yield exec.exec(`"${PowerShellToolRunner.psPath}" -Command "${command}"`, [], options); diff --git a/lib/PowerShell/Utilities/ScriptBuilder.js b/lib/PowerShell/Utilities/ScriptBuilder.js index 0308a0bd..2b6cdcc1 100644 --- a/lib/PowerShell/Utilities/ScriptBuilder.js +++ b/lib/PowerShell/Utilities/ScriptBuilder.js @@ -22,38 +22,39 @@ class ScriptBuilder { if (scheme === Constants_1.default.ServicePrincipal) { command += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ (New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString ${args.servicePrincipalKey} -AsPlainText -Force))) \ - -Environment ${args.environment};`; + -Environment ${args.environment} | out-null;`; if (args.scopeLevel === Constants_1.default.Subscription) { - command += `Set-AzContext -SubscriptionId ${args.subscriptionId} -TenantId ${tenantId};`; + command += `Set-AzContext -SubscriptionId ${args.subscriptionId} -TenantId ${tenantId} | out-null;`; } } - command += `Get-AzContext`; this.script += `try { - $$ErrorActionPreference = "Stop"; - $$output = @{}; + $ErrorActionPreference = "Stop" + $WarningPreference = "SilentlyContinue" + $output = @{} ${command} - $$output['${Constants_1.default.Success}'] = "true"; + $output['${Constants_1.default.Success}'] = "true" } catch { - $$output['${Constants_1.default.Error}'] = $$_.exception.Message; + $output['${Constants_1.default.Error}'] = $_.exception.Message } - return ConvertTo-Json $$a`; + return ConvertTo-Json $output`; core.debug(`Azure PowerShell Login Script: ${this.script}`); return this.script; } getLatestModuleScript(moduleName) { const command = `Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1`; this.script += `try { - $$ErrorActionPreference = "Stop"; - $$output = @{}; - $$data = ${command}; - $$output['${Constants_1.default.AzVersion}'] = $$data.Version.ToString(); - $$output['${Constants_1.default.Success}'] = "true"; + $ErrorActionPreference = "Stop" + $WarningPreference = "SilentlyContinue" + $output = @{} + $data = ${command} + $output['${Constants_1.default.AzVersion}'] = $data.Version.ToString() + $output['${Constants_1.default.Success}'] = "true" } catch { - $$output['${Constants_1.default.Error}'] = $$_.exception.Message; + $output['${Constants_1.default.Error}'] = $_.exception.Message } - return ConvertTo-Json $$a`; + return ConvertTo-Json $output`; core.debug(`GetLatestModuleScript: ${this.script}`); return this.script; } diff --git a/lib/PowerShell/Utilities/Utils.js b/lib/PowerShell/Utilities/Utils.js index e0d6f284..6314f6b2 100644 --- a/lib/PowerShell/Utilities/Utils.js +++ b/lib/PowerShell/Utilities/Utils.js @@ -26,8 +26,7 @@ class Utils { break; case "macos": case "darwin": - // TODO: add modulepath - break; + throw new Error(`OS not supported`); default: throw new Error(`Unknown os: ${runner.toLowerCase()}`); } diff --git a/lib/loginAzurePowerShell.js b/lib/loginAzurePowerShell.js deleted file mode 100644 index abe1ea05..00000000 --- a/lib/loginAzurePowerShell.js +++ /dev/null @@ -1,96 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - 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; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const os = __importStar(require("os")); -const core = __importStar(require("@actions/core")); -const exec = __importStar(require("@actions/exec")); -const io = __importStar(require("@actions/io")); -var psPath; -exports.initializeAz = (servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) => __awaiter(void 0, void 0, void 0, function* () { - psPath = yield io.which("pwsh", true); - yield importModule(); - yield loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId); -}); -function importModule() { - return __awaiter(this, void 0, void 0, function* () { - setPSModulePath(); - const prefix = "az_"; - const moduleName = "Az.Accounts"; - const azLatestVersion = yield getLatestModule(moduleName); - core.debug(`Az Module version used: ${azLatestVersion}`); - setPSModulePath(`${prefix}${azLatestVersion}`); - }); -} -function setPSModulePath(azPSVersion = "") { - let modulePath = ""; - const RUNNER = process.env.RUNNER_OS || os.type(); - switch (RUNNER) { - case "Linux": - modulePath = `/usr/share/${azPSVersion}:`; - break; - case "Windows": - case "Windows_NT": - modulePath = `C:\\Modules\\${azPSVersion};`; - break; - case "macOS": - case "Darwin": - // TODO: add modulepath - break; - } - process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; -} -function getLatestModule(moduleName) { - return __awaiter(this, void 0, void 0, function* () { - let output = ""; - let error = ""; - let options = { - listeners: { - stdout: (data) => { - output += data.toString(); - }, - stderr: (data) => { - error += data.toString(); - } - } - }; - yield executePowerShellCommand(`(Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()`, options); - return output.trim(); - }); -} -function loginToAzure(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) { - return __awaiter(this, void 0, void 0, function* () { - const environment = "AzureCloud"; - yield executePowerShellCommand(`Clear-AzContext -Scope Process`); - yield executePowerShellCommand(`Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue`); - yield executePowerShellCommand(`Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ - (New-Object System.Management.Automation.PSCredential('${servicePrincipalId}',(ConvertTo-SecureString ${servicePrincipalKey} -AsPlainText -Force))) \ - -Environment ${environment}`); - yield executePowerShellCommand(`Set-AzContext -SubscriptionId ${subscriptionId} -TenantId ${tenantId}`); - yield executePowerShellCommand(`Get-AzContext`); - }); -} -function executePowerShellCommand(command, options = {}) { - return __awaiter(this, void 0, void 0, function* () { - try { - yield exec.exec(`"${psPath}" -Command "${command}"`, [], options); - } - catch (error) { - throw new Error(error); - } - }); -} diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts index f4ac6d0c..181125a0 100644 --- a/src/PowerShell/ServicePrincipalLogin.ts +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -25,7 +25,7 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession { Utils.setPSModulePath(); const script: string = new ScriptBuilder().getLatestModuleScript(Constants.moduleName); const outputJson = await this.getLatestModule(script); - const azLatestVersion: string = outputJson.Constants.AzPSVersion; + const azLatestVersion: string = outputJson[Constants.AzVersion]; if (!(Constants.Success in outputJson) || !Utils.isValidVersion(azLatestVersion)) { throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); } @@ -43,7 +43,7 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession { } }; await PowerShellToolRunner.init(); - await PowerShellToolRunner.executePowerShellCommand(script, options); + await PowerShellToolRunner.executePowerShellScriptBlock(script, options); return JSON.parse(output.trim()); } @@ -65,10 +65,10 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession { } const script: string = new ScriptBuilder().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args); await PowerShellToolRunner.init(); - await PowerShellToolRunner.executePowerShellCommand(script, options); + await PowerShellToolRunner.executePowerShellScriptBlock(script, options); const outputJson: any = JSON.parse(output.trim()); if (!(Constants.Success in outputJson)) { - throw new Error(`Azure PowerShell login failed with error: ${outputJson.Constants.Error}`); + throw new Error(`Azure PowerShell login failed with error: ${outputJson[Constants.Error]}`); } } diff --git a/src/PowerShell/Utilities/PowerShellToolRunner.ts b/src/PowerShell/Utilities/PowerShellToolRunner.ts index 86014d79..648eddbf 100644 --- a/src/PowerShell/Utilities/PowerShellToolRunner.ts +++ b/src/PowerShell/Utilities/PowerShellToolRunner.ts @@ -10,6 +10,10 @@ export default class PowerShellToolRunner { } } + static async executePowerShellScriptBlock(scriptBlock: string, options: any = {}) { + await exec.exec(`${PowerShellToolRunner.psPath} -Command`, [scriptBlock], options) + } + static async executePowerShellCommand(command: string, options: any = {}) { await exec.exec(`"${PowerShellToolRunner.psPath}" -Command "${command}"`, [], options); } diff --git a/src/PowerShell/Utilities/ScriptBuilder.ts b/src/PowerShell/Utilities/ScriptBuilder.ts index 43b33b85..a6871a46 100644 --- a/src/PowerShell/Utilities/ScriptBuilder.ts +++ b/src/PowerShell/Utilities/ScriptBuilder.ts @@ -11,22 +11,22 @@ export default class ScriptBuilder { if (scheme === Constants.ServicePrincipal) { command += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \ (New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString ${args.servicePrincipalKey} -AsPlainText -Force))) \ - -Environment ${args.environment};`; + -Environment ${args.environment} | out-null;`; if (args.scopeLevel === Constants.Subscription) { - command += `Set-AzContext -SubscriptionId ${args.subscriptionId} -TenantId ${tenantId};`; + command += `Set-AzContext -SubscriptionId ${args.subscriptionId} -TenantId ${tenantId} | out-null;`; } } - command += `Get-AzContext`; this.script += `try { - $$ErrorActionPreference = "Stop"; - $$output = @{}; + $ErrorActionPreference = "Stop" + $WarningPreference = "SilentlyContinue" + $output = @{} ${command} - $$output['${Constants.Success}'] = "true"; + $output['${Constants.Success}'] = "true" } catch { - $$output['${Constants.Error}'] = $$_.exception.Message; + $output['${Constants.Error}'] = $_.exception.Message } - return ConvertTo-Json $$a`; + return ConvertTo-Json $output`; core.debug(`Azure PowerShell Login Script: ${this.script}`); return this.script; } @@ -34,16 +34,17 @@ export default class ScriptBuilder { getLatestModuleScript(moduleName: string): string { const command: string = `Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1`; this.script += `try { - $$ErrorActionPreference = "Stop"; - $$output = @{}; - $$data = ${command}; - $$output['${Constants.AzVersion}'] = $$data.Version.ToString(); - $$output['${Constants.Success}'] = "true"; + $ErrorActionPreference = "Stop" + $WarningPreference = "SilentlyContinue" + $output = @{} + $data = ${command} + $output['${Constants.AzVersion}'] = $data.Version.ToString() + $output['${Constants.Success}'] = "true" } catch { - $$output['${Constants.Error}'] = $$_.exception.Message; + $output['${Constants.Error}'] = $_.exception.Message } - return ConvertTo-Json $$a`; + return ConvertTo-Json $output`; core.debug(`GetLatestModuleScript: ${this.script}`); return this.script; } diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts index 1428c6ef..ac1ff55f 100644 --- a/src/PowerShell/Utilities/Utils.ts +++ b/src/PowerShell/Utilities/Utils.ts @@ -1,7 +1,6 @@ import * as os from 'os'; import Constants from '../Constants'; -import PowerShellToolRunner from './PowerShellToolRunner'; export default class Utils { static setPSModulePath(azPSVersion: string = "") { @@ -17,8 +16,7 @@ export default class Utils { break; case "macos": case "darwin": - // TODO: add modulepath - break; + throw new Error(`OS not supported`); default: throw new Error(`Unknown os: ${runner.toLowerCase()}`); } From 2e68c54666f22eba3eae50d3c2411477f59dc2e2 Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Fri, 20 Mar 2020 16:10:51 +0530 Subject: [PATCH 20/27] Modified description in action.yml --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 1e6373c6..17583e36 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,6 @@ # Login to Azure subscription name: 'Azure Login' -description: 'Azure Login wraps the az login, allowing Azure actions to log into Azure or to run Az CLI scripts. github.com/Azure/Actions' +description: 'Authenticate to Azure and run your Az CLI or Az PowerShell based Actions or scripts. github.com/Azure/Actions' inputs: creds: description: 'Paste output of `az ad sp create-for-rbac` as value of secret variable: AZURE_CREDENTIALS' From 0935db33063f10f64bd10ce67b4512baaba6b0ff Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Fri, 20 Mar 2020 16:32:12 +0530 Subject: [PATCH 21/27] Added telemetry info --- lib/main.js | 5 ++++- src/main.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/main.js b/lib/main.js index ca968e8b..fd711174 100644 --- a/lib/main.js +++ b/lib/main.js @@ -24,14 +24,17 @@ const actions_secret_parser_1 = require("actions-secret-parser"); const ServicePrincipalLogin_1 = require("./PowerShell/ServicePrincipalLogin"); var azPath; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; +var azPSHostEnv = !!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT}` : ""; function main() { return __awaiter(this, void 0, void 0, function* () { try { // Set user agent variable let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); let actionName = 'AzureLogin'; - let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS_${actionName}_${usrAgentRepo}`; + let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`; + let azurePSHostEnv = (!!azPSHostEnv ? `${azPSHostEnv}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`; core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString); + core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv); azPath = yield io.which("az", true); yield executeAzCliCommand("--version"); let creds = core.getInput('creds', { required: true }); diff --git a/src/main.ts b/src/main.ts index a9e7f461..dc67d1e0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,14 +8,17 @@ import { ServicePrincipalLogin } from './PowerShell/ServicePrincipalLogin'; var azPath: string; var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; +var azPSHostEnv = !!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT}` : ""; async function main() { try { // Set user agent variable let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); let actionName = 'AzureLogin'; - let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS_${actionName}_${usrAgentRepo}`; + let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`; + let azurePSHostEnv = (!!azPSHostEnv ? `${azPSHostEnv}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`; core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString); + core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv); azPath = await io.which("az", true); await executeAzCliCommand("--version"); From db864cee1a658244033494c4635af8154e50347a Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Sun, 22 Mar 2020 23:54:24 +0530 Subject: [PATCH 22/27] Code refactor --- lib/PowerShell/ServicePrincipalLogin.js | 22 +----------- lib/PowerShell/Utilities/Utils.js | 35 +++++++++++++++++++ src/PowerShell/ServicePrincipalLogin.ts | 21 +---------- .../Utilities/PowerShellToolRunner.ts | 1 + src/PowerShell/Utilities/Utils.ts | 25 +++++++++++++ 5 files changed, 63 insertions(+), 41 deletions(-) diff --git a/lib/PowerShell/ServicePrincipalLogin.js b/lib/PowerShell/ServicePrincipalLogin.js index babeb9da..59f5cc58 100644 --- a/lib/PowerShell/ServicePrincipalLogin.js +++ b/lib/PowerShell/ServicePrincipalLogin.js @@ -34,31 +34,11 @@ class ServicePrincipalLogin { initialize() { return __awaiter(this, void 0, void 0, function* () { Utils_1.default.setPSModulePath(); - const script = new ScriptBuilder_1.default().getLatestModuleScript(Constants_1.default.moduleName); - const outputJson = yield this.getLatestModule(script); - const azLatestVersion = outputJson[Constants_1.default.AzVersion]; - if (!(Constants_1.default.Success in outputJson) || !Utils_1.default.isValidVersion(azLatestVersion)) { - throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); - } + const azLatestVersion = yield Utils_1.default.getLatestModule(Constants_1.default.moduleName); core.debug(`Az Module version used: ${azLatestVersion}`); Utils_1.default.setPSModulePath(`${Constants_1.default.prefix}${azLatestVersion}`); }); } - getLatestModule(script) { - return __awaiter(this, void 0, void 0, function* () { - let output = ""; - const options = { - listeners: { - stdout: (data) => { - output += data.toString(); - } - } - }; - yield PowerShellToolRunner_1.default.init(); - yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(script, options); - return JSON.parse(output.trim()); - }); - } login() { return __awaiter(this, void 0, void 0, function* () { let output = ""; diff --git a/lib/PowerShell/Utilities/Utils.js b/lib/PowerShell/Utilities/Utils.js index 6314f6b2..0bddddb3 100644 --- a/lib/PowerShell/Utilities/Utils.js +++ b/lib/PowerShell/Utilities/Utils.js @@ -1,4 +1,13 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; @@ -12,6 +21,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) { Object.defineProperty(exports, "__esModule", { value: true }); const os = __importStar(require("os")); const Constants_1 = __importDefault(require("../Constants")); +const ScriptBuilder_1 = __importDefault(require("./ScriptBuilder")); +const PowerShellToolRunner_1 = __importDefault(require("./PowerShellToolRunner")); class Utils { static setPSModulePath(azPSVersion = "") { let modulePath = ""; @@ -32,6 +43,30 @@ class Utils { } process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } + static getLatestModule(moduleName) { + return __awaiter(this, void 0, void 0, function* () { + let output = ""; + const options = { + listeners: { + stdout: (data) => { + output += data.toString(); + } + } + }; + yield PowerShellToolRunner_1.default.init(); + yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(new ScriptBuilder_1.default() + .getLatestModuleScript(moduleName), options); + const outputJson = JSON.parse(output.trim()); + if (!(Constants_1.default.Success in outputJson)) { + throw new Error(outputJson[Constants_1.default.Error]); + } + const azLatestVersion = outputJson[Constants_1.default.AzVersion]; + if (!Utils.isValidVersion(azLatestVersion)) { + throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); + } + return azLatestVersion; + }); + } static isValidVersion(version) { return !!version.match(Constants_1.default.versionPattern); } diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts index 181125a0..1bb27daa 100644 --- a/src/PowerShell/ServicePrincipalLogin.ts +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -23,30 +23,11 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession { async initialize() { Utils.setPSModulePath(); - const script: string = new ScriptBuilder().getLatestModuleScript(Constants.moduleName); - const outputJson = await this.getLatestModule(script); - const azLatestVersion: string = outputJson[Constants.AzVersion]; - if (!(Constants.Success in outputJson) || !Utils.isValidVersion(azLatestVersion)) { - throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); - } + const azLatestVersion: string = await Utils.getLatestModule(Constants.moduleName); core.debug(`Az Module version used: ${azLatestVersion}`); Utils.setPSModulePath(`${Constants.prefix}${azLatestVersion}`); } - private async getLatestModule(script: string): Promise { - let output: string = ""; - const options: any = { - listeners: { - stdout: (data: Buffer) => { - output += data.toString(); - } - } - }; - await PowerShellToolRunner.init(); - await PowerShellToolRunner.executePowerShellScriptBlock(script, options); - return JSON.parse(output.trim()); - } - async login() { let output: string = ""; const options: any = { diff --git a/src/PowerShell/Utilities/PowerShellToolRunner.ts b/src/PowerShell/Utilities/PowerShellToolRunner.ts index 648eddbf..2f363f74 100644 --- a/src/PowerShell/Utilities/PowerShellToolRunner.ts +++ b/src/PowerShell/Utilities/PowerShellToolRunner.ts @@ -17,4 +17,5 @@ export default class PowerShellToolRunner { static async executePowerShellCommand(command: string, options: any = {}) { await exec.exec(`"${PowerShellToolRunner.psPath}" -Command "${command}"`, [], options); } + } \ No newline at end of file diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts index ac1ff55f..c8b4a00c 100644 --- a/src/PowerShell/Utilities/Utils.ts +++ b/src/PowerShell/Utilities/Utils.ts @@ -1,6 +1,8 @@ import * as os from 'os'; import Constants from '../Constants'; +import ScriptBuilder from './ScriptBuilder'; +import PowerShellToolRunner from './PowerShellToolRunner'; export default class Utils { static setPSModulePath(azPSVersion: string = "") { @@ -23,6 +25,29 @@ export default class Utils { process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`; } + static async getLatestModule(moduleName: string): Promise { + let output: string = ""; + const options: any = { + listeners: { + stdout: (data: Buffer) => { + output += data.toString(); + } + } + }; + await PowerShellToolRunner.init(); + await PowerShellToolRunner.executePowerShellScriptBlock(new ScriptBuilder() + .getLatestModuleScript(moduleName), options); + const outputJson = JSON.parse(output.trim()); + if (!(Constants.Success in outputJson)) { + throw new Error(outputJson[Constants.Error]); + } + const azLatestVersion: string = outputJson[Constants.AzVersion]; + if (!Utils.isValidVersion(azLatestVersion)) { + throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); + } + return azLatestVersion; + } + static isValidVersion(version: string): boolean { return !!version.match(Constants.versionPattern); } From 97c66dece89e7157f1ea9c7e6bffb39a0d81b21e Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Tue, 24 Mar 2020 14:17:39 +0530 Subject: [PATCH 23/27] added review comments --- src/PowerShell/ServicePrincipalLogin.ts | 6 +++--- src/PowerShell/Utilities/Utils.ts | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts index 1bb27daa..3ee2c891 100644 --- a/src/PowerShell/ServicePrincipalLogin.ts +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -47,9 +47,9 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession { const script: string = new ScriptBuilder().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args); await PowerShellToolRunner.init(); await PowerShellToolRunner.executePowerShellScriptBlock(script, options); - const outputJson: any = JSON.parse(output.trim()); - if (!(Constants.Success in outputJson)) { - throw new Error(`Azure PowerShell login failed with error: ${outputJson[Constants.Error]}`); + const result: any = JSON.parse(output.trim()); + if (!(Constants.Success in result)) { + throw new Error(`Azure PowerShell login failed with error: ${result[Constants.Error]}`); } } diff --git a/src/PowerShell/Utilities/Utils.ts b/src/PowerShell/Utilities/Utils.ts index c8b4a00c..1fa3635e 100644 --- a/src/PowerShell/Utilities/Utils.ts +++ b/src/PowerShell/Utilities/Utils.ts @@ -5,6 +5,15 @@ import ScriptBuilder from './ScriptBuilder'; import PowerShellToolRunner from './PowerShellToolRunner'; export default class Utils { + /** + * Add the folder path where Az modules are present to PSModulePath based on runner + * + * @param azPSVersion + * + * If azPSVersion is empty, folder path in which all Az modules are present are set + * If azPSVersion is not empty, folder path of exact Az module version is set + * + */ static setPSModulePath(azPSVersion: string = "") { let modulePath: string = ""; const runner: string = process.env.RUNNER_OS || os.type(); @@ -37,11 +46,11 @@ export default class Utils { await PowerShellToolRunner.init(); await PowerShellToolRunner.executePowerShellScriptBlock(new ScriptBuilder() .getLatestModuleScript(moduleName), options); - const outputJson = JSON.parse(output.trim()); - if (!(Constants.Success in outputJson)) { - throw new Error(outputJson[Constants.Error]); + const result = JSON.parse(output.trim()); + if (!(Constants.Success in result)) { + throw new Error(result[Constants.Error]); } - const azLatestVersion: string = outputJson[Constants.AzVersion]; + const azLatestVersion: string = result[Constants.AzVersion]; if (!Utils.isValidVersion(azLatestVersion)) { throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); } From 6df92eb73095f462c802d61e1995b7ba2d9769f6 Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Tue, 24 Mar 2020 15:40:30 +0530 Subject: [PATCH 24/27] added review comments --- lib/PowerShell/ServicePrincipalLogin.js | 6 +++--- lib/PowerShell/Utilities/Utils.js | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/PowerShell/ServicePrincipalLogin.js b/lib/PowerShell/ServicePrincipalLogin.js index 59f5cc58..7d9e8288 100644 --- a/lib/PowerShell/ServicePrincipalLogin.js +++ b/lib/PowerShell/ServicePrincipalLogin.js @@ -59,9 +59,9 @@ class ServicePrincipalLogin { const script = new ScriptBuilder_1.default().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args); yield PowerShellToolRunner_1.default.init(); yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(script, options); - const outputJson = JSON.parse(output.trim()); - if (!(Constants_1.default.Success in outputJson)) { - throw new Error(`Azure PowerShell login failed with error: ${outputJson[Constants_1.default.Error]}`); + const result = JSON.parse(output.trim()); + if (!(Constants_1.default.Success in result)) { + throw new Error(`Azure PowerShell login failed with error: ${result[Constants_1.default.Error]}`); } }); } diff --git a/lib/PowerShell/Utilities/Utils.js b/lib/PowerShell/Utilities/Utils.js index 0bddddb3..8b06d468 100644 --- a/lib/PowerShell/Utilities/Utils.js +++ b/lib/PowerShell/Utilities/Utils.js @@ -24,6 +24,15 @@ const Constants_1 = __importDefault(require("../Constants")); const ScriptBuilder_1 = __importDefault(require("./ScriptBuilder")); const PowerShellToolRunner_1 = __importDefault(require("./PowerShellToolRunner")); class Utils { + /** + * Add the folder path where Az modules are present to PSModulePath based on runner + * + * @param azPSVersion + * + * If azPSVersion is empty, folder path in which all Az modules are present are set + * If azPSVersion is not empty, folder path of exact Az module version is set + * + */ static setPSModulePath(azPSVersion = "") { let modulePath = ""; const runner = process.env.RUNNER_OS || os.type(); @@ -56,11 +65,11 @@ class Utils { yield PowerShellToolRunner_1.default.init(); yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(new ScriptBuilder_1.default() .getLatestModuleScript(moduleName), options); - const outputJson = JSON.parse(output.trim()); - if (!(Constants_1.default.Success in outputJson)) { - throw new Error(outputJson[Constants_1.default.Error]); + const result = JSON.parse(output.trim()); + if (!(Constants_1.default.Success in result)) { + throw new Error(result[Constants_1.default.Error]); } - const azLatestVersion = outputJson[Constants_1.default.AzVersion]; + const azLatestVersion = result[Constants_1.default.AzVersion]; if (!Utils.isValidVersion(azLatestVersion)) { throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`); } From 7c947326c29aff5af57577fab386f1c5e0dca676 Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Tue, 24 Mar 2020 16:38:57 +0530 Subject: [PATCH 25/27] removed tslint from package.json --- package-lock.json | 257 ---------------------------------------------- package.json | 3 +- 2 files changed, 1 insertion(+), 259 deletions(-) diff --git a/package-lock.json b/package-lock.json index e8b32c12..c3e3c9b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,24 +19,6 @@ "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.1.tgz", "integrity": "sha512-rhq+tfZukbtaus7xyUtwKfuiCRXd1hWSfmJNEpFgBQJ4woqPEpsBw04awicjwz9tyG2/MVhAEMfVn664Cri5zA==" }, - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, "@types/node": { "version": "12.7.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.11.tgz", @@ -54,89 +36,11 @@ "xpath": "0.0.27" } }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, "escodegen": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", @@ -176,64 +80,6 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - } - } - }, "jsonpath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.2.tgz", @@ -253,35 +99,6 @@ "type-check": "~0.3.2" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", - "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", - "requires": { - "minimist": "^1.2.5" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -295,45 +112,17 @@ "word-wrap": "~1.2.3" } }, - "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=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, - "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "optional": true }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, "static-eval": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", @@ -342,47 +131,6 @@ "escodegen": "^1.8.1" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" - }, - "tslint": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.0.tgz", - "integrity": "sha512-fXjYd/61vU6da04E505OZQGb2VCN2Mq3doeWcOIryuG+eqdmFUXTYVwdhnbEu2k46LNLgUYt9bI5icQze/j0bQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.10.0", - "tsutils": "^2.29.0" - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "requires": { - "tslib": "^1.8.1" - } - }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -407,11 +155,6 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, "xmldom": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", diff --git a/package.json b/package.json index 26e25c46..b0b60823 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "@actions/core": "^1.1.3", "@actions/exec": "^1.0.1", "@actions/io": "^1.0.1", - "actions-secret-parser": "^1.0.2", - "tslint": "^6.1.0" + "actions-secret-parser": "^1.0.2" } } From 28f29173ac1a8089cfd9d96ce9b82841a386b4d4 Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Fri, 27 Mar 2020 09:56:23 +0530 Subject: [PATCH 26/27] added log in ServicePrincipalLogin --- lib/PowerShell/ServicePrincipalLogin.js | 1 + src/PowerShell/ServicePrincipalLogin.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/PowerShell/ServicePrincipalLogin.js b/lib/PowerShell/ServicePrincipalLogin.js index 7d9e8288..7a4be40b 100644 --- a/lib/PowerShell/ServicePrincipalLogin.js +++ b/lib/PowerShell/ServicePrincipalLogin.js @@ -63,6 +63,7 @@ class ServicePrincipalLogin { if (!(Constants_1.default.Success in result)) { throw new Error(`Azure PowerShell login failed with error: ${result[Constants_1.default.Error]}`); } + console.log(`Azure PowerShell session successfully initialized`); }); } } diff --git a/src/PowerShell/ServicePrincipalLogin.ts b/src/PowerShell/ServicePrincipalLogin.ts index 3ee2c891..8aa293a4 100644 --- a/src/PowerShell/ServicePrincipalLogin.ts +++ b/src/PowerShell/ServicePrincipalLogin.ts @@ -51,6 +51,7 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession { if (!(Constants.Success in result)) { throw new Error(`Azure PowerShell login failed with error: ${result[Constants.Error]}`); } + console.log(`Azure PowerShell session successfully initialized`); } } \ No newline at end of file From 946067d034b5b21d393ba46a8b946e44aae6e49f Mon Sep 17 00:00:00 2001 From: Akshaya M Date: Fri, 27 Mar 2020 18:01:05 +0530 Subject: [PATCH 27/27] added boolean for error log --- lib/main.js | 10 +++++++++- src/main.ts | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/main.js b/lib/main.js index fd711174..54840a18 100644 --- a/lib/main.js +++ b/lib/main.js @@ -29,6 +29,7 @@ function main() { return __awaiter(this, void 0, void 0, function* () { try { // Set user agent variable + var isAzCLISuccess = false; let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); let actionName = 'AzureLogin'; let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`; @@ -50,6 +51,7 @@ function main() { // Attempting Az cli login yield executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`); yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`); + isAzCLISuccess = true; if (enablePSSession) { // Attempting Az PS login console.log(`Running Azure PS Login`); @@ -60,12 +62,18 @@ function main() { console.log("Login successful."); } catch (error) { - core.error("Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"); + if (!isAzCLISuccess) { + core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"); + } + else { + 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); } finally { // Reset AZURE_HTTP_USER_AGENT core.exportVariable('AZURE_HTTP_USER_AGENT', prefix); + core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv); } }); } diff --git a/src/main.ts b/src/main.ts index dc67d1e0..5c170683 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,6 +13,7 @@ var azPSHostEnv = !!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREP async function main() { try { // Set user agent variable + var isAzCLISuccess = false; let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); let actionName = 'AzureLogin'; let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`; @@ -36,6 +37,7 @@ async function main() { // Attempting Az cli login await executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`); await executeAzCliCommand(`account set --subscription "${subscriptionId}"`); + isAzCLISuccess = true; if (enablePSSession) { // Attempting Az PS login console.log(`Running Azure PS Login`); @@ -45,11 +47,16 @@ async function main() { } console.log("Login successful."); } catch (error) { - core.error("Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"); + if (!isAzCLISuccess) { + core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"); + } else { + 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); } finally { // Reset AZURE_HTTP_USER_AGENT core.exportVariable('AZURE_HTTP_USER_AGENT', prefix); + core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv); } }