Skip to content

Commit 45365ac

Browse files
authored
chore: pass fips/dualstack config to regionInfoProvider (#2982)
1 parent 447580b commit 45365ac

File tree

12 files changed

+84
-22
lines changed

12 files changed

+84
-22
lines changed

packages/config-resolver/src/endpointsConfig/resolveEndpointsConfig.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,17 @@ export interface EndpointsResolvedConfig extends Required<EndpointsInputConfig>
5757

5858
export const resolveEndpointsConfig = <T>(
5959
input: T & EndpointsInputConfig & PreviouslyResolved
60-
): T & EndpointsResolvedConfig => ({
61-
...input,
62-
tls: input.tls ?? true,
63-
endpoint: input.endpoint
64-
? normalizeEndpoint({ ...input, endpoint: input.endpoint })
65-
: () => getEndpointFromRegion(input),
66-
isCustomEndpoint: input.endpoint ? true : false,
67-
useDualstackEndpoint: normalizeBoolean(input.useDualstackEndpoint!),
68-
useFipsEndpoint: normalizeBoolean(input.useFipsEndpoint!),
69-
});
60+
): T & EndpointsResolvedConfig => {
61+
const useDualstackEndpoint = normalizeBoolean(input.useDualstackEndpoint!);
62+
const useFipsEndpoint = normalizeBoolean(input.useFipsEndpoint!);
63+
return {
64+
...input,
65+
tls: input.tls ?? true,
66+
endpoint: input.endpoint
67+
? normalizeEndpoint({ ...input, endpoint: input.endpoint })
68+
: () => getEndpointFromRegion({ ...input, useDualstackEndpoint, useFipsEndpoint }),
69+
isCustomEndpoint: input.endpoint ? true : false,
70+
useDualstackEndpoint,
71+
useFipsEndpoint,
72+
};
73+
};

packages/config-resolver/src/endpointsConfig/utils/getEndpointFromRegion.spec.ts

