Skip to content

Commit 95cbda4

Browse files
authored
Merge branch 'master' into huijbers/cli-default-profile
2 parents f6ccdf0 + 9098e29 commit 95cbda4

File tree

16 files changed

+471
-60
lines changed

16 files changed

+471
-60
lines changed

packages/@aws-cdk/aws-appsync/lib/private.ts

+94-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
function concatAndDedup<T>(left: T[], right: T[]): T[] {
2-
return left.concat(right).filter((elem, index, self) => {
3-
return index === self.indexOf(elem);
4-
});
5-
}
1+
import { Directive } from './schema-base';
2+
import { InterfaceType } from './schema-intermediate';
63

74
/**
85
* Utility enum for Schema class
@@ -12,6 +9,69 @@ export enum SchemaMode {
129
CODE = 'CODE',
1310
};
1411

12+
/**
13+
* Generates an addition to the schema
14+
*
15+
* ```
16+
* prefix name interfaces directives {
17+
* field
18+
* field
19+
* ...
20+
* }
21+
* ```
22+
*/
23+
export interface SchemaAdditionOptions {
24+
/**
25+
* the prefix for this additon (type, interface, enum, input, schema)
26+
*/
27+
readonly prefix: string;
28+
/**
29+
* the name for this addition (some additions dont need this [i.e. schema])
30+
*
31+
* @default - no name
32+
*/
33+
readonly name?: string;
34+
/**
35+
* the interface types if this is creating an object type
36+
*
37+
* @default - no interfaces
38+
*/
39+
readonly interfaceTypes?: InterfaceType[];
40+
/**
41+
* the directives for this type
42+
*
43+
* @default - no directives
44+
*/
45+
readonly directives?: Directive[];
46+
/**
47+
* the fields to reduce onto the addition
48+
*/
49+
readonly fields: string[];
50+
}
51+
52+
/**
53+
* Generates an addition to the schema
54+
*
55+
* @param options the options to produced a stringfied addition
56+
*
57+
* @returns the following shape:
58+
*
59+
* ```
60+
* prefix name interfaces directives {
61+
* field
62+
* field
63+
* ...
64+
* }
65+
* ```
66+
*/
67+
export function shapeAddition(options: SchemaAdditionOptions): string {
68+
const typeName = (): string => { return options.name ? ` ${options.name}` : ''; };
69+
const interfaces = generateInterfaces(options.interfaceTypes);
70+
const directives = generateDirectives(options.directives);
71+
return options.fields.reduce((acc, field) =>
72+
`${acc} ${field}\n`, `${options.prefix}${typeName()}${interfaces}${directives} {\n`) + '}';
73+
}
74+
1575
/**
1676
* Utility class to represent DynamoDB key conditions.
1777
*/
@@ -118,4 +178,33 @@ export class Between extends BaseKeyCondition {
118178
public args(): string[] {
119179
return [this.arg1, this.arg2];
120180
}
181+
}
182+
183+
function concatAndDedup<T>(left: T[], right: T[]): T[] {
184+
return left.concat(right).filter((elem, index, self) => {
185+
return index === self.indexOf(elem);
186+
});
187+
}
188+
189+
/**
190+
* Utility function to generate interfaces for object types
191+
*
192+
* @param interfaceTypes the interfaces this object type implements
193+
*/
194+
function generateInterfaces(interfaceTypes?: InterfaceType[]): string {
195+
if (!interfaceTypes || interfaceTypes.length === 0) return '';
196+
return interfaceTypes.reduce((acc, interfaceType) =>
197+
`${acc} ${interfaceType.name},`, ' implements').slice(0, -1);
198+
}
199+
200+
/**
201+
* Utility function to generate directives
202+
*
203+
* @param directives the directives of a given type
204+
* @param delimiter the separator betweeen directives (by default we will add a space)
205+
*/
206+
function generateDirectives(directives?: Directive[], delimiter?: string): string {
207+
if (!directives || directives.length === 0) return '';
208+
return directives.reduce((acc, directive) =>
209+
`${acc}${directive.statement}${delimiter ?? ' '}`, ' ').slice(0, -1);
121210
}

packages/@aws-cdk/aws-appsync/lib/schema-intermediate.ts

