mirror of
https://github.com/azure/login.git
synced 2026-03-15 09:20:56 -04:00
Compare commits
2 Commits
ps-login
...
users/aksm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f001fbb0b9 | ||
|
|
b4fcf5d07d |
@@ -57,7 +57,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Login via Az module
|
- name: Login via Az module
|
||||||
uses: azure/login@v1
|
uses: azure/login@v1.1
|
||||||
with:
|
with:
|
||||||
creds: ${{secrets.AZURE_CREDENTIALS}}
|
creds: ${{secrets.AZURE_CREDENTIALS}}
|
||||||
enable-AzPSSession: true
|
enable-AzPSSession: true
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ jest.mock('../../src/PowerShell/Utilities/PowerShellToolRunner');
|
|||||||
let spnlogin: ServicePrincipalLogin;
|
let spnlogin: ServicePrincipalLogin;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
spnlogin = new ServicePrincipalLogin("servicePrincipalID", "servicePrinicipalkey", "tenantId", "subscriptionId", false, null, null);
|
spnlogin = new ServicePrincipalLogin("servicePrincipalID", "servicePrinicipalkey", "tenantId", "subscriptionId", false);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|||||||
@@ -9,10 +9,6 @@ inputs:
|
|||||||
description: 'Set this value to true to enable Azure PowerShell Login in addition to Az CLI login'
|
description: 'Set this value to true to enable Azure PowerShell Login in addition to Az CLI login'
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
environment:
|
|
||||||
description: 'Name of the environment. Supported values are azurecloud, azurestack, azureusgovernment, azurechinacloud, azuregermancloud. Default being azurecloud'
|
|
||||||
required: false
|
|
||||||
default: azurecloud
|
|
||||||
allow-no-subscriptions:
|
allow-no-subscriptions:
|
||||||
description: 'Set this value to true to enable support for accessing tenants without subscriptions'
|
description: 'Set this value to true to enable support for accessing tenants without subscriptions'
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
@@ -1,23 +1,4 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
@@ -27,24 +8,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||||
|
result["default"] = mod;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.ServicePrincipalLogin = void 0;
|
|
||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const Utils_1 = __importDefault(require("./Utilities/Utils"));
|
const Utils_1 = __importDefault(require("./Utilities/Utils"));
|
||||||
const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner"));
|
const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner"));
|
||||||
const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder"));
|
const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder"));
|
||||||
const Constants_1 = __importDefault(require("./Constants"));
|
const Constants_1 = __importDefault(require("./Constants"));
|
||||||
class ServicePrincipalLogin {
|
class ServicePrincipalLogin {
|
||||||
constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin, environment, resourceManagerEndpointUrl) {
|
constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin) {
|
||||||
this.servicePrincipalId = servicePrincipalId;
|
this.servicePrincipalId = servicePrincipalId;
|
||||||
this.servicePrincipalKey = servicePrincipalKey;
|
this.servicePrincipalKey = servicePrincipalKey;
|
||||||
this.tenantId = tenantId;
|
this.tenantId = tenantId;
|
||||||
this.subscriptionId = subscriptionId;
|
this.subscriptionId = subscriptionId;
|
||||||
this.environment = environment;
|
|
||||||
this.resourceManagerEndpointUrl = resourceManagerEndpointUrl;
|
|
||||||
this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin;
|
this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin;
|
||||||
}
|
}
|
||||||
initialize() {
|
initialize() {
|
||||||
@@ -69,22 +54,22 @@ class ServicePrincipalLogin {
|
|||||||
servicePrincipalId: this.servicePrincipalId,
|
servicePrincipalId: this.servicePrincipalId,
|
||||||
servicePrincipalKey: this.servicePrincipalKey,
|
servicePrincipalKey: this.servicePrincipalKey,
|
||||||
subscriptionId: this.subscriptionId,
|
subscriptionId: this.subscriptionId,
|
||||||
environment: this.environment,
|
environment: ServicePrincipalLogin.environment,
|
||||||
scopeLevel: ServicePrincipalLogin.scopeLevel,
|
scopeLevel: ServicePrincipalLogin.scopeLevel,
|
||||||
allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin,
|
allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin
|
||||||
resourceManagerEndpointUrl: this.resourceManagerEndpointUrl
|
|
||||||
};
|
};
|
||||||
const script = new ScriptBuilder_1.default().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args);
|
const script = new ScriptBuilder_1.default().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args);
|
||||||
yield PowerShellToolRunner_1.default.init();
|
yield PowerShellToolRunner_1.default.init();
|
||||||
// await PowerShellToolRunner.executePowerShellScriptBlock(script, options);
|
yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(script, options);
|
||||||
// const result: any = JSON.parse(output.trim());
|
const result = JSON.parse(output.trim());
|
||||||
// if (!(Constants.Success in result)) {
|
if (!(Constants_1.default.Success in result)) {
|
||||||
// throw new Error(`Azure PowerShell login failed with error: ${result[Constants.Error]}`);
|
throw new Error(`Azure PowerShell login failed with error: ${result[Constants_1.default.Error]}`);
|
||||||
// }
|
}
|
||||||
console.log(`Azure PowerShell session successfully initialized`);
|
console.log(`Azure PowerShell session successfully initialized`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.ServicePrincipalLogin = ServicePrincipalLogin;
|
exports.ServicePrincipalLogin = ServicePrincipalLogin;
|
||||||
|
ServicePrincipalLogin.environment = Constants_1.default.AzureCloud;
|
||||||
ServicePrincipalLogin.scopeLevel = Constants_1.default.Subscription;
|
ServicePrincipalLogin.scopeLevel = Constants_1.default.Subscription;
|
||||||
ServicePrincipalLogin.scheme = Constants_1.default.ServicePrincipal;
|
ServicePrincipalLogin.scheme = Constants_1.default.ServicePrincipal;
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ class ScriptBuilder {
|
|||||||
let command = `Clear-AzContext -Scope Process;
|
let command = `Clear-AzContext -Scope Process;
|
||||||
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`;
|
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`;
|
||||||
if (scheme === Constants_1.default.ServicePrincipal) {
|
if (scheme === Constants_1.default.ServicePrincipal) {
|
||||||
if (args.environment.toLowerCase() == "azurestack") {
|
|
||||||
command += `Add-AzEnvironment -Name ${args.environment} -ARMEndpoint ${args.resourceManagerEndpointUrl} | out-null;`;
|
|
||||||
}
|
|
||||||
command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \
|
command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \
|
||||||
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \
|
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \
|
||||||
-Environment '${args.environment}' | out-null;`;
|
-Environment '${args.environment}' | out-null;`;
|
||||||
|
|||||||
83
lib/main.js
83
lib/main.js
@@ -36,104 +36,46 @@ function main() {
|
|||||||
core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString);
|
core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString);
|
||||||
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
|
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
|
||||||
azPath = yield io.which("az", true);
|
azPath = yield io.which("az", true);
|
||||||
let azureSupportedCloudName = new Set([
|
|
||||||
"azureusgovernment",
|
|
||||||
"azurechinacloud",
|
|
||||||
"azuregermancloud",
|
|
||||||
"azurecloud",
|
|
||||||
"azurestack"
|
|
||||||
]);
|
|
||||||
let output = "";
|
let output = "";
|
||||||
const execOptions = {
|
const options = {
|
||||||
listeners: {
|
listeners: {
|
||||||
stdout: (data) => {
|
stdout: (data) => {
|
||||||
output += data.toString();
|
output += data.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
yield executeAzCliCommand("--version", true, execOptions);
|
yield executeAzCliCommand("--version", true, options);
|
||||||
core.debug(`az cli version used:\n${output}`);
|
core.debug(`az cli version used:\n${output}`);
|
||||||
|
|
||||||
let creds = core.getInput('creds', { required: true });
|
let creds = core.getInput('creds', { required: true });
|
||||||
let secrets = new actions_secret_parser_1.SecretParser(creds, actions_secret_parser_1.FormatType.JSON);
|
let secrets = new actions_secret_parser_1.SecretParser(creds, actions_secret_parser_1.FormatType.JSON);
|
||||||
let servicePrincipalId = secrets.getSecret("$.clientId", false);
|
let servicePrincipalId = secrets.getSecret("$.clientId", false);
|
||||||
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
|
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
|
||||||
let tenantId = secrets.getSecret("$.tenantId", false);
|
let tenantId = secrets.getSecret("$.tenantId", false);
|
||||||
let subscriptionId = secrets.getSecret("$.subscriptionId", false);
|
let subscriptionId = secrets.getSecret("$.subscriptionId", false);
|
||||||
let resourceManagerEndpointUrl = secrets.getSecret("$.resourceManagerEndpointUrl", false);
|
|
||||||
let environment = core.getInput("environment").toLowerCase();
|
|
||||||
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
|
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
|
||||||
const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true";
|
const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true";
|
||||||
|
|
||||||
if (!servicePrincipalId || !servicePrincipalKey || !tenantId) {
|
if (!servicePrincipalId || !servicePrincipalKey || !tenantId) {
|
||||||
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied.");
|
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied.");
|
||||||
}
|
}
|
||||||
if (!subscriptionId && !allowNoSubscriptionsLogin) {
|
if (!subscriptionId && !allowNoSubscriptionsLogin) {
|
||||||
throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied.");
|
throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied.");
|
||||||
}
|
}
|
||||||
if (!azureSupportedCloudName.has(environment)) {
|
|
||||||
throw new Error("Unsupported value for environment is passed.The list of supported values for environment are ‘azureusgovernment', ‘azurechinacloud’, ‘azuregermancloud’, ‘azurecloud’ or ’azurestack’");
|
|
||||||
}
|
|
||||||
// TODO: refactor this into an Azure stack specific utility.
|
|
||||||
// Attempting Az cli login
|
|
||||||
if (environment == "azurestack") {
|
|
||||||
if (!resourceManagerEndpointUrl) {
|
|
||||||
throw new Error("resourceManagerEndpointUrl is a required parameter when environment is defined.");
|
|
||||||
}
|
|
||||||
console.log(`Unregistering cloud: "${environment}" first if it exists`);
|
|
||||||
try {
|
|
||||||
yield executeAzCliCommand(`cloud set -n AzureCloud`, true);
|
|
||||||
yield executeAzCliCommand(`cloud unregister -n "${environment}"`, false);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(`Ignore cloud not registered error: "${error}"`);
|
|
||||||
}
|
|
||||||
console.log(`Registering cloud: "${environment}" with ARM endpoint: "${resourceManagerEndpointUrl}"`);
|
|
||||||
try {
|
|
||||||
let baseUri = resourceManagerEndpointUrl;
|
|
||||||
if (baseUri.endsWith('/')) {
|
|
||||||
baseUri = baseUri.substring(0, baseUri.length - 1); // need to remove trailing / from resourceManagerEndpointUrl to correctly derive suffixes below
|
|
||||||
}
|
|
||||||
let suffixKeyvault = ".vault" + baseUri.substring(baseUri.indexOf('.')); // keyvault suffix starts with .
|
|
||||||
let suffixStorage = baseUri.substring(baseUri.indexOf('.') + 1); // storage suffix starts without .
|
|
||||||
let profileVersion = "2019-03-01-hybrid";
|
|
||||||
yield executeAzCliCommand(`cloud register -n "${environment}" --endpoint-resource-manager "${resourceManagerEndpointUrl}" --suffix-keyvault-dns "${suffixKeyvault}" --suffix-storage-endpoint "${suffixStorage}" --profile "${profileVersion}"`, false);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
core.error(`Error while trying to register cloud "${environment}": "${error}"`);
|
|
||||||
}
|
|
||||||
console.log(`Done registering cloud: "${environment}"`);
|
|
||||||
}
|
|
||||||
yield executeAzCliCommand(`cloud set -n "${environment}"`, false);
|
|
||||||
console.log(`Done setting cloud: "${environment}"`);
|
|
||||||
// Attempting Az cli login
|
// Attempting Az cli login
|
||||||
|
console.log(`ak - clientId: ${servicePrincipalId}`);
|
||||||
if (allowNoSubscriptionsLogin) {
|
if (allowNoSubscriptionsLogin) {
|
||||||
let args = [
|
yield executeAzCliCommand(`login --allow-no-subscriptions --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
|
||||||
"--allow-no-subscriptions",
|
|
||||||
"--service-principal",
|
|
||||||
"-u", servicePrincipalId,
|
|
||||||
"-p", servicePrincipalKey,
|
|
||||||
"--tenant", tenantId
|
|
||||||
];
|
|
||||||
yield executeAzCliCommand(`login`, true, {}, args);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let args = [
|
yield executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
|
||||||
"--service-principal",
|
yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`, true);
|
||||||
"-u", servicePrincipalId,
|
|
||||||
"-p", servicePrincipalKey,
|
|
||||||
"--tenant", tenantId
|
|
||||||
];
|
|
||||||
yield executeAzCliCommand(`login`, true, {}, args);
|
|
||||||
args = [
|
|
||||||
"--subscription",
|
|
||||||
subscriptionId
|
|
||||||
];
|
|
||||||
yield executeAzCliCommand(`account set`, true, {}, args);
|
|
||||||
}
|
}
|
||||||
isAzCLISuccess = true;
|
isAzCLISuccess = true;
|
||||||
if (enableAzPSSession) {
|
if (enableAzPSSession) {
|
||||||
// Attempting Az PS login
|
// Attempting Az PS login
|
||||||
console.log(`Running Azure PS Login`);
|
console.log(`Running Azure PS Login`);
|
||||||
const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin, environment, resourceManagerEndpointUrl);
|
const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin);
|
||||||
yield spnlogin.initialize();
|
yield spnlogin.initialize();
|
||||||
yield spnlogin.login();
|
yield spnlogin.login();
|
||||||
}
|
}
|
||||||
@@ -155,11 +97,12 @@ function main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function executeAzCliCommand(command, silent, execOptions = {}, args = []) {
|
|
||||||
|
function executeAzCliCommand(command, silent, options = {}) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
execOptions.silent = !!silent;
|
options.silent = !!silent;
|
||||||
try {
|
try {
|
||||||
yield exec.exec(`"${azPath}" ${command}`, args, execOptions);
|
yield exec.exec(`"${azPath}" ${command}`, [], options);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
|
|||||||
@@ -6,30 +6,24 @@ import ScriptBuilder from './Utilities/ScriptBuilder';
|
|||||||
import Constants from './Constants';
|
import Constants from './Constants';
|
||||||
|
|
||||||
export class ServicePrincipalLogin implements IAzurePowerShellSession {
|
export class ServicePrincipalLogin implements IAzurePowerShellSession {
|
||||||
|
static readonly environment: string = Constants.AzureCloud;
|
||||||
static readonly scopeLevel: string = Constants.Subscription;
|
static readonly scopeLevel: string = Constants.Subscription;
|
||||||
static readonly scheme: string = Constants.ServicePrincipal;
|
static readonly scheme: string = Constants.ServicePrincipal;
|
||||||
environment: string;
|
|
||||||
servicePrincipalId: string;
|
servicePrincipalId: string;
|
||||||
servicePrincipalKey: string;
|
servicePrincipalKey: string;
|
||||||
tenantId: string;
|
tenantId: string;
|
||||||
subscriptionId: string;
|
subscriptionId: string;
|
||||||
resourceManagerEndpointUrl: string;
|
|
||||||
allowNoSubscriptionsLogin: boolean;
|
allowNoSubscriptionsLogin: boolean;
|
||||||
|
|
||||||
constructor(servicePrincipalId: string,
|
constructor(servicePrincipalId: string,
|
||||||
servicePrincipalKey: string,
|
servicePrincipalKey: string,
|
||||||
tenantId: string,
|
tenantId: string,
|
||||||
subscriptionId: string,
|
subscriptionId: string,
|
||||||
allowNoSubscriptionsLogin: boolean,
|
allowNoSubscriptionsLogin: boolean) {
|
||||||
environment: string,
|
|
||||||
resourceManagerEndpointUrl: string) {
|
|
||||||
|
|
||||||
this.servicePrincipalId = servicePrincipalId;
|
this.servicePrincipalId = servicePrincipalId;
|
||||||
this.servicePrincipalKey = servicePrincipalKey;
|
this.servicePrincipalKey = servicePrincipalKey;
|
||||||
this.tenantId = tenantId;
|
this.tenantId = tenantId;
|
||||||
this.subscriptionId = subscriptionId;
|
this.subscriptionId = subscriptionId;
|
||||||
this.environment = environment;
|
|
||||||
this.resourceManagerEndpointUrl = resourceManagerEndpointUrl;
|
|
||||||
this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin;
|
this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,18 +47,17 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession {
|
|||||||
servicePrincipalId: this.servicePrincipalId,
|
servicePrincipalId: this.servicePrincipalId,
|
||||||
servicePrincipalKey: this.servicePrincipalKey,
|
servicePrincipalKey: this.servicePrincipalKey,
|
||||||
subscriptionId: this.subscriptionId,
|
subscriptionId: this.subscriptionId,
|
||||||
environment: this.environment,
|
environment: ServicePrincipalLogin.environment,
|
||||||
scopeLevel: ServicePrincipalLogin.scopeLevel,
|
scopeLevel: ServicePrincipalLogin.scopeLevel,
|
||||||
allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin,
|
allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin
|
||||||
resourceManagerEndpointUrl: this.resourceManagerEndpointUrl
|
|
||||||
}
|
}
|
||||||
const script: string = new ScriptBuilder().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args);
|
const script: string = new ScriptBuilder().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args);
|
||||||
await PowerShellToolRunner.init();
|
await PowerShellToolRunner.init();
|
||||||
// await PowerShellToolRunner.executePowerShellScriptBlock(script, options);
|
await PowerShellToolRunner.executePowerShellScriptBlock(script, options);
|
||||||
// const result: any = JSON.parse(output.trim());
|
const result: any = JSON.parse(output.trim());
|
||||||
// if (!(Constants.Success in result)) {
|
if (!(Constants.Success in result)) {
|
||||||
// throw new Error(`Azure PowerShell login failed with error: ${result[Constants.Error]}`);
|
throw new Error(`Azure PowerShell login failed with error: ${result[Constants.Error]}`);
|
||||||
// }
|
}
|
||||||
console.log(`Azure PowerShell session successfully initialized`);
|
console.log(`Azure PowerShell session successfully initialized`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,22 +8,14 @@ export default class ScriptBuilder {
|
|||||||
getAzPSLoginScript(scheme: string, tenantId: string, args: any): string {
|
getAzPSLoginScript(scheme: string, tenantId: string, args: any): string {
|
||||||
let command = `Clear-AzContext -Scope Process;
|
let command = `Clear-AzContext -Scope Process;
|
||||||
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`;
|
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`;
|
||||||
|
|
||||||
if (scheme === Constants.ServicePrincipal) {
|
if (scheme === Constants.ServicePrincipal) {
|
||||||
|
|
||||||
if (args.environment.toLowerCase() == "azurestack") {
|
|
||||||
command += `Add-AzEnvironment -Name ${args.environment} -ARMEndpoint ${args.resourceManagerEndpointUrl} | out-null;`;
|
|
||||||
}
|
|
||||||
|
|
||||||
command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \
|
command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \
|
||||||
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \
|
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \
|
||||||
-Environment '${args.environment}' | out-null;`;
|
-Environment '${args.environment}' | out-null;`;
|
||||||
|
|
||||||
if (args.scopeLevel === Constants.Subscription && !args.allowNoSubscriptionsLogin) {
|
if (args.scopeLevel === Constants.Subscription && !args.allowNoSubscriptionsLogin) {
|
||||||
command += `Set-AzContext -SubscriptionId '${args.subscriptionId}' -TenantId '${tenantId}' | out-null;`;
|
command += `Set-AzContext -SubscriptionId '${args.subscriptionId}' -TenantId '${tenantId}' | out-null;`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.script += `try {
|
this.script += `try {
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
$WarningPreference = "SilentlyContinue"
|
$WarningPreference = "SilentlyContinue"
|
||||||
@@ -35,7 +27,6 @@ export default class ScriptBuilder {
|
|||||||
$output['${Constants.Error}'] = $_.exception.Message
|
$output['${Constants.Error}'] = $_.exception.Message
|
||||||
}
|
}
|
||||||
return ConvertTo-Json $output`;
|
return ConvertTo-Json $output`;
|
||||||
|
|
||||||
core.debug(`Azure PowerShell Login Script: ${this.script}`);
|
core.debug(`Azure PowerShell Login Script: ${this.script}`);
|
||||||
return this.script;
|
return this.script;
|
||||||
}
|
}
|
||||||
|
|||||||
114
src/main.ts
114
src/main.ts
@@ -1,6 +1,7 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
|
|
||||||
import { FormatType, SecretParser } from 'actions-secret-parser';
|
import { FormatType, SecretParser } from 'actions-secret-parser';
|
||||||
import { ServicePrincipalLogin } from './PowerShell/ServicePrincipalLogin';
|
import { ServicePrincipalLogin } from './PowerShell/ServicePrincipalLogin';
|
||||||
|
|
||||||
@@ -20,23 +21,15 @@ async function main() {
|
|||||||
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
|
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
|
||||||
|
|
||||||
azPath = await io.which("az", true);
|
azPath = await io.which("az", true);
|
||||||
|
|
||||||
let azureSupportedCloudName = new Set([
|
|
||||||
"azureusgovernment",
|
|
||||||
"azurechinacloud",
|
|
||||||
"azuregermancloud",
|
|
||||||
"azurecloud",
|
|
||||||
"azurestack"]);
|
|
||||||
|
|
||||||
let output: string = "";
|
let output: string = "";
|
||||||
const execOptions: any = {
|
const options: any = {
|
||||||
listeners: {
|
listeners: {
|
||||||
stdout: (data: Buffer) => {
|
stdout: (data: Buffer) => {
|
||||||
output += data.toString();
|
output += data.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
await executeAzCliCommand("--version", true, execOptions);
|
await executeAzCliCommand("--version", true, options);
|
||||||
core.debug(`az cli version used:\n${output}`);
|
core.debug(`az cli version used:\n${output}`);
|
||||||
|
|
||||||
let creds = core.getInput('creds', { required: true });
|
let creds = core.getInput('creds', { required: true });
|
||||||
@@ -45,11 +38,8 @@ async function main() {
|
|||||||
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
|
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
|
||||||
let tenantId = secrets.getSecret("$.tenantId", false);
|
let tenantId = secrets.getSecret("$.tenantId", false);
|
||||||
let subscriptionId = secrets.getSecret("$.subscriptionId", false);
|
let subscriptionId = secrets.getSecret("$.subscriptionId", false);
|
||||||
let resourceManagerEndpointUrl = secrets.getSecret("$.resourceManagerEndpointUrl", false);
|
|
||||||
let environment = core.getInput("environment").toLowerCase();
|
|
||||||
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
|
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
|
||||||
const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true";
|
const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true";
|
||||||
|
|
||||||
if (!servicePrincipalId || !servicePrincipalKey || !tenantId) {
|
if (!servicePrincipalId || !servicePrincipalKey || !tenantId) {
|
||||||
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied.");
|
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied.");
|
||||||
}
|
}
|
||||||
@@ -57,120 +47,44 @@ async function main() {
|
|||||||
if (!subscriptionId && !allowNoSubscriptionsLogin) {
|
if (!subscriptionId && !allowNoSubscriptionsLogin) {
|
||||||
throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied.");
|
throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!azureSupportedCloudName.has(environment)){
|
|
||||||
throw new Error("Unsupported value for environment is passed.The list of supported values for environment are ‘azureusgovernment', ‘azurechinacloud’, ‘azuregermancloud’, ‘azurecloud’ or ’azurestack’");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: refactor this into an Azure stack specific utility.
|
|
||||||
// Attempting Az cli login
|
|
||||||
if (environment == "azurestack") {
|
|
||||||
if (!resourceManagerEndpointUrl) {
|
|
||||||
throw new Error("resourceManagerEndpointUrl is a required parameter when environment is defined.");
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Unregistering cloud: "${environment}" first if it exists`);
|
|
||||||
try {
|
|
||||||
await executeAzCliCommand(`cloud set -n AzureCloud`, true);
|
|
||||||
await executeAzCliCommand(`cloud unregister -n "${environment}"`, false);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(`Ignore cloud not registered error: "${error}"`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Registering cloud: "${environment}" with ARM endpoint: "${resourceManagerEndpointUrl}"`);
|
|
||||||
try {
|
|
||||||
let baseUri = resourceManagerEndpointUrl;
|
|
||||||
if (baseUri.endsWith('/')) {
|
|
||||||
baseUri = baseUri.substring(0, baseUri.length-1); // need to remove trailing / from resourceManagerEndpointUrl to correctly derive suffixes below
|
|
||||||
}
|
|
||||||
let suffixKeyvault = ".vault" + baseUri.substring(baseUri.indexOf('.')); // keyvault suffix starts with .
|
|
||||||
let suffixStorage = baseUri.substring(baseUri.indexOf('.')+1); // storage suffix starts without .
|
|
||||||
let profileVersion = "2019-03-01-hybrid";
|
|
||||||
await executeAzCliCommand(`cloud register -n "${environment}" --endpoint-resource-manager "${resourceManagerEndpointUrl}" --suffix-keyvault-dns "${suffixKeyvault}" --suffix-storage-endpoint "${suffixStorage}" --profile "${profileVersion}"`, false);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
core.error(`Error while trying to register cloud "${environment}": "${error}"`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Done registering cloud: "${environment}"`)
|
|
||||||
}
|
|
||||||
|
|
||||||
await executeAzCliCommand(`cloud set -n "${environment}"`, false);
|
|
||||||
console.log(`Done setting cloud: "${environment}"`);
|
|
||||||
|
|
||||||
// Attempting Az cli login
|
// Attempting Az cli login
|
||||||
if (allowNoSubscriptionsLogin) {
|
if (allowNoSubscriptionsLogin) {
|
||||||
let args = [
|
await executeAzCliCommand(`login --allow-no-subscriptions --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
|
||||||
"--allow-no-subscriptions",
|
|
||||||
"--service-principal",
|
|
||||||
"-u", servicePrincipalId,
|
|
||||||
"-p", servicePrincipalKey,
|
|
||||||
"--tenant", tenantId
|
|
||||||
];
|
|
||||||
await executeAzCliCommand(`login`, true, {}, args);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let args = [
|
await executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
|
||||||
"--service-principal",
|
await executeAzCliCommand(`account set --subscription "${subscriptionId}"`, true);
|
||||||
"-u", servicePrincipalId,
|
|
||||||
"-p", servicePrincipalKey,
|
|
||||||
"--tenant", tenantId
|
|
||||||
];
|
|
||||||
await executeAzCliCommand(`login`, true, {}, args);
|
|
||||||
args = [
|
|
||||||
"--subscription",
|
|
||||||
subscriptionId
|
|
||||||
];
|
|
||||||
await executeAzCliCommand(`account set`, true, {}, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isAzCLISuccess = true;
|
isAzCLISuccess = true;
|
||||||
if (enableAzPSSession) {
|
if (enableAzPSSession) {
|
||||||
// Attempting Az PS login
|
// Attempting Az PS login
|
||||||
console.log(`Running Azure PS Login`);
|
console.log(`Running Azure PS Login`);
|
||||||
const spnlogin: ServicePrincipalLogin = new ServicePrincipalLogin(
|
const spnlogin: ServicePrincipalLogin = new ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin);
|
||||||
servicePrincipalId,
|
|
||||||
servicePrincipalKey,
|
|
||||||
tenantId,
|
|
||||||
subscriptionId,
|
|
||||||
allowNoSubscriptionsLogin,
|
|
||||||
environment,
|
|
||||||
resourceManagerEndpointUrl);
|
|
||||||
await spnlogin.initialize();
|
await spnlogin.initialize();
|
||||||
await spnlogin.login();
|
await spnlogin.login();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Login successful.");
|
console.log("Login successful.");
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
if (!isAzCLISuccess) {
|
if (!isAzCLISuccess) {
|
||||||
core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows");
|
core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
core.error(`Azure PowerShell Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"`);
|
core.error(`Azure PowerShell Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"`);
|
||||||
}
|
}
|
||||||
core.setFailed(error);
|
core.setFailed(error);
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
// Reset AZURE_HTTP_USER_AGENT
|
// Reset AZURE_HTTP_USER_AGENT
|
||||||
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
|
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
|
||||||
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
|
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function executeAzCliCommand(
|
async function executeAzCliCommand(command: string, silent?: boolean, options: any = {}) {
|
||||||
command: string,
|
options.silent = !!silent;
|
||||||
silent?: boolean,
|
|
||||||
execOptions: any = {},
|
|
||||||
args: any = []) {
|
|
||||||
|
|
||||||
execOptions.silent = !!silent;
|
|
||||||
try {
|
try {
|
||||||
await exec.exec(`"${azPath}" ${command}`, args, execOptions);
|
await exec.exec(`"${azPath}" ${command}`, [], options);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch(error) {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user