mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-09-03 06:05:04 +09:00
Merge pull request #350 from paragbhingre/OIDCParallelRequest
fix: OIDC Parallel Requests error
This commit is contained in:
@@ -236,6 +236,29 @@ function getStsClient(region) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let defaultSleep = function (ms) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
};
|
||||||
|
let sleep = defaultSleep;
|
||||||
|
|
||||||
|
// retryAndBackoff retries with exponential backoff the promise if the error isRetryable upto maxRetries time.
|
||||||
|
const retryAndBackoff = async (fn, isRetryable, retries = 0, maxRetries = 12, base = 50) => {
|
||||||
|
try {
|
||||||
|
return await fn();
|
||||||
|
} catch (err) {
|
||||||
|
if (!isRetryable) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// It's retryable, so sleep and retry.
|
||||||
|
await sleep(Math.random() * (Math.pow(2, retries) * base) );
|
||||||
|
retries += 1;
|
||||||
|
if (retries === maxRetries) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
return await retryAndBackoff(fn, isRetryable, retries, maxRetries, base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
// Get inputs
|
// Get inputs
|
||||||
@@ -303,17 +326,18 @@ async function run() {
|
|||||||
|
|
||||||
// Get role credentials if configured to do so
|
// Get role credentials if configured to do so
|
||||||
if (roleToAssume) {
|
if (roleToAssume) {
|
||||||
const roleCredentials = await assumeRole({
|
const roleCredentials = await retryAndBackoff(
|
||||||
sourceAccountId,
|
async () => { return await assumeRole({
|
||||||
region,
|
sourceAccountId,
|
||||||
roleToAssume,
|
region,
|
||||||
roleExternalId,
|
roleToAssume,
|
||||||
roleDurationSeconds,
|
roleExternalId,
|
||||||
roleSessionName,
|
roleDurationSeconds,
|
||||||
roleSkipSessionTagging,
|
roleSessionName,
|
||||||
webIdentityTokenFile,
|
roleSkipSessionTagging,
|
||||||
webIdentityToken
|
webIdentityTokenFile,
|
||||||
});
|
webIdentityToken
|
||||||
|
}) }, true);
|
||||||
exportCredentials(roleCredentials);
|
exportCredentials(roleCredentials);
|
||||||
// We need to validate the credentials in 2 of our use-cases
|
// We need to validate the credentials in 2 of our use-cases
|
||||||
// First: self-hosted runners. If the GITHUB_ACTIONS environment variable
|
// First: self-hosted runners. If the GITHUB_ACTIONS environment variable
|
||||||
@@ -337,7 +361,14 @@ async function run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = run;
|
exports.withSleep = function (s) {
|
||||||
|
sleep = s;
|
||||||
|
};
|
||||||
|
exports.reset = function () {
|
||||||
|
sleep = defaultSleep;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.run = run
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
|||||||
+23
-1
@@ -1,7 +1,7 @@
|
|||||||
const core = require('@actions/core');
|
const core = require('@actions/core');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const aws = require('aws-sdk');
|
const aws = require('aws-sdk');
|
||||||
const run = require('./index.js');
|
const { run, withSleep, reset } = require('./index.js');
|
||||||
|
|
||||||
jest.mock('@actions/core');
|
jest.mock('@actions/core');
|
||||||
|
|
||||||
@@ -156,10 +156,15 @@ describe('Configure AWS Credentials', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
withSleep(() => {
|
||||||
|
return Promise.resolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
process.env = OLD_ENV;
|
process.env = OLD_ENV;
|
||||||
|
reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('exports env vars', async () => {
|
test('exports env vars', async () => {
|
||||||
@@ -612,6 +617,23 @@ describe('Configure AWS Credentials', () => {
|
|||||||
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_STS_SESSION_TOKEN);
|
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_STS_SESSION_TOKEN);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('role assumption fails after maximun trials using OIDC Provider', async () => {
|
||||||
|
process.env.GITHUB_ACTIONS = 'true';
|
||||||
|
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'test-token';
|
||||||
|
|
||||||
|
core.getInput = jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(mockGetInput({'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION}));
|
||||||
|
|
||||||
|
mockStsAssumeRoleWithWebIdentity.mockReset();
|
||||||
|
mockStsAssumeRoleWithWebIdentity.mockImplementation(() => {
|
||||||
|
throw new Error();
|
||||||
|
});
|
||||||
|
|
||||||
|
await assert.rejects(() => run());
|
||||||
|
expect(mockStsAssumeRoleWithWebIdentity).toHaveBeenCalledTimes(12)
|
||||||
|
});
|
||||||
|
|
||||||
test('role external ID provided', async () => {
|
test('role external ID provided', async () => {
|
||||||
core.getInput = jest
|
core.getInput = jest
|
||||||
.fn()
|
.fn()
|
||||||
|
|||||||
Reference in New Issue
Block a user