mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-09-04 06:15:07 +09:00
feat: add support for assuming a role (#17)
* first draft attempt at adding role assumption option * refinements * const not var * clean up asserts * set explicit sts endpoint and clarify required inputs error message * streamline mocks * add new inputs to Action definition * ignore .idea directory * add initial assume role test * make tests fail usefully when not in GitHub Actions * add logic to handle suppression of stack trace * pull credentials exports out into function * convert environment variable patching to use object for source and add needed members * add test for STS call * compartmentalization and use custom user agent in role assumption STS client * change DO_NOT_SUPRESS_STACK_TRACE to SHOW_STACK_TRACE * update role-to-assume input description
This commit is contained in:
committed by
Clare Liguori
parent
e3c83cfe60
commit
25960ab095
@@ -2,6 +2,7 @@ node_modules/
|
|||||||
|
|
||||||
# Editors
|
# Editors
|
||||||
.vscode
|
.vscode
|
||||||
|
.idea
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ inputs:
|
|||||||
mask-aws-account-id:
|
mask-aws-account-id:
|
||||||
description: "Whether to set the AWS account ID for these credentials as a secret value, so that it is masked in logs. Valid values are 'true' and 'false'. Defaults to true"
|
description: "Whether to set the AWS account ID for these credentials as a secret value, so that it is masked in logs. Valid values are 'true' and 'false'. Defaults to true"
|
||||||
required: false
|
required: false
|
||||||
|
role-to-assume:
|
||||||
|
description: "Use the provided credentials to assume a Role and output the assumed credentials for that Role rather than the provided credentials"
|
||||||
|
required: false
|
||||||
|
role-duration-seconds:
|
||||||
|
description: "Role duration in seconds (default: 6 hours)"
|
||||||
|
required: false
|
||||||
outputs:
|
outputs:
|
||||||
aws-account-id:
|
aws-account-id:
|
||||||
description: 'The AWS account ID for the provided credentials'
|
description: 'The AWS account ID for the provided credentials'
|
||||||
|
|||||||
@@ -1,16 +1,61 @@
|
|||||||
const core = require('@actions/core');
|
const core = require('@actions/core');
|
||||||
const aws = require('aws-sdk');
|
const aws = require('aws-sdk');
|
||||||
|
const assert = require('assert');
|
||||||
|
const util = require('util');
|
||||||
|
|
||||||
async function run() {
|
// The max time that a GitHub action is allowed to run is 6 hours.
|
||||||
try {
|
// That seems like a reasonable default to use if no role duration is defined.
|
||||||
// Get inputs
|
const MAX_ACTION_RUNTIME = 6 * 3600;
|
||||||
const accessKeyId = core.getInput('aws-access-key-id', { required: true });
|
const USER_AGENT = 'configure-aws-credentials-for-github-actions';
|
||||||
const secretAccessKey = core.getInput('aws-secret-access-key', { required: true });
|
|
||||||
const region = core.getInput('aws-region', { required: true });
|
|
||||||
const sessionToken = core.getInput('aws-session-token', { required: false });
|
|
||||||
const maskAccountId = core.getInput('mask-aws-account-id', { required: false });
|
|
||||||
|
|
||||||
|
async function assumeRole(params) {
|
||||||
|
// Assume a role to get short-lived credentials using longer-lived credentials.
|
||||||
|
const isDefined = i => !!i;
|
||||||
|
|
||||||
|
const {roleToAssume, roleDurationSeconds, accessKeyId, secretAccessKey, sessionToken, region} = params;
|
||||||
|
assert(
|
||||||
|
[roleToAssume, roleDurationSeconds, accessKeyId, secretAccessKey, region].every(isDefined),
|
||||||
|
"Missing required input when assuming a Role."
|
||||||
|
);
|
||||||
|
|
||||||
|
const {GITHUB_REPOSITORY, GITHUB_WORKFLOW, GITHUB_ACTION, GITHUB_ACTOR, GITHUB_REF, GITHUB_SHA} = process.env;
|
||||||
|
assert(
|
||||||
|
[GITHUB_REPOSITORY, GITHUB_WORKFLOW, GITHUB_ACTION, GITHUB_ACTOR, GITHUB_REF, GITHUB_SHA].every(isDefined),
|
||||||
|
'Missing required environment value. Are you running in GitHub Actions?'
|
||||||
|
);
|
||||||
|
|
||||||
|
const endpoint = util.format('https://sts.%s.amazonaws.com', region);
|
||||||
|
|
||||||
|
const sts = new aws.STS({
|
||||||
|
accessKeyId, secretAccessKey, sessionToken, region, endpoint, customUserAgent: USER_AGENT
|
||||||
|
});
|
||||||
|
return sts.assumeRole({
|
||||||
|
RoleArn: roleToAssume,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: roleDurationSeconds,
|
||||||
|
Tags: [
|
||||||
|
{Key: 'GitHub', Value: 'Actions'},
|
||||||
|
{Key: 'Repository', Value: GITHUB_REPOSITORY},
|
||||||
|
{Key: 'Workflow', Value: GITHUB_WORKFLOW},
|
||||||
|
{Key: 'Action', Value: GITHUB_ACTION},
|
||||||
|
{Key: 'Actor', Value: GITHUB_ACTOR},
|
||||||
|
{Key: 'Branch', Value: GITHUB_REF},
|
||||||
|
{Key: 'Commit', Value: GITHUB_SHA},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.promise()
|
||||||
|
.then(function (data) {
|
||||||
|
return {
|
||||||
|
accessKeyId: data.Credentials.AccessKeyId,
|
||||||
|
secretAccessKey: data.Credentials.SecretAccessKey,
|
||||||
|
sessionToken: data.Credentials.SessionToken,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportCredentials(params){
|
||||||
// Configure the AWS CLI and AWS SDKs using environment variables
|
// Configure the AWS CLI and AWS SDKs using environment variables
|
||||||
|
const {accessKeyId, secretAccessKey, sessionToken} = params;
|
||||||
|
|
||||||
// AWS_ACCESS_KEY_ID:
|
// AWS_ACCESS_KEY_ID:
|
||||||
// Specifies an AWS access key associated with an IAM user or role
|
// Specifies an AWS access key associated with an IAM user or role
|
||||||
@@ -25,25 +70,60 @@ async function run() {
|
|||||||
if (sessionToken) {
|
if (sessionToken) {
|
||||||
core.exportVariable('AWS_SESSION_TOKEN', sessionToken);
|
core.exportVariable('AWS_SESSION_TOKEN', sessionToken);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportRegion(region) {
|
||||||
// AWS_DEFAULT_REGION and AWS_REGION:
|
// AWS_DEFAULT_REGION and AWS_REGION:
|
||||||
// Specifies the AWS Region to send requests to
|
// Specifies the AWS Region to send requests to
|
||||||
core.exportVariable('AWS_DEFAULT_REGION', region);
|
core.exportVariable('AWS_DEFAULT_REGION', region);
|
||||||
core.exportVariable('AWS_REGION', region);
|
core.exportVariable('AWS_REGION', region);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function exportAccountId(maskAccountId) {
|
||||||
// Get the AWS account ID
|
// Get the AWS account ID
|
||||||
const sts = new aws.STS({
|
const sts = new aws.STS({customUserAgent: USER_AGENT});
|
||||||
customUserAgent: 'configure-aws-credentials-for-github-actions'
|
|
||||||
});
|
|
||||||
const identity = await sts.getCallerIdentity().promise();
|
const identity = await sts.getCallerIdentity().promise();
|
||||||
const accountId = identity.Account;
|
const accountId = identity.Account;
|
||||||
core.setOutput('aws-account-id', accountId);
|
core.setOutput('aws-account-id', accountId);
|
||||||
if (!maskAccountId || maskAccountId.toLowerCase() == 'true') {
|
if (!maskAccountId || maskAccountId.toLowerCase() == 'true') {
|
||||||
core.setSecret(accountId);
|
core.setSecret(accountId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
try {
|
||||||
|
// Get inputs
|
||||||
|
const accessKeyId = core.getInput('aws-access-key-id', { required: true });
|
||||||
|
const secretAccessKey = core.getInput('aws-secret-access-key', { required: true });
|
||||||
|
const region = core.getInput('aws-region', { required: true });
|
||||||
|
const sessionToken = core.getInput('aws-session-token', { required: false });
|
||||||
|
const maskAccountId = core.getInput('mask-aws-account-id', { required: false });
|
||||||
|
const roleToAssume = core.getInput('role-to-assume', {required: false});
|
||||||
|
const roleDurationSeconds = core.getInput('role-duration-seconds', {required: false}) || MAX_ACTION_RUNTIME;
|
||||||
|
|
||||||
|
// Get role credentials if configured to do so
|
||||||
|
if (roleToAssume) {
|
||||||
|
const roleCredentials = await assumeRole(
|
||||||
|
{accessKeyId, secretAccessKey, sessionToken, region, roleToAssume, roleDurationSeconds}
|
||||||
|
);
|
||||||
|
exportCredentials(roleCredentials);
|
||||||
|
} else {
|
||||||
|
exportCredentials({accessKeyId, secretAccessKey, sessionToken});
|
||||||
|
}
|
||||||
|
|
||||||
|
exportRegion(region);
|
||||||
|
|
||||||
|
await exportAccountId(maskAccountId);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
|
|
||||||
|
const showStackTrace = process.env.SHOW_STACK_TRACE;
|
||||||
|
|
||||||
|
if (showStackTrace === 'true') {
|
||||||
|
throw(error)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+162
-30
@@ -1,89 +1,148 @@
|
|||||||
const core = require('@actions/core');
|
const core = require('@actions/core');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
const run = require('.');
|
const run = require('.');
|
||||||
|
|
||||||
jest.mock('@actions/core');
|
jest.mock('@actions/core');
|
||||||
|
|
||||||
|
const FAKE_ACCESS_KEY_ID = 'MY-AWS-ACCESS-KEY-ID';
|
||||||
|
const FAKE_SECRET_ACCESS_KEY = 'MY-AWS-SECRET-ACCESS-KEY';
|
||||||
|
const FAKE_SESSION_TOKEN = 'MY-AWS-SESSION-TOKEN';
|
||||||
|
const FAKE_STS_ACCESS_KEY_ID = 'STS-AWS-ACCESS-KEY-ID';
|
||||||
|
const FAKE_STS_SECRET_ACCESS_KEY = 'STS-AWS-SECRET-ACCESS-KEY';
|
||||||
|
const FAKE_STS_SESSION_TOKEN = 'STS-AWS-SESSION-TOKEN';
|
||||||
|
const FAKE_REGION = 'fake-region-1';
|
||||||
|
const FAKE_ACCOUNT_ID = '123456789012';
|
||||||
|
const ROLE_NAME = 'MY-ROLE';
|
||||||
|
const ENVIRONMENT_VARIABLE_OVERRIDES = {
|
||||||
|
SHOW_STACK_TRACE: 'true',
|
||||||
|
GITHUB_REPOSITORY: 'MY-REPOSITORY-NAME',
|
||||||
|
GITHUB_WORKFLOW: 'MY-WORKFLOW-ID',
|
||||||
|
GITHUB_ACTION: 'MY-ACTION-NAME',
|
||||||
|
GITHUB_ACTOR: 'MY-USERNAME',
|
||||||
|
GITHUB_REF: 'MY-BRANCH',
|
||||||
|
GITHUB_SHA: 'MY-COMMIT-ID',
|
||||||
|
};
|
||||||
|
|
||||||
|
function mockGetInput(requestResponse) {
|
||||||
|
return function (name, options) { // eslint-disable-line no-unused-vars
|
||||||
|
return requestResponse[name]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const REQUIRED_INPUTS = {
|
||||||
|
'aws-access-key-id': FAKE_ACCESS_KEY_ID,
|
||||||
|
'aws-secret-access-key': FAKE_SECRET_ACCESS_KEY
|
||||||
|
};
|
||||||
|
const DEFAULT_INPUTS = {
|
||||||
|
...REQUIRED_INPUTS,
|
||||||
|
'aws-session-token': FAKE_SESSION_TOKEN,
|
||||||
|
'aws-region': FAKE_REGION,
|
||||||
|
'mask-aws-account-id': 'TRUE'
|
||||||
|
};
|
||||||
|
const ASSUME_ROLE_INPUTS = {...REQUIRED_INPUTS, 'role-to-assume': ROLE_NAME, 'aws-region': FAKE_REGION};
|
||||||
|
|
||||||
const mockStsCallerIdentity = jest.fn();
|
const mockStsCallerIdentity = jest.fn();
|
||||||
|
const mockStsAssumeRole = jest.fn();
|
||||||
|
|
||||||
jest.mock('aws-sdk', () => {
|
jest.mock('aws-sdk', () => {
|
||||||
return {
|
return {
|
||||||
STS: jest.fn(() => ({
|
STS: jest.fn(() => ({
|
||||||
getCallerIdentity: mockStsCallerIdentity
|
getCallerIdentity: mockStsCallerIdentity,
|
||||||
|
assumeRole: mockStsAssumeRole,
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Configure AWS Credentials', () => {
|
describe('Configure AWS Credentials', () => {
|
||||||
|
const OLD_ENV = process.env;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = {...OLD_ENV, ...ENVIRONMENT_VARIABLE_OVERRIDES};
|
||||||
|
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
|
||||||
core.getInput = jest
|
core.getInput = jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockReturnValueOnce('MY-AWS-ACCESS-KEY-ID') // aws-access-key-id
|
.mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||||
.mockReturnValueOnce('MY-AWS-SECRET-ACCESS-KEY') // aws-secret-access-key
|
|
||||||
.mockReturnValueOnce('us-east-2') // aws-default-region
|
|
||||||
.mockReturnValueOnce('MY-AWS-SESSION-TOKEN') // aws-session-token
|
|
||||||
.mockReturnValueOnce('TRUE'); // mask-aws-account-id
|
|
||||||
|
|
||||||
mockStsCallerIdentity.mockImplementation(() => {
|
mockStsCallerIdentity.mockImplementation(() => {
|
||||||
return {
|
return {
|
||||||
promise() {
|
promise() {
|
||||||
return Promise.resolve({ Account: '123456789012' });
|
return Promise.resolve({ Account: FAKE_ACCOUNT_ID });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mockStsAssumeRole.mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
promise() {
|
||||||
|
return Promise.resolve({
|
||||||
|
Credentials: {
|
||||||
|
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||||
|
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||||
|
SessionToken: FAKE_STS_SESSION_TOKEN
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = OLD_ENV;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('exports env vars', async () => {
|
test('exports env vars', async () => {
|
||||||
await run();
|
await run();
|
||||||
|
expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
|
||||||
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', 'MY-AWS-ACCESS-KEY-ID');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', 'MY-AWS-SECRET-ACCESS-KEY');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', 'MY-AWS-SESSION-TOKEN');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', FAKE_SESSION_TOKEN);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'us-east-2');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', FAKE_REGION);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'us-east-2');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', FAKE_REGION);
|
||||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', '123456789012');
|
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||||
expect(core.setSecret).toHaveBeenCalledWith('123456789012');
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('session token is optional', async () => {
|
test('session token is optional', async () => {
|
||||||
|
const mockInputs = {...REQUIRED_INPUTS, 'aws-region': 'eu-west-1'};
|
||||||
core.getInput = jest
|
core.getInput = jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockReturnValueOnce('MY-AWS-ACCESS-KEY-ID') // aws-access-key-id
|
.mockImplementation(mockGetInput(mockInputs));
|
||||||
.mockReturnValueOnce('MY-AWS-SECRET-ACCESS-KEY') // aws-secret-access-key
|
|
||||||
.mockReturnValueOnce('eu-west-1'); // aws-default-region
|
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
|
expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
|
||||||
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', 'MY-AWS-ACCESS-KEY-ID');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', 'MY-AWS-SECRET-ACCESS-KEY');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
|
||||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', '123456789012');
|
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||||
expect(core.setSecret).toHaveBeenCalledWith('123456789012');
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can opt out of masking account ID', async () => {
|
test('can opt out of masking account ID', async () => {
|
||||||
|
const mockInputs = {...REQUIRED_INPUTS, 'aws-region': 'us-east-1', 'mask-aws-account-id': 'false'};
|
||||||
core.getInput = jest
|
core.getInput = jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockReturnValueOnce('MY-AWS-ACCESS-KEY-ID') // aws-access-key-id
|
.mockImplementation(mockGetInput(mockInputs));
|
||||||
.mockReturnValueOnce('MY-AWS-SECRET-ACCESS-KEY') // aws-secret-access-key
|
|
||||||
.mockReturnValueOnce('us-east-1') // aws-default-region
|
|
||||||
.mockReturnValueOnce('') // aws-session-token
|
|
||||||
.mockReturnValueOnce('false'); // mask-aws-account-id
|
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
|
expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
|
||||||
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', 'MY-AWS-ACCESS-KEY-ID');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', 'MY-AWS-SECRET-ACCESS-KEY');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'us-east-1');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'us-east-1');
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'us-east-1');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'us-east-1');
|
||||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', '123456789012');
|
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||||
expect(core.setSecret).toHaveBeenCalledTimes(0);
|
expect(core.setSecret).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('error is caught by core.setFailed', async () => {
|
test('error is caught by core.setFailed and caught', async () => {
|
||||||
|
process.env.SHOW_STACK_TRACE = 'false';
|
||||||
|
|
||||||
mockStsCallerIdentity.mockImplementation(() => {
|
mockStsCallerIdentity.mockImplementation(() => {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
});
|
});
|
||||||
@@ -92,4 +151,77 @@ describe('Configure AWS Credentials', () => {
|
|||||||
|
|
||||||
expect(core.setFailed).toBeCalled();
|
expect(core.setFailed).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('error is caught by core.setFailed and passed', async () => {
|
||||||
|
|
||||||
|
mockStsCallerIdentity.mockImplementation(() => {
|
||||||
|
throw new Error();
|
||||||
|
});
|
||||||
|
|
||||||
|
await assert.rejects(() => run());
|
||||||
|
|
||||||
|
expect(core.setFailed).toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('basic role assumption exports', async () => {
|
||||||
|
core.getInput = jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
expect(mockStsAssumeRole).toHaveBeenCalledTimes(1);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_STS_ACCESS_KEY_ID);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_STS_SECRET_ACCESS_KEY);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', FAKE_STS_SESSION_TOKEN);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', FAKE_REGION);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', FAKE_REGION);
|
||||||
|
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption tags', async () => {
|
||||||
|
core.getInput = jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||||
|
RoleArn: ROLE_NAME,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 6 * 3600,
|
||||||
|
Tags: [
|
||||||
|
{Key: 'GitHub', Value: 'Actions'},
|
||||||
|
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||||
|
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||||
|
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||||
|
{Key: 'Actor', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTOR},
|
||||||
|
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||||
|
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption duration provided', async () => {
|
||||||
|
core.getInput = jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-duration-seconds': 5}));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||||
|
RoleArn: ROLE_NAME,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 5,
|
||||||
|
Tags: [
|
||||||
|
{Key: 'GitHub', Value: 'Actions'},
|
||||||
|
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||||
|
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||||
|
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||||
|
{Key: 'Actor', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTOR},
|
||||||
|
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||||
|
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user