+13-37
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { shapeAddition } from './private';
12
import { Resolver } from './resolver';
23
import { Directive, IField, IIntermediateType } from './schema-base';
34
import { BaseTypeOptions, GraphqlType, ResolvableFieldOptions } from './schema-field';
@@ -59,13 +60,12 @@ export class InterfaceType implements IIntermediateType {
5960
* Generate the string of this object type
6061
*/
6162
public toString(): string {
62-
let schemaAddition = `interface ${this.name} {\n`;
63-
Object.keys(this.definition).forEach( (key) => {
64-
const attribute = this.definition[key];
65-
const args = attribute.argsToString();
66-
schemaAddition = `${schemaAddition} ${key}${args}: ${attribute.toString()}\n`;
63+
return shapeAddition({
64+
prefix: 'interface',
65+
name: this.name,
66+
fields: Object.keys(this.definition).map((key) =>
67+
`${key}${this.definition[key].argsToString()}: ${this.definition[key].toString()}`),
6768
});
68-
return `${schemaAddition}}`;
6969
}
7070

7171
/**
@@ -159,38 +159,14 @@ export class ObjectType extends InterfaceType implements IIntermediateType {
159159
* Generate the string of this object type
160160
*/
161161
public toString(): string {
162-
let title = this.name;
163-
if (this.interfaceTypes && this.interfaceTypes.length) {
164-
title = `${title} implements`;
165-
this.interfaceTypes.map((interfaceType) => {
166-
title = `${title} ${interfaceType.name},`;
167-
});
168-
title = title.slice(0, -1);
169-
}
170-
const directives = this.generateDirectives(this.directives);
171-
let schemaAddition = `type ${title} ${directives}{\n`;
172-
Object.keys(this.definition).forEach( (key) => {
173-
const attribute = this.definition[key];
174-
const args = attribute.argsToString();
175-
schemaAddition = `${schemaAddition} ${key}${args}: ${attribute.toString()}\n`;
176-
});
177-
return `${schemaAddition}}`;
178-
}
179-
180-
/**
181-
* Utility function to generate directives
182-
*
183-
* @param directives the directives of a given type
184-
* @param delimiter the separator betweeen directives
185-
* @default - ' '
186-
*/
187-
private generateDirectives(directives?: Directive[], delimiter?: string): string {
188-
let schemaAddition = '';
189-
if (!directives) { return schemaAddition; }
190-
directives.map((directive) => {
191-
schemaAddition = `${schemaAddition}${directive.statement}${delimiter ?? ' '}`;
162+
return shapeAddition({
163+
prefix: 'type',
164+
name: this.name,
165+
interfaceTypes: this.interfaceTypes,
166+
directives: this.directives,
167+
fields: Object.keys(this.definition).map((key) =>
168+
`${key}${this.definition[key].argsToString()}: ${this.definition[key].toString()}`),
192169
});
193-
return schemaAddition;
194170
}
195171

196172
/**

packages/@aws-cdk/aws-cloudfront/README.md

+14-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ new cloudfront.Distribution(this, 'myDist', {
8282
});
8383
```
8484

85-
## From an HTTP endpoint
85+
#### From an HTTP endpoint
8686

8787
Origins can also be created from any other HTTP endpoint, given the domain name, and optionally, other origin properties.
8888

@@ -246,6 +246,18 @@ new cloudfront.Distribution(this, 'myDist', {
246246
});
247247
```
248248

249+
### Importing Distributions
250+
251+
Existing distributions can be imported as well; note that like most imported constructs, an imported distribution cannot be modified.
252+
However, it can be used as a reference for other higher-level constructs.
253+
254+
```ts
255+
const distribution = cloudfront.Distribution.fromDistributionAttributes(scope, 'ImportedDist', {
256+
domainName: 'd111111abcdef8.cloudfront.net',
257+
distributionId: '012345ABCDEF',
258+
});
259+
```
260+
249261
## CloudFrontWebDistribution API - Stable
250262

251263
![cdk-constructs: Stable](https://img.shields.io/badge/cdk--constructs-stable-success.svg?style=for-the-badge)
@@ -305,7 +317,7 @@ Example:
305317

306318
[create a distrubution with an iam certificate example](test/example.iam-cert-alias.lit.ts)
307319

308-
#### Restrictions
320+
### Restrictions
309321

310322
CloudFront supports adding restrictions to your distribution.
311323

packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import * as iam from '@aws-cdk/aws-iam';
12
import { CfnDistribution } from '../cloudfront.generated';
2-
import { AddBehaviorOptions, ViewerProtocolPolicy } from '../distribution';
3+
import { AddBehaviorOptions, EdgeLambda, ViewerProtocolPolicy } from '../distribution';
34

45
/**
56
* Properties for specifying custom behaviors for origins.
@@ -24,6 +25,8 @@ export class CacheBehavior {
2425

2526
constructor(originId: string, private readonly props: CacheBehaviorProps) {
2627
this.originId = originId;
28+
29+
this.grantEdgeLambdaFunctionExecutionRole(props.edgeLambdas);
2730
}
2831

2932
/**
@@ -55,4 +58,17 @@ export class CacheBehavior {
5558
: undefined,
5659
};
5760
}
61+
62+
private grantEdgeLambdaFunctionExecutionRole(edgeLambdas?: EdgeLambda[]) {
63+
if (!edgeLambdas || edgeLambdas.length === 0) { return; }
64+
edgeLambdas.forEach((edgeLambda) => {
65+
const role = edgeLambda.functionVersion.role;
66+
if (role && role instanceof iam.Role && role.assumeRolePolicy) {
67+
role.assumeRolePolicy.addStatements(new iam.PolicyStatement({
68+
actions: ['sts:AssumeRole'],
69+
principals: [new iam.ServicePrincipal('edgelambda.amazonaws.com')],
70+
}));
71+
}
72+
});
73+
}
5874
}

packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts

+40
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,27 @@ interface BehaviorWithOrigin extends Behavior {
628628
readonly targetOriginId: string;
629629
}
630630

631+
/**
632+
* Attributes used to import a Distribution.
633+
*
634+
* @experimental
635+
*/
636+
export interface CloudFrontWebDistributionAttributes {
637+
/**
638+
* The generated domain name of the Distribution, such as d111111abcdef8.cloudfront.net.
639+
*
640+
* @attribute
641+
*/
642+
readonly domainName: string;
643+
644+
/**
645+
* The distribution ID for this distribution.
646+
*
647+
* @attribute
648+
*/
649+
readonly distributionId: string;
650+
}
651+
631652
/**
632653
* Amazon CloudFront is a global content delivery network (CDN) service that securely delivers data, videos,
633654
* applications, and APIs to your viewers with low latency and high transfer speeds.
@@ -659,6 +680,25 @@ interface BehaviorWithOrigin extends Behavior {
659680
* @resource AWS::CloudFront::Distribution
660681
*/
661682
export class CloudFrontWebDistribution extends cdk.Resource implements IDistribution {
683+
684+
/**
685+
* Creates a construct that represents an external (imported) distribution.
686+
*/
687+
public static fromDistributionAttributes(scope: cdk.Construct, id: string, attrs: CloudFrontWebDistributionAttributes): IDistribution {
688+
return new class extends cdk.Resource implements IDistribution {
689+
public readonly domainName: string;
690+
public readonly distributionDomainName: string;
691+
public readonly distributionId: string;
692+
693+
constructor() {
694+
super(scope, id);
695+
this.domainName = attrs.domainName;
696+
this.distributionDomainName = attrs.domainName;
697+
this.distributionId = attrs.distributionId;
698+
}
699+
}();
700+
}
701+
662702
/**
663703
* The logging bucket for this CloudFront distribution.
664704
* If logging is not enabled for this distribution - this property will be undefined.

packages/@aws-cdk/aws-cloudfront/test/distribution.test.ts

+36
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,42 @@ describe('with Lambda@Edge functions', () => {
489489
});
490490
});
491491

492+
test('edgelambda.amazonaws.com is added to the trust policy of lambda', () => {
493+
new Distribution(stack, 'MyDist', {
494+
defaultBehavior: {
495+
origin,
496+
edgeLambdas: [
497+
{
498+
functionVersion: lambdaFunction.currentVersion,
499+
eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
500+
},
501+
],
502+
},
503+
});
504+
505+
expect(stack).toHaveResource('AWS::IAM::Role', {
506+
AssumeRolePolicyDocument: {
507+
Statement: [
508+
{
509+
Action: 'sts:AssumeRole',
510+
Effect: 'Allow',
511+
Principal: {
512+
Service: 'lambda.amazonaws.com',
513+
},
514+
},
515+
{
516+
Action: 'sts:AssumeRole',
517+
Effect: 'Allow',
518+
Principal: {
519+
Service: 'edgelambda.amazonaws.com',
520+
},
521+
},
522+
],
523+
Version: '2012-10-17',
524+
},
525+
});
526+
});
527+
492528
test('can add an edge lambdas to additional behaviors', () => {
493529
new Distribution(stack, 'MyDist', {
494530
defaultBehavior: { origin },

0 commit comments

Comments
 (0)