From 9acb952c4c9d8b21217535fdbdf76792fbdbb1f5 Mon Sep 17 00:00:00 2001 From: Andre Fuentes Date: Thu, 27 Feb 2025 15:12:33 -0600 Subject: [PATCH] adding 3 retries with 3 second delay for core.getIDToken and added jwt test case --- dist/index.js | 29 ++++++++++++++++++++++++++++- src/auth.js | 29 ++++++++++++++++++++++++++++- src/auth.test.js | 20 ++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 56af7b14..83c1c874 100644 --- a/dist/index.js +++ b/dist/index.js @@ -18847,7 +18847,10 @@ async function retrieveToken(method, client) { const githubAudience = core.getInput('jwtGithubAudience', { required: false }); if (!privateKey) { - jwt = await core.getIDToken(githubAudience) + jwt = await retryAsyncFunction( 3, 3000, core.getIDToken, githubAudience) + .then((result) => { + return result; + }); } else { jwt = generateJwt(privateKey, keyPassword, Number(tokenTtl)); } @@ -18954,6 +18957,30 @@ async function getClientToken(client, method, path, payload) { } } +/*** + * Generic function for retrying an async function + * @param {number} retries + * @param {number} delay milliseconds + * @param {Function} func + * @param {any[]} args + */ +async function retryAsyncFunction(retries, delay, func, ...args) { + let attempt = 0; + while (attempt < retries) { + try { + const result = await func(...args); + return result; + } catch (error) { + attempt++; + if (attempt < retries) { + await new Promise(resolve => setTimeout(resolve, delay)); + } else { + throw error; + } + } + } +} + /*** * @typedef {Object} VaultLoginResponse * @property {{ diff --git a/src/auth.js b/src/auth.js index 630ad1ec..329c9158 100644 --- a/src/auth.js +++ b/src/auth.js @@ -35,7 +35,10 @@ async function retrieveToken(method, client) { const githubAudience = core.getInput('jwtGithubAudience', { required: false }); if (!privateKey) { - jwt = await core.getIDToken(githubAudience) + jwt = await retryAsyncFunction( 3, 3000, core.getIDToken, githubAudience) + .then((result) => { + return result; + }); } else { jwt = generateJwt(privateKey, keyPassword, Number(tokenTtl)); } @@ -142,6 +145,30 @@ async function getClientToken(client, method, path, payload) { } } +/*** + * Generic function for retrying an async function + * @param {number} retries + * @param {number} delay milliseconds + * @param {Function} func + * @param {any[]} args + */ +async function retryAsyncFunction(retries, delay, func, ...args) { + let attempt = 0; + while (attempt < retries) { + try { + const result = await func(...args); + return result; + } catch (error) { + attempt++; + if (attempt < retries) { + await new Promise(resolve => setTimeout(resolve, delay)); + } else { + throw error; + } + } + } +} + /*** * @typedef {Object} VaultLoginResponse * @property {{ diff --git a/src/auth.test.js b/src/auth.test.js index ac689d3c..3525f99e 100644 --- a/src/auth.test.js +++ b/src/auth.test.js @@ -85,4 +85,24 @@ describe("test retrival for token", () => { const url = got.post.mock.calls[0][0] expect(url).toContain('differentK8sPath') }) + + it("test retrieval with jwt", async () => { + const method = "jwt" + const jwtToken = "someTestToken" + const testRole = "testRole" + const privateKeyRaw = "" + + mockApiResponse() + mockInput("role", testRole) + mockInput("jwtPrivateKey", privateKeyRaw) + core.getIDToken = jest.fn() + core.getIDToken.mockReturnValueOnce(jwtToken) + const token = await retrieveToken(method, got) + expect(token).toEqual(testToken) + const payload = got.post.mock.calls[0][1].json + expect(payload).toEqual({ jwt: jwtToken, role: testRole }) + const url = got.post.mock.calls[0][0] + expect(url).toContain('jwt') + }) + })