From e7297216c5598798816a07616cf5a19e75fd34d3 Mon Sep 17 00:00:00 2001 From: George Fu Date: Mon, 29 Jan 2024 16:55:47 +0000 Subject: [PATCH] feat(credential-provider-ini): defer other credential providers in ini provider --- .../credential-provider-ini/src/fromIni.ts | 2 +- .../src/resolveAssumeRoleCredentials.ts | 6 ++-- .../src/resolveCredentialSource.spec.ts | 31 ++++++++++++------- .../src/resolveCredentialSource.ts | 15 ++++----- .../src/resolveProcessCredentials.ts | 14 ++++----- .../src/resolveWebIdentityCredentials.ts | 15 ++++----- 6 files changed, 47 insertions(+), 36 deletions(-) diff --git a/packages/credential-provider-ini/src/fromIni.ts b/packages/credential-provider-ini/src/fromIni.ts index 52cc0b8ca80e..f178196698ba 100644 --- a/packages/credential-provider-ini/src/fromIni.ts +++ b/packages/credential-provider-ini/src/fromIni.ts @@ -1,4 +1,4 @@ -import { AssumeRoleWithWebIdentityParams } from "@aws-sdk/credential-provider-web-identity"; +import type { AssumeRoleWithWebIdentityParams } from "@aws-sdk/credential-provider-web-identity"; import type { CredentialProviderOptions } from "@aws-sdk/types"; import { getProfileName, parseKnownFiles, SourceProfileInit } from "@smithy/shared-ini-file-loader"; import type { AwsCredentialIdentity, AwsCredentialIdentityProvider, Pluggable } from "@smithy/types"; diff --git a/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts b/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts index c3fe41d6fa5e..b107c043aab2 100644 --- a/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts +++ b/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts @@ -1,6 +1,6 @@ import { CredentialsProviderError } from "@smithy/property-provider"; import { getProfileName } from "@smithy/shared-ini-file-loader"; -import { ParsedIniData, Profile } from "@smithy/types"; +import { AwsCredentialIdentity, ParsedIniData, Profile } from "@smithy/types"; import { FromIniInit } from "./fromIni"; import { resolveCredentialSource } from "./resolveCredentialSource"; @@ -101,12 +101,12 @@ export const resolveAssumeRoleCredentials = async ( ); } - const sourceCredsProvider = source_profile + const sourceCredsProvider: Promise = source_profile ? resolveProfileData(source_profile, profiles, options, { ...visitedProfiles, [source_profile]: true, }) - : resolveCredentialSource(data.credential_source!, profileName)(options)(); + : (await resolveCredentialSource(data.credential_source!, profileName)(options))(); const params: AssumeRoleParams = { RoleArn: data.role_arn!, diff --git a/packages/credential-provider-ini/src/resolveCredentialSource.spec.ts b/packages/credential-provider-ini/src/resolveCredentialSource.spec.ts index ef5413de5986..5e0923b2f3aa 100644 --- a/packages/credential-provider-ini/src/resolveCredentialSource.spec.ts +++ b/packages/credential-provider-ini/src/resolveCredentialSource.spec.ts @@ -1,25 +1,25 @@ +jest.mock("@aws-sdk/credential-provider-env"); +jest.mock("@smithy/credential-provider-imds"); + import { fromEnv } from "@aws-sdk/credential-provider-env"; import { fromContainerMetadata, fromInstanceMetadata } from "@smithy/credential-provider-imds"; import { CredentialsProviderError } from "@smithy/property-provider"; import { resolveCredentialSource } from "./resolveCredentialSource"; -jest.mock("@aws-sdk/credential-provider-env"); -jest.mock("@smithy/credential-provider-imds"); - describe(resolveCredentialSource.name, () => { const mockProfileName = "mockProfileName"; - const mockCreds = { - accessKeyId: "mockAccessKeyId", - secretAccessKey: "mockSecretAccessKey", - }; - const mockFakeCreds = { accessKeyId: "mockFakeAccessKeyId", secretAccessKey: "mockFakeSecretAccessKey", }; + const mockCreds = { + accessKeyId: "mockAccessKeyId", + secretAccessKey: "mockSecretAccessKey", + }; + beforeEach(() => { (fromEnv as jest.Mock).mockReturnValue(() => Promise.resolve(mockFakeCreds)); (fromContainerMetadata as jest.Mock).mockReturnValue(() => Promise.resolve(mockFakeCreds)); @@ -36,9 +36,16 @@ describe(resolveCredentialSource.name, () => { ["Environment", fromEnv], ])("when credentialSource=%s, calls %p", async (credentialSource, fromFn) => { (fromFn as jest.Mock).mockReturnValue(() => Promise.resolve(mockCreds)); - const receivedCreds = await resolveCredentialSource(credentialSource, mockProfileName)()(); + const providerFactory = resolveCredentialSource(credentialSource, mockProfileName); + expect(typeof providerFactory).toEqual("function"); + + const provider = await providerFactory(); + expect(typeof provider).toEqual("function"); + + const receivedCreds = await provider(); expect(receivedCreds).toStrictEqual(mockCreds); - expect(fromFn).toHaveBeenCalledWith(); + + expect(fromFn).toHaveBeenCalled(); [fromContainerMetadata, fromInstanceMetadata, fromEnv] .filter((fn) => fn !== fromFn) .forEach((fnNotCalled) => { @@ -53,7 +60,9 @@ describe(resolveCredentialSource.name, () => { `expected EcsContainer or Ec2InstanceMetadata or Environment.` ); try { - await resolveCredentialSource(mockCredentialSource, mockProfileName)()(); + await ( + await resolveCredentialSource(mockCredentialSource, mockProfileName)() + )(); fail(`expected ${expectedError}`); } catch (error) { expect(error).toStrictEqual(expectedError); diff --git a/packages/credential-provider-ini/src/resolveCredentialSource.ts b/packages/credential-provider-ini/src/resolveCredentialSource.ts index 496c8e09c8f2..0e1f69af1c0d 100644 --- a/packages/credential-provider-ini/src/resolveCredentialSource.ts +++ b/packages/credential-provider-ini/src/resolveCredentialSource.ts @@ -1,6 +1,4 @@ -import { fromEnv } from "@aws-sdk/credential-provider-env"; import type { CredentialProviderOptions } from "@aws-sdk/types"; -import { fromContainerMetadata, fromInstanceMetadata } from "@smithy/credential-provider-imds"; import { CredentialsProviderError } from "@smithy/property-provider"; import { AwsCredentialIdentityProvider } from "@smithy/types"; @@ -16,11 +14,14 @@ import { AwsCredentialIdentityProvider } from "@smithy/types"; export const resolveCredentialSource = ( credentialSource: string, profileName: string -): ((options?: CredentialProviderOptions) => AwsCredentialIdentityProvider) => { - const sourceProvidersMap: Record AwsCredentialIdentityProvider> = { - EcsContainer: fromContainerMetadata, - Ec2InstanceMetadata: fromInstanceMetadata, - Environment: fromEnv, +): ((options?: CredentialProviderOptions) => Promise) => { + const sourceProvidersMap = { + EcsContainer: (options?: CredentialProviderOptions) => + import("@smithy/credential-provider-imds").then(({ fromContainerMetadata }) => fromContainerMetadata(options)), + Ec2InstanceMetadata: (options?: CredentialProviderOptions) => + import("@smithy/credential-provider-imds").then(({ fromInstanceMetadata }) => fromInstanceMetadata(options)), + Environment: (options?: CredentialProviderOptions) => + import("@aws-sdk/credential-provider-env").then(({ fromEnv }) => fromEnv(options)), }; if (credentialSource in sourceProvidersMap) { return sourceProvidersMap[credentialSource]; diff --git a/packages/credential-provider-ini/src/resolveProcessCredentials.ts b/packages/credential-provider-ini/src/resolveProcessCredentials.ts index 26bbef43a8cf..152f9db5d11a 100644 --- a/packages/credential-provider-ini/src/resolveProcessCredentials.ts +++ b/packages/credential-provider-ini/src/resolveProcessCredentials.ts @@ -1,6 +1,4 @@ -import { fromProcess } from "@aws-sdk/credential-provider-process"; -import { Credentials } from "@aws-sdk/types"; -import { Profile } from "@smithy/types"; +import { Credentials, Profile } from "@aws-sdk/types"; import { FromIniInit } from "./fromIni"; @@ -21,7 +19,9 @@ export const isProcessProfile = (arg: any): arg is ProcessProfile => * @internal */ export const resolveProcessCredentials = async (options: FromIniInit, profile: string): Promise => - fromProcess({ - ...options, - profile, - })(); + import("@aws-sdk/credential-provider-process").then(({ fromProcess }) => + fromProcess({ + ...options, + profile, + })() + ); diff --git a/packages/credential-provider-ini/src/resolveWebIdentityCredentials.ts b/packages/credential-provider-ini/src/resolveWebIdentityCredentials.ts index 5a59d03c353c..f55a9c34a12e 100644 --- a/packages/credential-provider-ini/src/resolveWebIdentityCredentials.ts +++ b/packages/credential-provider-ini/src/resolveWebIdentityCredentials.ts @@ -1,4 +1,3 @@ -import { fromTokenFile } from "@aws-sdk/credential-provider-web-identity"; import { AwsCredentialIdentity, Profile } from "@smithy/types"; import { FromIniInit } from "./fromIni"; @@ -29,9 +28,11 @@ export const resolveWebIdentityCredentials = async ( profile: WebIdentityProfile, options: FromIniInit ): Promise => - fromTokenFile({ - webIdentityTokenFile: profile.web_identity_token_file, - roleArn: profile.role_arn, - roleSessionName: profile.role_session_name, - roleAssumerWithWebIdentity: options.roleAssumerWithWebIdentity, - })(); + import("@aws-sdk/credential-provider-web-identity").then(({ fromTokenFile }) => + fromTokenFile({ + webIdentityTokenFile: profile.web_identity_token_file, + roleArn: profile.role_arn, + roleSessionName: profile.role_session_name, + roleAssumerWithWebIdentity: options.roleAssumerWithWebIdentity, + })() + );