Skip to content

Commit

Permalink
Merge branch 'master' into otaviom/appsync-optional-caching-config
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Dec 10, 2021
2 parents e193e58 + f02fcb4 commit 4b27c9e
Show file tree
Hide file tree
Showing 15 changed files with 574 additions and 139 deletions.
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-cognito/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ new cognito.UserPool(this, 'myuserpool', {
});
```

Sending emails through SES requires that SES be configured (as described above) in one of the regions - `us-east-1`, `us-west-1`, or `eu-west-1`.
Sending emails through SES requires that SES be configured (as described above) in a valid SES region.
If the UserPool is being created in a different region, `sesRegion` must be used to specify the correct SES region.

```ts
Expand Down
11 changes: 0 additions & 11 deletions packages/@aws-cdk/aws-cognito/lib/user-pool-email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import { Stack, Token } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { toASCII as punycodeEncode } from 'punycode/';

/**
* The valid Amazon SES configuration regions
*/
const REGIONS = ['us-east-1', 'us-west-2', 'eu-west-1'];

/**
* Configuration for Cognito sending emails via Amazon SES
*/
Expand Down Expand Up @@ -164,12 +159,6 @@ class SESEmail extends UserPoolEmail {
throw new Error('Your stack region cannot be determined so "sesRegion" is required in SESOptions');
}

if (this.options.sesRegion && !REGIONS.includes(this.options.sesRegion)) {
throw new Error(`sesRegion must be one of 'us-east-1', 'us-west-2', 'eu-west-1'. received ${this.options.sesRegion}`);
} else if (!this.options.sesRegion && !REGIONS.includes(region)) {
throw new Error(`Your stack is in ${region}, which is not a SES Region. Please provide a valid value for 'sesRegion'`);
}

let from = this.options.fromEmail;
if (this.options.fromName) {
from = `${this.options.fromName} <${this.options.fromEmail}>`;
Expand Down
40 changes: 0 additions & 40 deletions packages/@aws-cdk/aws-cognito/test/user-pool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1701,48 +1701,8 @@ describe('User Pool', () => {
},
});

});
test('email withSES invalid region throws error', () => {
// GIVEN
const stack = new Stack(undefined, undefined, {
env: {
region: 'us-east-2',
account: '11111111111',
},
});

// WHEN
expect(() => new UserPool(stack, 'Pool', {
email: UserPoolEmail.withSES({
fromEmail: 'mycustomemail@example.com',
fromName: 'My Custom Email',
replyTo: 'reply@example.com',
configurationSetName: 'default',
}),
})).toThrow(/Please provide a valid value/);

});

test('email withSES invalid sesRegion throws error', () => {
// GIVEN
const stack = new Stack(undefined, undefined, {
env: {
account: '11111111111',
},
});

// WHEN
expect(() => new UserPool(stack, 'Pool', {
email: UserPoolEmail.withSES({
sesRegion: 'us-east-2',
fromEmail: 'mycustomemail@example.com',
fromName: 'My Custom Email',
replyTo: 'reply@example.com',
configurationSetName: 'default',
}),
})).toThrow(/sesRegion must be one of/);

});
});

