Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Aug 2, 2021
2 parents a671778 + 823dfda commit 01921a9
Show file tree
Hide file tree
Showing 92 changed files with 1,885 additions and 642 deletions.
12 changes: 1 addition & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -759,17 +759,7 @@ The pattern is simple:
through `cdk init`.
4. In your PR title (which goes into CHANGELOG), add a `(under feature flag)` suffix. e.g:

```
fix(core): impossible to use the same physical stack name for two stacks (under feature flag)
```
5. Under `BREAKING CHANGES` in your commit message describe this new behavior:
```
BREAKING CHANGE: template file names for new projects created through "cdk init"
will use the template artifact ID instead of the physical stack name to enable
multiple stacks to use the same name. This is enabled through the flag
`@aws-cdk/core:enableStackNameDuplicates` in newly generated `cdk.json` files.
```
`fix(core): impossible to use the same physical stack name for two stacks (under feature flag)`

In the [next major version of the
CDK](https://github.com/aws/aws-cdk/issues/3398) we will either remove the
Expand Down
10 changes: 5 additions & 5 deletions packages/@aws-cdk/assertions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@

Functions for writing test asserting against CDK applications, with focus on CloudFormation templates.

The `TemplateAssertions` class includes a set of methods for writing assertions against CloudFormation templates. Use one of the `TemplateAssertions.fromXxx()` static methods to create an instance of this class.
The `Template` class includes a set of methods for writing assertions against CloudFormation templates. Use one of the `Template.fromXxx()` static methods to create an instance of this class.

To create `TemplateAssertions` from CDK stack, start off with:
To create `Template` from CDK stack, start off with:

```ts
import { Stack } from '@aws-cdk/core';
import { TemplateAssertions } from '@aws-cdk/assertions';
import { Template } from '@aws-cdk/assertions';

const stack = new Stack(...)
...
const assert = TemplateAssertions.fromStack(stack);
const assert = Template.fromStack(stack);
```

Alternatively, assertions can be run on an existing CloudFormation template -

```ts
const template = fs.readFileSync('/path/to/template/file');
const assert = TemplateAssertions.fromString(template);
const assert = Template.fromString(template);
```

## Full Template Match
Expand Down
14 changes: 7 additions & 7 deletions packages/@aws-cdk/assertions/lib/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,31 @@ import * as assert from './vendored/assert';
* Typically used, as part of unit tests, to validate that the rendered
* CloudFormation template has expected resources and properties.
*/
export class TemplateAssertions {
export class Template {

/**
* Base your assertions on the CloudFormation template synthesized by a CDK `Stack`.
* @param stack the CDK Stack to run assertions on
*/
public static fromStack(stack: Stack): TemplateAssertions {
return new TemplateAssertions(toTemplate(stack));
public static fromStack(stack: Stack): Template {
return new Template(toTemplate(stack));
}

/**
* Base your assertions from an existing CloudFormation template formatted as a
* nested set of records.
* @param template the CloudFormation template formatted as a nested set of records
*/
public static fromTemplate(template: { [key: string] : any }): TemplateAssertions {
return new TemplateAssertions(template);
public static fromTemplate(template: { [key: string] : any }): Template {
return new Template(template);
}

/**
* Base your assertions from an existing CloudFormation template formatted as a string.
* @param template the CloudFormation template in
*/
public static fromString(template: string): TemplateAssertions {
return new TemplateAssertions(JSON.parse(template));
public static fromString(template: string): Template {
return new Template(JSON.parse(template));
}

private readonly inspector: assert.StackInspector;
Expand Down
40 changes: 20 additions & 20 deletions packages/@aws-cdk/assertions/test/template.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { CfnResource, Stack } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { Match, TemplateAssertions } from '../lib';
import { Match, Template } from '../lib';

describe('TemplateAssertions', () => {
describe('Template', () => {
describe('fromString', () => {
test('default', () => {
const assertions = TemplateAssertions.fromString(`{
const assertions = Template.fromString(`{
"Resources": {
"Foo": {
"Type": "Baz::Qux",
Expand All @@ -21,7 +21,7 @@ describe('TemplateAssertions', () => {
test('fails when root is not a stage', () => {
const c = new Construct(undefined as any, '');
const stack = new Stack(c, 'MyStack');
expect(() => TemplateAssertions.fromStack(stack)).toThrow(/must be part of a Stage or an App/);
expect(() => Template.fromStack(stack)).toThrow(/must be part of a Stage or an App/);
});
});

Expand All @@ -32,7 +32,7 @@ describe('TemplateAssertions', () => {
type: 'Foo::Bar',
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
inspect.resourceCountIs('Foo::Bar', 1);

expect(() => inspect.resourceCountIs('Foo::Bar', 0)).toThrow(/has 1 resource of type Foo::Bar/);
Expand All @@ -44,7 +44,7 @@ describe('TemplateAssertions', () => {
test('no resource', () => {
const stack = new Stack();

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
inspect.resourceCountIs('Foo::Bar', 0);

expect(() => inspect.resourceCountIs('Foo::Bar', 1)).toThrow(/has 0 resource of type Foo::Bar/);
Expand All @@ -59,7 +59,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
inspect.templateMatches({
Resources: {
Foo: {
Expand All @@ -77,7 +77,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
expect(() => inspect.templateMatches({
Resources: {
Foo: {
Expand All @@ -97,7 +97,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
inspect.hasResource('Foo::Bar', {
Properties: { baz: 'qux' },
});
Expand All @@ -118,7 +118,7 @@ describe('TemplateAssertions', () => {
properties: { baz: ['qux', 'quy'] },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
inspect.hasResource('Foo::Bar', {
Properties: { baz: Match.arrayWith(['qux']) },
});
Expand All @@ -139,7 +139,7 @@ describe('TemplateAssertions', () => {
properties: { flob: ['qux'] },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);

expectToThrow(() => {
inspect.hasResource('Foo::Bar', {
Expand All @@ -157,7 +157,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux', fred: 'waldo' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
inspect.hasResource('Foo::Bar', {
Properties: Match.objectLike({ baz: 'qux' }),
});
Expand All @@ -181,7 +181,7 @@ describe('TemplateAssertions', () => {
properties: { flob: 'waldo' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);

expectToThrow(() => {
inspect.hasResource('Foo::Bar', {
Expand All @@ -199,7 +199,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
inspect.hasResource('Foo::Bar', {
Properties: Match.objectLike({ foo: Match.absentProperty() }),
});
Expand All @@ -215,7 +215,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux', fred: 'waldo' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
expect(() => inspect.hasResource('Foo::Baz', {
Properties: Match.objectLike({ baz: 'qux' }),
})).toThrow(/No resource/);
Expand All @@ -230,7 +230,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux', fred: 'waldo' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
expect(inspect.findResources('Foo::Bar')).toEqual([{
Type: 'Foo::Bar',
Properties: { baz: 'qux', fred: 'waldo' },
Expand All @@ -244,7 +244,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux', fred: 'waldo' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
expect(inspect.findResources('Foo::Baz')).toEqual([]);
});

Expand All @@ -255,7 +255,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux', fred: 'waldo' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
expect(inspect.findResources('Foo::Bar', {
Properties: { baz: 'qux' },
}).length).toEqual(1);
Expand All @@ -268,7 +268,7 @@ describe('TemplateAssertions', () => {
properties: { baz: 'qux', fred: 'waldo' },
});

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
expect(inspect.findResources('Foo::Bar', {
Properties: { baz: 'waldo' },
})).toEqual([]);
Expand All @@ -279,7 +279,7 @@ describe('TemplateAssertions', () => {
new CfnResource(stack, 'Foo', { type: 'Foo::Bar' });
new CfnResource(stack, 'Bar', { type: 'Foo::Bar' });

const inspect = TemplateAssertions.fromStack(stack);
const inspect = Template.fromStack(stack);
expect(inspect.findResources('Foo::Bar').length).toEqual(2);
});
});
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,10 @@ export class GraphqlApi extends GraphqlApiBase {
private validateAuthorizationProps(modes: AuthorizationMode[]) {
modes.map((mode) => {
if (mode.authorizationType === AuthorizationType.OIDC && !mode.openIdConnectConfig) {
throw new Error('Missing default OIDC Configuration');
throw new Error('Missing OIDC Configuration');
}
if (mode.authorizationType === AuthorizationType.USER_POOL && !mode.userPoolConfig) {
throw new Error('Missing default OIDC Configuration');
throw new Error('Missing User Pool Configuration');
}
});
if (modes.filter((mode) => mode.authorizationType === AuthorizationType.API_KEY).length > 1) {
Expand Down
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-cloudfront/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ your domain name, and provide one (or more) domain names from the certificate fo

The certificate must be present in the AWS Certificate Manager (ACM) service in the US East (N. Virginia) region; the certificate
may either be created by ACM, or created elsewhere and imported into ACM. When a certificate is used, the distribution will support HTTPS connections
from SNI only and a minimum protocol version of TLSv1.2_2019.
from SNI only and a minimum protocol version of TLSv1.2_2021 if the '@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021' feature flag is set, and TLSv1.2_2019 otherwise.

```ts
const myCertificate = new acm.DnsValidatedCertificate(this, 'mySiteCert', {
Expand Down Expand Up @@ -590,13 +590,15 @@ new CloudFrontWebDistribution(stack, 'ADistribution', {
originHeaders: {
'myHeader': '42',
},
originShieldRegion: 'us-west-2'
},
failoverS3OriginSource: {
s3BucketSource: s3.Bucket.fromBucketName(stack, 'aBucketFallback', 'myoriginbucketfallback'),
originPath: '/somewhere',
originHeaders: {
'myHeader2': '21',
},
originShieldRegion: 'us-east-1'
},
failoverCriteriaStatusCodes: [FailoverStatusCode.INTERNAL_SERVER_ERROR],
behaviors: [
Expand Down
15 changes: 11 additions & 4 deletions packages/@aws-cdk/aws-cloudfront/lib/distribution.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as acm from '@aws-cdk/aws-certificatemanager';
import * as lambda from '@aws-cdk/aws-lambda';
import * as s3 from '@aws-cdk/aws-s3';
import { IResource, Lazy, Resource, Stack, Token, Duration, Names } from '@aws-cdk/core';
import { IResource, Lazy, Resource, Stack, Token, Duration, Names, FeatureFlags } from '@aws-cdk/core';
import { CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021 } from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
import { ICachePolicy } from './cache-policy';
import { CfnDistribution } from './cloudfront.generated';
Expand Down Expand Up @@ -215,7 +216,7 @@ export interface DistributionProps {
* CloudFront serves your objects only to browsers or devices that support at
* least the SSL version that you specify.
*
* @default SecurityPolicyProtocol.TLS_V1_2_2019
* @default - SecurityPolicyProtocol.TLS_V1_2_2021 if the '@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021' feature flag is set; otherwise, SecurityPolicyProtocol.TLS_V1_2_2019.
*/
readonly minimumProtocolVersion?: SecurityPolicyProtocol;
}
Expand Down Expand Up @@ -446,7 +447,12 @@ export class Distribution extends Resource implements IDistribution {
}

private renderViewerCertificate(certificate: acm.ICertificate,
minimumProtocolVersion: SecurityPolicyProtocol = SecurityPolicyProtocol.TLS_V1_2_2019): CfnDistribution.ViewerCertificateProperty {
minimumProtocolVersionProp?: SecurityPolicyProtocol): CfnDistribution.ViewerCertificateProperty {

const defaultVersion = FeatureFlags.of(this).isEnabled(CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021)
? SecurityPolicyProtocol.TLS_V1_2_2021 : SecurityPolicyProtocol.TLS_V1_2_2019;
const minimumProtocolVersion = minimumProtocolVersionProp ?? defaultVersion;

return {
acmCertificateArn: certificate.certificateArn,
sslSupportMethod: SSLMethod.SNI,
Expand Down Expand Up @@ -531,7 +537,8 @@ export enum SecurityPolicyProtocol {
TLS_V1_2016 = 'TLSv1_2016',
TLS_V1_1_2016 = 'TLSv1.1_2016',
TLS_V1_2_2018 = 'TLSv1.2_2018',
TLS_V1_2_2019 = 'TLSv1.2_2019'
TLS_V1_2_2019 = 'TLSv1.2_2019',
TLS_V1_2_2021 = 'TLSv1.2_2021'
}

/**
Expand Down
21 changes: 21 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/lib/origin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ export interface OriginProps {
* @default {}
*/
readonly customHeaders?: Record<string, string>;

/**
* When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance
*
* @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/origin-shield.html
*
* @default - origin shield not enabled
*/
readonly originShieldRegion?: string;
}

/**
Expand All @@ -106,6 +115,7 @@ export abstract class OriginBase implements IOrigin {
private readonly connectionTimeout?: Duration;
private readonly connectionAttempts?: number;
private readonly customHeaders?: Record<string, string>;
private readonly originShieldRegion?: string

protected constructor(domainName: string, props: OriginProps = {}) {
validateIntInRangeOrUndefined('connectionTimeout', 1, 10, props.connectionTimeout?.toSeconds());
Expand All @@ -116,6 +126,7 @@ export abstract class OriginBase implements IOrigin {
this.connectionTimeout = props.connectionTimeout;
this.connectionAttempts = props.connectionAttempts;
this.customHeaders = props.customHeaders;
this.originShieldRegion = props.originShieldRegion;
}

/**
Expand All @@ -139,6 +150,7 @@ export abstract class OriginBase implements IOrigin {
originCustomHeaders: this.renderCustomHeaders(),
s3OriginConfig,
customOriginConfig,
originShield: this.renderOriginShield(this.originShieldRegion),
},
};
}
Expand Down Expand Up @@ -172,6 +184,15 @@ export abstract class OriginBase implements IOrigin {
if (path.endsWith('/')) { path = path.substr(0, path.length - 1); }
return path;
}

/**
* Takes origin shield region and converts to CfnDistribution.OriginShieldProperty
*/
private renderOriginShield(originShieldRegion?: string): CfnDistribution.OriginShieldProperty | undefined {
return originShieldRegion
? { enabled: true, originShieldRegion }
: undefined;
}
}

/**
Expand Down
Loading

0 comments on commit 01921a9

Please sign in to comment.