mirror of
https://github.com/azure/login.git
synced 2026-03-15 09:20:56 -04:00
Add pre: and post: action for cleaning up (#384)
* pre and post cleanup-cli * exec azpath * enable azure powershell part * set user agent * extract utils * divide cleanup * extract azpsconfig class * fix test * move runpsscript * change to AzPSUtils * fix typo
This commit is contained in:
@@ -1,92 +1,92 @@
|
||||
import * as os from 'os';
|
||||
|
||||
import { AzPSLogin } from '../../src/PowerShell/AzPSLogin';
|
||||
import { LoginConfig } from '../../src/common/LoginConfig';
|
||||
import AzPSConstants from '../../src/PowerShell/AzPSConstants';
|
||||
|
||||
let azpsLogin: AzPSLogin;
|
||||
jest.setTimeout(30000);
|
||||
|
||||
beforeAll(() => {
|
||||
var loginConfig = new LoginConfig();
|
||||
loginConfig.servicePrincipalId = "servicePrincipalID";
|
||||
loginConfig.servicePrincipalSecret = "servicePrincipalSecret";
|
||||
loginConfig.tenantId = "tenantId";
|
||||
loginConfig.subscriptionId = "subscriptionId";
|
||||
azpsLogin = new AzPSLogin(loginConfig);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('Testing login', () => {
|
||||
let loginSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
loginSpy = jest.spyOn(azpsLogin, 'login');
|
||||
});
|
||||
|
||||
test('ServicePrincipal login should pass', async () => {
|
||||
loginSpy.mockImplementationOnce(() => Promise.resolve());
|
||||
await azpsLogin.login();
|
||||
expect(loginSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Testing set module path', () => {
|
||||
test('setDefaultPSModulePath should work', () => {
|
||||
azpsLogin.setPSModulePathForGitHubRunner();
|
||||
const runner: string = process.env.RUNNER_OS || os.type();
|
||||
if(runner.toLowerCase() === "linux"){
|
||||
expect(process.env.PSModulePath).toContain(AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX);
|
||||
}
|
||||
if(runner.toLowerCase().startsWith("windows")){
|
||||
expect(process.env.PSModulePath).toContain(AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Testing runPSScript', () => {
|
||||
test('Get PowerShell Version', async () => {
|
||||
let script = `try {
|
||||
$ErrorActionPreference = "Stop"
|
||||
$WarningPreference = "SilentlyContinue"
|
||||
$output = @{}
|
||||
$output['Success'] = $true
|
||||
$output['Result'] = $PSVersionTable.PSVersion.ToString()
|
||||
}
|
||||
catch {
|
||||
$output['Success'] = $false
|
||||
$output['Error'] = $_.exception.Message
|
||||
}
|
||||
return ConvertTo-Json $output`;
|
||||
|
||||
let psVersion: string = await AzPSLogin.runPSScript(script);
|
||||
expect(psVersion === null).toBeFalsy();
|
||||
});
|
||||
|
||||
test('Get PowerShell Version with Wrong Name', async () => {
|
||||
let script = `try {
|
||||
$ErrorActionPreference = "Stop"
|
||||
$WarningPreference = "SilentlyContinue"
|
||||
$output = @{}
|
||||
$output['Success'] = $true
|
||||
$output['Result'] = $PSVersionTableWrongName.PSVersion.ToString()
|
||||
}
|
||||
catch {
|
||||
$output['Success'] = $false
|
||||
$output['Error'] = $_.exception.Message
|
||||
}
|
||||
return ConvertTo-Json $output`;
|
||||
|
||||
try{
|
||||
await AzPSLogin.runPSScript(script);
|
||||
throw new Error("The last step should fail.");
|
||||
}catch(error){
|
||||
expect(error.message.includes("Azure PowerShell login failed with error: You cannot call a method on a null-valued expression.")).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
import * as os from 'os';
|
||||
|
||||
import { AzPSLogin } from '../../src/PowerShell/AzPSLogin';
|
||||
import { LoginConfig } from '../../src/common/LoginConfig';
|
||||
import { AzPSConstants, AzPSUtils } from '../../src/PowerShell/AzPSUtils';
|
||||
|
||||
let azpsLogin: AzPSLogin;
|
||||
jest.setTimeout(30000);
|
||||
|
||||
beforeAll(() => {
|
||||
var loginConfig = new LoginConfig();
|
||||
loginConfig.servicePrincipalId = "servicePrincipalID";
|
||||
loginConfig.servicePrincipalSecret = "servicePrincipalSecret";
|
||||
loginConfig.tenantId = "tenantId";
|
||||
loginConfig.subscriptionId = "subscriptionId";
|
||||
azpsLogin = new AzPSLogin(loginConfig);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('Testing login', () => {
|
||||
let loginSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
loginSpy = jest.spyOn(azpsLogin, 'login');
|
||||
});
|
||||
|
||||
test('ServicePrincipal login should pass', async () => {
|
||||
loginSpy.mockImplementationOnce(() => Promise.resolve());
|
||||
await azpsLogin.login();
|
||||
expect(loginSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Testing set module path', () => {
|
||||
test('setDefaultPSModulePath should work', () => {
|
||||
AzPSUtils.setPSModulePathForGitHubRunner();
|
||||
const runner: string = process.env.RUNNER_OS || os.type();
|
||||
if(runner.toLowerCase() === "linux"){
|
||||
expect(process.env.PSModulePath).toContain(AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX);
|
||||
}
|
||||
if(runner.toLowerCase().startsWith("windows")){
|
||||
expect(process.env.PSModulePath).toContain(AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Testing runPSScript', () => {
|
||||
test('Get PowerShell Version', async () => {
|
||||
let script = `try {
|
||||
$ErrorActionPreference = "Stop"
|
||||
$WarningPreference = "SilentlyContinue"
|
||||
$output = @{}
|
||||
$output['Success'] = $true
|
||||
$output['Result'] = $PSVersionTable.PSVersion.ToString()
|
||||
}
|
||||
catch {
|
||||
$output['Success'] = $false
|
||||
$output['Error'] = $_.exception.Message
|
||||
}
|
||||
return ConvertTo-Json $output`;
|
||||
|
||||
let psVersion: string = await AzPSUtils.runPSScript(script);
|
||||
expect(psVersion === null).toBeFalsy();
|
||||
});
|
||||
|
||||
test('Get PowerShell Version with Wrong Name', async () => {
|
||||
let script = `try {
|
||||
$ErrorActionPreference = "Stop"
|
||||
$WarningPreference = "SilentlyContinue"
|
||||
$output = @{}
|
||||
$output['Success'] = $true
|
||||
$output['Result'] = $PSVersionTableWrongName.PSVersion.ToString()
|
||||
}
|
||||
catch {
|
||||
$output['Success'] = $false
|
||||
$output['Error'] = $_.exception.Message
|
||||
}
|
||||
return ConvertTo-Json $output`;
|
||||
|
||||
try{
|
||||
await AzPSUtils.runPSScript(script);
|
||||
throw new Error("The last step should fail.");
|
||||
}catch(error){
|
||||
expect(error.message.includes("Azure PowerShell login failed with error: You cannot call a method on a null-valued expression.")).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,153 +1,153 @@
|
||||
import AzPSSCriptBuilder from "../../src/PowerShell/AzPSScriptBuilder";
|
||||
import { LoginConfig } from "../../src/common/LoginConfig";
|
||||
|
||||
describe("Getting AzLogin PS script", () => {
|
||||
|
||||
function setEnv(name: string, value: string) {
|
||||
process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] = value;
|
||||
}
|
||||
|
||||
function cleanEnv() {
|
||||
for (const envKey in process.env) {
|
||||
if (envKey.startsWith('INPUT_')) {
|
||||
delete process.env[envKey]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
cleanEnv();
|
||||
});
|
||||
|
||||
test('getImportLatestModuleScript', () => {
|
||||
expect(AzPSSCriptBuilder.getImportLatestModuleScript("TestModule")).toContain("(Get-Module -Name 'TestModule' -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Path");
|
||||
expect(AzPSSCriptBuilder.getImportLatestModuleScript("TestModule")).toContain("Import-Module -Name $latestModulePath");
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for SP+secret with allowNoSubscriptionsLogin=true', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'true');
|
||||
setEnv('auth-type', 'SERVICE_PRINCIPAL');
|
||||
let creds = {
|
||||
'clientId': 'client-id',
|
||||
'clientSecret': "client-secret",
|
||||
'tenantId': 'tenant-id',
|
||||
'subscriptionId': 'subscription-id'
|
||||
}
|
||||
setEnv('creds', JSON.stringify(creds));
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; $psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('service principal with secret');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for SP+secret with allowNoSubscriptionsLogin=true, secret with single-quote', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'true');
|
||||
setEnv('auth-type', 'SERVICE_PRINCIPAL');
|
||||
let creds = {
|
||||
'clientId': 'client-id',
|
||||
'clientSecret': "client-se'cret",
|
||||
'tenantId': 'tenant-id',
|
||||
'subscriptionId': 'subscription-id'
|
||||
}
|
||||
setEnv('creds', JSON.stringify(creds));
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; $psLoginSecrets = ConvertTo-SecureString 'client-se''cret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('service principal with secret');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for SP+secret with allowNoSubscriptionsLogin=false', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'false'); // same as true
|
||||
setEnv('auth-type', 'SERVICE_PRINCIPAL');
|
||||
let creds = {
|
||||
'clientId': 'client-id',
|
||||
'clientSecret': 'client-secret',
|
||||
'tenantId': 'tenant-id',
|
||||
'subscriptionId': 'subscription-id'
|
||||
}
|
||||
setEnv('creds', JSON.stringify(creds));
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; $psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('service principal with secret');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for OIDC', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'false');
|
||||
setEnv('tenant-id', 'tenant-id');
|
||||
setEnv('subscription-id', 'subscription-id');
|
||||
setEnv('client-id', 'client-id');
|
||||
setEnv('auth-type', 'SERVICE_PRINCIPAL');
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
jest.spyOn(loginConfig, 'getFederatedToken').mockImplementation(async () => {loginConfig.federatedToken = "fake-token";});
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -ApplicationId 'client-id' -FederatedToken 'fake-token' | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('OIDC');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for System MI', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'false');
|
||||
setEnv('subscription-id', 'subscription-id');
|
||||
setEnv('auth-type', 'IDENTITY');
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; Connect-AzAccount -Identity -Environment 'azurecloud' -Subscription 'subscription-id' | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('system-assigned managed identity');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for System MI without subscription id', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'false');
|
||||
// setEnv('subscription-id', 'subscription-id');
|
||||
setEnv('auth-type', 'IDENTITY');
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; Connect-AzAccount -Identity -Environment 'azurecloud' | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('system-assigned managed identity');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for user-assigned MI', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'true');
|
||||
setEnv('auth-type', 'IDENTITY');
|
||||
setEnv('client-id', 'client-id');
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; Connect-AzAccount -Identity -Environment 'azurecloud' -AccountId 'client-id' | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('user-assigned managed identity');
|
||||
});
|
||||
});
|
||||
|
||||
import AzPSSCriptBuilder from "../../src/PowerShell/AzPSScriptBuilder";
|
||||
import { LoginConfig } from "../../src/common/LoginConfig";
|
||||
|
||||
describe("Getting AzLogin PS script", () => {
|
||||
|
||||
function setEnv(name: string, value: string) {
|
||||
process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] = value;
|
||||
}
|
||||
|
||||
function cleanEnv() {
|
||||
for (const envKey in process.env) {
|
||||
if (envKey.startsWith('INPUT_')) {
|
||||
delete process.env[envKey]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
cleanEnv();
|
||||
});
|
||||
|
||||
test('getImportLatestModuleScript', () => {
|
||||
expect(AzPSSCriptBuilder.getImportLatestModuleScript("TestModule")).toContain("(Get-Module -Name 'TestModule' -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Path");
|
||||
expect(AzPSSCriptBuilder.getImportLatestModuleScript("TestModule")).toContain("Import-Module -Name $latestModulePath");
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for SP+secret with allowNoSubscriptionsLogin=true', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'true');
|
||||
setEnv('auth-type', 'SERVICE_PRINCIPAL');
|
||||
let creds = {
|
||||
'clientId': 'client-id',
|
||||
'clientSecret': "client-secret",
|
||||
'tenantId': 'tenant-id',
|
||||
'subscriptionId': 'subscription-id'
|
||||
}
|
||||
setEnv('creds', JSON.stringify(creds));
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('service principal with secret');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for SP+secret with allowNoSubscriptionsLogin=true, secret with single-quote', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'true');
|
||||
setEnv('auth-type', 'SERVICE_PRINCIPAL');
|
||||
let creds = {
|
||||
'clientId': 'client-id',
|
||||
'clientSecret': "client-se'cret",
|
||||
'tenantId': 'tenant-id',
|
||||
'subscriptionId': 'subscription-id'
|
||||
}
|
||||
setEnv('creds', JSON.stringify(creds));
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-se''cret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('service principal with secret');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for SP+secret with allowNoSubscriptionsLogin=false', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'false'); // same as true
|
||||
setEnv('auth-type', 'SERVICE_PRINCIPAL');
|
||||
let creds = {
|
||||
'clientId': 'client-id',
|
||||
'clientSecret': 'client-secret',
|
||||
'tenantId': 'tenant-id',
|
||||
'subscriptionId': 'subscription-id'
|
||||
}
|
||||
setEnv('creds', JSON.stringify(creds));
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('service principal with secret');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for OIDC', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'false');
|
||||
setEnv('tenant-id', 'tenant-id');
|
||||
setEnv('subscription-id', 'subscription-id');
|
||||
setEnv('client-id', 'client-id');
|
||||
setEnv('auth-type', 'SERVICE_PRINCIPAL');
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
jest.spyOn(loginConfig, 'getFederatedToken').mockImplementation(async () => {loginConfig.federatedToken = "fake-token";});
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -ApplicationId 'client-id' -FederatedToken 'fake-token' | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('OIDC');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for System MI', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'false');
|
||||
setEnv('subscription-id', 'subscription-id');
|
||||
setEnv('auth-type', 'IDENTITY');
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -Subscription 'subscription-id' | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('system-assigned managed identity');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for System MI without subscription id', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'false');
|
||||
// setEnv('subscription-id', 'subscription-id');
|
||||
setEnv('auth-type', 'IDENTITY');
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('system-assigned managed identity');
|
||||
});
|
||||
});
|
||||
|
||||
test('getAzPSLoginScript for user-assigned MI', () => {
|
||||
setEnv('environment', 'azurecloud');
|
||||
setEnv('enable-AzPSSession', 'true');
|
||||
setEnv('allow-no-subscriptions', 'true');
|
||||
setEnv('auth-type', 'IDENTITY');
|
||||
setEnv('client-id', 'client-id');
|
||||
|
||||
let loginConfig = new LoginConfig();
|
||||
loginConfig.initialize();
|
||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -AccountId 'client-id' | out-null;")).toBeTruthy();
|
||||
expect(loginMethod).toBe('user-assigned managed identity');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -39,4 +39,6 @@ branding:
|
||||
color: 'blue'
|
||||
runs:
|
||||
using: 'node16'
|
||||
pre: 'lib/cleanup.js'
|
||||
main: 'lib/main.js'
|
||||
post: 'lib/cleanup.js'
|
||||
|
||||
@@ -17,9 +17,6 @@ export class AzureCliLogin {
|
||||
async login() {
|
||||
core.info(`Running Azure CLI Login.`);
|
||||
this.azPath = await io.which("az", true);
|
||||
if (!this.azPath) {
|
||||
throw new Error("Azure CLI is not found in the runner.");
|
||||
}
|
||||
core.debug(`Azure CLI path: ${this.azPath}`);
|
||||
|
||||
let output: string = "";
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
export default class AzPSConstants {
|
||||
static readonly DEFAULT_AZ_PATH_ON_LINUX: string = '/usr/share';
|
||||
static readonly DEFAULT_AZ_PATH_ON_WINDOWS: string = 'C:\\Modules';
|
||||
static readonly AzAccounts: string = "Az.Accounts";
|
||||
static readonly PowerShell_CmdName = "pwsh";
|
||||
}
|
||||
|
||||
@@ -1,100 +1,24 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
import * as io from '@actions/io';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
|
||||
import AzPSScriptBuilder from './AzPSScriptBuilder';
|
||||
import AzPSConstants from './AzPSConstants';
|
||||
import { LoginConfig } from '../common/LoginConfig';
|
||||
|
||||
interface PSResultType {
|
||||
Result: string;
|
||||
Success: boolean;
|
||||
Error: string;
|
||||
}
|
||||
|
||||
export class AzPSLogin {
|
||||
loginConfig: LoginConfig;
|
||||
|
||||
constructor(loginConfig: LoginConfig) {
|
||||
this.loginConfig = loginConfig;
|
||||
}
|
||||
|
||||
async login() {
|
||||
core.info(`Running Azure PowerShell Login.`);
|
||||
this.setPSModulePathForGitHubRunner();
|
||||
await this.importLatestAzAccounts();
|
||||
|
||||
const [loginMethod, loginScript] = await AzPSScriptBuilder.getAzPSLoginScript(this.loginConfig);
|
||||
core.info(`Attempting Azure PowerShell login by using ${loginMethod}...`);
|
||||
core.debug(`Azure PowerShell Login Script: ${loginScript}`);
|
||||
await AzPSLogin.runPSScript(loginScript);
|
||||
console.log(`Running Azure PowerShell Login successfully.`);
|
||||
}
|
||||
|
||||
setPSModulePathForGitHubRunner() {
|
||||
const runner: string = process.env.RUNNER_OS || os.type();
|
||||
switch (runner.toLowerCase()) {
|
||||
case "linux":
|
||||
this.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX);
|
||||
break;
|
||||
case "windows":
|
||||
case "windows_nt":
|
||||
this.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS);
|
||||
break;
|
||||
case "macos":
|
||||
case "darwin":
|
||||
core.warning(`Skip setting the default PowerShell module path for OS ${runner.toLowerCase()}.`);
|
||||
break;
|
||||
default:
|
||||
core.warning(`Skip setting the default PowerShell module path for unknown OS ${runner.toLowerCase()}.`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private pushPSModulePath(psModulePath: string) {
|
||||
process.env.PSModulePath = `${psModulePath}${path.delimiter}${process.env.PSModulePath}`;
|
||||
core.debug(`Set PSModulePath as ${process.env.PSModulePath}`);
|
||||
}
|
||||
|
||||
private async importLatestAzAccounts() {
|
||||
let importLatestAccountsScript: string = AzPSScriptBuilder.getImportLatestModuleScript(AzPSConstants.AzAccounts);
|
||||
core.debug(`The script to import the latest Az.Accounts: ${importLatestAccountsScript}`);
|
||||
let azAccountsPath: string = await AzPSLogin.runPSScript(importLatestAccountsScript);
|
||||
core.debug(`The latest Az.Accounts used: ${azAccountsPath}`);
|
||||
}
|
||||
|
||||
static async runPSScript(psScript: string): Promise<string> {
|
||||
let outputString: string = "";
|
||||
let commandStdErr = false;
|
||||
const options: any = {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
outputString += data.toString();
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
let error = data.toString();
|
||||
if (error && error.trim().length !== 0) {
|
||||
commandStdErr = true;
|
||||
core.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let psPath: string = await io.which(AzPSConstants.PowerShell_CmdName, true);
|
||||
await exec.exec(`"${psPath}"`, ["-Command", psScript], options)
|
||||
if (commandStdErr) {
|
||||
throw new Error('Azure PowerShell login failed with errors.');
|
||||
}
|
||||
const result: PSResultType = JSON.parse(outputString.trim());
|
||||
console.log(result);
|
||||
if (!(result.Success)) {
|
||||
throw new Error(`Azure PowerShell login failed with error: ${result.Error}`);
|
||||
}
|
||||
return result.Result;
|
||||
}
|
||||
}
|
||||
|
||||
import * as core from '@actions/core';
|
||||
|
||||
import AzPSScriptBuilder from './AzPSScriptBuilder';
|
||||
import { AzPSUtils } from './AzPSUtils';
|
||||
import { LoginConfig } from '../common/LoginConfig';
|
||||
|
||||
export class AzPSLogin {
|
||||
loginConfig: LoginConfig;
|
||||
|
||||
constructor(loginConfig: LoginConfig) {
|
||||
this.loginConfig = loginConfig;
|
||||
}
|
||||
|
||||
async login() {
|
||||
core.info(`Running Azure PowerShell Login.`);
|
||||
AzPSUtils.setPSModulePathForGitHubRunner();
|
||||
await AzPSUtils.importLatestAzAccounts();
|
||||
const [loginMethod, loginScript] = await AzPSScriptBuilder.getAzPSLoginScript(this.loginConfig);
|
||||
core.info(`Attempting Azure PowerShell login by using ${loginMethod}...`);
|
||||
core.debug(`Azure PowerShell Login Script: ${loginScript}`);
|
||||
await AzPSUtils.runPSScript(loginScript);
|
||||
console.log(`Running Azure PowerShell Login successfully.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,113 +1,111 @@
|
||||
import AzPSConstants from "./AzPSConstants";
|
||||
import { LoginConfig } from '../common/LoginConfig';
|
||||
|
||||
export default class AzPSScriptBuilder {
|
||||
|
||||
static getImportLatestModuleScript(moduleName: string): string {
|
||||
let script = `try {
|
||||
$ErrorActionPreference = "Stop"
|
||||
$WarningPreference = "SilentlyContinue"
|
||||
$output = @{}
|
||||
$latestModulePath = (Get-Module -Name '${moduleName}' -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Path
|
||||
Import-Module -Name $latestModulePath
|
||||
$output['Success'] = $true
|
||||
$output['Result'] = $latestModulePath
|
||||
}
|
||||
catch {
|
||||
$output['Success'] = $false
|
||||
$output['Error'] = $_.exception.Message
|
||||
}
|
||||
return ConvertTo-Json $output`;
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
static async getAzPSLoginScript(loginConfig: LoginConfig) {
|
||||
let loginMethodName = "";
|
||||
let commands = 'Clear-AzContext -Scope Process; ';
|
||||
commands += 'Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; ';
|
||||
|
||||
if (loginConfig.environment.toLowerCase() == "azurestack") {
|
||||
commands += `Add-AzEnvironment -Name '${loginConfig.environment}' -ARMEndpoint '${loginConfig.resourceManagerEndpointUrl}' | out-null;`;
|
||||
}
|
||||
if (loginConfig.authType === LoginConfig.AUTH_TYPE_SERVICE_PRINCIPAL) {
|
||||
if (loginConfig.servicePrincipalSecret) {
|
||||
commands += AzPSScriptBuilder.loginWithSecret(loginConfig);
|
||||
loginMethodName = 'service principal with secret';
|
||||
} else {
|
||||
commands += await AzPSScriptBuilder.loginWithOIDC(loginConfig);
|
||||
loginMethodName = "OIDC";
|
||||
}
|
||||
} else {
|
||||
if (loginConfig.servicePrincipalId) {
|
||||
commands += AzPSScriptBuilder.loginWithUserAssignedIdentity(loginConfig);
|
||||
loginMethodName = 'user-assigned managed identity';
|
||||
} else {
|
||||
commands += AzPSScriptBuilder.loginWithSystemAssignedIdentity(loginConfig);
|
||||
loginMethodName = 'system-assigned managed identity';
|
||||
}
|
||||
}
|
||||
|
||||
let script = `try {
|
||||
$ErrorActionPreference = "Stop"
|
||||
$WarningPreference = "SilentlyContinue"
|
||||
$output = @{}
|
||||
${commands}
|
||||
$output['Success'] = $true
|
||||
$output['Result'] = ""
|
||||
}
|
||||
catch {
|
||||
$output['Success'] = $false
|
||||
$output['Error'] = $_.exception.Message
|
||||
}
|
||||
return ConvertTo-Json $output`;
|
||||
|
||||
return [loginMethodName, script];
|
||||
}
|
||||
|
||||
private static loginWithSecret(loginConfig: LoginConfig): string {
|
||||
let servicePrincipalSecret: string = loginConfig.servicePrincipalSecret.split("'").join("''");
|
||||
let loginCmdlet = `$psLoginSecrets = ConvertTo-SecureString '${servicePrincipalSecret}' -AsPlainText -Force; `;
|
||||
loginCmdlet += `$psLoginCredential = New-Object System.Management.Automation.PSCredential('${loginConfig.servicePrincipalId}', $psLoginSecrets); `;
|
||||
|
||||
let cmdletSuffix = "-Credential $psLoginCredential";
|
||||
loginCmdlet += AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix);
|
||||
|
||||
return loginCmdlet;
|
||||
}
|
||||
|
||||
private static async loginWithOIDC(loginConfig: LoginConfig) {
|
||||
await loginConfig.getFederatedToken();
|
||||
let cmdletSuffix = `-ApplicationId '${loginConfig.servicePrincipalId}' -FederatedToken '${loginConfig.federatedToken}'`;
|
||||
return AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix);
|
||||
}
|
||||
|
||||
private static loginWithSystemAssignedIdentity(loginConfig: LoginConfig): string {
|
||||
let cmdletSuffix = "";
|
||||
return AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix);
|
||||
}
|
||||
|
||||
static loginWithUserAssignedIdentity(loginConfig: LoginConfig): string {
|
||||
let cmdletSuffix = `-AccountId '${loginConfig.servicePrincipalId}'`;
|
||||
return AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix);
|
||||
}
|
||||
|
||||
private static psLoginCmdlet(authType:string, environment:string, tenantId:string, subscriptionId:string, cmdletSuffix:string){
|
||||
let loginCmdlet = `Connect-AzAccount `;
|
||||
if(authType === LoginConfig.AUTH_TYPE_SERVICE_PRINCIPAL){
|
||||
loginCmdlet += "-ServicePrincipal ";
|
||||
}else{
|
||||
loginCmdlet += "-Identity ";
|
||||
}
|
||||
loginCmdlet += `-Environment '${environment}' `;
|
||||
if(tenantId){
|
||||
loginCmdlet += `-Tenant '${tenantId}' `;
|
||||
}
|
||||
if(subscriptionId){
|
||||
loginCmdlet += `-Subscription '${subscriptionId}' `;
|
||||
}
|
||||
loginCmdlet += `${cmdletSuffix} | out-null;`;
|
||||
return loginCmdlet;
|
||||
}
|
||||
}
|
||||
|
||||
import { LoginConfig } from '../common/LoginConfig';
|
||||
|
||||
export default class AzPSScriptBuilder {
|
||||
|
||||
static getImportLatestModuleScript(moduleName: string): string {
|
||||
let script = `try {
|
||||
$ErrorActionPreference = "Stop"
|
||||
$WarningPreference = "SilentlyContinue"
|
||||
$output = @{}
|
||||
$latestModulePath = (Get-Module -Name '${moduleName}' -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Path
|
||||
Import-Module -Name $latestModulePath
|
||||
$output['Success'] = $true
|
||||
$output['Result'] = $latestModulePath
|
||||
}
|
||||
catch {
|
||||
$output['Success'] = $false
|
||||
$output['Error'] = $_.exception.Message
|
||||
}
|
||||
return ConvertTo-Json $output`;
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
static async getAzPSLoginScript(loginConfig: LoginConfig) {
|
||||
let loginMethodName = "";
|
||||
let commands = "";
|
||||
|
||||
if (loginConfig.environment.toLowerCase() == "azurestack") {
|
||||
commands += `Add-AzEnvironment -Name '${loginConfig.environment}' -ARMEndpoint '${loginConfig.resourceManagerEndpointUrl}' | out-null;`;
|
||||
}
|
||||
if (loginConfig.authType === LoginConfig.AUTH_TYPE_SERVICE_PRINCIPAL) {
|
||||
if (loginConfig.servicePrincipalSecret) {
|
||||
commands += AzPSScriptBuilder.loginWithSecret(loginConfig);
|
||||
loginMethodName = 'service principal with secret';
|
||||
} else {
|
||||
commands += await AzPSScriptBuilder.loginWithOIDC(loginConfig);
|
||||
loginMethodName = "OIDC";
|
||||
}
|
||||
} else {
|
||||
if (loginConfig.servicePrincipalId) {
|
||||
commands += AzPSScriptBuilder.loginWithUserAssignedIdentity(loginConfig);
|
||||
loginMethodName = 'user-assigned managed identity';
|
||||
} else {
|
||||
commands += AzPSScriptBuilder.loginWithSystemAssignedIdentity(loginConfig);
|
||||
loginMethodName = 'system-assigned managed identity';
|
||||
}
|
||||
}
|
||||
|
||||
let script = `try {
|
||||
$ErrorActionPreference = "Stop"
|
||||
$WarningPreference = "SilentlyContinue"
|
||||
$output = @{}
|
||||
${commands}
|
||||
$output['Success'] = $true
|
||||
$output['Result'] = ""
|
||||
}
|
||||
catch {
|
||||
$output['Success'] = $false
|
||||
$output['Error'] = $_.exception.Message
|
||||
}
|
||||
return ConvertTo-Json $output`;
|
||||
|
||||
return [loginMethodName, script];
|
||||
}
|
||||
|
||||
private static loginWithSecret(loginConfig: LoginConfig): string {
|
||||
let servicePrincipalSecret: string = loginConfig.servicePrincipalSecret.split("'").join("''");
|
||||
let loginCmdlet = `$psLoginSecrets = ConvertTo-SecureString '${servicePrincipalSecret}' -AsPlainText -Force; `;
|
||||
loginCmdlet += `$psLoginCredential = New-Object System.Management.Automation.PSCredential('${loginConfig.servicePrincipalId}', $psLoginSecrets); `;
|
||||
|
||||
let cmdletSuffix = "-Credential $psLoginCredential";
|
||||
loginCmdlet += AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix);
|
||||
|
||||
return loginCmdlet;
|
||||
}
|
||||
|
||||
private static async loginWithOIDC(loginConfig: LoginConfig) {
|
||||
await loginConfig.getFederatedToken();
|
||||
let cmdletSuffix = `-ApplicationId '${loginConfig.servicePrincipalId}' -FederatedToken '${loginConfig.federatedToken}'`;
|
||||
return AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix);
|
||||
}
|
||||
|
||||
private static loginWithSystemAssignedIdentity(loginConfig: LoginConfig): string {
|
||||
let cmdletSuffix = "";
|
||||
return AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix);
|
||||
}
|
||||
|
||||
static loginWithUserAssignedIdentity(loginConfig: LoginConfig): string {
|
||||
let cmdletSuffix = `-AccountId '${loginConfig.servicePrincipalId}'`;
|
||||
return AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix);
|
||||
}
|
||||
|
||||
private static psLoginCmdlet(authType:string, environment:string, tenantId:string, subscriptionId:string, cmdletSuffix:string){
|
||||
let loginCmdlet = `Connect-AzAccount `;
|
||||
if(authType === LoginConfig.AUTH_TYPE_SERVICE_PRINCIPAL){
|
||||
loginCmdlet += "-ServicePrincipal ";
|
||||
}else{
|
||||
loginCmdlet += "-Identity ";
|
||||
}
|
||||
loginCmdlet += `-Environment '${environment}' `;
|
||||
if(tenantId){
|
||||
loginCmdlet += `-Tenant '${tenantId}' `;
|
||||
}
|
||||
if(subscriptionId){
|
||||
loginCmdlet += `-Subscription '${subscriptionId}' `;
|
||||
}
|
||||
loginCmdlet += `${cmdletSuffix} | out-null;`;
|
||||
return loginCmdlet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
85
src/PowerShell/AzPSUtils.ts
Normal file
85
src/PowerShell/AzPSUtils.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as exec from '@actions/exec';
|
||||
import * as io from '@actions/io';
|
||||
import AzPSScriptBuilder from './AzPSScriptBuilder';
|
||||
|
||||
interface PSResultType {
|
||||
Result: string;
|
||||
Success: boolean;
|
||||
Error: string;
|
||||
}
|
||||
|
||||
export class AzPSConstants {
|
||||
static readonly DEFAULT_AZ_PATH_ON_LINUX: string = '/usr/share';
|
||||
static readonly DEFAULT_AZ_PATH_ON_WINDOWS: string = 'C:\\Modules';
|
||||
static readonly AzAccounts: string = "Az.Accounts";
|
||||
static readonly PowerShell_CmdName = "pwsh";
|
||||
}
|
||||
|
||||
export class AzPSUtils {
|
||||
static async setPSModulePathForGitHubRunner() {
|
||||
const runner: string = process.env.RUNNER_OS || os.type();
|
||||
switch (runner.toLowerCase()) {
|
||||
case "linux":
|
||||
AzPSUtils.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX);
|
||||
break;
|
||||
case "windows":
|
||||
case "windows_nt":
|
||||
AzPSUtils.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS);
|
||||
break;
|
||||
case "macos":
|
||||
case "darwin":
|
||||
core.warning(`Skip setting the default PowerShell module path for OS ${runner.toLowerCase()}.`);
|
||||
break;
|
||||
default:
|
||||
core.warning(`Skip setting the default PowerShell module path for unknown OS ${runner.toLowerCase()}.`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static pushPSModulePath(psModulePath: string) {
|
||||
process.env.PSModulePath = `${psModulePath}${path.delimiter}${process.env.PSModulePath}`;
|
||||
core.debug(`Set PSModulePath as ${process.env.PSModulePath}`);
|
||||
}
|
||||
|
||||
static async importLatestAzAccounts() {
|
||||
let importLatestAccountsScript: string = AzPSScriptBuilder.getImportLatestModuleScript(AzPSConstants.AzAccounts);
|
||||
core.debug(`The script to import the latest Az.Accounts: ${importLatestAccountsScript}`);
|
||||
let azAccountsPath: string = await AzPSUtils.runPSScript(importLatestAccountsScript);
|
||||
core.debug(`The latest Az.Accounts used: ${azAccountsPath}`);
|
||||
}
|
||||
|
||||
static async runPSScript(psScript: string): Promise<string> {
|
||||
let outputString: string = "";
|
||||
let commandStdErr = false;
|
||||
const options: any = {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
outputString += data.toString();
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
let error = data.toString();
|
||||
if (error && error.trim().length !== 0) {
|
||||
commandStdErr = true;
|
||||
core.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let psPath: string = await io.which(AzPSConstants.PowerShell_CmdName, true);
|
||||
await exec.exec(`"${psPath}"`, ["-Command", psScript], options)
|
||||
if (commandStdErr) {
|
||||
throw new Error('Azure PowerShell login failed with errors.');
|
||||
}
|
||||
const result: PSResultType = JSON.parse(outputString.trim());
|
||||
console.log(result);
|
||||
if (!(result.Success)) {
|
||||
throw new Error(`Azure PowerShell login failed with error: ${result.Error}`);
|
||||
}
|
||||
return result.Result;
|
||||
}
|
||||
}
|
||||
19
src/cleanup.ts
Normal file
19
src/cleanup.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import * as core from '@actions/core';
|
||||
import { setUserAgent, cleanupAzCLIAccounts, cleanupAzPSAccounts } from './common/Utils';
|
||||
|
||||
async function cleanup() {
|
||||
try {
|
||||
setUserAgent();
|
||||
await cleanupAzCLIAccounts();
|
||||
if(core.getInput('enable-AzPSSession').toLowerCase() === "true"){
|
||||
await cleanupAzPSAccounts();
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(`Login cleanup failed with ${error}. Make sure 'az' is installed on the runner. If 'enable-AzPSSession' is true, make sure 'pwsh' is installed on the runner together with Azure PowerShell module.`);
|
||||
core.debug(error.stack);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup();
|
||||
|
||||
36
src/common/Utils.ts
Normal file
36
src/common/Utils.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
import * as io from '@actions/io';
|
||||
import * as crypto from 'crypto';
|
||||
import { AzPSConstants, AzPSUtils } from '../PowerShell/AzPSUtils';
|
||||
|
||||
export function setUserAgent(): void {
|
||||
let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex');
|
||||
let actionName = 'AzureLogin';
|
||||
process.env.AZURE_HTTP_USER_AGENT = (!!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT} ` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
|
||||
process.env.AZUREPS_HOST_ENVIRONMENT = (!!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT} ` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
|
||||
}
|
||||
|
||||
export async function cleanupAzCLIAccounts(): Promise<void> {
|
||||
let azPath = await io.which("az", true);
|
||||
if (!azPath) {
|
||||
throw new Error("Azure CLI is not found in the runner.");
|
||||
}
|
||||
core.debug(`Azure CLI path: ${azPath}`);
|
||||
core.info("Clearing azure cli accounts from the local cache.");
|
||||
await exec.exec(`"${azPath}"`, ["account", "clear"]);
|
||||
}
|
||||
|
||||
export async function cleanupAzPSAccounts(): Promise<void> {
|
||||
let psPath: string = await io.which(AzPSConstants.PowerShell_CmdName, true);
|
||||
if (!psPath) {
|
||||
throw new Error("PowerShell is not found in the runner.");
|
||||
}
|
||||
core.debug(`PowerShell path: ${psPath}`);
|
||||
core.debug("Importing Azure PowerShell module.");
|
||||
AzPSUtils.setPSModulePathForGitHubRunner();
|
||||
await AzPSUtils.importLatestAzAccounts();
|
||||
core.info("Clearing azure powershell accounts from the local cache.");
|
||||
await exec.exec(`"${psPath}"`, ["-Command", "Clear-AzContext", "-Scope", "Process"]);
|
||||
await exec.exec(`"${psPath}"`, ["-Command", "Clear-AzContext", "-Scope", "CurrentUser", "-Force", "-ErrorAction", "SilentlyContinue"]);
|
||||
}
|
||||
18
src/main.ts
18
src/main.ts
@@ -1,19 +1,12 @@
|
||||
import * as core from '@actions/core';
|
||||
import { setUserAgent } from './common/Utils';
|
||||
import { AzPSLogin } from './PowerShell/AzPSLogin';
|
||||
import { LoginConfig } from './common/LoginConfig';
|
||||
import { AzureCliLogin } from './Cli/AzureCliLogin';
|
||||
|
||||
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 {
|
||||
let usrAgentRepo = `${process.env.GITHUB_REPOSITORY}`;
|
||||
let actionName = 'AzureLogin';
|
||||
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);
|
||||
setUserAgent();
|
||||
|
||||
// prepare the login configuration
|
||||
var loginConfig = new LoginConfig();
|
||||
@@ -31,14 +24,9 @@ async function main() {
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(`Login failed with ${error}. Make sure 'az' is installed on the runner. If 'enable-AzPSSession' is true, make sure 'pwsh' is installed on the runner together with Azure PowerShell module. Double check if the 'auth-type' is correct. Refer to https://github.com/Azure/login#readme for more information.`);
|
||||
core.setFailed(`Login failed with ${error}. Double check if the 'auth-type' is correct. Refer to https://github.com/Azure/login#readme for more information.`);
|
||||
core.debug(error.stack);
|
||||
}
|
||||
finally {
|
||||
// Reset AZURE_HTTP_USER_AGENT
|
||||
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
|
||||
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
Reference in New Issue
Block a user