Skip to content

Commit e19e206

Browse files
authored
See CHANGELOG
2 parents d0dfe79 + 49f7537 commit e19e206

File tree

6 files changed

+77
-16
lines changed

6 files changed

+77
-16
lines changed

Diff for: CHANGELOG.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
## [1.32.2](https://github.com/aws/aws-cdk/compare/v1.32.1...v1.32.2) (2020-04-10)
6+
7+
### Bug Fixes
8+
9+
* **cli:** profile AssumeRole credentials don't work via proxy ([#7292](https://github.com/aws/aws-cdk/pull/7292))
10+
511
## [1.32.1](https://github.com/aws/aws-cdk/compare/v1.32.0...v1.32.1) (2020-04-09)
612

713

@@ -28,7 +34,7 @@ code provider. The props `repository`, `accessToken` and `oauthToken` do not exi
2834
anymore in `AppProps`.
2935
* **kinesis:** `retentionPeriodHours` is now `retentionPeriod` and of type `Duration`
3036
* **eks:** `Cluster` now creates a default managed nodegroup as its default capacity. Set the new cluster property `defaultCapacityType` to `DefaultCapacityType.EC2` to preserve `EC2` as its default capacity.
31-
* **cognito:** `add*Trigger()` methods to configure
37+
* **cognito:** `add*Trigger()` methods to configure
3238
lambda triggers has now been replaced by a single
3339
`addTrigger()` method.
3440
* **cognito:** `addTrigger()` method will fail if a trigger

Diff for: lerna.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
"tools/*"
1111
],
1212
"rejectCycles": "true",
13-
"version": "1.32.1"
13+
"version": "1.32.2"
1414
}