test('device tracking is configured correctly', () => {
Expand Down
9 changes: 8 additions & 1 deletion packages/@aws-cdk/aws-ec2/lib/vpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,13 @@ export interface VpcProps {
* @default - No flow logs.
*/
readonly flowLogs?: { [id: string]: FlowLogOptions }

/**
* The VPC name.
*
* @default this.node.path
*/
readonly vpcName?: string;
}

/**
Expand Down Expand Up @@ -1298,7 +1305,7 @@ export class Vpc extends VpcBase {
this.vpcDefaultSecurityGroup = this.resource.attrDefaultSecurityGroup;
this.vpcIpv6CidrBlocks = this.resource.attrIpv6CidrBlocks;

Tags.of(this).add(NAME_TAG, this.node.path);
Tags.of(this).add(NAME_TAG, props.vpcName || this.node.path);

this.availabilityZones = stack.availabilityZones;

Expand Down
51 changes: 49 additions & 2 deletions packages/@aws-cdk/aws-ec2/test/vpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,55 @@ describe('vpc', () => {
});
}).toThrow(/subnet cannot include mapPublicIpOnLaunch parameter/);
});
test('verify the Default VPC name', () => {
const stack = getTestStack();
const tagName = { Key: 'Name', Value: `${stack.node.path}/VPC` };
new Vpc(stack, 'VPC', {
maxAzs: 1,
subnetConfiguration: [
{
name: 'public',
subnetType: SubnetType.PUBLIC,
},
{
name: 'private',
subnetType: SubnetType.PRIVATE_WITH_NAT,
},
],
});
expect(stack).toCountResources('AWS::EC2::Subnet', 2);
expect(stack).toHaveResource('AWS::EC2::NatGateway');
expect(stack).toHaveResource('AWS::EC2::Subnet', {
MapPublicIpOnLaunch: true,
});
expect(stack).toHaveResource('AWS::EC2::VPC', hasTags([tagName]));
});
test('verify the assigned VPC name passing the "vpcName" prop', () => {
const stack = getTestStack();
const tagNameDefault = { Key: 'Name', Value: `${stack.node.path}/VPC` };
const tagName = { Key: 'Name', Value: 'CustomVPCName' };
new Vpc(stack, 'VPC', {
maxAzs: 1,
subnetConfiguration: [
{
name: 'public',
subnetType: SubnetType.PUBLIC,
},
{
name: 'private',
subnetType: SubnetType.PRIVATE_WITH_NAT,
},
],
vpcName: 'CustomVPCName',
});
expect(stack).toCountResources('AWS::EC2::Subnet', 2);
expect(stack).toHaveResource('AWS::EC2::NatGateway');
expect(stack).toHaveResource('AWS::EC2::Subnet', {
MapPublicIpOnLaunch: true,
});
expect(stack).not.toHaveResource('AWS::EC2::VPC', hasTags([tagNameDefault]));
expect(stack).toHaveResource('AWS::EC2::VPC', hasTags([tagName]));
});
test('maxAZs defaults to 3 if unset', () => {
const stack = getTestStack();
new Vpc(stack, 'VPC');
Expand All @@ -524,8 +573,6 @@ describe('vpc', () => {
DestinationCidrBlock: '0.0.0.0/0',
NatGatewayId: {},
});


});

test('with maxAZs set to 2', () => {
Expand Down
19 changes: 8 additions & 11 deletions packages/@aws-cdk/aws-iam/lib/managed-policy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ArnFormat, IResolveContext, Lazy, Resource, Stack } from '@aws-cdk/core';
import { ArnFormat, Resource, Stack, Arn, Aws } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { IGroup } from './group';
import { CfnManagedPolicy } from './iam.generated';
Expand Down Expand Up @@ -156,16 +156,13 @@ export class ManagedPolicy extends Resource implements IManagedPolicy {
*/
public static fromAwsManagedPolicyName(managedPolicyName: string): IManagedPolicy {
class AwsManagedPolicy implements IManagedPolicy {
public readonly managedPolicyArn = Lazy.uncachedString({
produce(ctx: IResolveContext) {
return Stack.of(ctx.scope).formatArn({
service: 'iam',
region: '', // no region for managed policy
account: 'aws', // the account for a managed policy is 'aws'
resource: 'policy',
resourceName: managedPolicyName,
});
},
public readonly managedPolicyArn = Arn.format({
partition: Aws.PARTITION,
service: 'iam',
region: '', // no region for managed policy
account: 'aws', // the account for a managed policy is 'aws'
resource: 'policy',
resourceName: managedPolicyName,
});
}
return new AwsManagedPolicy();
Expand Down
7 changes: 7 additions & 0 deletions packages/@aws-cdk/aws-iam/test/managed-policy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -614,3 +614,10 @@ describe('managed policy', () => {
});
});
});

test('ARN for two instances of the same AWS Managed Policy is the same', () => {
const mp1 = ManagedPolicy.fromAwsManagedPolicyName('foo/bar');
const mp2 = ManagedPolicy.fromAwsManagedPolicyName('foo/bar');

expect(mp1.managedPolicyArn).toEqual(mp2.managedPolicyArn);
});
14 changes: 10 additions & 4 deletions packages/@aws-cdk/core/lib/arn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,16 @@ export class Arn {
* the 'scope' is attached to. If all ARN pieces are supplied, the supplied scope
* can be 'undefined'.
*/
public static format(components: ArnComponents, stack: Stack): string {
const partition = components.partition ?? stack.partition;
const region = components.region ?? stack.region;
const account = components.account ?? stack.account;
public static format(components: ArnComponents, stack?: Stack): string {
const partition = components.partition ?? stack?.partition;
const region = components.region ?? stack?.region;
const account = components.account ?? stack?.account;

// Catch both 'null' and 'undefined'
if (partition == null || region == null || account == null) {
throw new Error(`Arn.format: partition (${partition}), region (${region}), and account (${account}) must all be passed if stack is not passed.`);
}

const sep = components.sep ?? (components.arnFormat === ArnFormat.COLON_RESOURCE_NAME ? ':' : '/');

const values = [
Expand Down
8 changes: 8 additions & 0 deletions packages/@aws-cdk/core/test/arn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ describe('arn', () => {

});

test('cannot rely on defaults when stack not known', () => {
expect(() =>
Arn.format({
service: 'sqs',
resource: 'myqueuename',
})).toThrow(/must all be passed if stack is not/);
});

test('create from components with specific values for the various components', () => {
const stack = new Stack();

Expand Down
4 changes: 3 additions & 1 deletion packages/aws-cdk-migration/bin/rewrite-imports-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ async function main() {
const files = await glob(arg, { ignore, matchBase: true });
for (const file of files) {
const input = await fs.promises.readFile(file, { encoding: 'utf8' });
const output = rewriteMonoPackageImports(input, 'aws-cdk-lib', file);
const output = rewriteMonoPackageImports(input, 'aws-cdk-lib', file, {
rewriteConstructsImports: true,
});
if (output.trim() !== input.trim()) {
await fs.promises.writeFile(file, output);
}
Expand Down
Loading

0 comments on commit 4b27c9e

Please sign in to comment.