+23-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@ describe(getEndpointFromRegion.name, () => {
44
const mockRegion = jest.fn();
55
const mockUrlParser = jest.fn();
66
const mockRegionInfoProvider = jest.fn();
7+
const mockUseFipsEndpoint = jest.fn();
8+
const mockUseDualstackEndpoint = jest.fn();
79

8-
const mockInput = { region: mockRegion, urlParser: mockUrlParser, regionInfoProvider: mockRegionInfoProvider };
10+
const mockInput = {
11+
region: mockRegion,
12+
urlParser: mockUrlParser,
13+
regionInfoProvider: mockRegionInfoProvider,
14+
useDualstackEndpoint: mockUseDualstackEndpoint,
15+
useFipsEndpoint: mockUseFipsEndpoint,
16+
};
917

1018
const mockRegionValue = "mockRegion";
1119
const mockEndpoint = {
@@ -19,6 +27,8 @@ describe(getEndpointFromRegion.name, () => {
1927
mockRegion.mockResolvedValue(mockRegionValue);
2028
mockUrlParser.mockResolvedValue(mockEndpoint);
2129
mockRegionInfoProvider.mockResolvedValue(mockRegionInfo);
30+
mockUseFipsEndpoint.mockResolvedValue(false);
31+
mockUseDualstackEndpoint.mockResolvedValue(false);
2232
});
2333

2434
afterEach(() => {
@@ -28,7 +38,10 @@ describe(getEndpointFromRegion.name, () => {
2838

2939
describe("tls", () => {
3040
afterEach(() => {
31-
expect(mockRegionInfoProvider).toHaveBeenCalledWith(mockRegionValue);
41+
expect(mockRegionInfoProvider).toHaveBeenCalledWith(mockRegionValue, {
42+
useDualstackEndpoint: false,
43+
useFipsEndpoint: false,
44+
});
3245
});
3346

3447
it("uses protocol https when not defined", async () => {
@@ -81,14 +94,20 @@ describe(getEndpointFromRegion.name, () => {
8194
} catch (error) {
8295
expect(error.message).toEqual(errorMsg);
8396
}
84-
expect(mockRegionInfoProvider).toHaveBeenCalledWith(mockRegionValue);
97+
expect(mockRegionInfoProvider).toHaveBeenCalledWith(mockRegionValue, {
98+
useDualstackEndpoint: false,
99+
useFipsEndpoint: false,
100+
});
85101
expect(mockUrlParser).not.toHaveBeenCalled();
86102
});
87103

88104
it("returns parsed endpoint", async () => {
89105
const endpoint = await getEndpointFromRegion(mockInput);
90106
expect(endpoint).toEqual(mockEndpoint);
91-
expect(mockRegionInfoProvider).toHaveBeenCalledWith(mockRegionValue);
107+
expect(mockRegionInfoProvider).toHaveBeenCalledWith(mockRegionValue, {
108+
useDualstackEndpoint: false,
109+
useFipsEndpoint: false,
110+
});
92111
expect(mockUrlParser).toHaveBeenCalledWith(`https://${mockRegionInfo.hostname}`);
93112
});
94113
});

packages/config-resolver/src/endpointsConfig/utils/getEndpointFromRegion.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ interface GetEndpointFromRegionOptions {
55
tls?: boolean;
66
regionInfoProvider: RegionInfoProvider;
77
urlParser: UrlParser;
8+
useDualstackEndpoint: Provider<boolean>;
9+
useFipsEndpoint: Provider<boolean>;
810
}
911

1012
export const getEndpointFromRegion = async (input: GetEndpointFromRegionOptions) => {
@@ -16,7 +18,9 @@ export const getEndpointFromRegion = async (input: GetEndpointFromRegionOptions)
1618
throw new Error("Invalid region in client config");
1719
}
1820

19-
const { hostname } = (await input.regionInfoProvider(region)) ?? {};
21+
const useDualstackEndpoint = await input.useDualstackEndpoint();
22+
const useFipsEndpoint = await input.useFipsEndpoint();
23+
const { hostname } = (await input.regionInfoProvider(region, { useDualstackEndpoint, useFipsEndpoint })) ?? {};
2024
if (!hostname) {
2125
throw new Error("Cannot resolve hostname from client config");
2226
}

packages/middleware-bucket-endpoint/src/bucketEndpointMiddleware.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ describe("bucketEndpointMiddleware", () => {
3434
.fn()
3535
.mockResolvedValue({ hostname: "foo.us-foo-2.amazonaws.com", partition: "aws-foo", signingRegion: mockRegion }),
3636
useArnRegion: jest.fn().mockResolvedValue(false),
37+
useFipsEndpoint: () => Promise.resolve(false),
3738
useDualstackEndpoint: () => Promise.resolve(false),
3839
};
3940

packages/middleware-bucket-endpoint/src/bucketEndpointMiddleware.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ export const bucketEndpointMiddleware =
3131
} else if (validateArn(bucketName)) {
3232
const bucketArn = parseArn(bucketName);
3333
const clientRegion = getPseudoRegion(await options.region());
34-
const { partition, signingRegion = clientRegion } = (await options.regionInfoProvider(clientRegion)) || {};
34+
const useDualstackEndpoint = await options.useDualstackEndpoint();
35+
const useFipsEndpoint = await options.useFipsEndpoint();
36+
const { partition, signingRegion = clientRegion } =
37+
(await options.regionInfoProvider(clientRegion, { useDualstackEndpoint, useFipsEndpoint })) || {};
3538
const useArnRegion = await options.useArnRegion();
36-
const dualstackEndpoint = await options.useDualstackEndpoint();
3739
const {
3840
hostname,
3941
bucketEndpoint,
@@ -43,7 +45,7 @@ export const bucketEndpointMiddleware =
4345
bucketName: bucketArn,
4446
baseHostname: request.hostname,
4547
accelerateEndpoint: options.useAccelerateEndpoint,
46-
dualstackEndpoint,
48+
dualstackEndpoint: useDualstackEndpoint,
4749
pathStyleEndpoint: options.forcePathStyle,
4850
tlsCompatible: request.protocol === "https:",
4951
useArnRegion,

packages/middleware-bucket-endpoint/src/configurations.ts

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface PreviouslyResolved {
2828
isCustomEndpoint: boolean;
2929
region: Provider<string>;
3030
regionInfoProvider: RegionInfoProvider;
31+
useFipsEndpoint: Provider<boolean>;
3132
useDualstackEndpoint: Provider<boolean>;
3233
}
3334

@@ -49,6 +50,10 @@ export interface BucketEndpointResolvedConfig {
4950
* Resolved value for input config {@link BucketEndpointInputConfig.useAccelerateEndpoint}
5051
*/
5152
useAccelerateEndpoint: boolean;
53+
/**
54+
* Enables FIPS compatible endpoints.
55+
*/
56+
useFipsEndpoint: Provider<boolean>;
5257
/**
5358
* Enables IPv6/IPv4 dualstack endpoint.
5459
*/

packages/middleware-sdk-s3-control/src/configurations.ts

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ interface PreviouslyResolved {
1212
isCustomEndpoint: boolean;
1313
region: Provider<string>;
1414
regionInfoProvider: RegionInfoProvider;
15+
useFipsEndpoint: Provider<boolean>;
1516
useDualstackEndpoint: Provider<boolean>;
1617
}
1718

@@ -21,6 +22,10 @@ export interface S3ControlResolvedConfig {
2122
* @internal
2223
*/
2324
isCustomEndpoint: boolean;
25+
/**
26+
* Enables FIPS compatible endpoints.
27+
*/
28+
useFipsEndpoint: Provider<boolean>;
2429
/**
2530
* Enables IPv6/IPv4 dualstack endpoint.
2631
*/

packages/middleware-sdk-s3-control/src/process-arnables-plugin/parse-outpost-arnables.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ export const parseOutpostArnablesMiddleaware =
3636
if (!parameter) return next(args);
3737

3838
const clientRegion = await options.region();
39-
const { regionInfoProvider } = options;
4039
const useArnRegion = await options.useArnRegion();
40+
const useFipsEndpoint = await options.useFipsEndpoint();
4141
const useDualstackEndpoint = await options.useDualstackEndpoint();
4242
const baseRegion = getPseudoRegion(clientRegion);
43-
const { partition: clientPartition, signingRegion = baseRegion } = (await regionInfoProvider(baseRegion))!;
43+
const { partition: clientPartition, signingRegion = baseRegion } = (await options.regionInfoProvider(baseRegion, {
44+
useFipsEndpoint,
45+
useDualstackEndpoint,
46+
}))!;
4447
const validatorOptions: ValidateOutpostsArnOptions = {
4548
useDualstackEndpoint,
4649
clientRegion,

packages/middleware-sdk-s3-control/src/process-arnables-plugin/plugin.spec.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ describe("getProcessArnablesMiddleware", () => {
1010
region: string;
1111
regionInfoProvider?: Provider<RegionInfo>;
1212
useAccelerateEndpoint?: boolean;
13+
useFipsEndpoint?: Provider<boolean>;
1314
useDualstackEndpoint?: Provider<boolean>;
1415
useArnRegion?: boolean;
1516
};
1617
const setupPluginOptions = (options: FakeOptions): S3ControlResolvedConfig => {
1718
return {
19+
useFipsEndpoint: () => Promise.resolve(false),
1820
useDualstackEndpoint: () => Promise.resolve(false),
1921
...options,
2022
regionInfoProvider: options.regionInfoProvider ?? jest.fn().mockResolvedValue({ partition: "aws" }),

packages/middleware-sdk-sts/src/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ import { AwsAuthInputConfig, AwsAuthResolvedConfig, resolveAwsAuthConfig } from
22
import { Client, Credentials, HashConstructor, Pluggable, Provider, RegionInfoProvider } from "@aws-sdk/types";
33

44
export interface StsAuthInputConfig extends AwsAuthInputConfig {}
5+
56
interface PreviouslyResolved {
67
credentialDefaultProvider: (input: any) => Provider<Credentials>;
78
region: string | Provider<string>;
89
regionInfoProvider: RegionInfoProvider;
910
signingName?: string;
1011
serviceId: string;
1112
sha256: HashConstructor;
13+
useFipsEndpoint: Provider<boolean>;
14+
useDualstackEndpoint: Provider<boolean>;
1215
}
16+
1317
export interface StsAuthResolvedConfig extends AwsAuthResolvedConfig {
1418
/**
1519
* Reference to STSClient class constructor.

packages/middleware-signing/src/configuration.spec.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { HttpRequest } from "@aws-sdk/protocol-http";
33
import { resolveAwsAuthConfig, resolveSigV4AuthConfig } from "./configurations";
44

55
describe("AuthConfig", () => {
6-
76
describe("resolveAwsAuthConfig", () => {
87
const inputParams = {
98
credentialDefaultProvider: () => () => Promise.resolve({ accessKeyId: "key", secretAccessKey: "secret" }),
@@ -15,6 +14,8 @@ describe("AuthConfig", () => {
1514
digest: jest.fn().mockReturnValue("SHA256 hash"),
1615
}),
1716
credentials: jest.fn().mockResolvedValue({ accessKeyId: "key", secretAccessKey: "secret" }),
17+
useFipsEndpoint: () => Promise.resolve(false),
18+
useDualstackEndpoint: () => Promise.resolve(false),
1819
};
1920

2021
beforeEach(() => {

packages/middleware-signing/src/configurations.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { memoize } from "@aws-sdk/property-provider";
22
import { SignatureV4, SignatureV4CryptoInit, SignatureV4Init } from "@aws-sdk/signature-v4";
33
import { Credentials, HashConstructor, Provider, RegionInfo, RegionInfoProvider, RequestSigner } from "@aws-sdk/types";
4+
import { options } from "yargs";
45

56
// 5 minutes buffer time the refresh the credential before it really expires
67
const CREDENTIAL_EXPIRE_WINDOW = 300000;
@@ -73,6 +74,8 @@ interface PreviouslyResolved {
7374
signingName?: string;
7475
serviceId: string;
7576
sha256: HashConstructor;
77+
useFipsEndpoint: Provider<boolean>;
78+
useDualstackEndpoint: Provider<boolean>;
7679
}
7780

7881
interface SigV4PreviouslyResolved {
@@ -118,7 +121,16 @@ export const resolveAwsAuthConfig = <T>(
118121
//construct a provider inferring signing from region.
119122
signer = () =>
120123
normalizeProvider(input.region)()
121-
.then(async (region) => [(await input.regionInfoProvider(region)) || {}, region] as [RegionInfo, string])
124+
.then(
125+
async (region) =>
126+
[
127+
(await input.regionInfoProvider(region, {
128+
useFipsEndpoint: await input.useFipsEndpoint(),
129+
useDualstackEndpoint: await input.useDualstackEndpoint(),
130+
})) || {},
131+
region,
132+
] as [RegionInfo, string]
133+
)
122134
.then(([regionInfo, region]) => {
123135
const { signingRegion, signingService } = regionInfo;
124136
//update client's singing region and signing service config if they are resolved.

0 commit comments

Comments
 (0)