Diff for: packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ export class AwsCliCompatible {
3030
* 3. Respects $AWS_SHARED_CREDENTIALS_FILE.
3131
* 4. Respects $AWS_DEFAULT_PROFILE in addition to $AWS_PROFILE.
3232
*/
33-
public static async credentialChain(profile: string | undefined, ec2creds: boolean | undefined, containerCreds: boolean | undefined) {
33+
public static async credentialChain(
34+
profile: string | undefined,
35+
ec2creds: boolean | undefined,
36+
containerCreds: boolean | undefined,
37+
httpOptions: AWS.HTTPOptions | undefined) {
3438
await forceSdkToReadConfigIfPresent();
3539

3640
profile = profile || process.env.AWS_PROFILE || process.env.AWS_DEFAULT_PROFILE || 'default';
@@ -41,11 +45,11 @@ export class AwsCliCompatible {
4145
];
4246

4347
if (await fs.pathExists(credentialsFileName())) {
44-
sources.push(() => new AWS.SharedIniFileCredentials({ profile, filename: credentialsFileName() }));
48+
sources.push(() => new AWS.SharedIniFileCredentials({ profile, filename: credentialsFileName(), httpOptions }));
4549
}
4650

4751
if (await fs.pathExists(configFileName())) {
48-
sources.push(() => new AWS.SharedIniFileCredentials({ profile, filename: credentialsFileName() }));
52+
sources.push(() => new AWS.SharedIniFileCredentials({ profile, filename: credentialsFileName(), httpOptions }));
4953
}
5054

5155
if (containerCreds ?? hasEcsCredentials()) {

Diff for: packages/aws-cdk/lib/api/aws-auth/sdk-provider.ts

+13-10
Original file line numberDiff line numberDiff line change
@@ -88,23 +88,23 @@ export class SdkProvider {
8888
* class `AwsCliCompatible` for the details.
8989
*/
9090
public static async withAwsCliCompatibleDefaults(options: SdkProviderOptions = {}) {
91-
const chain = await AwsCliCompatible.credentialChain(options.profile, options.ec2creds, options.containerCreds);
91+
const sdkOptions = parseHttpOptions(options.httpOptions ?? {});
92+
93+
const chain = await AwsCliCompatible.credentialChain(options.profile, options.ec2creds, options.containerCreds, sdkOptions.httpOptions);
9294
const region = await AwsCliCompatible.region(options.profile);
9395

94-
return new SdkProvider(chain, region, options.httpOptions);
96+
return new SdkProvider(chain, region, sdkOptions);
9597
}
9698

9799
private readonly plugins = new CredentialPlugins();
98-
private readonly httpOptions: ConfigurationOptions;
99100

100101
public constructor(
101102
private readonly defaultChain: AWS.CredentialProviderChain,
102103
/**
103104
* Default region
104105
*/
105106
public readonly defaultRegion: string,
106-
httpOptions: SdkHttpOptions = {}) {
107-
this.httpOptions = defaultHttpOptions(httpOptions);
107+
private readonly sdkOptions: ConfigurationOptions = {}) {
108108
}
109109

110110
/**
@@ -116,7 +116,7 @@ export class SdkProvider {
116116
public async forEnvironment(accountId: string | undefined, region: string | undefined, mode: Mode): Promise<ISDK> {
117117
const env = await this.resolveEnvironment(accountId, region);
118118
const creds = await this.obtainCredentials(env.account, mode);
119-
return new SDK(creds, env.region, this.httpOptions);
119+
return new SDK(creds, env.region, this.sdkOptions);
120120
}
121121

122122
/**
@@ -139,12 +139,12 @@ export class SdkProvider {
139139
},
140140
stsConfig: {
141141
region,
142-
...this.httpOptions,
142+
...this.sdkOptions,
143143
},
144144
masterCredentials: await this.defaultCredentials(),
145145
});
146146

147-
return new SDK(creds, region, this.httpOptions);
147+
return new SDK(creds, region, this.sdkOptions);
148148
}
149149

150150
/**
@@ -199,7 +199,7 @@ export class SdkProvider {
199199
throw new Error('Unable to resolve AWS credentials (setup with "aws configure")');
200200
}
201201

202-
return new SDK(creds, this.defaultRegion, this.httpOptions).currentAccount();
202+
return new SDK(creds, this.defaultRegion, this.sdkOptions).currentAccount();
203203
} catch (e) {
204204
debug('Unable to determine the default AWS account:', e);
205205
return undefined;
@@ -269,8 +269,11 @@ export interface Account {
269269
* Get HTTP options for the SDK
270270
*
271271
* Read from user input or environment variables.
272+
*
273+
* Returns a complete `ConfigurationOptions` object because that's where
274+
* `customUserAgent` lives, but `httpOptions` is the most important attribute.
272275
*/
273-
function defaultHttpOptions(options: SdkHttpOptions) {
276+
function parseHttpOptions(options: SdkHttpOptions) {
274277
const config: ConfigurationOptions = {};
275278
config.httpOptions = {};
276279

Diff for: packages/aws-cdk/test/api/sdk-provider.test.ts

+48
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ beforeEach(() => {
3434
[foo]
3535
aws_access_key_id=${uid}fooccess
3636
aws_secret_access_key=secret
37+
38+
[assumer]
39+
aws_access_key_id=${uid}assumer
40+
aws_secret_access_key=secret
3741
`),
3842
'/home/me/.bxt/config': dedent(`
3943
[default]
@@ -46,6 +50,13 @@ beforeEach(() => {
4650
aws_access_key_id=${uid}booccess
4751
aws_secret_access_key=boocret
4852
# No region here
53+
54+
[profile assumable]
55+
role_arn=arn:aws:iam::12356789012:role/Assumable
56+
source_profile=assumer
57+
58+
[profile assumer]
59+
region=us-east-2
4960
`),
5061
});
5162

@@ -138,6 +149,43 @@ describe('CLI compatible credentials loading', () => {
138149

139150
await expect(provider.forEnvironment(`${uid}some_account_#`, 'def', Mode.ForReading)).rejects.toThrow('Need to perform AWS calls');
140151
});
152+
153+
test('even when using a profile to assume another profile, STS calls goes through the proxy', async () => {
154+
// Messy mocking
155+
let called = false;
156+
jest.mock('proxy-agent', () => {
157+
// eslint-disable-next-line @typescript-eslint/no-require-imports
158+
class FakeAgent extends require('https').Agent {
159+
public addRequest(_: any, __: any) {
160+
// FIXME: this error takes 6 seconds to be completely handled. It
161+
// might be retries in the SDK somewhere, or something about the Node
162+
// event loop. I've spent an hour trying to figure it out and I can't,
163+
// and I gave up. We'll just have to live with this until someone gets
164+
// inspired.
165+
const error = new Error('ABORTED BY TEST');
166+
(error as any).code = 'RequestAbortedError';
167+
(error as any).retryable = false;
168+
called = true;
169+
throw error;
170+
}
171+
}
172+
return FakeAgent;
173+
});
174+
175+
// WHEN
176+
const provider = await SdkProvider.withAwsCliCompatibleDefaults({ ...defaultCredOptions,
177+
ec2creds: false,
178+
profile: 'assumable',
179+
httpOptions: {
180+
proxyAddress: 'http://DOESNTMATTER/',
181+
}
182+
});
183+
184+
await provider.defaultAccount();
185+
186+
// THEN -- the fake proxy agent got called, we don't care about the result
187+
expect(called).toEqual(true);
188+
});
141189
});
142190

143191
describe('Plugins', () => {

Diff for: packages/aws-cdk/test/util/mock-sdk.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class MockSdkProvider extends SdkProvider {
1212
private readonly sdk: ISDK;
1313

1414
constructor() {
15-
super(new AWS.CredentialProviderChain([]), 'bermuda-triangle-1337', { userAgent: 'aws-cdk/jest' });
15+
super(new AWS.CredentialProviderChain([]), 'bermuda-triangle-1337', { customUserAgent: 'aws-cdk/jest' });
1616

1717
// SDK contains a real SDK, since some test use 'AWS-mock' to replace the underlying
1818
// AWS calls which a real SDK would do, and some tests use the 'stub' functionality below.

0 commit comments

Comments
 (0)