From 71b60e49ee7d80767ea1f32d4aad1c79f2abba64 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 25 Dec 2018 12:42:17 +0200 Subject: [PATCH 01/26] Convert FnXxx to Fn.xxx() --- docs/src/cloudformation.rst | 2 +- .../advanced-usage/index.ts | 14 +- package.json | 2 +- .../@aws-cdk/assets-docker/lib/image-asset.ts | 6 +- packages/@aws-cdk/assets/lib/asset.ts | 4 +- .../aws-autoscaling/lib/auto-scaling-group.ts | 2 +- .../aws-cloudfront/lib/web_distribution.ts | 4 +- packages/@aws-cdk/aws-cloudtrail/lib/index.ts | 2 +- .../@aws-cdk/aws-codebuild/lib/project.ts | 4 +- .../aws-codebuild/test/test.codebuild.ts | 12 +- .../@aws-cdk/aws-codecommit/lib/repository.ts | 7 +- .../lib/shared/base-target-group.ts | 4 +- .../@aws-cdk/aws-events/lib/input-options.ts | 10 +- packages/@aws-cdk/aws-events/lib/rule.ts | 4 +- .../@aws-cdk/aws-events/test/test.rule.ts | 4 +- .../aws-iam/test/test.policy-document.ts | 4 +- packages/@aws-cdk/aws-kinesis/lib/stream.ts | 2 +- .../@aws-cdk/aws-lambda/lib/lambda-ref.ts | 4 +- packages/@aws-cdk/aws-s3/lib/bucket.ts | 8 +- packages/@aws-cdk/aws-s3/test/test.util.ts | 3 +- .../@aws-cdk/cdk/lib/cloudformation/arn.ts | 37 ++- .../cloudformation/cloudformation-token.ts | 86 ++++++- .../@aws-cdk/cdk/lib/cloudformation/fn.ts | 229 ++++++++++-------- .../cdk/lib/cloudformation/mapping.ts | 6 +- .../@aws-cdk/cdk/lib/cloudformation/output.ts | 11 +- .../cdk/lib/cloudformation/parameter.ts | 12 + .../cdk/test/cloudformation/test.arn.ts | 58 +---- .../test.cloudformation-json.ts | 6 +- .../cdk/test/cloudformation/test.fn.ts | 18 +- .../@aws-cdk/cdk/test/core/test.tokens.ts | 6 +- .../build-tools/create-missing-libraries.ts | 2 +- 31 files changed, 314 insertions(+), 259 deletions(-) diff --git a/docs/src/cloudformation.rst b/docs/src/cloudformation.rst index de199914b5ae3..1042536300834 100644 --- a/docs/src/cloudformation.rst +++ b/docs/src/cloudformation.rst @@ -172,7 +172,7 @@ Intrinsic Functions .. code-block:: js import cdk = require('@aws-cdk/cdk'); - new cdk.FnJoin(",", [...]) + cdk.Fn.join(",", [...]) .. _pseudo_parameters: diff --git a/examples/cdk-examples-typescript/advanced-usage/index.ts b/examples/cdk-examples-typescript/advanced-usage/index.ts index 5c27436deb4aa..233df2d25be1a 100644 --- a/examples/cdk-examples-typescript/advanced-usage/index.ts +++ b/examples/cdk-examples-typescript/advanced-usage/index.ts @@ -157,7 +157,7 @@ class CloudFormationExample extends cdk.Stack { // outputs are constructs the synthesize into the template's "Outputs" section new cdk.Output(this, 'Output', { description: 'This is an output of the template', - value: new cdk.FnConcat(new cdk.AwsAccountId(), '/', param.ref) + value: `${new cdk.AwsAccountId()}/${param.ref}` }); // stack.templateOptions can be used to specify template-level options @@ -176,13 +176,13 @@ class CloudFormationExample extends cdk.Stack { new cdk.AwsStackName(), ], - // all CloudFormation's intrinsic functions are supported via the `cdk.FnXxx` classes + // all CloudFormation's intrinsic functions are supported via the `cdk.Fn.xxx` static methods. IntrinsicFunctions: [ - new cdk.FnAnd( - new cdk.FnFindInMap('MyMap', 'K1', 'K2'), - new cdk.FnSub('hello ${world}', { - world: new cdk.FnBase64(param.ref) // resolves to { Ref: } - })) + cdk.Fn.join('', [ + cdk.Fn.findInMap('MyMap', 'K1', 'K2'), + cdk.Fn.sub('hello ${world}', { + world: cdk.Fn.base64(param.ref) // resolves to { Ref: } + }) ]) ], }; } diff --git a/package.json b/package.json index 71f9ea04ba8d7..bce50c9707226 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "pkglint": "tools/pkglint/bin/pkglint -f ." }, "devDependencies": { - "@types/node": "^8.10.38", + "@types/node": "8.10.38", "@types/nodeunit": "^0.0.30", "conventional-changelog-cli": "^2.0.5", "lerna": "^3.3.0", diff --git a/packages/@aws-cdk/assets-docker/lib/image-asset.ts b/packages/@aws-cdk/assets-docker/lib/image-asset.ts index 7b76d91d20560..8226d0635ef24 100644 --- a/packages/@aws-cdk/assets-docker/lib/image-asset.ts +++ b/packages/@aws-cdk/assets-docker/lib/image-asset.ts @@ -61,9 +61,9 @@ export class DockerImageAsset extends cdk.Construct { this.addMetadata(cxapi.ASSET_METADATA, asset); // parse repository name and tag from the parameter (:) - const components = new cdk.FnSplit(':', imageNameParameter.value); - const repositoryName = new cdk.FnSelect(0, components).toString(); - const imageTag = new cdk.FnSelect(1, components).toString(); + const components = cdk.Fn.split(':', imageNameParameter.valueAsString); + const repositoryName = cdk.Fn.select(0, components).toString(); + const imageTag = cdk.Fn.select(1, components).toString(); // Require that repository adoption happens first, so we route the // input ARN into the Custom Resource and then get the URI which we use to diff --git a/packages/@aws-cdk/assets/lib/asset.ts b/packages/@aws-cdk/assets/lib/asset.ts index a075ef5829be0..92af4aeba3588 100644 --- a/packages/@aws-cdk/assets/lib/asset.ts +++ b/packages/@aws-cdk/assets/lib/asset.ts @@ -110,8 +110,8 @@ export class Asset extends cdk.Construct { }); this.s3BucketName = bucketParam.value.toString(); - this.s3Prefix = new cdk.FnSelect(0, new cdk.FnSplit(cxapi.ASSET_PREFIX_SEPARATOR, keyParam.value)).toString(); - const s3Filename = new cdk.FnSelect(1, new cdk.FnSplit(cxapi.ASSET_PREFIX_SEPARATOR, keyParam.value)).toString(); + this.s3Prefix = cdk.Fn.select(0, cdk.Fn.split(cxapi.ASSET_PREFIX_SEPARATOR, keyParam.valueAsString)).toString(); + const s3Filename = cdk.Fn.select(1, cdk.Fn.split(cxapi.ASSET_PREFIX_SEPARATOR, keyParam.valueAsString)).toString(); this.s3ObjectKey = `${this.s3Prefix}${s3Filename}`; this.bucket = s3.BucketRef.import(this, 'AssetBucket', { diff --git a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts index 0ce9a18e26d4f..5a91728d53d70 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -222,7 +222,7 @@ export class AutoScalingGroup extends cdk.Construct implements IAutoScalingGroup // use delayed evaluation const machineImage = props.machineImage.getImage(this); - const userDataToken = new cdk.Token(() => new cdk.FnBase64((machineImage.os.createUserData(this.userDataLines)))); + const userDataToken = new cdk.Token(() => cdk.Fn.base64((machineImage.os.createUserData(this.userDataLines)))); const securityGroupsToken = new cdk.Token(() => this.securityGroups.map(sg => sg.securityGroupId)); const launchConfig = new CfnLaunchConfiguration(this, 'LaunchConfig', { diff --git a/packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts b/packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts index d8f575d67b303..e5b15fddd4721 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts @@ -574,9 +574,7 @@ export class CloudFrontWebDistribution extends cdk.Construct implements route53. if (originConfig.s3OriginSource && originConfig.s3OriginSource.originAccessIdentity) { originProperty.s3OriginConfig = { - originAccessIdentity: new cdk.FnConcat( - "origin-access-identity/cloudfront/", originConfig.s3OriginSource.originAccessIdentity.ref - ), + originAccessIdentity: `origin-access-identity/cloudfront/${originConfig.s3OriginSource.originAccessIdentity.ref}` }; } else if (originConfig.s3OriginSource) { originProperty.s3OriginConfig = {}; diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts index 8c625b9d6fd91..cdbe5749261cd 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts @@ -138,7 +138,7 @@ export class CloudTrail extends cdk.Construct { .addServicePrincipal(cloudTrailPrincipal)); s3bucket.addToResourcePolicy(new iam.PolicyStatement() - .addResource(s3bucket.arnForObjects(new cdk.FnConcat('AWSLogs/', new cdk.AwsAccountId(), "/*"))) + .addResource(s3bucket.arnForObjects(`AWSLogs/${new cdk.AwsAccountId()}/*`)) .addActions("s3:PutObject") .addServicePrincipal(cloudTrailPrincipal) .setCondition("StringEquals", {'s3:x-amz-acl': "bucket-owner-full-control"})); diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index 00c12034c7c8b..4ce51ac2412e0 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -495,10 +495,10 @@ export class Project extends ProjectRef { let cache: CfnProject.ProjectCacheProperty | undefined; if (props.cacheBucket) { - const cacheDir = props.cacheDir != null ? props.cacheDir : new cdk.AwsNoValue(); + const cacheDir = props.cacheDir != null ? props.cacheDir : new cdk.AwsNoValue().toString(); cache = { type: 'S3', - location: new cdk.FnJoin('/', [props.cacheBucket.bucketName, cacheDir]), + location: cdk.Fn.join('/', [props.cacheBucket.bucketName, cacheDir]), }; props.cacheBucket.grantReadWrite(this.role); diff --git a/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts b/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts index c3c4490c51053..187b72cbcacb7 100644 --- a/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts +++ b/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts @@ -855,14 +855,14 @@ export = { new codebuild.Project(stack, 'Project', { source: new codebuild.CodePipelineSource(), environment: { - environmentVariables: { - FOO: { value: '1234' }, - BAR: { value: new cdk.FnConcat('111', { twotwotwo: '222' }), type: codebuild.BuildEnvironmentVariableType.ParameterStore } - } + environmentVariables: { + FOO: { value: '1234' }, + BAR: { value: `111${new cdk.CloudFormationToken({ twotwotwo: '222' })}`, type: codebuild.BuildEnvironmentVariableType.ParameterStore } + } }, environmentVariables: { - GOO: { value: 'ABC' }, - FOO: { value: 'OVERRIDE!' } + GOO: { value: 'ABC' }, + FOO: { value: 'OVERRIDE!' } } }); diff --git a/packages/@aws-cdk/aws-codecommit/lib/repository.ts b/packages/@aws-cdk/aws-codecommit/lib/repository.ts index a49022376e0e3..c28be77131b21 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/repository.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/repository.ts @@ -196,12 +196,7 @@ class ImportedRepositoryRef extends RepositoryRef { } private repositoryCloneUrl(protocol: 'https' | 'ssh'): string { - return new cdk.FnConcat(`${protocol}://git-codecommit.`, - new cdk.AwsRegion(), - '.', - new cdk.AwsURLSuffix(), - '/v1/repos/', - this.repositoryName).toString(); + return `${protocol}://git-codecommit.${new cdk.AwsRegion()}.${new cdk.AwsURLSuffix()}/v1/repos/${this.repositoryName}`; } } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts index 4574d4485f7b4..0a50e3dfe13ee 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts @@ -373,6 +373,6 @@ export interface LoadBalancerTargetProps { * app/my-load-balancer/50dc6c495c0c9188 */ export function loadBalancerNameFromListenerArn(listenerArn: string) { - const arnParts = new cdk.FnSplit('/', listenerArn); - return `${new cdk.FnSelect(1, arnParts)}/${new cdk.FnSelect(2, arnParts)}/${new cdk.FnSelect(3, arnParts)}`; + const arnParts = cdk.Fn.split('/', listenerArn); + return `${cdk.Fn.select(1, arnParts)}/${cdk.Fn.select(2, arnParts)}/${cdk.Fn.select(3, arnParts)}`; } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events/lib/input-options.ts b/packages/@aws-cdk/aws-events/lib/input-options.ts index a0f58db566ccd..4bf55aa3fe6a8 100644 --- a/packages/@aws-cdk/aws-events/lib/input-options.ts +++ b/packages/@aws-cdk/aws-events/lib/input-options.ts @@ -16,13 +16,13 @@ export interface TargetInputTemplate { * @example * * { - * textTemplate: 'Build started', - * pathsMap: { - * buildid: '$.detail.id' - * } + * textTemplate: 'Build started', + * pathsMap: { + * buildid: '$.detail.id' + * } * } */ - textTemplate?: any; + textTemplate?: string; /** * Input template where you can use the values of the keys from diff --git a/packages/@aws-cdk/aws-events/lib/rule.ts b/packages/@aws-cdk/aws-events/lib/rule.ts index e64171b6402fb..3a2eaf5a0f3a5 100644 --- a/packages/@aws-cdk/aws-events/lib/rule.ts +++ b/packages/@aws-cdk/aws-events/lib/rule.ts @@ -1,4 +1,4 @@ -import { Construct, FnConcat, Token } from '@aws-cdk/cdk'; +import { Construct, Token } from '@aws-cdk/cdk'; import { EventPattern } from './event-pattern'; import { CfnRule } from './events.generated'; import { TargetInputTemplate } from './input-options'; @@ -133,7 +133,7 @@ export class EventRule extends EventRuleRef { } else if (typeof(inputOptions.textTemplate) === 'string') { inputTemplate = JSON.stringify(inputOptions.textTemplate); } else { - inputTemplate = new FnConcat('"', inputOptions.textTemplate, '"'); + inputTemplate = `"${inputOptions.textTemplate}"`; } return { diff --git a/packages/@aws-cdk/aws-events/test/test.rule.ts b/packages/@aws-cdk/aws-events/test/test.rule.ts index 6343e7edfcaf0..72743367c59d0 100644 --- a/packages/@aws-cdk/aws-events/test/test.rule.ts +++ b/packages/@aws-cdk/aws-events/test/test.rule.ts @@ -238,7 +238,7 @@ export = { // tokens are used here (FnConcat), but this is a text template so we // expect it to be wrapped in double quotes automatically for us. rule.addTarget(t1, { - textTemplate: new cdk.FnConcat('a', 'b') + textTemplate: cdk.Fn.join('', [ 'a', 'b' ]).toString() }); // jsonTemplate can be used to format JSON documents with replacements @@ -252,7 +252,7 @@ export = { // tokens can also used for JSON templates, but that means escaping is // the responsibility of the user. rule.addTarget(t4, { - jsonTemplate: new cdk.FnJoin(' ', ['"', 'hello', '\"world\"', '"']), + jsonTemplate: cdk.Fn.join(' ', ['"', 'hello', '\"world\"', '"']), }); expect(stack).toMatch({ diff --git a/packages/@aws-cdk/aws-iam/test/test.policy-document.ts b/packages/@aws-cdk/aws-iam/test/test.policy-document.ts index a96eee423f7b7..7cb0e3997aa94 100644 --- a/packages/@aws-cdk/aws-iam/test/test.policy-document.ts +++ b/packages/@aws-cdk/aws-iam/test/test.policy-document.ts @@ -1,4 +1,4 @@ -import { FnConcat, resolve } from '@aws-cdk/cdk'; +import { resolve, Token } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; import { Anyone, AnyPrincipal, CanonicalUserPrincipal, PolicyDocument, PolicyPrincipal, PolicyStatement } from '../lib'; import { ArnPrincipal, CompositePrincipal, FederatedPrincipal, PrincipalPolicyFragment, ServicePrincipal } from '../lib'; @@ -12,7 +12,7 @@ export = { p.addResource('yourQueue'); p.addAllResources(); - p.addAwsAccountPrincipal(new FnConcat('my', { account: 'account' }, 'name').toString()); + p.addAwsAccountPrincipal(`my${new Token({ account: 'account' })}name`); p.limitToAccount('12221121221'); test.deepEqual(resolve(p), { Action: diff --git a/packages/@aws-cdk/aws-kinesis/lib/stream.ts b/packages/@aws-cdk/aws-kinesis/lib/stream.ts index fb0a550872cae..a7261a929c0bf 100644 --- a/packages/@aws-cdk/aws-kinesis/lib/stream.ts +++ b/packages/@aws-cdk/aws-kinesis/lib/stream.ts @@ -170,7 +170,7 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr if (!this.cloudWatchLogsRole) { // Create a role to be assumed by CWL that can write to this stream and pass itself. this.cloudWatchLogsRole = new iam.Role(this, 'CloudWatchLogsCanPutRecords', { - assumedBy: new iam.ServicePrincipal(new cdk.FnConcat('logs.', new cdk.AwsRegion(), '.amazonaws.com').toString()), + assumedBy: new iam.ServicePrincipal(`logs.${new cdk.AwsRegion()}.amazonaws.com`) }); this.cloudWatchLogsRole.addToPolicy(new iam.PolicyStatement().addAction('kinesis:PutRecord').addResource(this.streamArn)); this.cloudWatchLogsRole.addToPolicy(new iam.PolicyStatement().addAction('iam:PassRole').addResource(this.cloudWatchLogsRole.roleArn)); diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts index 58ae13e62af25..2971dc26c76d8 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts @@ -320,7 +320,7 @@ export abstract class FunctionRef extends cdk.Construct // // (Wildcards in principals are unfortunately not supported. this.addPermission('InvokedByCloudWatchLogs', { - principal: new iam.ServicePrincipal(new cdk.FnConcat('logs.', new cdk.AwsRegion(), '.amazonaws.com').toString()), + principal: new iam.ServicePrincipal(`logs.${new cdk.AwsRegion()}.amazonaws.com`), sourceArn: arn }); this.logSubscriptionDestinationPolicyAddedFor.push(arn); @@ -451,6 +451,6 @@ class LambdaRefImport extends FunctionRef { * @returns `FnSelect(6, FnSplit(':', arn))` */ private extractNameFromArn(arn: string) { - return new cdk.FnSelect(6, new cdk.FnSplit(':', arn)).toString(); + return cdk.Fn.select(6, cdk.Fn.split(':', arn)).toString(); } } diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index b059f0463ab48..397ee7dce012f 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -165,7 +165,7 @@ export abstract class BucketRef extends cdk.Construct { * bucket is returned. * @returns an ObjectS3Url token */ - public urlForObject(key?: any): string { + public urlForObject(key?: string): string { const components = [ 'https://', 's3.', new cdk.AwsRegion(), '.', new cdk.AwsURLSuffix(), '/', this.bucketName ]; if (key) { // trim prepending '/' @@ -176,7 +176,7 @@ export abstract class BucketRef extends cdk.Construct { components.push(key); } - return new cdk.FnConcat(...components).toString(); + return components.join(''); } /** @@ -188,8 +188,8 @@ export abstract class BucketRef extends cdk.Construct { * arnForObjects('home/', team, '/', user, '/*') * */ - public arnForObjects(...keyPattern: any[]): string { - return new cdk.FnConcat(this.bucketArn, '/', ...keyPattern).toString(); + public arnForObjects(...keyPattern: string[]): string { + return `${this.bucketArn}/${keyPattern.join('')}`; } /** diff --git a/packages/@aws-cdk/aws-s3/test/test.util.ts b/packages/@aws-cdk/aws-s3/test/test.util.ts index 68a2e3ca756e1..2f33e12c81a02 100644 --- a/packages/@aws-cdk/aws-s3/test/test.util.ts +++ b/packages/@aws-cdk/aws-s3/test/test.util.ts @@ -1,4 +1,5 @@ import cdk = require('@aws-cdk/cdk'); +import { CloudFormationToken } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; import { parseBucketArn, parseBucketName } from '../lib/util'; @@ -41,7 +42,7 @@ export = { }, 'undefined if cannot extract name from a non-string arn'(test: Test) { - const bucketArn = new cdk.FnConcat('arn:aws:s3:::', { Ref: 'my-bucket' }).toString(); + const bucketArn = `arn:aws:s3:::${new CloudFormationToken({ Ref: 'my-bucket' })}`; test.deepEqual(cdk.resolve(parseBucketName({ bucketArn })), undefined); test.done(); }, diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts b/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts index 01ce8c7a7b53a..52e2fb3a563a3 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts @@ -1,7 +1,6 @@ -import { AwsAccountId, AwsPartition, AwsRegion, FnConcat, Token } from '..'; -import { FnSelect, FnSplit } from '../cloudformation/fn'; +import { AwsAccountId, AwsPartition, AwsRegion } from '..'; +import { Fn } from '../cloudformation/fn'; import { unresolved } from '../core/tokens'; -import { CloudFormationToken } from './cloudformation-token'; /** * An Amazon Resource Name (ARN). @@ -45,7 +44,7 @@ export class ArnUtils { values.push(components.resourceName); } - return new FnConcat(...values).toString(); + return values.join(''); } /** @@ -87,7 +86,7 @@ export class ArnUtils { */ public static parse(arn: string, sepIfToken: string = '/', hasName: boolean = true): ArnComponents { if (unresolved(arn)) { - return ArnUtils.parseToken(new CloudFormationToken(arn), sepIfToken, hasName); + return ArnUtils.parseToken(arn, sepIfToken, hasName); } const components = arn.split(':') as Array; @@ -184,7 +183,7 @@ export class ArnUtils { * but simply 'path'. This is a limitation because there is no slicing * functionality in CloudFormation templates. * - * @param arn The input token that contains an ARN + * @param arnToken The input token that contains an ARN * @param sep The separator used to separate resource from resourceName * @param hasName Whether there is a name component in the ARN at all. * For example, SNS Topics ARNs have the 'resource' component contain the @@ -192,7 +191,7 @@ export class ArnUtils { * @returns an ArnComponents object which allows access to the various * components of the ARN. */ - public static parseToken(arn: Token, sep: string = '/', hasName: boolean = true): ArnComponents { + public static parseToken(arnToken: string, sep: string = '/', hasName: boolean = true): ArnComponents { // Arn ARN looks like: // arn:partition:service:region:account-id:resource // arn:partition:service:region:account-id:resourcetype/resource @@ -201,23 +200,23 @@ export class ArnUtils { // We need the 'hasName' argument because {Fn::Select}ing a nonexistent field // throws an error. - const components = new FnSplit(':', arn); + const components = Fn.split(':', arnToken); - const partition = new FnSelect(1, components).toString(); - const service = new FnSelect(2, components).toString(); - const region = new FnSelect(3, components).toString(); - const account = new FnSelect(4, components).toString(); + const partition = Fn.select(1, components).toString(); + const service = Fn.select(2, components).toString(); + const region = Fn.select(3, components).toString(); + const account = Fn.select(4, components).toString(); if (sep === ':') { - const resource = new FnSelect(5, components).toString(); - const resourceName = hasName ? new FnSelect(6, components).toString() : undefined; + const resource = Fn.select(5, components).toString(); + const resourceName = hasName ? Fn.select(6, components).toString() : undefined; return { partition, service, region, account, resource, resourceName, sep }; } else { - const lastComponents = new FnSplit(sep, new FnSelect(5, components)); + const lastComponents = Fn.split(sep, Fn.select(5, components)); - const resource = new FnSelect(0, lastComponents).toString(); - const resourceName = hasName ? new FnSelect(1, lastComponents).toString() : undefined; + const resource = Fn.select(0, lastComponents).toString(); + const resourceName = hasName ? Fn.select(1, lastComponents).toString() : undefined; return { partition, service, region, account, resource, resourceName, sep }; } @@ -227,14 +226,14 @@ export class ArnUtils { * Return a Token that represents the resource component of the ARN */ public static resourceComponent(arn: string, sep: string = '/'): string { - return ArnUtils.parseToken(new Token(arn), sep).resource; + return ArnUtils.parseToken(arn, sep).resource; } /** * Return a Token that represents the resource Name component of the ARN */ public static resourceNameComponent(arn: string, sep: string = '/'): string { - return ArnUtils.parseToken(new Token(arn), sep, true).resourceName!; + return ArnUtils.parseToken(arn, sep, true).resourceName!; } } diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/cloudformation-token.ts b/packages/@aws-cdk/cdk/lib/cloudformation/cloudformation-token.ts index 024414218e3ce..467de44968370 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/cloudformation-token.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/cloudformation-token.ts @@ -1,4 +1,4 @@ -import { resolve, Token } from "../core/tokens"; +import { resolve, Token, unresolved } from "../core/tokens"; /** * Base class for CloudFormation built-ins @@ -9,12 +9,10 @@ export class CloudFormationToken extends Token { if (left !== undefined) { parts.push(left); } parts.push(resolve(this)); if (right !== undefined) { parts.push(right); } - return new FnConcat(...parts); + return new FnJoin('', parts); } } -import { FnConcat } from "./fn"; - /** * Return whether the given value represents a CloudFormation intrinsic */ @@ -26,3 +24,83 @@ export function isIntrinsic(x: any) { return keys[0] === 'Ref' || keys[0].startsWith('Fn::'); } + +/** + * The intrinsic function ``Fn::Join`` appends a set of values into a single value, separated by + * the specified delimiter. If a delimiter is the empty string, the set of values are concatenated + * with no delimiter. + */ +export class FnJoin extends CloudFormationToken { + private readonly delimiter: string; + private readonly listOfValues: any[]; + // Cache for the result of resolveValues() - since it otherwise would be computed several times + private _resolvedValues?: any[]; + private canOptimize: boolean; + + /** + * Creates an ``Fn::Join`` function. + * @param delimiter The value you want to occur between fragments. The delimiter will occur between fragments only. + * It will not terminate the final value. + * @param listOfValues The list of values you want combined. + */ + constructor(delimiter: string, listOfValues: any[]) { + if (listOfValues.length === 0) { + throw new Error(`FnJoin requires at least one value to be provided`); + } + // Passing the values as a token, optimization requires resolving stringified tokens, we should be deferred until + // this token is itself being resolved. + super({ 'Fn::Join': [ delimiter, new Token(() => this.resolveValues()) ] }); + this.delimiter = delimiter; + this.listOfValues = listOfValues; + this.canOptimize = true; + } + + public resolve(): any { + const resolved = this.resolveValues(); + if (this.canOptimize && resolved.length === 1) { + return resolved[0]; + } + return super.resolve(); + } + + /** + * Optimization: if an Fn::Join is nested in another one and they share the same delimiter, then flatten it up. Also, + * if two concatenated elements are literal strings (not tokens), then pre-concatenate them with the delimiter, to + * generate shorter output. + */ + private resolveValues() { + if (this._resolvedValues) { return this._resolvedValues; } + + if (unresolved(this.listOfValues)) { + // This is a list token, don't resolve and also don't optimize. + this.canOptimize = false; + return this._resolvedValues = this.listOfValues; + } + + const resolvedValues = [...this.listOfValues.map(e => resolve(e))]; + let i = 0; + while (i < resolvedValues.length) { + const el = resolvedValues[i]; + if (isFnJoinIntrinsicWithSameDelimiter.call(this, el)) { + resolvedValues.splice(i, 1, ...el['Fn::Join'][1]); + } else if (i > 0 && isPlainString(resolvedValues[i - 1]) && isPlainString(resolvedValues[i])) { + resolvedValues[i - 1] += this.delimiter + resolvedValues[i]; + resolvedValues.splice(i, 1); + } else { + i += 1; + } + } + + return this._resolvedValues = resolvedValues; + + function isFnJoinIntrinsicWithSameDelimiter(this: FnJoin, obj: any): boolean { + return isIntrinsic(obj) + && Object.keys(obj)[0] === 'Fn::Join' + && obj['Fn::Join'][0] === this.delimiter; + } + + function isPlainString(obj: any): boolean { + return typeof obj === 'string' && !unresolved(obj); + } + } +} diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts index 5b9a705e355c1..1f89ca23aa62d 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts @@ -1,12 +1,122 @@ -import { resolve, Token, unresolved } from '../core/tokens'; -import { CloudFormationToken, isIntrinsic } from './cloudformation-token'; +import { CloudFormationToken, FnJoin } from './cloudformation-token'; + // tslint:disable:max-line-length /** * CloudFormation intrinsic functions. * http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html */ -export class Fn extends CloudFormationToken { +export class Fn { + + /** + * The intrinsic function ``Fn::Join`` appends a set of values into a single + * value, separated by the specified delimiter. If a delimiter is the empty + * string, the set of values are concatenated with no delimiter. + * @param delimiter The value you want to occur between fragments. The + * delimiter will occur between fragments only. It will not terminate the + * final value. + * @param listOfValues The list of values you want combined. + */ + public static join(delimiter: string, listOfValues: string[]): string { + return new FnJoin(delimiter, listOfValues).toString(); + } + + /** + * To split a string into a list of string values so that you can select an element from the + * resulting string list, use the ``Fn::Split`` intrinsic function. Specify the location of splits + * with a delimiter, such as , (a comma). After you split a string, use the ``Fn::Select`` function + * to pick a specific element. + * @param delimiter A string value that determines where the source string is divided. + * @param source The string value that you want to split. + */ + public static split(delimiter: string, source: string): string[] { + return new FnSplit(delimiter, source).toList(); + } + + /** + * The intrinsic function ``Fn::Select`` returns a single object from a list of objects by index. + * @param index The index of the object to retrieve. This must be a value from zero to N-1, where N represents the number of elements in the array. + * @param array The list of objects to select from. This list must not be null, nor can it have null entries. + */ + public static select(index: number, array: string[]): string { + return new FnSelect(index, array).toString(); + } + + /** + * The intrinsic function ``Fn::Sub`` substitutes variables in an input string + * with values that you specify. In your templates, you can use this function + * to construct commands or outputs that include values that aren't available + * until you create or update a stack. + * @param body A string with variables that AWS CloudFormation substitutes + * with their associated values at runtime. Write variables as ${MyVarName}. + * Variables can be template parameter names, resource logical IDs, resource + * attributes, or a variable in a key-value map. If you specify only template + * parameter names, resource logical IDs, and resource attributes, don't + * specify a key-value map. + * @param variables The name of a variable that you included in the String + * parameter. The value that AWS CloudFormation substitutes for the associated + * variable name at runtime. + */ + public static sub(body: string, variables?: { [key: string]: string }): string { + return new FnSub(body, variables).toString(); + } + + /** + * The intrinsic function ``Fn::Base64`` returns the Base64 representation of the input string. + * This function is typically used to pass encoded data to Amazon EC2 instances by way of + * the UserData property. + * @param data The string value you want to convert to Base64. + */ + public static base64(data: string): string { + return new FnBase64(data).toString(); + } + + /** + * The intrinsic function ``Fn::Cidr`` returns the specified Cidr address block. + * @param ipBlock The user-specified default Cidr address block. + * @param count The number of subnets' Cidr block wanted. Count can be 1 to 256. + * @param sizeMask The digit covered in the subnet. + */ + public static cidr(ipBlock: string, count: number, sizeMask?: string): string { + return new FnCidr(ipBlock, count, sizeMask).toString(); + } + + /** + * The intrinsic function ``Fn::GetAZs`` returns an array that lists Availability Zones for a + * specified region. Because customers have access to different Availability Zones, the intrinsic + * function ``Fn::GetAZs`` enables template authors to write templates that adapt to the calling + * user's access. That way you don't have to hard-code a full list of Availability Zones for a + * specified region. + * @param region The name of the region for which you want to get the + * Availability Zones. You can use the AWS::Region pseudo parameter to specify + * the region in which the stack is created. Specifying an empty string is + * equivalent to specifying AWS::Region. + */ + public static getAZs(region?: string): string[] { + return new FnGetAZs(region).toList(); + } + + /** + * The intrinsic function ``Fn::ImportValue`` returns the value of an output exported by another stack. + * You typically use this function to create cross-stack references. In the following example + * template snippets, Stack A exports VPC security group values and Stack B imports them. + * @param sharedValueToImport The stack output value that you want to import. + */ + public static importValue(sharedValueToImport: string): string { + return new FnImportValue(sharedValueToImport).toString(); + } + + /** + * The intrinsic function ``Fn::FindInMap`` returns the value corresponding to keys in a two-level + * map that is declared in the Mappings section. + */ + public static findInMap(mapName: string, topLevelKey: string, secondLevelKey: string): string { + return new FnFindInMap(mapName, topLevelKey, secondLevelKey).toString(); + } + +} + +export class FnBase extends CloudFormationToken { constructor(name: string, value: any) { super(() => ({ [name]: value })); } @@ -16,7 +126,7 @@ export class Fn extends CloudFormationToken { * The intrinsic function ``Fn::FindInMap`` returns the value corresponding to keys in a two-level * map that is declared in the Mappings section. */ -export class FnFindInMap extends Fn { +class FnFindInMap extends FnBase { /** * Creates an ``Fn::FindInMap`` function. * @param mapName The logical name of a mapping declared in the Mappings section that contains the keys and values. @@ -31,7 +141,7 @@ export class FnFindInMap extends Fn { /** * The ``Fn::GetAtt`` intrinsic function returns the value of an attribute from a resource in the template. */ -export class FnGetAtt extends Fn { +export class FnGetAtt extends FnBase { /** * Creates a ``Fn::GetAtt`` function. * @param logicalNameOfResource The logical name (also called logical ID) of the resource that contains the attribute that you want. @@ -49,7 +159,7 @@ export class FnGetAtt extends Fn { * user's access. That way you don't have to hard-code a full list of Availability Zones for a * specified region. */ -export class FnGetAZs extends Fn { +class FnGetAZs extends FnBase { /** * Creates an ``Fn::GetAZs`` function. * @param region The name of the region for which you want to get the Availability Zones. @@ -67,7 +177,7 @@ export class FnGetAZs extends Fn { * You typically use this function to create cross-stack references. In the following example * template snippets, Stack A exports VPC security group values and Stack B imports them. */ -export class FnImportValue extends Fn { +class FnImportValue extends FnBase { /** * Creates an ``Fn::ImportValue`` function. * @param sharedValueToImport The stack output value that you want to import. @@ -77,103 +187,10 @@ export class FnImportValue extends Fn { } } -/** - * The intrinsic function ``Fn::Join`` appends a set of values into a single value, separated by - * the specified delimiter. If a delimiter is the empty string, the set of values are concatenated - * with no delimiter. - */ -export class FnJoin extends Fn { - private readonly delimiter: string; - private readonly listOfValues: any[]; - // Cache for the result of resolveValues() - since it otherwise would be computed several times - private _resolvedValues?: any[]; - private canOptimize: boolean; - - /** - * Creates an ``Fn::Join`` function. - * @param delimiter The value you want to occur between fragments. The delimiter will occur between fragments only. - * It will not terminate the final value. - * @param listOfValues The list of values you want combined. - */ - constructor(delimiter: string, listOfValues: any[]) { - if (listOfValues.length === 0) { - throw new Error(`FnJoin requires at least one value to be provided`); - } - // Passing the values as a token, optimization requires resolving stringified tokens, we should be deferred until - // this token is itself being resolved. - super('Fn::Join', [ delimiter, new Token(() => this.resolveValues()) ]); - this.delimiter = delimiter; - this.listOfValues = listOfValues; - this.canOptimize = true; - } - - public resolve(): any { - const resolved = this.resolveValues(); - if (this.canOptimize && resolved.length === 1) { - return resolved[0]; - } - return super.resolve(); - } - - /** - * Optimization: if an Fn::Join is nested in another one and they share the same delimiter, then flatten it up. Also, - * if two concatenated elements are literal strings (not tokens), then pre-concatenate them with the delimiter, to - * generate shorter output. - */ - private resolveValues() { - if (this._resolvedValues) { return this._resolvedValues; } - - if (unresolved(this.listOfValues)) { - // This is a list token, don't resolve and also don't optimize. - this.canOptimize = false; - return this._resolvedValues = this.listOfValues; - } - - const resolvedValues = [...this.listOfValues.map(e => resolve(e))]; - let i = 0; - while (i < resolvedValues.length) { - const el = resolvedValues[i]; - if (isFnJoinIntrinsicWithSameDelimiter.call(this, el)) { - resolvedValues.splice(i, 1, ...el['Fn::Join'][1]); - } else if (i > 0 && isPlainString(resolvedValues[i - 1]) && isPlainString(resolvedValues[i])) { - resolvedValues[i - 1] += this.delimiter + resolvedValues[i]; - resolvedValues.splice(i, 1); - } else { - i += 1; - } - } - - return this._resolvedValues = resolvedValues; - - function isFnJoinIntrinsicWithSameDelimiter(this: FnJoin, obj: any): boolean { - return isIntrinsic(obj) - && Object.keys(obj)[0] === 'Fn::Join' - && obj['Fn::Join'][0] === this.delimiter; - } - - function isPlainString(obj: any): boolean { - return typeof obj === 'string' && !unresolved(obj); - } - } -} - -/** - * Alias for ``FnJoin('', listOfValues)``. - */ -export class FnConcat extends FnJoin { - /** - * Creates an ``Fn::Join`` function with an empty delimiter. - * @param listOfValues The list of values to concatenate. - */ - constructor(...listOfValues: any[]) { - super('', listOfValues); - } -} - /** * The intrinsic function ``Fn::Select`` returns a single object from a list of objects by index. */ -export class FnSelect extends Fn { +class FnSelect extends FnBase { /** * Creates an ``Fn::Select`` function. * @param index The index of the object to retrieve. This must be a value from zero to N-1, where N represents the number of elements in the array. @@ -190,7 +207,7 @@ export class FnSelect extends Fn { * with a delimiter, such as , (a comma). After you split a string, use the ``Fn::Select`` function * to pick a specific element. */ -export class FnSplit extends Fn { +class FnSplit extends FnBase { /** * Create an ``Fn::Split`` function. * @param delimiter A string value that determines where the source string is divided. @@ -206,7 +223,7 @@ export class FnSplit extends Fn { * you specify. In your templates, you can use this function to construct commands or outputs * that include values that aren't available until you create or update a stack. */ -export class FnSub extends Fn { +class FnSub extends FnBase { /** * Creates an ``Fn::Sub`` function. * @param body A string with variables that AWS CloudFormation substitutes with their @@ -227,7 +244,7 @@ export class FnSub extends Fn { * This function is typically used to pass encoded data to Amazon EC2 instances by way of * the UserData property. */ -export class FnBase64 extends Fn { +class FnBase64 extends FnBase { /** * Creates an ``Fn::Base64`` function. @@ -241,7 +258,7 @@ export class FnBase64 extends Fn { /** * The intrinsic function ``Fn::Cidr`` returns the specified Cidr address block. */ -export class FnCidr extends Fn { +class FnCidr extends FnBase { /** * Creates an ``Fn::Cidr`` function. * @param ipBlock The user-specified default Cidr address block. @@ -275,7 +292,7 @@ export class FnCidr extends Fn { * conditions, you can define which resources are created and how they're configured for each * environment type. */ -export class FnCondition extends Fn { +export class FnCondition extends FnBase { } diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/mapping.ts b/packages/@aws-cdk/cdk/lib/cloudformation/mapping.ts index b77b3af8f1673..8601012b60d47 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/mapping.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/mapping.ts @@ -1,5 +1,5 @@ import { Construct } from '../core/construct'; -import { FnFindInMap } from './fn'; +import { Fn } from './fn'; import { Referenceable } from './stack'; export interface MappingProps { @@ -31,7 +31,7 @@ export class Mapping extends Referenceable { /** * @returns A reference to a value in the map based on the two keys. */ - public findInMap(key1: any, key2: any) { + public findInMap(key1: string, key2: string): string { if (!(key1 in this.mapping)) { throw new Error(`Mapping doesn't contain top-level key '${key1}'`); } @@ -40,7 +40,7 @@ export class Mapping extends Referenceable { throw new Error(`Mapping doesn't contain second-level key '${key2}'`); } - return new FnFindInMap(this.logicalId, key1, key2); + return Fn.findInMap(this.logicalId, key1, key2); } public toCloudFormation(): object { diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/output.ts b/packages/@aws-cdk/cdk/lib/cloudformation/output.ts index fa39cf0990f0c..ecaedb4ef488c 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/output.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/output.ts @@ -1,7 +1,6 @@ import { Construct } from '../core/construct'; -import { Token } from '../core/tokens'; import { Condition } from './condition'; -import { FnImportValue, FnJoin, FnSelect, FnSplit } from './fn'; +import { Fn } from './fn'; import { Stack, StackElement } from './stack'; export interface OutputProps { @@ -104,7 +103,7 @@ export class Output extends StackElement { if (!this.export) { throw new Error('Cannot create an ImportValue without an export name'); } - return new FnImportValue(this.export); + return Fn.importValue(this.export); } public toCloudFormation(): object { @@ -207,19 +206,19 @@ export class StringListOutput extends Construct { condition: props.condition, disableExport: props.disableExport, export: props.export, - value: new FnJoin(this.separator, props.values) + value: Fn.join(this.separator, props.values) }); } /** * Return an array of imported values for this Output */ - public makeImportValues(): Token[] { + public makeImportValues(): string[] { const combined = this.output.makeImportValue(); const ret = []; for (let i = 0; i < this.length; i++) { - ret.push(new FnSelect(i, new FnSplit(this.separator, combined))); + ret.push(Fn.select(i, Fn.split(this.separator, combined))); } return ret; diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/parameter.ts b/packages/@aws-cdk/cdk/lib/cloudformation/parameter.ts index a7ec01fb989d0..9605363188fd3 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/parameter.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/parameter.ts @@ -76,6 +76,16 @@ export class Parameter extends Referenceable { */ public value: Token; + /** + * The parameter value token represented as a string. + */ + public valueAsString: string; + + /** + * The parameter value token represented as a string array. + */ + public valueAsList: string[]; + private properties: ParameterProps; /** @@ -90,6 +100,8 @@ export class Parameter extends Referenceable { super(parent, name); this.properties = props; this.value = new Ref(this); + this.valueAsString = this.value.toString(); + this.valueAsList = this.value.toList(); } public toCloudFormation(): object { diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts index 3584d20d39766..18b90b460db69 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts @@ -1,5 +1,5 @@ import { Test } from 'nodeunit'; -import { ArnComponents, ArnUtils, FnConcat, resolve, Token } from '../../lib'; +import { ArnComponents, ArnUtils, AwsAccountId, AwsPartition, AwsRegion, resolve, Token } from '../../lib'; export = { 'create from components with defaults'(test: Test) { @@ -9,17 +9,7 @@ export = { }); test.deepEqual(resolve(arn), - resolve(new FnConcat('arn', - ':', - { Ref: 'AWS::Partition' }, - ':', - 'sqs', - ':', - { Ref: 'AWS::Region' }, - ':', - { Ref: 'AWS::AccountId' }, - ':', - 'myqueuename'))); + resolve(`arn:${new AwsPartition()}:sqs:${new AwsRegion()}:${new AwsAccountId()}:myqueuename`)); test.done(); }, @@ -34,19 +24,7 @@ export = { }); test.deepEqual(resolve(arn), - resolve(new FnConcat('arn', - ':', - 'aws-cn', - ':', - 'dynamodb', - ':', - 'us-east-1', - ':', - '123456789012', - ':', - 'table', - '/', - 'mytable/stream/label'))); + 'arn:aws-cn:dynamodb:us-east-1:123456789012:table/mytable/stream/label'); test.done(); }, @@ -60,17 +38,7 @@ export = { }); test.deepEqual(resolve(arn), - resolve(new FnConcat('arn', - ':', - 'aws-cn', - ':', - 's3', - ':', - '', - ':', - '', - ':', - 'my-bucket'))); + 'arn:aws-cn:s3:::my-bucket'); test.done(); }, @@ -84,19 +52,7 @@ export = { }); test.deepEqual(resolve(arn), - resolve(new FnConcat('arn', - ':', - { Ref: 'AWS::Partition' }, - ':', - 'codedeploy', - ':', - { Ref: 'AWS::Region' }, - ':', - { Ref: 'AWS::AccountId' }, - ':', - 'application', - ':', - 'WordPress_App'))); + resolve(`arn:${new AwsPartition()}:codedeploy:${new AwsRegion()}:${new AwsAccountId()}:application:WordPress_App`)); test.done(); }, @@ -182,7 +138,7 @@ export = { 'a Token with : separator'(test: Test) { const theToken = { Ref: 'SomeParameter' }; - const parsed = ArnUtils.parseToken(new Token(() => theToken), ':'); + const parsed = ArnUtils.parseToken(new Token(() => theToken).toString(), ':'); test.deepEqual(resolve(parsed.partition), { 'Fn::Select': [ 1, { 'Fn::Split': [ ':', theToken ]} ]}); test.deepEqual(resolve(parsed.service), { 'Fn::Select': [ 2, { 'Fn::Split': [ ':', theToken ]} ]}); @@ -197,7 +153,7 @@ export = { 'a Token with / separator'(test: Test) { const theToken = { Ref: 'SomeParameter' }; - const parsed = ArnUtils.parseToken(new Token(() => theToken)); + const parsed = ArnUtils.parseToken(new Token(() => theToken).toString()); test.equal(parsed.sep, '/'); diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.cloudformation-json.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.cloudformation-json.ts index 1ddfd6269dacb..ecc52f95aea52 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.cloudformation-json.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.cloudformation-json.ts @@ -1,5 +1,5 @@ import { Test } from 'nodeunit'; -import { CloudFormationJSON, CloudFormationToken, FnConcat, resolve, Token } from '../../lib'; +import { CloudFormationJSON, CloudFormationToken, Fn, resolve, Token } from '../../lib'; import { evaluateCFN } from './evaluate-cfn'; export = { @@ -87,7 +87,7 @@ export = { 'embedded string literals in intrinsics are escaped when calling TokenJSON.stringify()'(test: Test) { // WHEN - const token = new FnConcat('Hello', 'This\nIs', 'Very "cool"'); + const token = Fn.join('', [ 'Hello', 'This\nIs', 'Very "cool"' ]); // WHEN const resolved = resolve(CloudFormationJSON.stringify({ @@ -105,7 +105,7 @@ export = { 'Tokens in Tokens are handled correctly'(test: Test) { // GIVEN const bucketName = new CloudFormationToken({ Ref: 'MyBucket' }); - const combinedName = new FnConcat('The bucket name is ', bucketName); + const combinedName = Fn.join('', [ 'The bucket name is ', bucketName.toString() ]); // WHEN const resolved = resolve(CloudFormationJSON.stringify({ theBucket: combinedName })); diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.fn.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.fn.ts index 509834e7f2e72..649fb553a835d 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.fn.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.fn.ts @@ -1,7 +1,7 @@ import fc = require('fast-check'); import _ = require('lodash'); import nodeunit = require('nodeunit'); -import fn = require('../../lib/cloudformation/fn'); +import { Fn } from '../../lib/cloudformation/fn'; import { resolve } from '../../lib/core/tokens'; function asyncTest(cb: (test: nodeunit.Test) => Promise): (test: nodeunit.Test) => void { @@ -27,14 +27,14 @@ const anyValue = fc.oneof(nonEmptyString, tokenish); export = nodeunit.testCase({ FnJoin: { 'rejects empty list of arguments to join'(test: nodeunit.Test) { - test.throws(() => new fn.FnJoin('.', [])); + test.throws(() => Fn.join('.', [])); test.done(); }, 'resolves to the value if only one value is joined': asyncTest(async () => { await fc.assert( fc.property( fc.string(), anyValue, - (delimiter, value) => _.isEqual(resolve(new fn.FnJoin(delimiter, [value])), value) + (delimiter, value) => _.isEqual(resolve(Fn.join(delimiter, [value])), value) ), { verbose: true } ); @@ -43,7 +43,7 @@ export = nodeunit.testCase({ await fc.assert( fc.property( fc.string(), fc.array(nonEmptyString, 1, 15), - (delimiter, values) => resolve(new fn.FnJoin(delimiter, values)) === values.join(delimiter) + (delimiter, values) => resolve(Fn.join(delimiter, values)) === values.join(delimiter) ), { verbose: true } ); @@ -53,7 +53,7 @@ export = nodeunit.testCase({ fc.property( fc.string(), fc.array(nonEmptyString, 1, 3), tokenish, fc.array(nonEmptyString, 1, 3), (delimiter, prefix, obj, suffix) => - _.isEqual(resolve(new fn.FnJoin(delimiter, [...prefix, obj, ...suffix])), + _.isEqual(resolve(Fn.join(delimiter, [...prefix, obj as any, ...suffix])), { 'Fn::Join': [delimiter, [prefix.join(delimiter), obj, suffix.join(delimiter)]] }) ), { verbose: true, seed: 1539874645005, path: "0:0:0:0:0:0:0:0:0" } @@ -67,8 +67,8 @@ export = nodeunit.testCase({ fc.array(anyValue), (delimiter, prefix, nested, suffix) => // Gonna test - _.isEqual(resolve(new fn.FnJoin(delimiter, [...prefix, new fn.FnJoin(delimiter, nested), ...suffix])), - resolve(new fn.FnJoin(delimiter, [...prefix, ...nested, ...suffix]))) + _.isEqual(resolve(Fn.join(delimiter, [...prefix, Fn.join(delimiter, nested), ...suffix])), + resolve(Fn.join(delimiter, [...prefix, ...nested, ...suffix]))) ), { verbose: true } ); @@ -80,9 +80,9 @@ export = nodeunit.testCase({ fc.array(anyValue, 1, 3), fc.array(tokenish, 2, 3), fc.array(anyValue, 3), - (delimiter1, delimiter2, prefix, nested, suffix) => { + (delimiter1, delimiter2, prefix, nested, suffix) => { fc.pre(delimiter1 !== delimiter2); - const join = new fn.FnJoin(delimiter1, [...prefix, new fn.FnJoin(delimiter2, nested), ...suffix]); + const join = Fn.join(delimiter1, [...prefix, Fn.join(delimiter2, nested as any), ...suffix]); const resolved = resolve(join); return resolved['Fn::Join'][1].find((e: any) => typeof e === 'object' && ('Fn::Join' in e) diff --git a/packages/@aws-cdk/cdk/test/core/test.tokens.ts b/packages/@aws-cdk/cdk/test/core/test.tokens.ts index badab37cd1b47..341730aa91bce 100644 --- a/packages/@aws-cdk/cdk/test/core/test.tokens.ts +++ b/packages/@aws-cdk/cdk/test/core/test.tokens.ts @@ -1,5 +1,5 @@ import { Test } from 'nodeunit'; -import { CloudFormationToken, FnJoin, FnSelect, resolve, Token, unresolved } from '../../lib'; +import { CloudFormationToken, Fn, resolve, Token, unresolved } from '../../lib'; import { evaluateCFN } from '../cloudformation/evaluate-cfn'; export = { @@ -326,7 +326,7 @@ export = { const encoded: string[] = new CloudFormationToken({ Ref: 'Other' }).toList(); // WHEN - const struct = new FnSelect(1, encoded); + const struct = Fn.select(1, encoded); // THEN test.deepEqual(resolve(struct), { @@ -341,7 +341,7 @@ export = { const encoded: string[] = new CloudFormationToken({ Ref: 'Other' }).toList(); // WHEN - const struct = new FnJoin('/', encoded); + const struct = Fn.join('/', encoded); // THEN test.deepEqual(resolve(struct), { diff --git a/packages/@aws-cdk/cfnspec/build-tools/create-missing-libraries.ts b/packages/@aws-cdk/cfnspec/build-tools/create-missing-libraries.ts index 158e4d2b815cf..5d33a4a404369 100644 --- a/packages/@aws-cdk/cfnspec/build-tools/create-missing-libraries.ts +++ b/packages/@aws-cdk/cfnspec/build-tools/create-missing-libraries.ts @@ -224,7 +224,7 @@ main().catch(e => { }); async function exec(command: string) { - const child = child_process.spawn(command, { + const child = child_process.spawn(command, [], { stdio: [ 'ignore', 'inherit', 'inherit' ], shell: true }); From 69da340816ce21cefb2a72327fa28f404aed6c48 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 25 Dec 2018 12:58:11 +0200 Subject: [PATCH 02/26] Pseudo parameters from new Aws.Xxx() to Aws.xxx --- docs/src/cloudformation.rst | 2 +- docs/src/constructs.rst | 2 +- .../advanced-usage/index.ts | 18 +++--- packages/@aws-cdk/aws-apigateway/lib/stage.ts | 2 +- packages/@aws-cdk/aws-cloudtrail/lib/index.ts | 2 +- packages/@aws-cdk/aws-cloudwatch/lib/graph.ts | 8 +-- .../@aws-cdk/aws-codebuild/lib/project.ts | 2 +- .../@aws-cdk/aws-codecommit/lib/repository.ts | 2 +- .../aws-codedeploy/lib/deployment-group.ts | 4 +- .../aws-ecs/lib/log-drivers/aws-log-driver.ts | 2 +- .../lib/shared/imported.ts | 2 +- .../@aws-cdk/aws-iam/lib/policy-document.ts | 6 +- packages/@aws-cdk/aws-kinesis/lib/stream.ts | 2 +- packages/@aws-cdk/aws-kms/test/integ.key.ts | 4 +- .../@aws-cdk/aws-lambda/lib/lambda-ref.ts | 4 +- .../@aws-cdk/aws-lambda/test/test.lambda.ts | 2 +- .../@aws-cdk/aws-route53/lib/hosted-zone.ts | 2 +- packages/@aws-cdk/aws-s3/lib/bucket.ts | 2 +- .../aws-stepfunctions/lib/state-machine.ts | 2 +- .../@aws-cdk/cdk/lib/cloudformation/arn.ts | 8 +-- .../@aws-cdk/cdk/lib/cloudformation/pseudo.ts | 58 +++++++++++++++---- .../cdk/test/cloudformation/test.arn.ts | 6 +- packages/@aws-cdk/runtime-values/lib/rtv.ts | 4 +- 23 files changed, 92 insertions(+), 54 deletions(-) diff --git a/docs/src/cloudformation.rst b/docs/src/cloudformation.rst index 1042536300834..2bfd502d92f3a 100644 --- a/docs/src/cloudformation.rst +++ b/docs/src/cloudformation.rst @@ -184,7 +184,7 @@ Pseudo Parameters .. code-block:: js import cdk = require('@aws-cdk/cdk'); - new cdk.AwsRegion() + cdk.Aws.region .. Add a new topic in "Advanced Topics" about integrating cdk synch > mytemplate diff --git a/docs/src/constructs.rst b/docs/src/constructs.rst index f21c583119dd9..b2594f00dacd8 100644 --- a/docs/src/constructs.rst +++ b/docs/src/constructs.rst @@ -145,7 +145,7 @@ Construct IDs may be any string with the following caveats: * Path separators (``/``s) will be replaced by double-dashes ``--``. This means that if you are trying to look up a child construct that may have a path separator, you will need to manually replace it with ``--``. -* Construct IDs may not include unresolved tokens (such as `new AwsRegion()`). This is +* Construct IDs may not include unresolved tokens (such as `Aws.region`). This is because those tokens are only resolved during deployment, and therefore cannot be used to render a stable logical ID for any resources in this tree. diff --git a/examples/cdk-examples-typescript/advanced-usage/index.ts b/examples/cdk-examples-typescript/advanced-usage/index.ts index 233df2d25be1a..579e326898dd2 100644 --- a/examples/cdk-examples-typescript/advanced-usage/index.ts +++ b/examples/cdk-examples-typescript/advanced-usage/index.ts @@ -157,7 +157,7 @@ class CloudFormationExample extends cdk.Stack { // outputs are constructs the synthesize into the template's "Outputs" section new cdk.Output(this, 'Output', { description: 'This is an output of the template', - value: `${new cdk.AwsAccountId()}/${param.ref}` + value: `${cdk.Aws.accountId}/${param.ref}` }); // stack.templateOptions can be used to specify template-level options @@ -166,14 +166,14 @@ class CloudFormationExample extends cdk.Stack { // all CloudFormation's pseudo-parameters are supported via the `cdk.AwsXxx` classes PseudoParameters: [ - new cdk.AwsAccountId(), - new cdk.AwsDomainSuffix(), - new cdk.AwsNotificationARNs(), - new cdk.AwsNoValue(), - new cdk.AwsPartition(), - new cdk.AwsRegion(), - new cdk.AwsStackId(), - new cdk.AwsStackName(), + cdk.Aws.accountId, + cdk.Aws.domainSuffix, + cdk.Aws.notificationARNs, + cdk.Aws.noValue, + cdk.Aws.partition, + cdk.Aws.region, + cdk.Aws.stackId, + cdk.Aws.stackName, ], // all CloudFormation's intrinsic functions are supported via the `cdk.Fn.xxx` static methods. diff --git a/packages/@aws-cdk/aws-apigateway/lib/stage.ts b/packages/@aws-cdk/aws-apigateway/lib/stage.ts index a2bac5bf90e2b..782dad780bcb5 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/stage.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/stage.ts @@ -173,7 +173,7 @@ export class Stage extends cdk.Construct implements cdk.IDependable { if (!path.startsWith('/')) { throw new Error(`Path must begin with "/": ${path}`); } - return `https://${this.restApi.restApiId}.execute-api.${new cdk.AwsRegion()}.amazonaws.com/${this.stageName}${path}`; + return `https://${this.restApi.restApiId}.execute-api.${cdk.Aws.region}.amazonaws.com/${this.stageName}${path}`; } private renderMethodSettings(props: StageProps): CfnStage.MethodSettingProperty[] | undefined { diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts index cdbe5749261cd..75735e83c51a6 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts @@ -138,7 +138,7 @@ export class CloudTrail extends cdk.Construct { .addServicePrincipal(cloudTrailPrincipal)); s3bucket.addToResourcePolicy(new iam.PolicyStatement() - .addResource(s3bucket.arnForObjects(`AWSLogs/${new cdk.AwsAccountId()}/*`)) + .addResource(s3bucket.arnForObjects(`AWSLogs/${cdk.Aws.accountId}/*`)) .addActions("s3:PutObject") .addServicePrincipal(cloudTrailPrincipal) .setCondition("StringEquals", {'s3:x-amz-acl': "bucket-owner-full-control"})); diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts b/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts index 27dc9c4cb44b4..2fc2d2baf48a3 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts @@ -1,4 +1,4 @@ -import { AwsRegion } from "@aws-cdk/cdk"; +import { Aws } from "@aws-cdk/cdk"; import { Alarm } from "./alarm"; import { Metric } from "./metric"; import { parseStatistic } from './util.statistic'; @@ -73,7 +73,7 @@ export class AlarmWidget extends ConcreteWidget { properties: { view: 'timeSeries', title: this.props.title, - region: this.props.region || new AwsRegion(), + region: this.props.region || Aws.region, annotations: { alarms: [this.props.alarm.alarmArn] }, @@ -150,7 +150,7 @@ export class GraphWidget extends ConcreteWidget { properties: { view: 'timeSeries', title: this.props.title, - region: this.props.region || new AwsRegion(), + region: this.props.region || Aws.region, metrics: (this.props.left || []).map(m => metricJson(m, 'left')).concat( (this.props.right || []).map(m => metricJson(m, 'right'))), annotations: { @@ -197,7 +197,7 @@ export class SingleValueWidget extends ConcreteWidget { properties: { view: 'singleValue', title: this.props.title, - region: this.props.region || new AwsRegion(), + region: this.props.region || Aws.region, metrics: this.props.metrics.map(m => metricJson(m, 'left')) } }]; diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index 4ce51ac2412e0..d67b61250b31a 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -495,7 +495,7 @@ export class Project extends ProjectRef { let cache: CfnProject.ProjectCacheProperty | undefined; if (props.cacheBucket) { - const cacheDir = props.cacheDir != null ? props.cacheDir : new cdk.AwsNoValue().toString(); + const cacheDir = props.cacheDir != null ? props.cacheDir : cdk.Aws.noValue; cache = { type: 'S3', location: cdk.Fn.join('/', [props.cacheBucket.bucketName, cacheDir]), diff --git a/packages/@aws-cdk/aws-codecommit/lib/repository.ts b/packages/@aws-cdk/aws-codecommit/lib/repository.ts index c28be77131b21..22ea9737a3f44 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/repository.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/repository.ts @@ -196,7 +196,7 @@ class ImportedRepositoryRef extends RepositoryRef { } private repositoryCloneUrl(protocol: 'https' | 'ssh'): string { - return `${protocol}://git-codecommit.${new cdk.AwsRegion()}.${new cdk.AwsURLSuffix()}/v1/repos/${this.repositoryName}`; + return `${protocol}://git-codecommit.${cdk.Aws.region}.${cdk.Aws.urlSuffix}/v1/repos/${this.repositoryName}`; } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts index 95b3557ad70c7..d5a1defffb1a7 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts @@ -304,7 +304,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef { this._autoScalingGroups = props.autoScalingGroups || []; this.installAgent = props.installAgent === undefined ? true : props.installAgent; - const region = (new cdk.AwsRegion()).toString(); + const region = (cdk.Aws.region).toString(); this.codeDeployBucket = s3.BucketRef.import(this, 'CodeDeployBucket', { bucketName: `aws-codedeploy-${region}`, }); @@ -371,7 +371,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef { this.codeDeployBucket.grantRead(asg.role, 'latest/*'); - const region = (new cdk.AwsRegion()).toString(); + const region = (cdk.Aws.region).toString(); switch (asg.osType) { case ec2.OperatingSystemType.Linux: asg.addUserData( diff --git a/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts b/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts index 0a5a445d7e5c0..5e43f5549fa50 100644 --- a/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts +++ b/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts @@ -78,7 +78,7 @@ export class AwsLogDriver extends LogDriver { options: removeEmpty({ 'awslogs-group': this.logGroup.logGroupName, 'awslogs-stream-prefix': this.props.streamPrefix, - 'awslogs-region': `${new cdk.AwsRegion()}`, + 'awslogs-region': cdk.Aws.region, 'awslogs-datetime-format': this.props.datetimeFormat, 'awslogs-multiline-pattern': this.props.multilinePattern, }), diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts index fe989ed60a789..e16b7b56cb9c4 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts @@ -19,6 +19,6 @@ export class BaseImportedTargetGroup extends cdk.Construct { super(parent, id); this.targetGroupArn = props.targetGroupArn; - this.loadBalancerArns = props.loadBalancerArns || new cdk.AwsNoValue().toString(); + this.loadBalancerArns = props.loadBalancerArns || cdk.Aws.noValue; } } diff --git a/packages/@aws-cdk/aws-iam/lib/policy-document.ts b/packages/@aws-cdk/aws-iam/lib/policy-document.ts index 5022a6f7445ca..0f201f71f7c62 100644 --- a/packages/@aws-cdk/aws-iam/lib/policy-document.ts +++ b/packages/@aws-cdk/aws-iam/lib/policy-document.ts @@ -1,4 +1,4 @@ -import { AwsAccountId, AwsPartition, Token } from '@aws-cdk/cdk'; +import { Aws, Token } from '@aws-cdk/cdk'; export class PolicyDocument extends Token { private statements = new Array(); @@ -82,7 +82,7 @@ export class ArnPrincipal extends PolicyPrincipal { export class AccountPrincipal extends ArnPrincipal { constructor(public readonly accountId: any) { - super(`arn:${new AwsPartition()}:iam::${accountId}:root`); + super(`arn:${Aws.partition}:iam::${accountId}:root`); } } @@ -137,7 +137,7 @@ export class FederatedPrincipal extends PolicyPrincipal { export class AccountRootPrincipal extends AccountPrincipal { constructor() { - super(new AwsAccountId()); + super(Aws.accountId); } } diff --git a/packages/@aws-cdk/aws-kinesis/lib/stream.ts b/packages/@aws-cdk/aws-kinesis/lib/stream.ts index a7261a929c0bf..2fa21ca8bbc6a 100644 --- a/packages/@aws-cdk/aws-kinesis/lib/stream.ts +++ b/packages/@aws-cdk/aws-kinesis/lib/stream.ts @@ -170,7 +170,7 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr if (!this.cloudWatchLogsRole) { // Create a role to be assumed by CWL that can write to this stream and pass itself. this.cloudWatchLogsRole = new iam.Role(this, 'CloudWatchLogsCanPutRecords', { - assumedBy: new iam.ServicePrincipal(`logs.${new cdk.AwsRegion()}.amazonaws.com`) + assumedBy: new iam.ServicePrincipal(`logs.${cdk.Aws.region}.amazonaws.com`) }); this.cloudWatchLogsRole.addToPolicy(new iam.PolicyStatement().addAction('kinesis:PutRecord').addResource(this.streamArn)); this.cloudWatchLogsRole.addToPolicy(new iam.PolicyStatement().addAction('iam:PassRole').addResource(this.cloudWatchLogsRole.roleArn)); diff --git a/packages/@aws-cdk/aws-kms/test/integ.key.ts b/packages/@aws-cdk/aws-kms/test/integ.key.ts index f682b1d19fe6e..f9920bb406698 100644 --- a/packages/@aws-cdk/aws-kms/test/integ.key.ts +++ b/packages/@aws-cdk/aws-kms/test/integ.key.ts @@ -1,5 +1,5 @@ import { PolicyStatement } from '@aws-cdk/aws-iam'; -import { App, AwsAccountId, Stack } from '@aws-cdk/cdk'; +import { App, Aws, Stack } from '@aws-cdk/cdk'; import { EncryptionKey } from '../lib'; const app = new App(); @@ -11,7 +11,7 @@ const key = new EncryptionKey(stack, 'MyKey'); key.addToResourcePolicy(new PolicyStatement() .addAllResources() .addAction('kms:encrypt') - .addAwsPrincipal(new AwsAccountId().toString())); + .addAwsPrincipal(Aws.accountId)); key.addAlias('alias/bar'); diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts index 2971dc26c76d8..4bafd28ce8933 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts @@ -320,7 +320,7 @@ export abstract class FunctionRef extends cdk.Construct // // (Wildcards in principals are unfortunately not supported. this.addPermission('InvokedByCloudWatchLogs', { - principal: new iam.ServicePrincipal(`logs.${new cdk.AwsRegion()}.amazonaws.com`), + principal: new iam.ServicePrincipal(`logs.${cdk.Aws.region}.amazonaws.com`), sourceArn: arn }); this.logSubscriptionDestinationPolicyAddedFor.push(arn); @@ -348,7 +348,7 @@ export abstract class FunctionRef extends cdk.Construct const permissionId = `AllowBucketNotificationsFrom${bucketId}`; if (!this.tryFindChild(permissionId)) { this.addPermission(permissionId, { - sourceAccount: new cdk.AwsAccountId().toString(), + sourceAccount: cdk.Aws.accountId.toString(), principal: new iam.ServicePrincipal('s3.amazonaws.com'), sourceArn: bucketArn, }); diff --git a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts index ebcca95f660e6..1241cfd5ba89c 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts @@ -118,7 +118,7 @@ export = { fn.addPermission('S3Permission', { action: 'lambda:*', principal: new iam.ServicePrincipal('s3.amazonaws.com'), - sourceAccount: new cdk.AwsAccountId().toString(), + sourceAccount: cdk.Aws.accountId, sourceArn: 'arn:aws:s3:::my_bucket' }); diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index 4769734048bc1..4a5a76aa59bb2 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts @@ -121,7 +121,7 @@ export class PrivateHostedZone extends HostedZoneRef { } function toVpcProperty(vpc: ec2.VpcNetworkRef): CfnHostedZone.VPCProperty { - return { vpcId: vpc.vpcId, vpcRegion: new cdk.AwsRegion() }; + return { vpcId: vpc.vpcId, vpcRegion: cdk.Aws.region }; } function determineHostedZoneProps(props: PublicHostedZoneProps) { diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 397ee7dce012f..2a654e7cde16d 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -166,7 +166,7 @@ export abstract class BucketRef extends cdk.Construct { * @returns an ObjectS3Url token */ public urlForObject(key?: string): string { - const components = [ 'https://', 's3.', new cdk.AwsRegion(), '.', new cdk.AwsURLSuffix(), '/', this.bucketName ]; + const components = [ 'https://', 's3.', cdk.Aws.region, '.', cdk.Aws.urlSuffix, '/', this.bucketName ]; if (key) { // trim prepending '/' if (typeof key === 'string' && key.startsWith('/')) { diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts index 1368bc599f37a..7ac12dfcad853 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts @@ -72,7 +72,7 @@ export class StateMachine extends cdk.Construct implements IStateMachine { super(parent, id); this.role = props.role || new iam.Role(this, 'Role', { - assumedBy: new iam.ServicePrincipal(`states.${new cdk.AwsRegion()}.amazonaws.com`), + assumedBy: new iam.ServicePrincipal(`states.${cdk.Aws.region}.amazonaws.com`) }); const graph = new StateGraph(props.definition.startState, `State Machine ${id} definition`); diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts b/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts index 52e2fb3a563a3..61670850f7336 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts @@ -1,4 +1,4 @@ -import { AwsAccountId, AwsPartition, AwsRegion } from '..'; +import { Aws } from '..'; import { Fn } from '../cloudformation/fn'; import { unresolved } from '../core/tokens'; @@ -23,13 +23,13 @@ export class ArnUtils { */ public static fromComponents(components: ArnComponents): string { const partition = components.partition == null - ? new AwsPartition() + ? Aws.partition : components.partition; const region = components.region == null - ? new AwsRegion() + ? Aws.region : components.region; const account = components.account == null - ? new AwsAccountId() + ? Aws.accountId : components.account; const values = [ 'arn', ':', partition, ':', components.service, ':', region, ':', account, ':', components.resource ]; diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/pseudo.ts b/packages/@aws-cdk/cdk/lib/cloudformation/pseudo.ts index e576320655ec2..c0121d2a07e9a 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/pseudo.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/pseudo.ts @@ -1,60 +1,98 @@ import { CloudFormationToken } from './cloudformation-token'; -export class PseudoParameter extends CloudFormationToken { +export class Aws { + public static get accountId(): string { + return new AwsAccountId().toString(); + } + + public static get domainSuffix(): string { + return new AwsDomainSuffix().toString(); + } + + public static get urlSuffix(): string { + return new AwsURLSuffix().toString(); + } + + public static get notificationARNs(): string[] { + return new AwsNotificationARNs().toList(); + } + + public static get noValue(): string { + return new AwsNoValue().toString(); + } + + public static get partition(): string { + return new AwsPartition().toString(); + } + + public static get region(): string { + return new AwsRegion().toString(); + } + + public static get stackId(): string { + return new AwsStackId().toString(); + } + + public static get stackName(): string { + return new AwsStackName().toString(); + } +} + +class PseudoParameter extends CloudFormationToken { constructor(name: string) { super({ Ref: name }, name); } } -export class AwsAccountId extends PseudoParameter { +class AwsAccountId extends PseudoParameter { constructor() { super('AWS::AccountId'); } } -export class AwsDomainSuffix extends PseudoParameter { +class AwsDomainSuffix extends PseudoParameter { constructor() { super('AWS::DomainSuffix'); } } -export class AwsURLSuffix extends PseudoParameter { +class AwsURLSuffix extends PseudoParameter { constructor() { super('AWS::URLSuffix'); } } -export class AwsNotificationARNs extends PseudoParameter { +class AwsNotificationARNs extends PseudoParameter { constructor() { super('AWS::NotificationARNs'); } } -export class AwsNoValue extends PseudoParameter { +class AwsNoValue extends PseudoParameter { constructor() { super('AWS::NoValue'); } } -export class AwsPartition extends PseudoParameter { +class AwsPartition extends PseudoParameter { constructor() { super('AWS::Partition'); } } -export class AwsRegion extends PseudoParameter { +class AwsRegion extends PseudoParameter { constructor() { super('AWS::Region'); } } -export class AwsStackId extends PseudoParameter { +class AwsStackId extends PseudoParameter { constructor() { super('AWS::StackId'); } } -export class AwsStackName extends PseudoParameter { +class AwsStackName extends PseudoParameter { constructor() { super('AWS::StackName'); } diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts index 18b90b460db69..5869eb6eb00bd 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts @@ -1,5 +1,5 @@ import { Test } from 'nodeunit'; -import { ArnComponents, ArnUtils, AwsAccountId, AwsPartition, AwsRegion, resolve, Token } from '../../lib'; +import { ArnComponents, ArnUtils, Aws, resolve, Token } from '../../lib'; export = { 'create from components with defaults'(test: Test) { @@ -9,7 +9,7 @@ export = { }); test.deepEqual(resolve(arn), - resolve(`arn:${new AwsPartition()}:sqs:${new AwsRegion()}:${new AwsAccountId()}:myqueuename`)); + resolve(`arn:${Aws.partition}:sqs:${Aws.region}:${Aws.accountId}:myqueuename`)); test.done(); }, @@ -52,7 +52,7 @@ export = { }); test.deepEqual(resolve(arn), - resolve(`arn:${new AwsPartition()}:codedeploy:${new AwsRegion()}:${new AwsAccountId()}:application:WordPress_App`)); + resolve(`arn:${Aws.partition}:codedeploy:${Aws.region}:${Aws.accountId}:application:WordPress_App`)); test.done(); }, diff --git a/packages/@aws-cdk/runtime-values/lib/rtv.ts b/packages/@aws-cdk/runtime-values/lib/rtv.ts index d909df03cf86c..975170df63101 100644 --- a/packages/@aws-cdk/runtime-values/lib/rtv.ts +++ b/packages/@aws-cdk/runtime-values/lib/rtv.ts @@ -30,7 +30,7 @@ export class RuntimeValue extends cdk.Construct { /** * The value to assign to the `RTV_STACK_NAME` environment variable. */ - public static readonly ENV_VALUE = new cdk.AwsStackName(); + public static readonly ENV_VALUE = cdk.Aws.stackName; /** * IAM actions needed to read a value from an SSM parameter. @@ -54,7 +54,7 @@ export class RuntimeValue extends cdk.Construct { constructor(parent: cdk.Construct, name: string, props: RuntimeValueProps) { super(parent, name); - this.parameterName = `/rtv/${new cdk.AwsStackName()}/${props.package}/${name}`; + this.parameterName = `/rtv/${cdk.Aws.stackName}/${props.package}/${name}`; new ssm.CfnParameter(this, 'Parameter', { name: this.parameterName, From f2827d0bbf8ed7e196151f3d9572b81fdd37d2c2 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 25 Dec 2018 14:35:06 +0200 Subject: [PATCH 03/26] Finalize change --- CHANGELOG.md | 2 +- docs/src/cloudformation.rst | 8 +- .../@aws-cdk/aws-ecr/test/test.repository.ts | 8 +- .../@aws-cdk/cdk/lib/cloudformation/fn.ts | 222 +++++++++++++++--- .../cdk/test/cloudformation/test.resource.ts | 4 +- .../cdk/test/cloudformation/test.rule.ts | 6 +- 6 files changed, 209 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b868c6a3b3229..5e55e6526b886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1700,7 +1700,7 @@ Fn.if_(Fn.equals(param.ref, 'True'), 'Encrypted', Pseudo.NO_VALUE) After: ```javascript -new FnIf(new FnEquals(param.ref, 'True'), 'Encrypted', new AwsNoValue()) +new FnIf(Fn.equals(param.ref, 'True'), 'Encrypted', new AwsNoValue()) ``` - CloudFormation template options (`templateFormatVersion`, `description` and `transform`) are now grouped under `Stack.templateOptions` instead of directly under `Stack`. diff --git a/docs/src/cloudformation.rst b/docs/src/cloudformation.rst index 2bfd502d92f3a..8bf7ce6f708dc 100644 --- a/docs/src/cloudformation.rst +++ b/docs/src/cloudformation.rst @@ -171,8 +171,8 @@ Intrinsic Functions .. code-block:: js - import cdk = require('@aws-cdk/cdk'); - cdk.Fn.join(",", [...]) + import { Fn } from'@aws-cdk/cdk'; + Fn.join(",", [...]) .. _pseudo_parameters: @@ -183,8 +183,8 @@ Pseudo Parameters .. code-block:: js - import cdk = require('@aws-cdk/cdk'); - cdk.Aws.region + import { Aws } from '@aws-cdk/cdk'; + Aws.region .. Add a new topic in "Advanced Topics" about integrating cdk synch > mytemplate diff --git a/packages/@aws-cdk/aws-ecr/test/test.repository.ts b/packages/@aws-cdk/aws-ecr/test/test.repository.ts index e62819e6584cd..a9b58c486b04c 100644 --- a/packages/@aws-cdk/aws-ecr/test/test.repository.ts +++ b/packages/@aws-cdk/aws-ecr/test/test.repository.ts @@ -192,7 +192,7 @@ export = { // WHEN/THEN test.throws(() => ecr.Repository.import(stack, 'Repo', { - repositoryArn: new cdk.FnGetAtt('Boom', 'Boom').toString() + repositoryArn: cdk.Fn.getAtt('Boom', 'Boom').toString() }), /repositoryArn is a late-bound value, and therefore repositoryName is required/); test.done(); @@ -204,8 +204,8 @@ export = { // WHEN const repo = ecr.Repository.import(stack, 'Repo', { - repositoryArn: new cdk.FnGetAtt('Boom', 'Arn').toString(), - repositoryName: new cdk.FnGetAtt('Boom', 'Name').toString() + repositoryArn: cdk.Fn.getAtt('Boom', 'Arn').toString(), + repositoryName: cdk.Fn.getAtt('Boom', 'Name').toString() }); // THEN @@ -242,7 +242,7 @@ export = { 'arnForLocalRepository can be used to render an ARN for a local repository'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const repoName = new cdk.FnGetAtt('Boom', 'Name').toString(); + const repoName = cdk.Fn.getAtt('Boom', 'Name').toString(); // WHEN const repo = ecr.Repository.import(stack, 'Repo', { diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts index 1f89ca23aa62d..14fd3b61fcda7 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts @@ -8,6 +8,20 @@ import { CloudFormationToken, FnJoin } from './cloudformation-token'; */ export class Fn { + /** + * The ``Fn::GetAtt`` intrinsic function returns the value of an attribute + * from a resource in the template. + * @param logicalNameOfResource The logical name (also called logical ID) of + * the resource that contains the attribute that you want. + * @param attributeName The name of the resource-specific attribute whose + * value you want. See the resource's reference page for details about the + * attributes available for that resource type. + * @returns a CloudFormationToken object + */ + public static getAtt(logicalNameOfResource: string, attributeName: string): CloudFormationToken { + return new FnGetAtt(logicalNameOfResource, attributeName); + } + /** * The intrinsic function ``Fn::Join`` appends a set of values into a single * value, separated by the specified delimiter. If a delimiter is the empty @@ -16,6 +30,7 @@ export class Fn { * delimiter will occur between fragments only. It will not terminate the * final value. * @param listOfValues The list of values you want combined. + * @returns a token represented as a string */ public static join(delimiter: string, listOfValues: string[]): string { return new FnJoin(delimiter, listOfValues).toString(); @@ -28,6 +43,7 @@ export class Fn { * to pick a specific element. * @param delimiter A string value that determines where the source string is divided. * @param source The string value that you want to split. + * @returns a token represented as a string array */ public static split(delimiter: string, source: string): string[] { return new FnSplit(delimiter, source).toList(); @@ -37,6 +53,7 @@ export class Fn { * The intrinsic function ``Fn::Select`` returns a single object from a list of objects by index. * @param index The index of the object to retrieve. This must be a value from zero to N-1, where N represents the number of elements in the array. * @param array The list of objects to select from. This list must not be null, nor can it have null entries. + * @returns a token represented as a string */ public static select(index: number, array: string[]): string { return new FnSelect(index, array).toString(); @@ -56,16 +73,18 @@ export class Fn { * @param variables The name of a variable that you included in the String * parameter. The value that AWS CloudFormation substitutes for the associated * variable name at runtime. + * @returns a token represented as a string */ public static sub(body: string, variables?: { [key: string]: string }): string { return new FnSub(body, variables).toString(); } /** - * The intrinsic function ``Fn::Base64`` returns the Base64 representation of the input string. - * This function is typically used to pass encoded data to Amazon EC2 instances by way of - * the UserData property. + * The intrinsic function ``Fn::Base64`` returns the Base64 representation of + * the input string. This function is typically used to pass encoded data to + * Amazon EC2 instances by way of the UserData property. * @param data The string value you want to convert to Base64. + * @returns a token represented as a string */ public static base64(data: string): string { return new FnBase64(data).toString(); @@ -76,49 +95,198 @@ export class Fn { * @param ipBlock The user-specified default Cidr address block. * @param count The number of subnets' Cidr block wanted. Count can be 1 to 256. * @param sizeMask The digit covered in the subnet. + * @returns a token represented as a string */ public static cidr(ipBlock: string, count: number, sizeMask?: string): string { return new FnCidr(ipBlock, count, sizeMask).toString(); } /** - * The intrinsic function ``Fn::GetAZs`` returns an array that lists Availability Zones for a - * specified region. Because customers have access to different Availability Zones, the intrinsic - * function ``Fn::GetAZs`` enables template authors to write templates that adapt to the calling - * user's access. That way you don't have to hard-code a full list of Availability Zones for a - * specified region. + * The intrinsic function ``Fn::GetAZs`` returns an array that lists + * Availability Zones for a specified region. Because customers have access to + * different Availability Zones, the intrinsic function ``Fn::GetAZs`` enables + * template authors to write templates that adapt to the calling user's + * access. That way you don't have to hard-code a full list of Availability + * Zones for a specified region. * @param region The name of the region for which you want to get the * Availability Zones. You can use the AWS::Region pseudo parameter to specify * the region in which the stack is created. Specifying an empty string is * equivalent to specifying AWS::Region. + * @returns a token represented as a string array */ public static getAZs(region?: string): string[] { return new FnGetAZs(region).toList(); } /** - * The intrinsic function ``Fn::ImportValue`` returns the value of an output exported by another stack. - * You typically use this function to create cross-stack references. In the following example - * template snippets, Stack A exports VPC security group values and Stack B imports them. + * The intrinsic function ``Fn::ImportValue`` returns the value of an output + * exported by another stack. You typically use this function to create + * cross-stack references. In the following example template snippets, Stack A + * exports VPC security group values and Stack B imports them. * @param sharedValueToImport The stack output value that you want to import. + * @returns a token represented as a string */ public static importValue(sharedValueToImport: string): string { return new FnImportValue(sharedValueToImport).toString(); } /** - * The intrinsic function ``Fn::FindInMap`` returns the value corresponding to keys in a two-level - * map that is declared in the Mappings section. + * The intrinsic function ``Fn::FindInMap`` returns the value corresponding to + * keys in a two-level map that is declared in the Mappings section. + * @returns a token represented as a string */ public static findInMap(mapName: string, topLevelKey: string, secondLevelKey: string): string { return new FnFindInMap(mapName, topLevelKey, secondLevelKey).toString(); } + /** + * Returns true if all the specified conditions evaluate to true, or returns + * false if any one of the conditions evaluates to false. ``Fn::And`` acts as + * an AND operator. The minimum number of conditions that you can include is + * 2, and the maximum is 10. + * @param conditions conditions to AND + * @returns an FnCondition token + */ + public static andCondition(...conditions: FnCondition[]): FnCondition { + return new FnAnd(...conditions); + } + + /** + * Compares if two values are equal. Returns true if the two values are equal + * or false if they aren't. + * @param lhs A value of any type that you want to compare. + * @param rhs A value of any type that you want to compare. + * @returns an FnCondition token + */ + public static equalsCondition(lhs: any, rhs: any): FnCondition { + return new FnEquals(lhs, rhs); + } + + /** + * Returns one value if the specified condition evaluates to true and another + * value if the specified condition evaluates to false. Currently, AWS + * CloudFormation supports the ``Fn::If`` intrinsic function in the metadata + * attribute, update policy attribute, and property values in the Resources + * section and Outputs sections of a template. You can use the AWS::NoValue + * pseudo parameter as a return value to remove the corresponding property. + * @param condition A reference to a condition in the Conditions section. Use + * the condition's name to reference it. + * @param valueIfTrue A value to be returned if the specified condition + * evaluates to true. + * @param valueIfFalse A value to be returned if the specified condition + * evaluates to false. + * @returns an FnCondition token + */ + public static ifCondition(conditionId: string, valueIfTrue: any, valueIfFalse: any): FnCondition { + return new FnIf(conditionId, valueIfTrue, valueIfFalse); + } + + /** + * Returns true for a condition that evaluates to false or returns false for a + * condition that evaluates to true. ``Fn::Not`` acts as a NOT operator. + * @param condition A condition such as ``Fn::Equals`` that evaluates to true + * or false. + * @returns an FnCondition token + */ + public static notCondition(condition: FnCondition): FnCondition { + return new FnNot(condition); + } + + /** + * Returns true if any one of the specified conditions evaluate to true, or + * returns false if all of the conditions evaluates to false. ``Fn::Or`` acts + * as an OR operator. The minimum number of conditions that you can include is + * 2, and the maximum is 10. + * @param conditions conditions that evaluates to true or false. + * @returns an FnCondition token + */ + public static orCondition(...conditions: FnCondition[]): FnCondition { + return new FnOr(...conditions); + } + + /** + * Returns true if a specified string matches at least one value in a list of + * strings. + * @param listOfStrings A list of strings, such as "A", "B", "C". + * @param value A string, such as "A", that you want to compare against a list of strings. + * @returns an FnCondition token + */ + public static containsCondition(listOfStrings: string[], value: string): FnCondition { + return new FnContains(listOfStrings, value); + } + + /** + * Returns true if a specified string matches all values in a list. + * @param listOfStrings A list of strings, such as "A", "B", "C". + * @param value A string, such as "A", that you want to compare against a list + * of strings. + * @returns an FnCondition token + */ + public eachMemberEqualsCondition(listOfStrings: string[], value: string): FnCondition { + return new FnEachMemberEquals(listOfStrings, value); + } + + /** + * Returns true if each member in a list of strings matches at least one value + * in a second list of strings. + * @param stringsToCheck A list of strings, such as "A", "B", "C". AWS + * CloudFormation checks whether each member in the strings_to_check parameter + * is in the strings_to_match parameter. + * @param stringsToMatch A list of strings, such as "A", "B", "C". Each member + * in the strings_to_match parameter is compared against the members of the + * strings_to_check parameter. + * @returns an FnCondition token + */ + public eachMemberInCondition(stringsToCheck: string[], stringsToMatch: string): FnCondition { + return new FnEachMemberIn(stringsToCheck, stringsToMatch); + } + + /** + * Returns all values for a specified parameter type. + * @param parameterType An AWS-specific parameter type, such as + * AWS::EC2::SecurityGroup::Id or AWS::EC2::VPC::Id. For more information, see + * Parameters in the AWS CloudFormation User Guide. + * @returns a token represented as a string array + */ + public refAll(parameterType: string): string[] { + return new FnRefAll(parameterType).toList(); + } + + /** + * Returns an attribute value or list of values for a specific parameter and + * attribute. + * @param parameterOrLogicalId The name of a parameter for which you want to + * retrieve attribute values. The parameter must be declared in the Parameters + * section of the template. + * @param attribute The name of an attribute from which you want to retrieve a + * value. + * @returns a token represented as a string + */ + public valueOf(parameterOrLogicalId: string, attribute: string): string { + return new FnValueOf(parameterOrLogicalId, attribute).toString(); + } + + /** + * Returns a list of all attribute values for a given parameter type and + * attribute. + * @param parameterType An AWS-specific parameter type, such as + * AWS::EC2::SecurityGroup::Id or AWS::EC2::VPC::Id. For more information, see + * Parameters in the AWS CloudFormation User Guide. + * @param attribute The name of an attribute from which you want to retrieve a + * value. For more information about attributes, see Supported Attributes. + * @returns a token represented as a string array + */ + public valueOfAll(parameterType: string, attribute: string): string[] { + return new FnValueOfAll(parameterType, attribute).toList(); + } } -export class FnBase extends CloudFormationToken { +/** + * Base class for tokens that represent CloudFormation intrinsic functions. + */ +class FnBase extends CloudFormationToken { constructor(name: string, value: any) { - super(() => ({ [name]: value })); + super({ [name]: value }); } } @@ -141,7 +309,7 @@ class FnFindInMap extends FnBase { /** * The ``Fn::GetAtt`` intrinsic function returns the value of an attribute from a resource in the template. */ -export class FnGetAtt extends FnBase { +class FnGetAtt extends FnBase { /** * Creates a ``Fn::GetAtt`` function. * @param logicalNameOfResource The logical name (also called logical ID) of the resource that contains the attribute that you want. @@ -301,7 +469,7 @@ export class FnCondition extends FnBase { * of the conditions evaluates to false. ``Fn::And`` acts as an AND operator. The minimum number of * conditions that you can include is 2, and the maximum is 10. */ -export class FnAnd extends FnCondition { +class FnAnd extends FnCondition { constructor(...condition: FnCondition[]) { super('Fn::And', condition); } @@ -311,7 +479,7 @@ export class FnAnd extends FnCondition { * Compares if two values are equal. Returns true if the two values are equal or false * if they aren't. */ -export class FnEquals extends FnCondition { +class FnEquals extends FnCondition { /** * Creates an ``Fn::Equals`` condition function. * @param lhs A value of any type that you want to compare. @@ -329,7 +497,7 @@ export class FnEquals extends FnCondition { * in the Resources section and Outputs sections of a template. You can use the AWS::NoValue * pseudo parameter as a return value to remove the corresponding property. */ -export class FnIf extends FnCondition { +class FnIf extends FnCondition { /** * Creates an ``Fn::If`` condition function. * @param condition A reference to a condition in the Conditions section. Use the condition's name to reference it. @@ -345,7 +513,7 @@ export class FnIf extends FnCondition { * Returns true for a condition that evaluates to false or returns false for a condition that evaluates to true. * ``Fn::Not`` acts as a NOT operator. */ -export class FnNot extends FnCondition { +class FnNot extends FnCondition { /** * Creates an ``Fn::Not`` condition function. * @param condition A condition such as ``Fn::Equals`` that evaluates to true or false. @@ -360,7 +528,7 @@ export class FnNot extends FnCondition { * all of the conditions evaluates to false. ``Fn::Or`` acts as an OR operator. The minimum number * of conditions that you can include is 2, and the maximum is 10. */ -export class FnOr extends FnCondition { +class FnOr extends FnCondition { /** * Creates an ``Fn::Or`` condition function. * @param condition A condition that evaluates to true or false. @@ -373,7 +541,7 @@ export class FnOr extends FnCondition { /** * Returns true if a specified string matches at least one value in a list of strings. */ -export class FnContains extends FnCondition { +class FnContains extends FnCondition { /** * Creates an ``Fn::Contains`` function. * @param listOfStrings A list of strings, such as "A", "B", "C". @@ -387,7 +555,7 @@ export class FnContains extends FnCondition { /** * Returns true if a specified string matches all values in a list. */ -export class FnEachMemberEquals extends FnCondition { +class FnEachMemberEquals extends FnCondition { /** * Creates an ``Fn::EachMemberEquals`` function. * @param listOfStrings A list of strings, such as "A", "B", "C". @@ -402,7 +570,7 @@ export class FnEachMemberEquals extends FnCondition { * Returns true if each member in a list of strings matches at least one value in a second * list of strings. */ -export class FnEachMemberIn extends FnCondition { +class FnEachMemberIn extends FnCondition { /** * Creates an ``Fn::EachMemberIn`` function. * @param stringsToCheck A list of strings, such as "A", "B", "C". AWS CloudFormation checks whether each member in the strings_to_check parameter is in the strings_to_match parameter. @@ -416,7 +584,7 @@ export class FnEachMemberIn extends FnCondition { /** * Returns all values for a specified parameter type. */ -export class FnRefAll extends FnCondition { +class FnRefAll extends FnBase { /** * Creates an ``Fn::RefAll`` function. * @param parameterType An AWS-specific parameter type, such as AWS::EC2::SecurityGroup::Id or @@ -431,7 +599,7 @@ export class FnRefAll extends FnCondition { /** * Returns an attribute value or list of values for a specific parameter and attribute. */ -export class FnValueOf extends FnCondition { +class FnValueOf extends FnBase { /** * Creates an ``Fn::ValueOf`` function. * @param parameterOrLogicalId The name of a parameter for which you want to retrieve attribute values. The parameter must be declared in the Parameters section of the template. @@ -445,7 +613,7 @@ export class FnValueOf extends FnCondition { /** * Returns a list of all attribute values for a given parameter type and attribute. */ -export class FnValueOfAll extends FnCondition { +class FnValueOfAll extends FnBase { /** * Creates an ``Fn::ValueOfAll`` function. * @param parameterType An AWS-specific parameter type, such as AWS::EC2::SecurityGroup::Id or AWS::EC2::VPC::Id. For more information, see Parameters in the AWS CloudFormation User Guide. diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts index 9b961a4de0cd4..7678da5ad89df 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts @@ -1,7 +1,7 @@ import cxapi = require('@aws-cdk/cx-api'); import { Test } from 'nodeunit'; import { applyRemovalPolicy, Condition, Construct, DeletionPolicy, - FnEquals, FnNot, HashedAddressingScheme, IDependable, + Fn, HashedAddressingScheme, IDependable, RemovalPolicy, resolve, Resource, Root, Stack } from '../../lib'; export = { @@ -154,7 +154,7 @@ export = { 'conditions can be attached to a resource'(test: Test) { const stack = new Stack(); const r1 = new Resource(stack, 'Resource', { type: 'Type' }); - const cond = new Condition(stack, 'MyCondition', { expression: new FnNot(new FnEquals('a', 'b')) }); + const cond = new Condition(stack, 'MyCondition', { expression: Fn.notCondition(Fn.equalsCondition('a', 'b')) }); r1.options.condition = cond; test.deepEqual(stack.toCloudFormation(), { diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.rule.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.rule.ts index 9ca9acd6458ee..6635bafa652f7 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.rule.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.rule.ts @@ -1,13 +1,13 @@ import { Test } from 'nodeunit'; -import { FnAnd, FnContains, FnEquals, FnNot, Rule, Stack } from '../../lib'; +import { Fn, Rule, Stack } from '../../lib'; export = { 'Rule can be used to create rules'(test: Test) { const stack = new Stack(); const rule = new Rule(stack, 'MyRule'); - rule.addAssertion(new FnEquals('lhs', 'rhs'), 'lhs equals rhs'); - rule.addAssertion(new FnNot(new FnAnd(new FnContains([ 'hello', 'world' ], "world"))), 'some assertion'); + rule.addAssertion(Fn.equalsCondition('lhs', 'rhs'), 'lhs equals rhs'); + rule.addAssertion(Fn.notCondition(Fn.andCondition(Fn.containsCondition([ 'hello', 'world' ], "world"))), 'some assertion'); test.deepEqual(stack.toCloudFormation(), { Rules: { From 0424e80c05b1bd887669ceb3a891aa8d8e0fc3d8 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 25 Dec 2018 14:50:24 +0200 Subject: [PATCH 04/26] Move FnCondition to condition.ts --- .../cdk/lib/cloudformation/condition.ts | 27 ++++++++++++++++++- .../@aws-cdk/cdk/lib/cloudformation/fn.ts | 24 +---------------- .../@aws-cdk/cdk/lib/cloudformation/rule.ts | 2 +- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/condition.ts b/packages/@aws-cdk/cdk/lib/cloudformation/condition.ts index e21558225a424..0d78f4191a071 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/condition.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/condition.ts @@ -1,5 +1,5 @@ import { Construct } from '../core/construct'; -import { FnCondition } from './fn'; +import { CloudFormationToken } from './cloudformation-token'; import { Referenceable } from './stack'; export interface ConditionProps { @@ -33,3 +33,28 @@ export class Condition extends Referenceable { }; } } + +/** + * You can use intrinsic functions, such as ``Fn::If``, ``Fn::Equals``, and ``Fn::Not``, to conditionally + * create stack resources. These conditions are evaluated based on input parameters that you + * declare when you create or update a stack. After you define all your conditions, you can + * associate them with resources or resource properties in the Resources and Outputs sections + * of a template. + * + * You define all conditions in the Conditions section of a template except for ``Fn::If`` conditions. + * You can use the ``Fn::If`` condition in the metadata attribute, update policy attribute, and property + * values in the Resources section and Outputs sections of a template. + * + * You might use conditions when you want to reuse a template that can create resources in different + * contexts, such as a test environment versus a production environment. In your template, you can + * add an EnvironmentType input parameter, which accepts either prod or test as inputs. For the + * production environment, you might include Amazon EC2 instances with certain capabilities; + * however, for the test environment, you want to use less capabilities to save costs. With + * conditions, you can define which resources are created and how they're configured for each + * environment type. + */ +export class FnCondition extends CloudFormationToken { + constructor(type: string, value: any) { + super({ [type]: value }); + } +} diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts index 14fd3b61fcda7..5e467ec1df0e8 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts @@ -1,4 +1,5 @@ import { CloudFormationToken, FnJoin } from './cloudformation-token'; +import { FnCondition } from './condition'; // tslint:disable:max-line-length @@ -441,29 +442,6 @@ class FnCidr extends FnBase { } } -/** - * You can use intrinsic functions, such as ``Fn::If``, ``Fn::Equals``, and ``Fn::Not``, to conditionally - * create stack resources. These conditions are evaluated based on input parameters that you - * declare when you create or update a stack. After you define all your conditions, you can - * associate them with resources or resource properties in the Resources and Outputs sections - * of a template. - * - * You define all conditions in the Conditions section of a template except for ``Fn::If`` conditions. - * You can use the ``Fn::If`` condition in the metadata attribute, update policy attribute, and property - * values in the Resources section and Outputs sections of a template. - * - * You might use conditions when you want to reuse a template that can create resources in different - * contexts, such as a test environment versus a production environment. In your template, you can - * add an EnvironmentType input parameter, which accepts either prod or test as inputs. For the - * production environment, you might include Amazon EC2 instances with certain capabilities; - * however, for the test environment, you want to use less capabilities to save costs. With - * conditions, you can define which resources are created and how they're configured for each - * environment type. - */ -export class FnCondition extends FnBase { - -} - /** * Returns true if all the specified conditions evaluate to true, or returns false if any one * of the conditions evaluates to false. ``Fn::And`` acts as an AND operator. The minimum number of diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/rule.ts b/packages/@aws-cdk/cdk/lib/cloudformation/rule.ts index 29a881032809e..039d32381e8ad 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/rule.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/rule.ts @@ -1,6 +1,6 @@ import { Construct } from '../core/construct'; import { capitalizePropertyNames } from '../core/util'; -import { FnCondition } from './fn'; +import { FnCondition } from './condition'; import { Referenceable } from './stack'; /** From 13b7d91835389ea0377c425ea5c46da0642f77bd Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 26 Dec 2018 11:53:16 +0200 Subject: [PATCH 05/26] feat: normalize import/export APIs of all AWS resources Normalize the import/export APIs for all AWS resources: * `IXxx`: an interface that contains all properties and methods that are common to both internal and imported resources. * `XxxAttributes`: includes the set of attributes that represent the resource (used to be `XxxRefProps`). * `XxxBase` (optional): abstract base class which implements `IXxx` and contains implementations that can be reused between internal and imported resources. --- design/imports-exports.md | 222 ++++++++++++++++ docs/src/aws-construct-lib.rst | 15 +- docs/src/passing-in-data.rst | 12 +- .../bucket-import-export/index.ts | 4 +- .../cdk-examples-typescript/chat-app/index.ts | 2 +- examples/cdk-examples-typescript/ec2/index.ts | 2 +- .../use-vpc-from-another-stack/index.ts | 2 +- .../assets-docker/lib/adopted-repository.ts | 9 +- packages/@aws-cdk/assets/lib/asset.ts | 4 +- .../@aws-cdk/aws-apigateway/lib/deployment.ts | 6 +- packages/@aws-cdk/aws-apigateway/lib/index.ts | 1 - .../aws-apigateway/lib/integrations/lambda.ts | 4 +- .../aws-apigateway/lib/restapi-ref.ts | 46 ---- .../@aws-cdk/aws-apigateway/lib/restapi.ts | 59 ++++- packages/@aws-cdk/aws-apigateway/lib/stage.ts | 4 +- .../aws-apigateway/test/test.restapi.ts | 22 +- .../aws-autoscaling/lib/auto-scaling-group.ts | 10 +- .../test/test.auto-scaling-group.ts | 2 +- .../lib/certificate-ref.ts | 47 ---- .../aws-certificatemanager/lib/certificate.ts | 59 ++++- .../aws-certificatemanager/lib/index.ts | 1 - .../test/test.certificate.ts | 4 +- .../aws-cloudformation/lib/custom-resource.ts | 4 +- .../aws-cloudfront/lib/web_distribution.ts | 4 +- .../test/integ.cloudfront-alias-target.ts | 3 +- packages/@aws-cdk/aws-cloudtrail/lib/index.ts | 2 +- .../@aws-cdk/aws-codebuild/lib/artifacts.ts | 2 +- .../aws-codebuild/lib/pipeline-actions.ts | 8 +- .../@aws-cdk/aws-codebuild/lib/project.ts | 215 +++++++++++++--- packages/@aws-cdk/aws-codebuild/lib/source.ts | 8 +- .../aws-codecommit/lib/pipeline-action.ts | 4 +- .../@aws-cdk/aws-codecommit/lib/repository.ts | 152 ++++++++--- packages/@aws-cdk/aws-codedeploy/README.md | 6 +- .../aws-codedeploy/lib/application.ts | 80 +++--- .../aws-codedeploy/lib/deployment-config.ts | 74 +++--- .../aws-codedeploy/lib/deployment-group.ts | 86 ++++--- .../aws-codedeploy/lib/pipeline-action.ts | 4 +- .../test/test.deployment-config.ts | 2 +- .../test/test.deployment-group.ts | 4 +- .../lib/manual-approval-action.ts | 4 +- .../@aws-cdk/aws-codepipeline/lib/pipeline.ts | 6 +- packages/@aws-cdk/aws-ec2/lib/connections.ts | 10 +- .../@aws-cdk/aws-ec2/lib/security-group.ts | 57 +++-- packages/@aws-cdk/aws-ec2/lib/util.ts | 11 +- .../aws-ec2/lib/vpc-network-provider.ts | 4 +- packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts | 230 +++++++---------- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 72 +++++- .../aws-ec2/test/example.share-vpcs.lit.ts | 8 +- .../test/integ.import-default-vpc.lit.ts | 2 +- .../@aws-cdk/aws-ec2/test/test.connections.ts | 3 +- packages/@aws-cdk/aws-ec2/test/test.vpc.ts | 4 +- .../@aws-cdk/aws-ecr/lib/repository-ref.ts | 25 +- packages/@aws-cdk/aws-ecr/lib/repository.ts | 12 +- .../@aws-cdk/aws-ecs/lib/base/base-service.ts | 2 +- packages/@aws-cdk/aws-ecs/lib/cluster.ts | 33 ++- .../@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts | 2 +- .../aws-ecs/lib/fargate/fargate-service.ts | 2 +- .../load-balanced-fargate-service-applet.ts | 4 +- .../lib/load-balanced-fargate-service.ts | 11 +- .../aws-ecs/lib/log-drivers/aws-log-driver.ts | 4 +- packages/@aws-cdk/aws-ecs/test/test.l3s.ts | 4 +- .../lib/load-balancer.ts | 11 +- .../lib/alb/application-listener.ts | 19 +- .../lib/alb/application-load-balancer.ts | 31 ++- .../lib/alb/application-target-group.ts | 12 +- .../lib/nlb/network-listener.ts | 17 +- .../lib/nlb/network-load-balancer.ts | 21 +- .../lib/nlb/network-target-group.ts | 12 +- .../lib/shared/base-load-balancer.ts | 4 +- .../lib/shared/base-target-group.ts | 14 +- .../lib/shared/imported.ts | 17 +- .../test/integ.alb-alias-target.ts | 3 +- packages/@aws-cdk/aws-events/lib/rule-ref.ts | 32 +-- packages/@aws-cdk/aws-events/lib/rule.ts | 23 +- packages/@aws-cdk/aws-kinesis/lib/stream.ts | 136 +++++++--- packages/@aws-cdk/aws-kms/lib/alias.ts | 4 +- packages/@aws-cdk/aws-kms/lib/key.ts | 103 +++++--- .../aws-lambda-event-sources/lib/s3.ts | 2 +- .../aws-lambda-event-sources/lib/sns.ts | 4 +- .../aws-lambda-event-sources/lib/sqs.ts | 4 +- packages/@aws-cdk/aws-lambda/lib/alias.ts | 12 +- packages/@aws-cdk/aws-lambda/lib/code.ts | 4 +- .../aws-lambda/lib/event-source-mapping.ts | 4 +- .../@aws-cdk/aws-lambda/lib/event-source.ts | 4 +- .../@aws-cdk/aws-lambda/lib/lambda-ref.ts | 207 +++++++-------- .../@aws-cdk/aws-lambda/lib/lambda-version.ts | 6 +- packages/@aws-cdk/aws-lambda/lib/lambda.ts | 109 +++++++- .../aws-lambda/lib/pipeline-action.ts | 4 +- .../aws-lambda/lib/singleton-lambda.ts | 14 +- .../@aws-cdk/aws-lambda/test/test.lambda.ts | 4 +- .../aws-lambda/test/test.vpc-lambda.ts | 2 +- .../aws-logs/lib/cross-account-destination.ts | 4 +- packages/@aws-cdk/aws-logs/lib/log-group.ts | 119 +++++++-- packages/@aws-cdk/aws-logs/lib/log-stream.ts | 64 ++--- .../@aws-cdk/aws-logs/lib/metric-filter.ts | 4 +- .../aws-logs/lib/subscription-filter.ts | 6 +- .../@aws-cdk/aws-logs/test/test.loggroup.ts | 4 +- .../aws-logs/test/test.subscriptionfilter.ts | 4 +- .../@aws-cdk/aws-quickstarts/lib/database.ts | 2 +- packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts | 4 +- .../lib/cluster-parameter-group-ref.ts | 46 ---- .../aws-rds/lib/cluster-parameter-group.ts | 57 ++++- packages/@aws-cdk/aws-rds/lib/cluster-ref.ts | 100 +------- packages/@aws-cdk/aws-rds/lib/cluster.ts | 98 ++++++- packages/@aws-cdk/aws-rds/lib/index.ts | 1 - packages/@aws-cdk/aws-rds/lib/props.ts | 2 +- .../@aws-cdk/aws-rds/test/test.cluster.ts | 4 +- packages/@aws-cdk/aws-route53/README.md | 2 +- .../aws-route53/lib/hosted-zone-provider.ts | 9 +- .../aws-route53/lib/hosted-zone-ref.ts | 37 +-- .../@aws-cdk/aws-route53/lib/hosted-zone.ts | 48 +++- .../@aws-cdk/aws-route53/lib/records/_util.ts | 4 +- .../@aws-cdk/aws-route53/lib/records/alias.ts | 12 +- .../@aws-cdk/aws-route53/lib/records/txt.ts | 9 +- .../lib/records/zone-delegation.ts | 12 +- .../aws-route53/test/integ.route53.ts | 1 + .../aws-route53/test/test.alias-record.ts | 1 + .../test/test.hosted-zone-provider.ts | 6 +- .../@aws-cdk/aws-route53/test/test.route53.ts | 7 +- .../aws-route53/test/test.txt-record.ts | 2 +- .../test/test.zone-delegation-record.ts | 1 + .../lib/bucket-deployment.ts | 2 +- .../@aws-cdk/aws-s3-deployment/lib/source.ts | 4 +- packages/@aws-cdk/aws-s3/lib/bucket-policy.ts | 4 +- packages/@aws-cdk/aws-s3/lib/bucket.ts | 240 +++++++++++++++--- .../@aws-cdk/aws-s3/lib/pipeline-action.ts | 4 +- packages/@aws-cdk/aws-s3/lib/util.ts | 6 +- .../aws-s3/test/demo.import-export.ts | 6 +- packages/@aws-cdk/aws-sns/lib/policy.ts | 4 +- packages/@aws-cdk/aws-sns/lib/subscription.ts | 6 +- packages/@aws-cdk/aws-sns/lib/topic-ref.ts | 159 ++++++++---- packages/@aws-cdk/aws-sns/lib/topic.ts | 43 +++- packages/@aws-cdk/aws-sns/test/test.sns.ts | 2 +- packages/@aws-cdk/aws-sqs/lib/policy.ts | 4 +- packages/@aws-cdk/aws-sqs/lib/queue-ref.ts | 146 ++++++++--- packages/@aws-cdk/aws-sqs/lib/queue.ts | 62 ++++- packages/@aws-cdk/aws-sqs/test/test.sqs.ts | 2 +- .../aws-stepfunctions/lib/state-machine.ts | 17 +- 138 files changed, 2610 insertions(+), 1315 deletions(-) create mode 100644 design/imports-exports.md delete mode 100644 packages/@aws-cdk/aws-certificatemanager/lib/certificate-ref.ts delete mode 100644 packages/@aws-cdk/aws-rds/lib/cluster-parameter-group-ref.ts diff --git a/design/imports-exports.md b/design/imports-exports.md new file mode 100644 index 0000000000000..9bf6aa575c4fc --- /dev/null +++ b/design/imports-exports.md @@ -0,0 +1,222 @@ +# AWS Construct Library Resource Design Guidelines + +The AWS Construct Library is a rich class library of CDK constructs which +represent all resources offered by the AWS Cloud. + +Resources are organized into modules based on their AWS service. For example, +the **Bucket** resource, which is offered by the Amazon S3 service will be +available under the **aws-s3** module. + +Module and resource names correspond to the AWS CloudFormation naming. For +example, the AWS CloudFormation resource **AWS::S3::Bucket** represents the +module name **S3** and the resource name **Bucket**. + +This document defines the design guidelines for AWS resource constructs. The +purpose of these guidelines is to provide a consistent developer experience +throughout the library. + +For the purpose of this document we will use "**Xxx**" to denote the name of the +resource (i.e. "Bucket", "Queue", "Topic", etc). + +## Resource Attributes + +Every AWS resource has a set of "physical" runtime attributes such as ARN, +physical names, URLs, etc. These attributes are commonly late-bound, which means +they can only be resolved when AWS CloudFormation actually provisions the +resource. + +Resource attributes almost always represent **string** values (URL, ARN, name). +Sometimes they might also represent a **list of strings**. + +Since we want +attributes can either be late-bound ("a promise to a string") or concrete ("a +string"), the AWS CDK has a mechanism called "tokens" which allows codifying +late-bound values into strings or string arrays. This approach was chosen in +order to dramatically simplify the type-system and ergonomics of CDK code. As +long as users treat these attributes as _opaque values_ (e.g. not try to parse +them or manipulate them), they can be used + + +One of the design tenets of the AWS CDK is to be strongly-typed. + +- Runtime attributes should be represented as readonly properties on the resource class. +- Runtime attributes should use a the `string` type if the attribute resolves + +## Resource Properties + + + +## Internal/External Polymorphism + + + + +The following patterns should be implemented by all resource classes in the AWS +Construct Library. + +Terminology: +- "Xxx": represents the CloudFormation resource name (). + +Let's start by defining an interface which represents a resource of the type +"Xxx" (e.g. `Bucket`, `Topic`, `Function`, etc). + +This interface should represent both resources defined within the same stack +(aka "internal", "owned") and existing resources that are defined in another +stack/app (aka "imported", "existing", "external" or "unowned"). Throughout this +document we shall refer to these two types of resources as **"internal"** and +**"external"**. Therefore, this is the recommended type to use in public APIs +that require this resource. + +The interface should include all methods and properties, and extend any other +interfaces that are applicable for both internal and external resources of this +type. + +Here's a template: + +```ts +// extends all interfaces that are applicable for both internal +// and external resources of this type +export interface IXxx extends IFoo, IGoo { + + // attributes + readonly xxxArn: string; + readonly xxxFoo: string; + readonly xxxBar: string; + + // security group connections (if applicable) + readonly connections: ec2.Connections; + + // permission grants (adds statements to the principal's policy) + grant(principal?: iam.IPrincipal, ...actions: string[]): void; + grantFoo(principal?: iam.IPrincipal): void; + grantBar(principal?: iam.IPrincipal): void; + + // resource policy (if applicable) + addToResourcePolicy(statement: iam.PolicyStatement): void; + + // role (if applicable) + addToRolePolicy(statement: iam.PolicyStatement): void; + + // pipeline (if applicable) + addToPipeline(stage: pipelineapi.IStage, name: string, props?: XxxActionProps): XxxAction; + + // metrics + metric(metricName: string, props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + metricFoo(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + metricBar(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + + // export + export(): XxxAttributes; + + // any other methods/properties that are applicable for both internal + // and external resources of this type. + // ... +} +``` + +As mentioned above, this is a polymorphic interface which represents both +internal and external resources of this type. When users wish to import an +external resource, they will the static method `Xxx.import(...)` which returns +an object that implements this interface. + +Since many of the methods above (such as metrics and grants) are applicable +for both internal and external resources, it's usually a good idea to implement +an abstract base class which can be used to reuse these implementations. + +The base class will likely be a `cdk.Construct` (since it is common for many +of these implementations to need to add constructs to the construct tree). +There are some implementations, such as `export` and the various attributes +which are likely to remain `abstract`, and will only become concrete when +we implement the actual resource and imported resource classes. + + +```ts +export abstract class XxxBase extends cdk.Construct implements IXxx { + + // attributes are usually still abstract at this level + public abstract readonly xxxArn: string; + public abstract readonly xxxBoo: string[]; + + // the "export" method is also still abstract + public abstract export(): XxxAttributes; + + // grants can usually be shared + public grantYyy(principal?: iam.IPrincipal) { + // ... + } + + // metrics can usually be shared + public metricFoo(...) { ... } +} +``` + +Now, let's define our main resource class: + +```ts +// extends the abstract base class and implement any interfaces that are not applicable +// for imported resources. This is quite rare usually, but can happen. +export class Xxx extends XxxBase implements IAnotherInterface { + + // the import method is always going to look like this. + public static import(parent: Construct, id: string, props: XxxAttributes): IXxx { + return new ImportedXxx(parent, id, props); + } + + // implement resource attributes as readonly properties + public readonly xxxArn: string; + + // ctor's 3rd argument is always XxxProps. It should be optional (`= { }`) in case + // there are no required properties. + constructor(parent: Construct, id: string, props: XxxProps) { + super(parent, id); + + // you would usually add a `CfnXxx` resource at this point. + const resource = new CfnXxx(this, 'Resource', { + // ... + }); + + // proxy resource properties + this.xxxArn = resource.xxxArn; + this.xxxFoo = resource.xxxFoo; + } + + // this is how export() should be implemented on internal resources + // they would produce a stack export and return the "Fn::ImportValue" token + // for them so they can be imported to another stack. + public export(): XxxAttributes { + return { + xxxArn: new cdk.Output(this, 'Arn', { value: this.xxxArn }).makeImportValue().toString(), + // ... + } + } +} +``` + +- It must have a method with the following signature: + +```ts +static import(parent: Construct, id: string, props: XxxAttributes): IXxx +``` + +### `interface XxxProps` + +The set of initialization properties for `Xxx`. + +### `interface XxxAttributes` + +An interface that can be used to import a resource of this type into the app. + +- Should have the minimum required properties, that is: if it is possible to + parse the resource name from the ARN (using `cdk.ArnUtils.parse`), then only + the ARN should be required. +- In cases where it is not possible to parse the ARN (e.g. if it is a token and + the resource name might have use "/" characters), both the ARN and the name + should be optional and runtime-checks should be performed to require that at + least one will be defined. See `ecr.RepositoryAttributes` for an example. + + + +A data interface with the set of attributes which represent an existing AWS +resource. Normally this would be something like `xxxArn`, `xxxName`, etc. This +class is used when "importing" an existing resource to an application. + diff --git a/docs/src/aws-construct-lib.rst b/docs/src/aws-construct-lib.rst index 9804dc9eb5f24..84c6b4ceb4ca8 100644 --- a/docs/src/aws-construct-lib.rst +++ b/docs/src/aws-construct-lib.rst @@ -39,7 +39,7 @@ function. Furthermore, most AWS Constructs expose ``grant*`` methods which allow intent-based permission definitions. For example, the AWS S3 :py:class:`Bucket <@aws-cdk/aws-s3.Bucket>` -construct has a :py:meth:`grantRead(principal) <@aws-cdk/aws-s3.BucketRef.grantRead>` +construct has a :py:meth:`grantRead(principal) <@aws-cdk/aws-s3.IBucket.grantRead>` method which accepts an AWS IAM :py:class:`Principal <@aws-cdk/aws-iam.IPrincipal>` such as a :py:class:`User <@aws-cdk/aws-iam.User>` or a :py:class:`Role <@aws-cdk/aws-iam.Role>`, and will modify their policy to allow the principal to read objects from the bucket. @@ -52,7 +52,7 @@ Event-Driven APIs Many of the AWS constructs include ``on*`` methods which can be used to react to events emitted by the construct. For example, the AWS CodeCommit :py:mod:`Repository <@aws-cdk/aws-codecommit.Repository>` construct has an -:py:meth:`onCommit <@aws-cdk/aws-codecommit.RepositoryRef.onCommit>` method. +:py:meth:`onCommit <@aws-cdk/aws-codecommit.IRepository.onCommit>` method. AWS Constructs that can be used as targets for various event providers implement interfaces such as :py:mod:`IEventRuleTarget <@aws-cdk/aws-events.IEventRuleTarget>` @@ -84,7 +84,7 @@ Many AWS resources emit AWS CloudWatch metrics as part of their normal operation be used to setup :py:mod:`Alarms <@aws-cdk/aws-cloudwatch.Alarm>` or included in :py:mod:`Dashboards <@aws-cdk/aws-cloudwatch.Dashboard>`. :py:mod:`Metric <@aws-cdk/aws-cloudwatch.Metric>` objects for AWS Constructs can be obtained -via ``metricXxx()`` methods. For example, the :py:meth:`metricDuration() <@aws-cdk/aws-lambda.FunctionRef.metricDuration>` +via ``metricXxx()`` methods. For example, the :py:meth:`metricDuration() <@aws-cdk/aws-lambda.IFunction.metricDuration>` method reports the execution time of an AWS Lambda function. For more information see the :doc:`refs/_aws-cdk_aws-cloudwatch` documentation. @@ -95,12 +95,15 @@ Imports ======= If you need to reference a resource which is defined outside of your CDK app (e.g. a bucket, a VPC, etc), -you can use the ``Xxxx.import(...)`` static methods which are available on AWS Constructs. For example, -the :py:meth:`Bucket.import() <@aws-cdk/aws-s3.BucketRef.import>` method can be used to obtain -a :py:mod:`BucketRef <@aws-cdk/aws-s3.BucketRef>` object which can be used in most places where +you can use the ``Xxxx.import(...)`` static methods which are available on AWS Constructs. + +For example, the :py:meth:`Bucket.import() <@aws-cdk/aws-s3.Bucket.import>` method can be used to obtain +an :py:mod:`IBucket <@aws-cdk/aws-s3.IBucket>` object which can be used in most places where a bucket is required. This patterns allows treating resources defined outside your app as if they were part of your app. + + .. _cloudformation_layer: Access the AWS CloudFormation Layer diff --git a/docs/src/passing-in-data.rst b/docs/src/passing-in-data.rst index 5f146e8a74a36..0a04174b40a02 100644 --- a/docs/src/passing-in-data.rst +++ b/docs/src/passing-in-data.rst @@ -174,15 +174,15 @@ in the stack property. class HelloCdkStack extends cdk.Stack { // Property that defines the stack you are exporting from - public readonly myBucketRefProps: s3.BucketRefProps; + public readonly myBucketAttributes: s3.BucketAttributes; constructor(parent: cdk.App, name: string, props?: cdk.StackProps) { super(parent, name, props); const mybucket = new s3.Bucket(this, "MyFirstBucket"); - // Save bucket's *BucketRefProps* - this.myBucketRefProps = mybucket.export(); + // Save bucket's *BucketAttributes* + this.myBucketAttributes = mybucket.export(); } } @@ -193,7 +193,7 @@ We use this interface to pass the bucket properties between the two stacks. // Interface we'll use to pass the bucket's properties to another stack interface MyCdkStackProps { - theBucketRefProps: s3.BucketRefProps; + theBucketAttributes: s3.BucketAttributes; } Create the second stack that gets a reference to the other bucket @@ -206,7 +206,7 @@ from the properties passed in through the constructor. constructor(parent: cdk.App, name: string, props: MyCdkStackProps) { super(parent, name); - const myOtherBucket = s3.Bucket.import(this, "MyOtherBucket", props.theBucketRefProps); + const myOtherBucket = s3.Bucket.import(this, "MyOtherBucket", props.theBucketAttributes); // Do something with myOtherBucket } @@ -221,7 +221,7 @@ Finally, connect the dots in your app. const myStack = new HelloCdkStack(app, "HelloCdkStack"); new MyCdkStack(app, "MyCdkStack", { - theBucketRefProps: myStack.myBucketRefProps + theBucketAttributes: myStack.myBucketAttributes }); app.run(); diff --git a/examples/cdk-examples-typescript/bucket-import-export/index.ts b/examples/cdk-examples-typescript/bucket-import-export/index.ts index ca3139123773b..8f7109e8ae1a7 100644 --- a/examples/cdk-examples-typescript/bucket-import-export/index.ts +++ b/examples/cdk-examples-typescript/bucket-import-export/index.ts @@ -7,7 +7,7 @@ import cdk = require('@aws-cdk/cdk'); // `Bucket.import`. class Producer extends cdk.Stack { - public readonly myBucketRef: s3.BucketRefProps; + public readonly myBucketRef: s3.BucketAttributes; constructor(parent: cdk.App, name: string) { super(parent, name); @@ -35,7 +35,7 @@ class ConsumerConstruct extends cdk.Construct { // this bucket and contents. interface ConsumerProps { - userBucketRef: s3.BucketRefProps; + userBucketRef: s3.BucketAttributes; } class Consumer extends cdk.Stack { diff --git a/examples/cdk-examples-typescript/chat-app/index.ts b/examples/cdk-examples-typescript/chat-app/index.ts index 98b2d31d1f69b..2f1e1ef3e7e85 100644 --- a/examples/cdk-examples-typescript/chat-app/index.ts +++ b/examples/cdk-examples-typescript/chat-app/index.ts @@ -12,7 +12,7 @@ class MyStack extends cdk.Stack { new CognitoChatRoomPool(this, 'UserPool'); - const bucket = s3.BucketRef.import(this, 'DougsBucket', { + const bucket = s3.Bucket.import(this, 'DougsBucket', { bucketName: 'dougs-chat-app' }); diff --git a/examples/cdk-examples-typescript/ec2/index.ts b/examples/cdk-examples-typescript/ec2/index.ts index 4d54db5723741..15d87ad5cda25 100644 --- a/examples/cdk-examples-typescript/ec2/index.ts +++ b/examples/cdk-examples-typescript/ec2/index.ts @@ -52,7 +52,7 @@ class MyApp extends cdk.Stack { } class CommonInfrastructure extends cdk.Stack { - public vpc: ec2.VpcNetworkRefProps; + public vpc: ec2.VpcNetworkAttributes; constructor(parent: cdk.App, name: string, props?: cdk.StackProps) { super(parent, name, props); diff --git a/examples/cdk-examples-typescript/use-vpc-from-another-stack/index.ts b/examples/cdk-examples-typescript/use-vpc-from-another-stack/index.ts index af3e7df400718..212891ad6c70a 100644 --- a/examples/cdk-examples-typescript/use-vpc-from-another-stack/index.ts +++ b/examples/cdk-examples-typescript/use-vpc-from-another-stack/index.ts @@ -17,7 +17,7 @@ const exportedVpc = new ec2.VpcNetwork(vpcStack, 'VPC', { const appStack = new cdk.Stack(app, 'AppStack'); -const importedVpc = ec2.VpcNetworkRef.import(appStack, 'VPC', exportedVpc.export()); +const importedVpc = ec2.VpcNetwork.import(appStack, 'VPC', exportedVpc.export()); const asg = new autoscaling.AutoScalingGroup(appStack, 'ASG', { vpc: importedVpc, diff --git a/packages/@aws-cdk/assets-docker/lib/adopted-repository.ts b/packages/@aws-cdk/assets-docker/lib/adopted-repository.ts index 3467bd8a94510..49fe6bfcce726 100644 --- a/packages/@aws-cdk/assets-docker/lib/adopted-repository.ts +++ b/packages/@aws-cdk/assets-docker/lib/adopted-repository.ts @@ -29,7 +29,7 @@ export class AdoptedRepository extends ecr.RepositoryBase { private readonly policyDocument = new iam.PolicyDocument(); - constructor(parent: cdk.Construct, id: string, props: AdoptedRepositoryProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: AdoptedRepositoryProps) { super(parent, id); const fn = new lambda.SingletonFunction(this, 'Function', { @@ -70,6 +70,13 @@ export class AdoptedRepository extends ecr.RepositoryBase { this.repositoryArn = ecr.Repository.arnForLocalRepository(this.repositoryName); } + /** + * Export this repository from the stack + */ + public export() { + return this.props; + } + /** * Adds a statement to the repository resource policy. * diff --git a/packages/@aws-cdk/assets/lib/asset.ts b/packages/@aws-cdk/assets/lib/asset.ts index 92af4aeba3588..841a9cf89d987 100644 --- a/packages/@aws-cdk/assets/lib/asset.ts +++ b/packages/@aws-cdk/assets/lib/asset.ts @@ -68,7 +68,7 @@ export class Asset extends cdk.Construct { /** * The S3 bucket in which this asset resides. */ - public readonly bucket: s3.BucketRef; + public readonly bucket: s3.IBucket; /** * Indicates if this asset is a zip archive. Allows constructs to ensure that the @@ -114,7 +114,7 @@ export class Asset extends cdk.Construct { const s3Filename = cdk.Fn.select(1, cdk.Fn.split(cxapi.ASSET_PREFIX_SEPARATOR, keyParam.valueAsString)).toString(); this.s3ObjectKey = `${this.s3Prefix}${s3Filename}`; - this.bucket = s3.BucketRef.import(this, 'AssetBucket', { + this.bucket = s3.Bucket.import(this, 'AssetBucket', { bucketName: this.s3BucketName }); diff --git a/packages/@aws-cdk/aws-apigateway/lib/deployment.ts b/packages/@aws-cdk/aws-apigateway/lib/deployment.ts index e5a371650e141..b4b04159f952b 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/deployment.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/deployment.ts @@ -1,13 +1,13 @@ import cdk = require('@aws-cdk/cdk'); import crypto = require('crypto'); import { CfnDeployment, CfnDeploymentProps } from './apigateway.generated'; -import { RestApiRef } from './restapi-ref'; +import { IRestApi } from './restapi'; export interface DeploymentProps { /** * The Rest API to deploy. */ - api: RestApiRef; + api: IRestApi; /** * A description of the purpose of the API Gateway deployment. @@ -56,7 +56,7 @@ export interface DeploymentProps { */ export class Deployment extends cdk.Construct implements cdk.IDependable { public readonly deploymentId: string; - public readonly api: RestApiRef; + public readonly api: IRestApi; /** * Allows taking a dependency on this construct. diff --git a/packages/@aws-cdk/aws-apigateway/lib/index.ts b/packages/@aws-cdk/aws-apigateway/lib/index.ts index b36594885a3d4..4cce185dd3fe0 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/index.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/index.ts @@ -1,5 +1,4 @@ export * from './restapi'; -export * from './restapi-ref'; export * from './resource'; export * from './method'; export * from './integration'; diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts index 72dde50ef2f1e..1970b71923455 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts @@ -34,10 +34,10 @@ export interface LambdaIntegrationOptions extends IntegrationOptions { * */ export class LambdaIntegration extends AwsIntegration { - private readonly handler: lambda.FunctionRef; + private readonly handler: lambda.IFunction; private readonly enableTest: boolean; - constructor(handler: lambda.FunctionRef, options: LambdaIntegrationOptions = { }) { + constructor(handler: lambda.IFunction, options: LambdaIntegrationOptions = { }) { const proxy = options.proxy === undefined ? true : options.proxy; super({ diff --git a/packages/@aws-cdk/aws-apigateway/lib/restapi-ref.ts b/packages/@aws-cdk/aws-apigateway/lib/restapi-ref.ts index 37f0af148f620..e69de29bb2d1d 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/restapi-ref.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/restapi-ref.ts @@ -1,46 +0,0 @@ -import cdk = require('@aws-cdk/cdk'); - -export interface RestApiRefProps { - /** - * The REST API ID of an existing REST API resource. - */ - restApiId: string; -} - -export abstract class RestApiRef extends cdk.Construct { - - /** - * Imports an existing REST API resource. - * @param parent Parent construct - * @param id Construct ID - * @param props Imported rest API properties - */ - public static import(parent: cdk.Construct, id: string, props: RestApiRefProps): RestApiRef { - return new ImportedRestApi(parent, id, props); - } - - /** - * The ID of this API Gateway RestApi. - */ - public readonly abstract restApiId: string; - - /** - * Exports a REST API resource from this stack. - * @returns REST API props that can be imported to another stack. - */ - public export(): RestApiRefProps { - return { - restApiId: new cdk.Output(this, 'RestApiId', { value: this.restApiId }).makeImportValue().toString() - }; - } -} - -class ImportedRestApi extends RestApiRef { - public restApiId: string; - - constructor(parent: cdk.Construct, id: string, props: RestApiRefProps) { - super(parent, id); - - this.restApiId = props.restApiId; - } -} diff --git a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts index e5ea1172c130b..053766791b0f8 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts @@ -5,9 +5,28 @@ import { Deployment } from './deployment'; import { Integration } from './integration'; import { Method, MethodOptions } from './method'; import { IRestApiResource, ProxyResource, Resource, ResourceOptions } from './resource'; -import { RestApiRef } from './restapi-ref'; import { Stage, StageOptions } from './stage'; +export interface RestApiAttributes { + /** + * The REST API ID of an existing REST API resource. + */ + restApiId: string; +} + +export interface IRestApi { + /** + * The ID of this API Gateway RestApi. + */ + readonly restApiId: string; + + /** + * Exports a REST API resource from this stack. + * @returns REST API props that can be imported to another stack. + */ + export(): RestApiAttributes; +} + export interface RestApiProps extends ResourceOptions { /** * Indicates if a Deployment should be automatically created for this API, @@ -118,7 +137,7 @@ export interface RestApiProps extends ResourceOptions { /** * The ID of the API Gateway RestApi resource that you want to clone. */ - cloneFrom?: RestApiRef; + cloneFrom?: IRestApi; /** * Automatically configure an AWS CloudWatch role for API Gateway. @@ -135,7 +154,17 @@ export interface RestApiProps extends ResourceOptions { * By default, the API will automatically be deployed and accessible from a * public endpoint. */ -export class RestApi extends RestApiRef implements cdk.IDependable { +export class RestApi extends cdk.Construct implements cdk.IDependable, IRestApi { + /** + * Imports an existing REST API resource. + * @param parent Parent construct + * @param id Construct ID + * @param props Imported rest API properties + */ + public static import(parent: cdk.Construct, id: string, props: RestApiAttributes): IRestApi { + return new ImportedRestApi(parent, id, props); + } + /** * The ID of this API Gateway RestApi. */ @@ -224,6 +253,16 @@ export class RestApi extends RestApiRef implements cdk.IDependable { }; } + /** + * Exports a REST API resource from this stack. + * @returns REST API props that can be imported to another stack. + */ + public export(): RestApiAttributes { + return { + restApiId: new cdk.Output(this, 'RestApiId', { value: this.restApiId }).makeImportValue().toString() + }; + } + /** * The deployed root URL of this REST API. */ @@ -366,3 +405,17 @@ export enum EndpointType { } export class RestApiUrl extends cdk.CloudFormationToken { } + +class ImportedRestApi extends cdk.Construct implements IRestApi { + public restApiId: string; + + constructor(parent: cdk.Construct, id: string, private readonly props: RestApiAttributes) { + super(parent, id); + + this.restApiId = props.restApiId; + } + + public export() { + return this.props; + } +} diff --git a/packages/@aws-cdk/aws-apigateway/lib/stage.ts b/packages/@aws-cdk/aws-apigateway/lib/stage.ts index 782dad780bcb5..690a7589203e4 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/stage.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/stage.ts @@ -1,7 +1,7 @@ import cdk = require('@aws-cdk/cdk'); import { CfnStage } from './apigateway.generated'; import { Deployment } from './deployment'; -import { RestApiRef } from './restapi-ref'; +import { IRestApi } from './restapi'; import { parseMethodOptionsPath } from './util'; export interface StageOptions extends MethodDeploymentOptions { @@ -130,7 +130,7 @@ export class Stage extends cdk.Construct implements cdk.IDependable { public readonly stageName: string; public readonly dependencyElements = new Array(); - private readonly restApi: RestApiRef; + private readonly restApi: IRestApi; constructor(parent: cdk.Construct, id: string, props: StageProps) { super(parent, id); diff --git a/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts b/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts index c15df7a2b486e..b6531ae26f0b2 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts @@ -379,20 +379,20 @@ export = { const imported = apigateway.RestApi.import(stack, 'imported-api', { restApiId: 'api-rxt4498f' }); - const exported = imported.export(); + + const api = new apigateway.RestApi(stack, 'MyRestApi'); + api.root.addMethod('GET'); + + const exported = api.export(); // THEN - expect(stack).toMatch({ - Outputs: { - importedapiRestApiIdC00F155A: { - Value: "api-rxt4498f", - Export: { - Name: "importedapiRestApiIdC00F155A" - } - } - } + stack.validateTree(); + test.deepEqual(stack.toCloudFormation().Outputs.MyRestApiRestApiIdB93C5C2D, { + Value: { Ref: 'MyRestApi2D1F47A9' }, + Export: { Name: 'MyRestApiRestApiIdB93C5C2D' } }); - test.deepEqual(cdk.resolve(exported), { restApiId: { 'Fn::ImportValue': 'importedapiRestApiIdC00F155A' } }); + test.deepEqual(cdk.resolve(imported.restApiId), 'api-rxt4498f'); + test.deepEqual(cdk.resolve(exported), { restApiId: { 'Fn::ImportValue': 'MyRestApiRestApiIdB93C5C2D' } }); test.done(); }, diff --git a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts index 5a91728d53d70..ecd94ebb58b55 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -60,7 +60,7 @@ export interface AutoScalingGroupProps { /** * VPC to launch these instances in. */ - vpc: ec2.VpcNetworkRef; + vpc: ec2.IVpcNetwork; /** * Where to place instances within the VPC @@ -71,7 +71,7 @@ export interface AutoScalingGroupProps { * SNS topic to send notifications about fleet changes * @default No fleet change notifications will be sent. */ - notificationsTopic?: sns.TopicRef; + notificationsTopic?: sns.ITopic; /** * Whether the instances can initiate connections to anywhere by default @@ -190,8 +190,8 @@ export class AutoScalingGroup extends cdk.Construct implements IAutoScalingGroup private readonly userDataLines = new Array(); private readonly autoScalingGroup: CfnAutoScalingGroup; - private readonly securityGroup: ec2.SecurityGroupRef; - private readonly securityGroups: ec2.SecurityGroupRef[] = []; + private readonly securityGroup: ec2.ISecurityGroup; + private readonly securityGroups: ec2.ISecurityGroup[] = []; private readonly loadBalancerNames: string[] = []; private readonly targetGroupArns: string[] = []; private albTargetGroup?: elbv2.ApplicationTargetGroup; @@ -287,7 +287,7 @@ export class AutoScalingGroup extends cdk.Construct implements IAutoScalingGroup * * @param securityGroup: The SecurityGroupRef to add */ - public addSecurityGroup(securityGroup: ec2.SecurityGroupRef): void { + public addSecurityGroup(securityGroup: ec2.ISecurityGroup): void { this.securityGroups.push(securityGroup); } diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts index 5186e6e6eae36..a4dbb1bf20aed 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts @@ -417,7 +417,7 @@ function mockVpc(stack: cdk.Stack) { } function mockSecurityGroup(stack: cdk.Stack) { - return ec2.SecurityGroupRef.import(stack, 'MySG', { + return ec2.SecurityGroup.import(stack, 'MySG', { securityGroupId: 'most-secure', }); } diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/certificate-ref.ts b/packages/@aws-cdk/aws-certificatemanager/lib/certificate-ref.ts deleted file mode 100644 index c0aa51dd3c872..0000000000000 --- a/packages/@aws-cdk/aws-certificatemanager/lib/certificate-ref.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Construct, Output } from "@aws-cdk/cdk"; - -/** - * Interface for certificate-like objects - */ -export abstract class CertificateRef extends Construct { - /** - * Import a certificate - */ - public static import(parent: Construct, name: string, props: CertificateRefProps): CertificateRef { - return new ImportedCertificate(parent, name, props); - } - - public abstract readonly certificateArn: string; - - /** - * Export this certificate from the stack - */ - public export(): CertificateRefProps { - return { - certificateArn: new Output(this, 'Arn', { value: this.certificateArn }).makeImportValue().toString() - }; - } -} - -/** - * A Certificate that has been imported from another stack - */ -class ImportedCertificate extends CertificateRef { - public readonly certificateArn: string; - - constructor(parent: Construct, name: string, props: CertificateRefProps) { - super(parent, name); - - this.certificateArn = props.certificateArn; - } -} - -/** - * Reference to an existing Certificate - */ -export interface CertificateRefProps { - /** - * The certificate's ARN - */ - certificateArn: string; -} diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts b/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts index c3fac839df84f..fb5f7f6bf5759 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts +++ b/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts @@ -1,8 +1,29 @@ -import { Construct } from '@aws-cdk/cdk'; -import { CertificateRef } from './certificate-ref'; +import { Construct, Output } from '@aws-cdk/cdk'; import { CfnCertificate } from './certificatemanager.generated'; import { apexDomain } from './util'; +export interface ICertificate { + /** + * The certificate's ARN + */ + readonly certificateArn: string; + + /** + * Export this certificate from the stack + */ + export(): CertificateAttributes; +} + +/** + * Reference to an existing Certificate + */ +export interface CertificateAttributes { + /** + * The certificate's ARN + */ + certificateArn: string; +} + /** * Properties for your certificate */ @@ -48,7 +69,14 @@ export interface CertificateProps { * * For every domain that you register. */ -export class Certificate extends CertificateRef { +export class Certificate extends Construct implements ICertificate { + /** + * Import a certificate + */ + public static import(parent: Construct, name: string, props: CertificateAttributes): ICertificate { + return new ImportedCertificate(parent, name, props); + } + /** * The certificate's ARN */ @@ -81,4 +109,29 @@ export class Certificate extends CertificateRef { } } + /** + * Export this certificate from the stack + */ + public export(): CertificateAttributes { + return { + certificateArn: new Output(this, 'Arn', { value: this.certificateArn }).makeImportValue().toString() + }; + } +} + +/** + * A Certificate that has been imported from another stack + */ +class ImportedCertificate extends Construct implements ICertificate { + public readonly certificateArn: string; + + constructor(parent: Construct, name: string, private readonly props: CertificateAttributes) { + super(parent, name); + + this.certificateArn = props.certificateArn; + } + + public export() { + return this.props; + } } diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/index.ts b/packages/@aws-cdk/aws-certificatemanager/lib/index.ts index 758cc2f3e0b24..50873fe8ee56f 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lib/index.ts +++ b/packages/@aws-cdk/aws-certificatemanager/lib/index.ts @@ -1,5 +1,4 @@ export * from './certificate'; -export * from './certificate-ref'; // AWS::CertificateManager CloudFormation Resources: export * from './certificatemanager.generated'; diff --git a/packages/@aws-cdk/aws-certificatemanager/test/test.certificate.ts b/packages/@aws-cdk/aws-certificatemanager/test/test.certificate.ts index b7cbadc90d752..b8237a6708cb8 100644 --- a/packages/@aws-cdk/aws-certificatemanager/test/test.certificate.ts +++ b/packages/@aws-cdk/aws-certificatemanager/test/test.certificate.ts @@ -1,7 +1,7 @@ import { expect, haveResource } from '@aws-cdk/assert'; import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { Certificate, CertificateRef } from '../lib'; +import { Certificate } from '../lib'; export = { 'apex domain selection by default'(test: Test) { @@ -49,7 +49,7 @@ export = { domainName: 'hello.com', }).export(); - CertificateRef.import(stack, 'Imported', refProps); + Certificate.import(stack, 'Imported', refProps); test.done(); } diff --git a/packages/@aws-cdk/aws-cloudformation/lib/custom-resource.ts b/packages/@aws-cdk/aws-cloudformation/lib/custom-resource.ts index 475ba73f8afa5..656cf77e13387 100644 --- a/packages/@aws-cdk/aws-cloudformation/lib/custom-resource.ts +++ b/packages/@aws-cdk/aws-cloudformation/lib/custom-resource.ts @@ -19,14 +19,14 @@ export interface CustomResourceProps { * * Optional, exactly one of lamdaProvider or topicProvider must be set. */ - lambdaProvider?: lambda.FunctionRef; + lambdaProvider?: lambda.IFunction; /** * The SNS Topic for the provider that implements this custom resource. * * Optional, exactly one of lamdaProvider or topicProvider must be set. */ - topicProvider?: sns.TopicRef; + topicProvider?: sns.ITopic; /** * Properties to pass to the Lambda diff --git a/packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts b/packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts index e5b15fddd4721..cd75a92c2e7a0 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts @@ -110,7 +110,7 @@ export interface LoggingConfiguration { * * @default A logging bucket is automatically created */ - readonly bucket?: s3.BucketRef, + readonly bucket?: s3.IBucket, /** * Whether to include the cookies in the logs @@ -489,7 +489,7 @@ export class CloudFrontWebDistribution extends cdk.Construct implements route53. * The logging bucket for this CloudFront distribution. * If logging is not enabled for this distribution - this property will be undefined. */ - public readonly loggingBucket?: s3.BucketRef; + public readonly loggingBucket?: s3.IBucket; /** * The domain name created by CloudFront for this distribution. diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-alias-target.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-alias-target.ts index 1f15c3408a374..83aed6458402c 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-alias-target.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-alias-target.ts @@ -24,7 +24,8 @@ const distribution = new cloudfront.CloudFrontWebDistribution(stack, 'MyDistribu ] }); -new route53.AliasRecord(zone, 'Alias', { +new route53.AliasRecord(stack, 'Alias', { + zone, recordName: '_foo', target: distribution }); diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts index 75735e83c51a6..0432e9eaea415 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts @@ -65,7 +65,7 @@ export interface CloudTrailProps { /** The AWS Key Management Service (AWS KMS) key ID that you want to use to encrypt CloudTrail logs. * @default none */ - kmsKey?: kms.EncryptionKeyRef; + kmsKey?: kms.IEncryptionKey; /** The name of an Amazon SNS topic that is notified when new log files are published. * @default none diff --git a/packages/@aws-cdk/aws-codebuild/lib/artifacts.ts b/packages/@aws-cdk/aws-codebuild/lib/artifacts.ts index c7302042d946c..e8d44528bf015 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/artifacts.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/artifacts.ts @@ -79,7 +79,7 @@ export interface S3BucketBuildArtifactsProps extends BuildArtifactsProps { /** * The name of the output bucket. */ - bucket: s3.BucketRef; + bucket: s3.IBucket; /** * The path inside of the bucket for the build output .zip file or folder. diff --git a/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts b/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts index 368bb68eadcdc..de532a4f9db8a 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts @@ -1,7 +1,7 @@ import codepipeline = require('@aws-cdk/aws-codepipeline-api'); import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { ProjectRef } from './project'; +import { IProject } from './project'; /** * Common construction properties of all CodeBuild Pipeline Actions. @@ -50,7 +50,7 @@ export interface PipelineBuildActionProps extends CommonPipelineBuildActionProps /** * The build project */ - project: ProjectRef; + project: IProject; } /** @@ -139,7 +139,7 @@ export interface PipelineTestActionProps extends CommonPipelineTestActionProps, /** * The build Project. */ - project: ProjectRef; + project: IProject; } export class PipelineTestAction extends codepipeline.TestAction { @@ -192,7 +192,7 @@ export class PipelineTestAction extends codepipeline.TestAction { } } -function setCodeBuildNeededPermissions(stage: codepipeline.IStage, project: ProjectRef, +function setCodeBuildNeededPermissions(stage: codepipeline.IStage, project: IProject, needsPipelineBucketWrite: boolean) { // grant the Pipeline role the required permissions to this Project stage.pipeline.role.addToPolicy(new iam.PolicyStatement() diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index d67b61250b31a..bc7f50889dac7 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -20,13 +20,150 @@ const CODEPIPELINE_TYPE = 'CODEPIPELINE'; const S3_BUCKET_ENV = 'SCRIPT_S3_BUCKET'; const S3_KEY_ENV = 'SCRIPT_S3_KEY'; +export interface IProject extends events.IEventRuleTarget { + /** The ARN of this Project. */ + readonly projectArn: string; + + /** The human-visible name of this Project. */ + readonly projectName: string; + + /** The IAM service Role of this Project. Undefined for imported Projects. */ + readonly role?: iam.Role; + + /** + * Convenience method for creating a new {@link PipelineBuildAction} build Action, + * and adding it to the given Stage. + * + * @param stage the Pipeline Stage to add the new Action to + * @param name the name of the newly created Action + * @param props the properties of the new Action + * @returns the newly created {@link PipelineBuildAction} build Action + */ + addToPipeline(stage: codepipeline.IStage, name: string, props?: CommonPipelineBuildActionProps): PipelineBuildAction; + + /** + * Convenience method for creating a new {@link PipelineTestAction} test Action, + * and adding it to the given Stage. + * + * @param stage the Pipeline Stage to add the new Action to + * @param name the name of the newly created Action + * @param props the properties of the new Action + * @returns the newly created {@link PipelineBuildAction} test Action + */ + addToPipelineAsTest(stage: codepipeline.IStage, name: string, props?: CommonPipelineTestActionProps): PipelineTestAction; + + /** + * Defines a CloudWatch event rule triggered when the build project state + * changes. You can filter specific build status events using an event + * pattern filter on the `build-status` detail field: + * + * const rule = project.onStateChange('OnBuildStarted', target); + * rule.addEventPattern({ + * detail: { + * 'build-status': [ + * "IN_PROGRESS", + * "SUCCEEDED", + * "FAILED", + * "STOPPED" + * ] + * } + * }); + * + * You can also use the methods `onBuildFailed` and `onBuildSucceeded` to define rules for + * these specific state changes. + * + * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html + */ + onStateChange(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines a CloudWatch event rule that triggers upon phase change of this + * build project. + * + * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html + */ + onPhaseChange(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines an event rule which triggers when a build starts. + */ + onBuildStarted(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines an event rule which triggers when a build fails. + */ + onBuildFailed(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines an event rule which triggers when a build completes successfully. + */ + onBuildSucceeded(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * @returns a CloudWatch metric associated with this build project. + * @param metricName The name of the metric + * @param props Customization properties + */ + metric(metricName: string, props: cloudwatch.MetricCustomization): cloudwatch.Metric; + + /** + * Measures the number of builds triggered. + * + * Units: Count + * + * Valid CloudWatch statistics: Sum + * + * @default sum over 5 minutes + */ + metricBuilds(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + + /** + * Measures the duration of all builds over time. + * + * Units: Seconds + * + * Valid CloudWatch statistics: Average (recommended), Maximum, Minimum + * + * @default average over 5 minutes + */ + metricDuration(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + + /** + * Measures the number of successful builds. + * + * Units: Count + * + * Valid CloudWatch statistics: Sum + * + * @default sum over 5 minutes + */ + metricSucceededBuilds(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + + /** + * Measures the number of builds that failed because of client error or + * because of a timeout. + * + * Units: Count + * + * Valid CloudWatch statistics: Sum + * + * @default sum over 5 minutes + */ + metricFailedBuilds(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + + /** + * Export this Project. Allows referencing this Project in a different CDK Stack. + */ + export(): ProjectAttributes; +} + /** * Properties of a reference to a CodeBuild Project. * - * @see ProjectRef.import - * @see ProjectRef.export + * @see Project.import + * @see Project.export */ -export interface ProjectRefProps { +export interface ProjectAttributes { /** * The human-readable name of the CodeBuild Project we're referencing. * The Project must be in the same account and region as the root Stack. @@ -44,26 +181,7 @@ export interface ProjectRefProps { * (or one defined in a different CDK Stack), * use the {@link import} method. */ -export abstract class ProjectRef extends cdk.Construct implements events.IEventRuleTarget { - /** - * Import a Project defined either outside the CDK, - * or in a different CDK Stack - * (and exported using the {@link export} method). - * - * @note if you're importing a CodeBuild Project for use - * in a CodePipeline, make sure the existing Project - * has permissions to access the S3 Bucket of that Pipeline - - * otherwise, builds in that Pipeline will always fail. - * - * @param parent the parent Construct for this Construct - * @param name the logical name of this Construct - * @param props the properties of the referenced Project - * @returns a reference to the existing Project - */ - public static import(parent: cdk.Construct, name: string, props: ProjectRefProps): ProjectRef { - return new ImportedProjectRef(parent, name, props); - } - +export abstract class ProjectBase extends cdk.Construct implements IProject { /** The ARN of this Project. */ public abstract readonly projectArn: string; @@ -76,14 +194,7 @@ export abstract class ProjectRef extends cdk.Construct implements events.IEventR /** A role used by CloudWatch events to trigger a build */ private eventsRole?: iam.Role; - /** - * Export this Project. Allows referencing this Project in a different CDK Stack. - */ - public export(): ProjectRefProps { - return { - projectName: new cdk.Output(this, 'ProjectName', { value: this.projectName }).makeImportValue().toString(), - }; - } + public abstract export(): ProjectAttributes; /** * Convenience method for creating a new {@link PipelineBuildAction} build Action, @@ -317,12 +428,12 @@ export abstract class ProjectRef extends cdk.Construct implements events.IEventR } } -class ImportedProjectRef extends ProjectRef { +class ImportedProject extends ProjectBase { public readonly projectArn: string; public readonly projectName: string; public readonly role?: iam.Role = undefined; - constructor(parent: cdk.Construct, name: string, props: ProjectRefProps) { + constructor(parent: cdk.Construct, name: string, private readonly props: ProjectAttributes) { super(parent, name); this.projectArn = cdk.ArnUtils.fromComponents({ @@ -333,6 +444,10 @@ class ImportedProjectRef extends ProjectRef { this.projectName = props.projectName; } + + public export() { + return this.props; + } } export interface CommonProjectProps { @@ -378,13 +493,13 @@ export interface CommonProjectProps { * Encryption key to use to read and write artifacts * If not specified, a role will be created. */ - encryptionKey?: kms.EncryptionKeyRef; + encryptionKey?: kms.IEncryptionKey; /** * Bucket to store cached source artifacts * If not specified, source artifacts will not be cached. */ - cacheBucket?: s3.BucketRef; + cacheBucket?: s3.IBucket; /** * Subdirectory to store cached artifacts @@ -461,7 +576,26 @@ export interface ProjectProps extends CommonProjectProps { /** * A representation of a CodeBuild Project. */ -export class Project extends ProjectRef { +export class Project extends ProjectBase { + /** + * Import a Project defined either outside the CDK, + * or in a different CDK Stack + * (and exported using the {@link export} method). + * + * @note if you're importing a CodeBuild Project for use + * in a CodePipeline, make sure the existing Project + * has permissions to access the S3 Bucket of that Pipeline - + * otherwise, builds in that Pipeline will always fail. + * + * @param parent the parent Construct for this Construct + * @param name the logical name of this Construct + * @param props the properties of the referenced Project + * @returns a reference to the existing Project + */ + public static import(parent: cdk.Construct, name: string, props: ProjectAttributes): IProject { + return new ImportedProject(parent, name, props); + } + /** * The IAM role for this project. */ @@ -589,6 +723,15 @@ export class Project extends ProjectRef { return ret; } + /** + * Export this Project. Allows referencing this Project in a different CDK Stack. + */ + public export(): ProjectAttributes { + return { + projectName: new cdk.Output(this, 'ProjectName', { value: this.projectName }).makeImportValue().toString(), + }; + } + /** * Add a permission only if there's a policy attached. * @param statement The permissions statement to add diff --git a/packages/@aws-cdk/aws-codebuild/lib/source.ts b/packages/@aws-cdk/aws-codebuild/lib/source.ts index 3d06591b38c23..c0ff41efb3a43 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/source.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/source.ts @@ -75,7 +75,7 @@ export class NoSource extends BuildSource { * Construction properties for {@link CodeCommitSource}. */ export interface CodeCommitSourceProps extends BuildSourceProps { - repository: codecommit.RepositoryRef; + repository: codecommit.IRepository; } /** @@ -83,7 +83,7 @@ export interface CodeCommitSourceProps extends BuildSourceProps { */ export class CodeCommitSource extends BuildSource { public readonly type: SourceType = SourceType.CodeCommit; - private readonly repo: codecommit.RepositoryRef; + private readonly repo: codecommit.IRepository; constructor(props: CodeCommitSourceProps) { super(props); @@ -108,7 +108,7 @@ export class CodeCommitSource extends BuildSource { * Construction properties for {@link S3BucketSource}. */ export interface S3BucketSourceProps extends BuildSourceProps { - bucket: s3.BucketRef; + bucket: s3.IBucket; path: string; } @@ -117,7 +117,7 @@ export interface S3BucketSourceProps extends BuildSourceProps { */ export class S3BucketSource extends BuildSource { public readonly type: SourceType = SourceType.S3; - private readonly bucket: s3.BucketRef; + private readonly bucket: s3.IBucket; private readonly path: string; constructor(props: S3BucketSourceProps) { diff --git a/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts b/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts index 95f9b3b304453..ff99ce394fdec 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts @@ -1,7 +1,7 @@ import codepipeline = require('@aws-cdk/aws-codepipeline-api'); import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { RepositoryRef } from './repository'; +import { IRepository } from './repository'; /** * Common properties for creating {@link PipelineSourceAction} - @@ -39,7 +39,7 @@ export interface PipelineSourceActionProps extends CommonPipelineSourceActionPro /** * The CodeCommit repository. */ - repository: RepositoryRef; + repository: IRepository; } /** diff --git a/packages/@aws-cdk/aws-codecommit/lib/repository.ts b/packages/@aws-cdk/aws-codecommit/lib/repository.ts index 22ea9737a3f44..725906bdb1e16 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/repository.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/repository.ts @@ -4,10 +4,94 @@ import cdk = require('@aws-cdk/cdk'); import { CfnRepository } from './codecommit.generated'; import { CommonPipelineSourceActionProps, PipelineSourceAction } from './pipeline-action'; +export interface IRepository { + /** The ARN of this Repository. */ + readonly repositoryArn: string; + + /** The human-visible name of this Repository. */ + readonly repositoryName: string; + + /** The HTTP clone URL */ + readonly repositoryCloneUrlHttp: string; + + /** The SSH clone URL */ + readonly repositoryCloneUrlSsh: string; + + /** + * Convenience method for creating a new {@link PipelineSourceAction}, + * and adding it to the given Stage. + * + * @param stage the Pipeline Stage to add the new Action to + * @param name the name of the newly created Action + * @param props the properties of the new Action + * @returns the newly created {@link PipelineSourceAction} + */ + addToPipeline(stage: actions.IStage, name: string, props?: CommonPipelineSourceActionProps): PipelineSourceAction; + + /** + * Defines a CloudWatch event rule which triggers for repository events. Use + * `rule.addEventPattern(pattern)` to specify a filter. + */ + onEvent(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines a CloudWatch event rule which triggers when a "CodeCommit + * Repository State Change" event occurs. + */ + onStateChange(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines a CloudWatch event rule which triggers when a reference is + * created (i.e. a new branch/tag is created) to the repository. + */ + onReferenceCreated(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines a CloudWatch event rule which triggers when a reference is + * updated (i.e. a commit is pushed to an existing or new branch) from the repository. + */ + onReferenceUpdated(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines a CloudWatch event rule which triggers when a reference is + * delete (i.e. a branch/tag is deleted) from the repository. + */ + onReferenceDeleted(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines a CloudWatch event rule which triggers when a pull request state is changed. + */ + onPullRequestStateChange(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines a CloudWatch event rule which triggers when a comment is made on a pull request. + */ + onCommentOnPullRequest(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines a CloudWatch event rule which triggers when a comment is made on a commit. + */ + onCommentOnCommit(name: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps): events.EventRule; + + /** + * Defines a CloudWatch event rule which triggers when a commit is pushed to a branch. + * @param target The target of the event + * @param branch The branch to monitor. Defaults to all branches. + */ + onCommit(name: string, target?: events.IEventRuleTarget, branch?: string): events.EventRule; + + /** + * Exports this Repository. Allows the same Repository to be used in 2 different Stacks. + * + * @see import + */ + export(): RepositoryAttributes; +} + /** - * Properties for the {@link RepositoryRef.import} method. + * Properties for the {@link Repository.import} method. */ -export interface RepositoryRefProps { +export interface RepositoryAttributes { /** * The name of an existing CodeCommit Repository that we are referencing. * Must be in the same account and region as the root Stack. @@ -22,42 +106,22 @@ export interface RepositoryRefProps { * use the {@link Repository} class. * * If you want to reference an already existing Repository, - * use the {@link RepositoryRef.import} method. + * use the {@link Repository.import} method. */ -export abstract class RepositoryRef extends cdk.Construct { - /** - * Import a Repository defined either outside the CDK, or in a different Stack - * (exported with the {@link export} method). - * - * @param parent the parent Construct for the Repository - * @param name the name of the Repository Construct - * @param props the properties used to identify the existing Repository - * @returns a reference to the existing Repository - */ - public static import(parent: cdk.Construct, name: string, props: RepositoryRefProps): RepositoryRef { - return new ImportedRepositoryRef(parent, name, props); - } - +export abstract class RepositoryBase extends cdk.Construct implements IRepository { /** The ARN of this Repository. */ public abstract readonly repositoryArn: string; /** The human-visible name of this Repository. */ public abstract readonly repositoryName: string; + /** The HTTP clone URL */ public abstract readonly repositoryCloneUrlHttp: string; + /** The SSH clone URL */ public abstract readonly repositoryCloneUrlSsh: string; - /** - * Exports this Repository. Allows the same Repository to be used in 2 different Stacks. - * - * @see import - */ - public export(): RepositoryRefProps { - return { - repositoryName: new cdk.Output(this, 'RepositoryName', { value: this.repositoryName }).makeImportValue().toString() - }; - } + public abstract export(): RepositoryAttributes; /** * Convenience method for creating a new {@link PipelineSourceAction}, @@ -173,11 +237,11 @@ export abstract class RepositoryRef extends cdk.Construct { } } -class ImportedRepositoryRef extends RepositoryRef { +class ImportedRepository extends RepositoryBase { public readonly repositoryArn: string; public readonly repositoryName: string; - constructor(parent: cdk.Construct, name: string, props: RepositoryRefProps) { + constructor(parent: cdk.Construct, name: string, private readonly props: RepositoryAttributes) { super(parent, name); this.repositoryArn = cdk.ArnUtils.fromComponents({ @@ -187,6 +251,10 @@ class ImportedRepositoryRef extends RepositoryRef { this.repositoryName = props.repositoryName; } + public export() { + return this.props; + } + public get repositoryCloneUrlHttp() { return this.repositoryCloneUrl('https'); } @@ -216,7 +284,20 @@ export interface RepositoryProps { /** * Provides a CodeCommit Repository */ -export class Repository extends RepositoryRef { +export class Repository extends RepositoryBase { + /** + * Import a Repository defined either outside the CDK, or in a different Stack + * (exported with the {@link export} method). + * + * @param parent the parent Construct for the Repository + * @param name the name of the Repository Construct + * @param props the properties used to identify the existing Repository + * @returns a reference to the existing Repository + */ + public static import(parent: cdk.Construct, name: string, props: RepositoryAttributes): IRepository { + return new ImportedRepository(parent, name, props); + } + private readonly repository: CfnRepository; private readonly triggers = new Array(); @@ -246,6 +327,17 @@ export class Repository extends RepositoryRef { return this.repository.repositoryName; } + /** + * Exports this Repository. Allows the same Repository to be used in 2 different Stacks. + * + * @see import + */ + public export(): RepositoryAttributes { + return { + repositoryName: new cdk.Output(this, 'RepositoryName', { value: this.repositoryName }).makeImportValue().toString() + }; + } + /** * Create a trigger to notify another service to run actions on repository events. * @param arn Arn of the resource that repository events will notify diff --git a/packages/@aws-cdk/aws-codedeploy/README.md b/packages/@aws-cdk/aws-codedeploy/README.md index 415024f7e7bc6..6bb1f64527847 100644 --- a/packages/@aws-cdk/aws-codedeploy/README.md +++ b/packages/@aws-cdk/aws-codedeploy/README.md @@ -15,7 +15,7 @@ const application = new codedeploy.ServerApplication(this, 'CodeDeployApplicatio To import an already existing Application: ```ts -const application = codedeploy.ServerApplicationRef.import(this, 'ExistingCodeDeployApplication', { +const application = codedeploy.ServerApplication.import(this, 'ExistingCodeDeployApplication', { applicationName: 'MyExistingApplication', }); ``` @@ -75,7 +75,7 @@ one will be automatically created. To import an already existing Deployment Group: ```ts -const deploymentGroup = codedeploy.ServerDeploymentGroupRef.import(this, 'ExistingCodeDeployDeploymentGroup', { +const deploymentGroup = codedeploy.ServerDeploymentGroup.import(this, 'ExistingCodeDeployDeploymentGroup', { application, deploymentGroupName: 'MyExistingDeploymentGroup', }); @@ -151,7 +151,7 @@ const deploymentConfig = new codedeploy.ServerDeploymentConfig(this, 'Deployment Or import an existing one: ```ts -const deploymentConfig = codedeploy.ServerDeploymentConfigRef.import(this, 'ExistingDeploymentConfiguration', { +const deploymentConfig = codedeploy.ServerDeploymentConfig.import(this, 'ExistingDeploymentConfiguration', { deploymentConfigName: 'MyExistingDeploymentConfiguration', }); ``` diff --git a/packages/@aws-cdk/aws-codedeploy/lib/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/application.ts index fb5c7f2049c51..ac713ee15293b 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/application.ts @@ -1,20 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import { CfnApplication } from './codedeploy.generated'; -/** - * Properties of a reference to a CodeDeploy EC2/on-premise Application. - * - * @see ServerApplicationRef#import - * @see ServerApplicationRef#export - */ -export interface ServerApplicationRefProps { - /** - * The physical, human-readable name of the CodeDeploy EC2/on-premise Application we're referencing. - * The Application must be in the same account and region as the root Stack. - */ - applicationName: string; -} - /** * Represents a reference to a CodeDeploy Application deploying to EC2/on-premise instances. * @@ -25,41 +11,42 @@ export interface ServerApplicationRefProps { * or one defined in a different CDK Stack, * use the {@link #import} method. */ -export abstract class ServerApplicationRef extends cdk.Construct { - /** - * Import an Application defined either outside the CDK, - * or in a different CDK Stack and exported using the {@link #export} method. - * - * @param parent the parent Construct for this new Construct - * @param id the logical ID of this new Construct - * @param props the properties of the referenced Application - * @returns a Construct representing a reference to an existing Application - */ - public static import(parent: cdk.Construct, id: string, props: ServerApplicationRefProps): ServerApplicationRef { - return new ImportedServerApplicationRef(parent, id, props); - } +export interface IServerApplication { + readonly applicationArn: string; - public abstract readonly applicationArn: string; + readonly applicationName: string; - public abstract readonly applicationName: string; + export(): ServerApplicationAttributes; +} - public export(): ServerApplicationRefProps { - return { - applicationName: new cdk.Output(this, 'ApplicationName', { value: this.applicationName }).makeImportValue().toString() - }; - } +/** + * Properties of a reference to a CodeDeploy EC2/on-premise Application. + * + * @see ServerApplication#import + * @see ServerApplication#export + */ +export interface ServerApplicationAttributes { + /** + * The physical, human-readable name of the CodeDeploy EC2/on-premise Application we're referencing. + * The Application must be in the same account and region as the root Stack. + */ + applicationName: string; } -class ImportedServerApplicationRef extends ServerApplicationRef { +class ImportedServerApplication extends cdk.Construct implements IServerApplication { public readonly applicationArn: string; public readonly applicationName: string; - constructor(parent: cdk.Construct, id: string, props: ServerApplicationRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: ServerApplicationAttributes) { super(parent, id); this.applicationName = props.applicationName; this.applicationArn = applicationName2Arn(this.applicationName); } + + public export() { + return this.props; + } } /** @@ -77,7 +64,20 @@ export interface ServerApplicationProps { /** * A CodeDeploy Application that deploys to EC2/on-premise instances. */ -export class ServerApplication extends ServerApplicationRef { +export class ServerApplication extends cdk.Construct implements IServerApplication { + /** + * Import an Application defined either outside the CDK, + * or in a different CDK Stack and exported using the {@link #export} method. + * + * @param parent the parent Construct for this new Construct + * @param id the logical ID of this new Construct + * @param props the properties of the referenced Application + * @returns a Construct representing a reference to an existing Application + */ + public static import(parent: cdk.Construct, id: string, props: ServerApplicationAttributes): IServerApplication { + return new ImportedServerApplication(parent, id, props); + } + public readonly applicationArn: string; public readonly applicationName: string; @@ -92,6 +92,12 @@ export class ServerApplication extends ServerApplicationRef { this.applicationName = resource.ref; this.applicationArn = applicationName2Arn(this.applicationName); } + + public export(): ServerApplicationAttributes { + return { + applicationName: new cdk.Output(this, 'ApplicationName', { value: this.applicationName }).makeImportValue().toString() + }; + } } function applicationName2Arn(applicationName: string): string { diff --git a/packages/@aws-cdk/aws-codedeploy/lib/deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/deployment-config.ts index 20e85708926ce..3b61aa367fdc9 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/deployment-config.ts @@ -11,15 +11,16 @@ import { CfnDeploymentConfig } from './codedeploy.generated'; export interface IServerDeploymentConfig { readonly deploymentConfigName: string; readonly deploymentConfigArn: string; + export(): ServerDeploymentConfigAttributes; } /** * Properties of a reference to a CodeDeploy EC2/on-premise Deployment Configuration. * - * @see ServerDeploymentConfigRef#import - * @see ServerDeploymentConfigRef#export + * @see ServerDeploymentConfig#import + * @see ServerDeploymentConfig#export */ -export interface ServerDeploymentConfigRefProps { +export interface ServerDeploymentConfigAttributes { /** * The physical, human-readable name of the custom CodeDeploy EC2/on-premise Deployment Configuration * that we are referencing. @@ -27,46 +28,20 @@ export interface ServerDeploymentConfigRefProps { deploymentConfigName: string; } -/** - * Reference to a custom Deployment Configuration for an EC2/on-premise Deployment Group. - */ -export abstract class ServerDeploymentConfigRef extends cdk.Construct implements IServerDeploymentConfig { - /** - * Import a custom Deployment Configuration for an EC2/on-premise Deployment Group defined either outside the CDK, - * or in a different CDK Stack and exported using the {@link #export} method. - * - * @param parent the parent Construct for this new Construct - * @param id the logical ID of this new Construct - * @param props the properties of the referenced custom Deployment Configuration - * @returns a Construct representing a reference to an existing custom Deployment Configuration - */ - public static import(parent: cdk.Construct, id: string, props: ServerDeploymentConfigRefProps): - ServerDeploymentConfigRef { - return new ImportedServerDeploymentConfigRef(parent, id, props); - } - - public abstract readonly deploymentConfigName: string; - public abstract readonly deploymentConfigArn: string; - - public export(): ServerDeploymentConfigRefProps { - return { - deploymentConfigName: new cdk.Output(this, 'DeploymentConfigName', { - value: this.deploymentConfigName, - }).makeImportValue().toString(), - }; - } -} - -class ImportedServerDeploymentConfigRef extends ServerDeploymentConfigRef { +class ImportedServerDeploymentConfig extends cdk.Construct implements IServerDeploymentConfig { public readonly deploymentConfigName: string; public readonly deploymentConfigArn: string; - constructor(parent: cdk.Construct, id: string, props: ServerDeploymentConfigRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: ServerDeploymentConfigAttributes) { super(parent, id); this.deploymentConfigName = props.deploymentConfigName; this.deploymentConfigArn = arnForDeploymentConfigName(this.deploymentConfigName); } + + public export() { + return this.props; + } } class DefaultServerDeploymentConfig implements IServerDeploymentConfig { @@ -77,6 +52,12 @@ class DefaultServerDeploymentConfig implements IServerDeploymentConfig { this.deploymentConfigName = deploymentConfigName; this.deploymentConfigArn = arnForDeploymentConfigName(this.deploymentConfigName); } + + public export(): ServerDeploymentConfigAttributes { + return { + deploymentConfigName: this.deploymentConfigName + }; + } } /** @@ -110,11 +91,24 @@ export interface ServerDeploymentConfigProps { /** * A custom Deployment Configuration for an EC2/on-premise Deployment Group. */ -export class ServerDeploymentConfig extends ServerDeploymentConfigRef { +export class ServerDeploymentConfig extends cdk.Construct implements IServerDeploymentConfig { public static readonly OneAtATime: IServerDeploymentConfig = new DefaultServerDeploymentConfig('CodeDeployDefault.OneAtATime'); public static readonly HalfAtATime: IServerDeploymentConfig = new DefaultServerDeploymentConfig('CodeDeployDefault.HalfAtATime'); public static readonly AllAtOnce: IServerDeploymentConfig = new DefaultServerDeploymentConfig('CodeDeployDefault.AllAtOnce'); + /** + * Import a custom Deployment Configuration for an EC2/on-premise Deployment Group defined either outside the CDK, + * or in a different CDK Stack and exported using the {@link #export} method. + * + * @param parent the parent Construct for this new Construct + * @param id the logical ID of this new Construct + * @param props the properties of the referenced custom Deployment Configuration + * @returns a Construct representing a reference to an existing custom Deployment Configuration + */ + public static import(parent: cdk.Construct, id: string, props: ServerDeploymentConfigAttributes): IServerDeploymentConfig { + return new ImportedServerDeploymentConfig(parent, id, props); + } + public readonly deploymentConfigName: string; public readonly deploymentConfigArn: string; @@ -130,6 +124,14 @@ export class ServerDeploymentConfig extends ServerDeploymentConfigRef { this.deploymentConfigArn = arnForDeploymentConfigName(this.deploymentConfigName); } + public export(): ServerDeploymentConfigAttributes { + return { + deploymentConfigName: new cdk.Output(this, 'DeploymentConfigName', { + value: this.deploymentConfigName, + }).makeImportValue().toString(), + }; + } + private minimumHealthyHosts(props: ServerDeploymentConfigProps): CfnDeploymentConfig.MinimumHealthyHostsProperty { if (props.minHealthyHostCount === undefined && props.minHealthyHostPercentage === undefined) { diff --git a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts index d5a1defffb1a7..2971a736c9ffe 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts @@ -6,23 +6,33 @@ import ec2 = require("@aws-cdk/aws-ec2"); import iam = require('@aws-cdk/aws-iam'); import s3 = require("@aws-cdk/aws-s3"); import cdk = require("@aws-cdk/cdk"); -import { ServerApplication, ServerApplicationRef } from "./application"; +import { IServerApplication, ServerApplication } from "./application"; import { CfnDeploymentGroup } from './codedeploy.generated'; import { IServerDeploymentConfig, ServerDeploymentConfig } from "./deployment-config"; import { CommonPipelineDeployActionProps, PipelineDeployAction } from "./pipeline-action"; +export interface IServerDeploymentGroup { + readonly application: IServerApplication; + readonly role?: iam.Role; + readonly deploymentGroupName: string; + readonly deploymentGroupArn: string; + readonly deploymentConfig: IServerDeploymentConfig; + readonly autoScalingGroups?: autoscaling.AutoScalingGroup[]; + export(): ServerDeploymentGroupAttributes; +} + /** * Properties of a reference to a CodeDeploy EC2/on-premise Deployment Group. * * @see ServerDeploymentGroupRef#import * @see ServerDeploymentGroupRef#export */ -export interface ServerDeploymentGroupRefProps { +export interface ServerDeploymentGroupAttributes { /** * The reference to the CodeDeploy EC2/on-premise Application * that this Deployment Group belongs to. */ - application: ServerApplicationRef; + application: IServerApplication; /** * The physical, human-readable name of the CodeDeploy EC2/on-premise Deployment Group @@ -48,21 +58,8 @@ export interface ServerDeploymentGroupRefProps { * or one defined in a different CDK Stack, * use the {@link #import} method. */ -export abstract class ServerDeploymentGroupRef extends cdk.Construct { - /** - * Import an EC2/on-premise Deployment Group defined either outside the CDK, - * or in a different CDK Stack and exported using the {@link #export} method. - * - * @param parent the parent Construct for this new Construct - * @param id the logical ID of this new Construct - * @param props the properties of the referenced Deployment Group - * @returns a Construct representing a reference to an existing Deployment Group - */ - public static import(parent: cdk.Construct, id: string, props: ServerDeploymentGroupRefProps): ServerDeploymentGroupRef { - return new ImportedServerDeploymentGroupRef(parent, id, props); - } - - public abstract readonly application: ServerApplicationRef; +export abstract class ServerDeploymentGroupBase extends cdk.Construct implements IServerDeploymentGroup { + public abstract readonly application: IServerApplication; public abstract readonly role?: iam.Role; public abstract readonly deploymentGroupName: string; public abstract readonly deploymentGroupArn: string; @@ -74,15 +71,7 @@ export abstract class ServerDeploymentGroupRef extends cdk.Construct { this.deploymentConfig = deploymentConfig || ServerDeploymentConfig.OneAtATime; } - public export(): ServerDeploymentGroupRefProps { - return { - application: this.application, - deploymentGroupName: new cdk.Output(this, 'DeploymentGroupName', { - value: this.deploymentGroupName - }).makeImportValue().toString(), - deploymentConfig: this.deploymentConfig, - }; - } + public abstract export(): ServerDeploymentGroupAttributes; /** * Convenience method for creating a new {@link PipelineDeployAction} @@ -103,14 +92,14 @@ export abstract class ServerDeploymentGroupRef extends cdk.Construct { } } -class ImportedServerDeploymentGroupRef extends ServerDeploymentGroupRef { - public readonly application: ServerApplicationRef; +class ImportedServerDeploymentGroup extends ServerDeploymentGroupBase { + public readonly application: IServerApplication; public readonly role?: iam.Role = undefined; public readonly deploymentGroupName: string; public readonly deploymentGroupArn: string; public readonly autoScalingGroups?: autoscaling.AutoScalingGroup[] = undefined; - constructor(parent: cdk.Construct, id: string, props: ServerDeploymentGroupRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: ServerDeploymentGroupAttributes) { super(parent, id, props.deploymentConfig); this.application = props.application; @@ -118,6 +107,10 @@ class ImportedServerDeploymentGroupRef extends ServerDeploymentGroupRef { this.deploymentGroupArn = deploymentGroupName2Arn(props.application.applicationName, props.deploymentGroupName); } + + public export() { + return this.props; + } } /** @@ -190,7 +183,7 @@ export interface ServerDeploymentGroupProps { * The CodeDeploy EC2/on-premise Application this Deployment Group belongs to. * If you don't provide one, a new Application will be created. */ - application?: ServerApplicationRef; + application?: IServerApplication; /** * The service Role of this Deployment Group. @@ -281,15 +274,28 @@ export interface ServerDeploymentGroupProps { /** * A CodeDeploy Deployment Group that deploys to EC2/on-premise instances. */ -export class ServerDeploymentGroup extends ServerDeploymentGroupRef { - public readonly application: ServerApplicationRef; +export class ServerDeploymentGroup extends ServerDeploymentGroupBase { + /** + * Import an EC2/on-premise Deployment Group defined either outside the CDK, + * or in a different CDK Stack and exported using the {@link #export} method. + * + * @param parent the parent Construct for this new Construct + * @param id the logical ID of this new Construct + * @param props the properties of the referenced Deployment Group + * @returns a Construct representing a reference to an existing Deployment Group + */ + public static import(parent: cdk.Construct, id: string, props: ServerDeploymentGroupAttributes): IServerDeploymentGroup { + return new ImportedServerDeploymentGroup(parent, id, props); + } + + public readonly application: IServerApplication; public readonly role?: iam.Role; public readonly deploymentGroupArn: string; public readonly deploymentGroupName: string; private readonly _autoScalingGroups: autoscaling.AutoScalingGroup[]; private readonly installAgent: boolean; - private readonly codeDeployBucket: s3.BucketRef; + private readonly codeDeployBucket: s3.IBucket; private readonly alarms: cloudwatch.Alarm[]; constructor(parent: cdk.Construct, id: string, props: ServerDeploymentGroupProps = {}) { @@ -305,7 +311,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef { this._autoScalingGroups = props.autoScalingGroups || []; this.installAgent = props.installAgent === undefined ? true : props.installAgent; const region = (cdk.Aws.region).toString(); - this.codeDeployBucket = s3.BucketRef.import(this, 'CodeDeployBucket', { + this.codeDeployBucket = s3.Bucket.import(this, 'CodeDeployBucket', { bucketName: `aws-codedeploy-${region}`, }); for (const asg of this._autoScalingGroups) { @@ -341,6 +347,16 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef { this.deploymentGroupName); } + public export(): ServerDeploymentGroupAttributes { + return { + application: this.application, + deploymentGroupName: new cdk.Output(this, 'DeploymentGroupName', { + value: this.deploymentGroupName + }).makeImportValue().toString(), + deploymentConfig: this.deploymentConfig, + }; + } + /** * Adds an additional auto-scaling group to this Deployment Group. * diff --git a/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts b/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts index 58985c522273d..a0f9e00c17d88 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts @@ -1,7 +1,7 @@ import codepipeline = require('@aws-cdk/aws-codepipeline-api'); import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { ServerDeploymentGroupRef } from './deployment-group'; +import { IServerDeploymentGroup } from './deployment-group'; /** * Common properties for creating a {@link PipelineDeployAction}, @@ -25,7 +25,7 @@ export interface PipelineDeployActionProps extends CommonPipelineDeployActionPro /** * The CodeDeploy Deployment Group to deploy to. */ - deploymentGroup: ServerDeploymentGroupRef; + deploymentGroup: IServerDeploymentGroup; } export class PipelineDeployAction extends codepipeline.DeployAction { diff --git a/packages/@aws-cdk/aws-codedeploy/test/test.deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/test/test.deployment-config.ts index b3cd26b8c205d..eea90cf28f523 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/test.deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/test.deployment-config.ts @@ -68,7 +68,7 @@ export = { 'can be imported'(test: Test) { const stack = new cdk.Stack(); - const deploymentConfig = codedeploy.ServerDeploymentConfigRef.import(stack, 'MyDC', { + const deploymentConfig = codedeploy.ServerDeploymentConfig.import(stack, 'MyDC', { deploymentConfigName: 'MyDC', }); diff --git a/packages/@aws-cdk/aws-codedeploy/test/test.deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/test/test.deployment-group.ts index 3e8d47bfc0798..4b470209cc461 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/test.deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/test.deployment-group.ts @@ -31,10 +31,10 @@ export = { 'can be imported'(test: Test) { const stack = new cdk.Stack(); - const application = codedeploy.ServerApplicationRef.import(stack, 'MyApp', { + const application = codedeploy.ServerApplication.import(stack, 'MyApp', { applicationName: 'MyApp', }); - const deploymentGroup = codedeploy.ServerDeploymentGroupRef.import(stack, 'MyDG', { + const deploymentGroup = codedeploy.ServerDeploymentGroup.import(stack, 'MyDG', { application, deploymentGroupName: 'MyDG', }); diff --git a/packages/@aws-cdk/aws-codepipeline/lib/manual-approval-action.ts b/packages/@aws-cdk/aws-codepipeline/lib/manual-approval-action.ts index 63089a872ed42..259fa080ae328 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/manual-approval-action.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/manual-approval-action.ts @@ -10,7 +10,7 @@ export interface ManualApprovalActionProps extends actions.CommonActionProps, /** * Optional SNS topic to send notifications to when an approval is pending. */ - notificationTopic?: sns.TopicRef; + notificationTopic?: sns.ITopic; /** * A list of email addresses to subscribe to notifications when this Action is pending approval. @@ -34,7 +34,7 @@ export class ManualApprovalAction extends actions.Action { * If no Topic was passed, but `notifyEmails` were provided, * a new Topic will be created. */ - public readonly notificationTopic?: sns.TopicRef; + public readonly notificationTopic?: sns.ITopic; constructor(parent: cdk.Construct, name: string, props: ManualApprovalActionProps) { super(parent, name, { diff --git a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts index 4baa3aff60dd7..db8688b22bffe 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts @@ -12,7 +12,7 @@ export interface PipelineProps { * The S3 bucket used by this Pipeline to store artifacts. * If not specified, a new S3 bucket will be created. */ - artifactBucket?: s3.BucketRef; + artifactBucket?: s3.IBucket; /** * Indicates whether to rerun the AWS CodePipeline pipeline after you update it. @@ -79,7 +79,7 @@ export class Pipeline extends cdk.Construct implements cpapi.IPipeline { /** * Bucket used to store output artifacts */ - public readonly artifactBucket: s3.BucketRef; + public readonly artifactBucket: s3.IBucket; private readonly stages = new Array(); private eventsRole?: iam.Role; @@ -314,7 +314,7 @@ export class Pipeline extends cdk.Construct implements cpapi.IPipeline { replicationBucketName = crossRegionScaffoldStack.replicationBucketName; } - const replicationBucket = s3.BucketRef.import(this, 'CrossRegionCodePipelineReplicationBucket-' + action.region, { + const replicationBucket = s3.Bucket.import(this, 'CrossRegionCodePipelineReplicationBucket-' + action.region, { bucketName: replicationBucketName, }); replicationBucket.grantReadWrite(this.role); diff --git a/packages/@aws-cdk/aws-ec2/lib/connections.ts b/packages/@aws-cdk/aws-ec2/lib/connections.ts index cd416a4c7ee1e..ff8810d3ba7da 100644 --- a/packages/@aws-cdk/aws-ec2/lib/connections.ts +++ b/packages/@aws-cdk/aws-ec2/lib/connections.ts @@ -1,4 +1,4 @@ -import { SecurityGroupRef } from "./security-group"; +import { ISecurityGroup } from "./security-group"; import { AnyIPv4, IPortRange, ISecurityGroupRule } from "./security-group-rule"; /** @@ -40,7 +40,7 @@ export interface ConnectionsProps { * * @default No security groups */ - securityGroups?: SecurityGroupRef[]; + securityGroups?: ISecurityGroup[]; /** * Default port range for initiating connections to and from this object @@ -75,7 +75,7 @@ export class Connections implements IConnectable { * May be empty if this Connections object is not managing a SecurityGroup, * but simply representing a Connectable peer. */ - private readonly _securityGroups = new ReactiveList(); + private readonly _securityGroups = new ReactiveList(); /** * The rule that defines how to represent this peer in a security group @@ -96,14 +96,14 @@ export class Connections implements IConnectable { this.defaultPortRange = props.defaultPortRange; } - public get securityGroups(): SecurityGroupRef[] { + public get securityGroups(): ISecurityGroup[] { return this._securityGroups.asArray(); } /** * Add a security group to the list of security groups managed by this object */ - public addSecurityGroup(...securityGroups: SecurityGroupRef[]) { + public addSecurityGroup(...securityGroups: ISecurityGroup[]) { for (const securityGroup of securityGroups) { this._securityGroups.push(securityGroup); this._securityGroupRules.push(securityGroup); diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index 8c7f8479fee3f..1eeb1e8590104 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -2,9 +2,16 @@ import { Construct, ITaggable, Output, TagManager, Tags, Token } from '@aws-cdk/ import { Connections, IConnectable } from './connections'; import { CfnSecurityGroup, CfnSecurityGroupEgress, CfnSecurityGroupIngress } from './ec2.generated'; import { IPortRange, ISecurityGroupRule } from './security-group-rule'; -import { VpcNetworkRef } from './vpc-ref'; +import { IVpcNetwork } from './vpc-ref'; -export interface SecurityGroupRefProps { +export interface ISecurityGroup extends ISecurityGroupRule, IConnectable { + readonly securityGroupId: string; + addIngressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string): void; + addEgressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string): void; + export(): SecurityGroupAttributes; +} + +export interface SecurityGroupAttributes { /** * ID of security group */ @@ -14,17 +21,10 @@ export interface SecurityGroupRefProps { /** * A SecurityGroup that is not created in this template */ -export abstract class SecurityGroupRef extends Construct implements ISecurityGroupRule, IConnectable { - /** - * Import an existing SecurityGroup - */ - public static import(parent: Construct, id: string, props: SecurityGroupRefProps): SecurityGroupRef { - return new ImportedSecurityGroup(parent, id, props); - } - +export abstract class SecurityGroupBase extends Construct implements ISecurityGroup { public abstract readonly securityGroupId: string; public readonly canInlineRule = false; - public readonly connections = new Connections({ securityGroups: [this] }); + public readonly connections: Connections = new Connections({ securityGroups: [this] }); /** * FIXME: Where to place this?? @@ -78,12 +78,7 @@ export abstract class SecurityGroupRef extends Construct implements ISecurityGro /** * Export this SecurityGroup for use in a different Stack */ - public export(): SecurityGroupRefProps { - return { - securityGroupId: new Output(this, 'SecurityGroupId', { value: this.securityGroupId }).makeImportValue().toString() - }; - } - + public abstract export(): SecurityGroupAttributes; } export interface SecurityGroupProps { @@ -114,7 +109,7 @@ export interface SecurityGroupProps { /** * The VPC in which to create the security group. */ - vpc: VpcNetworkRef; + vpc: IVpcNetwork; /** * Whether to allow all outbound traffic by default. @@ -135,7 +130,14 @@ export interface SecurityGroupProps { * inline ingress and egress rule (which saves on the total number of resources inside * the template). */ -export class SecurityGroup extends SecurityGroupRef implements ITaggable { +export class SecurityGroup extends SecurityGroupBase implements ITaggable { + /** + * Import an existing SecurityGroup + */ + public static import(parent: Construct, id: string, props: SecurityGroupAttributes): ISecurityGroup { + return new ImportedSecurityGroup(parent, id, props); + } + /** * An attribute that represents the security group name. */ @@ -186,6 +188,15 @@ export class SecurityGroup extends SecurityGroupRef implements ITaggable { this.addDefaultEgressRule(); } + /** + * Export this SecurityGroup for use in a different Stack + */ + public export(): SecurityGroupAttributes { + return { + securityGroupId: new Output(this, 'SecurityGroupId', { value: this.securityGroupId }).makeImportValue().toString() + }; + } + public addIngressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string) { if (!peer.canInlineRule || !connection.canInlineRule) { super.addIngressRule(peer, connection, description); @@ -378,14 +389,18 @@ export interface ConnectionRule { /** * A SecurityGroup that hasn't been created here */ -class ImportedSecurityGroup extends SecurityGroupRef { +class ImportedSecurityGroup extends SecurityGroupBase { public readonly securityGroupId: string; - constructor(parent: Construct, name: string, props: SecurityGroupRefProps) { + constructor(parent: Construct, name: string, private readonly props: SecurityGroupAttributes) { super(parent, name); this.securityGroupId = props.securityGroupId; } + + public export() { + return this.props; + } } /** diff --git a/packages/@aws-cdk/aws-ec2/lib/util.ts b/packages/@aws-cdk/aws-ec2/lib/util.ts index 430f383dce70a..a646aa8051470 100644 --- a/packages/@aws-cdk/aws-ec2/lib/util.ts +++ b/packages/@aws-cdk/aws-ec2/lib/util.ts @@ -1,5 +1,6 @@ import cdk = require('@aws-cdk/cdk'); -import { SubnetType, VpcSubnetRef } from "./vpc-ref"; +import { VpcSubnet } from './vpc'; +import { IVpcSubnet, SubnetType } from "./vpc-ref"; /** * Turn an arbitrary string into one that can be used as a CloudFormation identifier by stripping special characters @@ -24,7 +25,7 @@ export const DEFAULT_SUBNET_NAME = { * * All subnet names look like NAME <> "Subnet" <> INDEX */ -export function subnetName(subnet: VpcSubnetRef) { +export function subnetName(subnet: IVpcSubnet) { return subnet.id.replace(/Subnet\d+$/, ''); } @@ -47,7 +48,7 @@ export class ExportSubnetGroup { constructor( parent: cdk.Construct, exportName: string, - private readonly subnets: VpcSubnetRef[], + private readonly subnets: IVpcSubnet[], private readonly type: SubnetType, private readonly azs: number) { @@ -116,10 +117,10 @@ export class ImportSubnetGroup { this.names = this.normalizeNames(names, DEFAULT_SUBNET_NAME[type], nameField); } - public import(parent: cdk.Construct): VpcSubnetRef[] { + public import(parent: cdk.Construct): IVpcSubnet[] { return range(this.subnetIds.length).map(i => { const k = Math.floor(i / this.availabilityZones.length); - return VpcSubnetRef.import(parent, subnetId(this.names[k], i), { + return VpcSubnet.import(parent, subnetId(this.names[k], i), { availabilityZone: this.pickAZ(i), subnetId: this.subnetIds[i] }); diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts index 4312daa66bebb..e4f022ef0a4ff 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts @@ -1,6 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import cxapi = require('@aws-cdk/cx-api'); -import { VpcNetworkRefProps } from './vpc-ref'; +import { VpcNetworkAttributes } from './vpc-ref'; /** * Properties for looking up an existing VPC. @@ -66,7 +66,7 @@ export class VpcNetworkProvider { /** * Return the VPC import props matching the filter */ - public get vpcProps(): VpcNetworkRefProps { + public get vpcProps(): VpcNetworkAttributes { const ret: cxapi.VpcContextResponse = this.provider.getValue(DUMMY_VPC_PROPS); return ret; } diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts index 233754b08d879..49a4d0e88a6c0 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts @@ -1,6 +1,89 @@ -import { Construct, IDependable, Output } from "@aws-cdk/cdk"; -import { ExportSubnetGroup, ImportSubnetGroup, subnetName } from './util'; -import { VpcNetworkProvider, VpcNetworkProviderProps } from './vpc-network-provider'; +import { Construct, IDependable } from "@aws-cdk/cdk"; +import { subnetName } from './util'; + +export interface IVpcSubnet extends IDependable { + /** + * Logical ID of the subnet. + */ + readonly id: string; + + /** + * Construct path of this subnet. + */ + readonly path: string; + + /** + * The Availability Zone the subnet is located in + */ + readonly availabilityZone: string; + + /** + * The subnetId for this particular subnet + */ + readonly subnetId: string; + + /** + * Exports this subnet to another stack. + */ + export(): VpcSubnetAttributes; +} + +export interface IVpcNetwork extends IDependable { + /** + * Identifier for this VPC + */ + readonly vpcId: string; + + /** + * List of public subnets in this VPC + */ + readonly publicSubnets: IVpcSubnet[]; + + /** + * List of private subnets in this VPC + */ + readonly privateSubnets: IVpcSubnet[]; + + /** + * List of isolated subnets in this VPC + */ + readonly isolatedSubnets: IVpcSubnet[]; + + /** + * AZs for this VPC + */ + readonly availabilityZones: string[]; + + /** + * Take a dependency on internet connectivity having been added to this VPC + * + * Take a dependency on this if your constructs need an Internet Gateway + * added to the VPC before they can be constructed. + * + * This method is for construct authors; application builders should not + * need to call this. + */ + internetDependency(): IDependable; + + /** + * Return the subnets appropriate for the placement strategy + */ + subnets(placement?: VpcPlacementStrategy): IVpcSubnet[]; + + /** + * Return whether the given subnet is one of this VPC's public subnets. + * + * The subnet must literally be one of the subnet object obtained from + * this VPC. A subnet that merely represents the same subnet will + * never return true. + */ + isPublicSubnet(subnet: IVpcSubnet): boolean; + + /** + * Exports this VPC so it can be consumed by another stack. + */ + export(): VpcNetworkAttributes; +} /** * The type of Subnet @@ -74,20 +157,7 @@ export interface VpcPlacementStrategy { /** * A new or imported VPC */ -export abstract class VpcNetworkRef extends Construct implements IDependable { - /** - * Import an exported VPC - */ - public static import(parent: Construct, name: string, props: VpcNetworkRefProps): VpcNetworkRef { - return new ImportedVpcNetwork(parent, name, props); - } - - /** - * Import an existing VPC from context - */ - public static importFromContext(parent: Construct, name: string, props: VpcNetworkProviderProps): VpcNetworkRef { - return VpcNetworkRef.import(parent, name, new VpcNetworkProvider(parent, props).vpcProps); - } +export abstract class VpcNetworkBase extends Construct implements IVpcNetwork { /** * Identifier for this VPC @@ -97,17 +167,17 @@ export abstract class VpcNetworkRef extends Construct implements IDependable { /** * List of public subnets in this VPC */ - public abstract readonly publicSubnets: VpcSubnetRef[]; + public abstract readonly publicSubnets: IVpcSubnet[]; /** * List of private subnets in this VPC */ - public abstract readonly privateSubnets: VpcSubnetRef[]; + public abstract readonly privateSubnets: IVpcSubnet[]; /** * List of isolated subnets in this VPC */ - public abstract readonly isolatedSubnets: VpcSubnetRef[]; + public abstract readonly isolatedSubnets: IVpcSubnet[]; /** * AZs for this VPC @@ -122,12 +192,12 @@ export abstract class VpcNetworkRef extends Construct implements IDependable { /** * Dependencies for internet connectivity */ - protected readonly internetDependencies = new Array(); + public readonly internetDependencies = new Array(); /** * Return the subnets appropriate for the placement strategy */ - public subnets(placement: VpcPlacementStrategy = {}): VpcSubnetRef[] { + public subnets(placement: VpcPlacementStrategy = {}): IVpcSubnet[] { if (placement.subnetsToUse !== undefined && placement.subnetName !== undefined) { throw new Error('At most one of subnetsToUse and subnetName can be supplied'); } @@ -155,22 +225,7 @@ export abstract class VpcNetworkRef extends Construct implements IDependable { /** * Export this VPC from the stack */ - public export(): VpcNetworkRefProps { - const pub = new ExportSubnetGroup(this, 'PublicSubnetIDs', this.publicSubnets, SubnetType.Public, this.availabilityZones.length); - const priv = new ExportSubnetGroup(this, 'PrivateSubnetIDs', this.privateSubnets, SubnetType.Private, this.availabilityZones.length); - const iso = new ExportSubnetGroup(this, 'IsolatedSubnetIDs', this.isolatedSubnets, SubnetType.Isolated, this.availabilityZones.length); - - return { - vpcId: new Output(this, 'VpcId', { value: this.vpcId }).makeImportValue().toString(), - availabilityZones: this.availabilityZones, - publicSubnetIds: pub.ids, - publicSubnetNames: pub.names, - privateSubnetIds: priv.ids, - privateSubnetNames: priv.names, - isolatedSubnetIds: iso.ids, - isolatedSubnetNames: iso.names, - }; - } + public abstract export(): VpcNetworkAttributes; /** * Return whether the given subnet is one of this VPC's public subnets. @@ -179,7 +234,7 @@ export abstract class VpcNetworkRef extends Construct implements IDependable { * this VPC. A subnet that merely represents the same subnet will * never return true. */ - public isPublicSubnet(subnet: VpcSubnetRef) { + public isPublicSubnet(subnet: IVpcSubnet) { return this.publicSubnets.indexOf(subnet) > -1; } @@ -197,57 +252,10 @@ export abstract class VpcNetworkRef extends Construct implements IDependable { } } -/** - * An imported VpcNetwork - */ -class ImportedVpcNetwork extends VpcNetworkRef { - /** - * Identifier for this VPC - */ - public readonly vpcId: string; - - /** - * List of public subnets in this VPC - */ - public readonly publicSubnets: VpcSubnetRef[]; - - /** - * List of private subnets in this VPC - */ - public readonly privateSubnets: VpcSubnetRef[]; - - /** - * List of isolated subnets in this VPC - */ - public readonly isolatedSubnets: VpcSubnetRef[]; - - /** - * AZs for this VPC - */ - public readonly availabilityZones: string[]; - - constructor(parent: Construct, name: string, props: VpcNetworkRefProps) { - super(parent, name); - - this.vpcId = props.vpcId; - this.availabilityZones = props.availabilityZones; - - // tslint:disable:max-line-length - const pub = new ImportSubnetGroup(props.publicSubnetIds, props.publicSubnetNames, SubnetType.Public, this.availabilityZones, 'publicSubnetIds', 'publicSubnetNames'); - const priv = new ImportSubnetGroup(props.privateSubnetIds, props.privateSubnetNames, SubnetType.Private, this.availabilityZones, 'privateSubnetIds', 'privateSubnetNames'); - const iso = new ImportSubnetGroup(props.isolatedSubnetIds, props.isolatedSubnetNames, SubnetType.Isolated, this.availabilityZones, 'isolatedSubnetIds', 'isolatedSubnetNames'); - // tslint:enable:max-line-length - - this.publicSubnets = pub.import(this); - this.privateSubnets = priv.import(this); - this.isolatedSubnets = iso.import(this); - } -} - /** * Properties that reference an external VpcNetwork */ -export interface VpcNetworkRefProps { +export interface VpcNetworkAttributes { /** * VPC's identifier */ @@ -301,53 +309,7 @@ export interface VpcNetworkRefProps { isolatedSubnetNames?: string[]; } -/** - * A new or imported VPC Subnet - */ -export abstract class VpcSubnetRef extends Construct implements IDependable { - public static import(parent: Construct, name: string, props: VpcSubnetRefProps): VpcSubnetRef { - return new ImportedVpcSubnet(parent, name, props); - } - - /** - * The Availability Zone the subnet is located in - */ - public abstract readonly availabilityZone: string; - - /** - * The subnetId for this particular subnet - */ - public abstract readonly subnetId: string; - - /** - * Parts of this VPC subnet - */ - public readonly dependencyElements: IDependable[] = []; -} - -/** - * Subnet of an imported VPC - */ -class ImportedVpcSubnet extends VpcSubnetRef { - /** - * The Availability Zone the subnet is located in - */ - public readonly availabilityZone: string; - - /** - * The subnetId for this particular subnet - */ - public readonly subnetId: string; - - constructor(parent: Construct, name: string, props: VpcSubnetRefProps) { - super(parent, name); - - this.availabilityZone = props.availabilityZone; - this.subnetId = props.subnetId; - } -} - -export interface VpcSubnetRefProps { +export interface VpcSubnetAttributes { /** * The Availability Zone the subnet is located in */ diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 04a9a97882316..5a1997eeb7735 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -1,10 +1,12 @@ import cdk = require('@aws-cdk/cdk'); +import { Output } from '@aws-cdk/cdk'; import { CfnEIP, CfnInternetGateway, CfnNatGateway, CfnRoute } from './ec2.generated'; import { CfnRouteTable, CfnSubnet, CfnSubnetRouteTableAssociation, CfnVPC, CfnVPCGatewayAttachment } from './ec2.generated'; +import { ImportedVpcNetwork, ImportedVpcSubnet } from './imported-vpc'; import { NetworkBuilder } from './network-util'; -import { DEFAULT_SUBNET_NAME, subnetId } from './util'; -import { SubnetType, VpcNetworkRef, VpcPlacementStrategy, VpcSubnetRef } from './vpc-ref'; - +import { DEFAULT_SUBNET_NAME, ExportSubnetGroup, subnetId } from './util'; +import { VpcNetworkProvider, VpcNetworkProviderProps } from './vpc-network-provider'; +import { IVpcNetwork, IVpcSubnet, SubnetType, VpcNetworkAttributes, VpcNetworkBase, VpcPlacementStrategy, VpcSubnetAttributes } from './vpc-ref'; /** * Name tag constant */ @@ -184,7 +186,13 @@ export interface SubnetConfiguration { * * } */ -export class VpcNetwork extends VpcNetworkRef implements cdk.ITaggable { +export class VpcNetwork extends VpcNetworkBase implements cdk.ITaggable { + /** + * @returns The IPv4 CidrBlock as returned by the VPC + */ + public get cidr(): string { + return this.resource.getAtt("CidrBlock").toString(); + } /** * The default CIDR range used when creating VPCs. @@ -209,6 +217,20 @@ export class VpcNetwork extends VpcNetworkRef implements cdk.ITaggable { } ]; + /** + * Import an exported VPC + */ + public static import(parent: cdk.Construct, name: string, props: VpcNetworkAttributes): IVpcNetwork { + return new ImportedVpcNetwork(parent, name, props); + } + + /** + * Import an existing VPC from context + */ + public static importFromContext(parent: cdk.Construct, name: string, props: VpcNetworkProviderProps): IVpcNetwork { + return VpcNetwork.import(parent, name, new VpcNetworkProvider(parent, props).vpcProps); + } + /** * Identifier for this VPC */ @@ -217,17 +239,17 @@ export class VpcNetwork extends VpcNetworkRef implements cdk.ITaggable { /** * List of public subnets in this VPC */ - public readonly publicSubnets: VpcSubnetRef[] = []; + public readonly publicSubnets: IVpcSubnet[] = []; /** * List of private subnets in this VPC */ - public readonly privateSubnets: VpcSubnetRef[] = []; + public readonly privateSubnets: IVpcSubnet[] = []; /** * List of isolated subnets in this VPC */ - public readonly isolatedSubnets: VpcSubnetRef[] = []; + public readonly isolatedSubnets: IVpcSubnet[] = []; /** * AZs for this VPC @@ -340,10 +362,23 @@ export class VpcNetwork extends VpcNetworkRef implements cdk.ITaggable { } /** - * @returns The IPv4 CidrBlock as returned by the VPC + * Export this VPC from the stack */ - public get cidr(): string { - return this.resource.getAtt("CidrBlock").toString(); + public export(): VpcNetworkAttributes { + const pub = new ExportSubnetGroup(this, 'PublicSubnetIDs', this.publicSubnets, SubnetType.Public, this.availabilityZones.length); + const priv = new ExportSubnetGroup(this, 'PrivateSubnetIDs', this.privateSubnets, SubnetType.Private, this.availabilityZones.length); + const iso = new ExportSubnetGroup(this, 'IsolatedSubnetIDs', this.isolatedSubnets, SubnetType.Isolated, this.availabilityZones.length); + + return { + vpcId: new Output(this, 'VpcId', { value: this.vpcId }).makeImportValue().toString(), + availabilityZones: this.availabilityZones, + publicSubnetIds: pub.ids, + publicSubnetNames: pub.names, + privateSubnetIds: priv.ids, + privateSubnetNames: priv.names, + isolatedSubnetIds: iso.ids, + isolatedSubnetNames: iso.names, + }; } private createNatGateways(gateways?: number, placement?: VpcPlacementStrategy): void { @@ -485,7 +520,10 @@ export interface VpcSubnetProps { /** * Represents a new VPC subnet resource */ -export class VpcSubnet extends VpcSubnetRef implements cdk.ITaggable { +export class VpcSubnet extends cdk.Construct implements IVpcSubnet, cdk.ITaggable, cdk.IDependable { + public static import(parent: cdk.Construct, name: string, props: VpcSubnetAttributes): IVpcSubnet { + return new ImportedVpcSubnet(parent, name, props); + } /** * The Availability Zone the subnet is located in @@ -502,6 +540,11 @@ export class VpcSubnet extends VpcSubnetRef implements cdk.ITaggable { */ public readonly tags: cdk.TagManager; + /** + * Parts of this VPC subnet + */ + public readonly dependencyElements: cdk.IDependable[] = []; + /** * The routeTableId attached to this subnet. */ @@ -536,6 +579,13 @@ export class VpcSubnet extends VpcSubnetRef implements cdk.ITaggable { this.dependencyElements.push(subnet, table, routeAssoc); } + public export(): VpcSubnetAttributes { + return { + availabilityZone: new cdk.Output(this, 'AvailabilityZone', { value: this.availabilityZone }).makeImportValue().toString(), + subnetId: new cdk.Output(this, 'VpcSubnetId', { value: this.subnetId }).makeImportValue().toString(), + }; + } + protected addDefaultRouteToNAT(natGatewayId: string) { new CfnRoute(this, `DefaultRoute`, { routeTableId: this.routeTableId, diff --git a/packages/@aws-cdk/aws-ec2/test/example.share-vpcs.lit.ts b/packages/@aws-cdk/aws-ec2/test/example.share-vpcs.lit.ts index 6a6f4e997193c..b96d34371c5c4 100644 --- a/packages/@aws-cdk/aws-ec2/test/example.share-vpcs.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/example.share-vpcs.lit.ts @@ -4,7 +4,7 @@ import ec2 = require("../lib"); const app = new cdk.App(); interface ConstructThatTakesAVpcProps { - vpc: ec2.VpcNetworkRef; + vpc: ec2.IVpcNetwork; } class ConstructThatTakesAVpc extends cdk.Construct { @@ -15,7 +15,7 @@ class ConstructThatTakesAVpc extends cdk.Construct { /// !show class Stack1 extends cdk.Stack { - public readonly vpcProps: ec2.VpcNetworkRefProps; + public readonly vpcProps: ec2.VpcNetworkAttributes; constructor(parent: cdk.App, id: string, props?: cdk.StackProps) { super(parent, id, props); @@ -28,7 +28,7 @@ class Stack1 extends cdk.Stack { } interface Stack2Props extends cdk.StackProps { - vpcProps: ec2.VpcNetworkRefProps; + vpcProps: ec2.VpcNetworkAttributes; } class Stack2 extends cdk.Stack { @@ -36,7 +36,7 @@ class Stack2 extends cdk.Stack { super(parent, id, props); // Import the VPC from a set of properties - const vpc = ec2.VpcNetworkRef.import(this, 'VPC', props.vpcProps); + const vpc = ec2.VpcNetwork.import(this, 'VPC', props.vpcProps); new ConstructThatTakesAVpc(this, 'Construct', { vpc diff --git a/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts b/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts index 2a9fb8921c65f..19fcff0cb4d04 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts @@ -5,7 +5,7 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-ec2-import'); /// !show -const vpc = ec2.VpcNetworkRef.importFromContext(stack, 'VPC', { +const vpc = ec2.VpcNetwork.importFromContext(stack, 'VPC', { // This imports the default VPC but you can also // specify a 'vpcName' or 'tags'. isDefault: true diff --git a/packages/@aws-cdk/aws-ec2/test/test.connections.ts b/packages/@aws-cdk/aws-ec2/test/test.connections.ts index bcdaf8c1627bf..9cc0482c1f9f2 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.connections.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.connections.ts @@ -6,7 +6,6 @@ import { Connections, IConnectable, SecurityGroup, - SecurityGroupRef, TcpAllPorts, TcpPort, VpcNetwork @@ -38,7 +37,7 @@ export = { const sg1 = new SecurityGroup(stack, 'SomeSecurityGroup', { vpc, allowAllOutbound: false }); const somethingConnectable = new SomethingConnectable(new Connections({ securityGroups: [sg1] })); - const securityGroup = SecurityGroupRef.import(stack, 'ImportedSG', { securityGroupId: 'sg-12345' }); + const securityGroup = SecurityGroup.import(stack, 'ImportedSG', { securityGroupId: 'sg-12345' }); // WHEN somethingConnectable.connections.allowTo(securityGroup, new TcpAllPorts(), 'Connect there'); diff --git a/packages/@aws-cdk/aws-ec2/test/test.vpc.ts b/packages/@aws-cdk/aws-ec2/test/test.vpc.ts index 4c730a03ccb02..f4cab6224ea79 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpc.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.vpc.ts @@ -1,7 +1,7 @@ import { countResources, expect, haveResource, haveResourceLike, isSuperObject } from '@aws-cdk/assert'; import { AvailabilityZoneProvider, Construct, resolve, Stack, Tags } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { DefaultInstanceTenancy, SubnetType, VpcNetwork, VpcNetworkRef } from '../lib'; +import { DefaultInstanceTenancy, IVpcNetwork, SubnetType, VpcNetwork } from '../lib'; export = { "When creating a VPC": { @@ -531,7 +531,7 @@ function getTestStack(): Stack { /** * Do a complete import/export test, return the imported VPC */ -function doImportExportTest(constructFn: (parent: Construct) => VpcNetwork): VpcNetworkRef { +function doImportExportTest(constructFn: (parent: Construct) => VpcNetwork): IVpcNetwork { // GIVEN const stack1 = getTestStack(); const stack2 = getTestStack(); diff --git a/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts b/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts index 4b758330cc6b8..a8d2286c530a9 100644 --- a/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts +++ b/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts @@ -75,9 +75,14 @@ export interface IRepository { * @param imageTag Only trigger on the specific image tag */ onImagePushed(name: string, target?: events.IEventRuleTarget, imageTag?: string): events.EventRule; + + /** + * Export this repository from the stack + */ + export(): RepositoryAttributes; } -export interface ImportRepositoryProps { +export interface RepositoryAttributes { /** * The ARN of the repository to import. * @@ -109,7 +114,7 @@ export abstract class RepositoryBase extends cdk.Construct implements IRepositor /** * Import a repository */ - public static import(parent: cdk.Construct, id: string, props: ImportRepositoryProps): IRepository { + public static import(parent: cdk.Construct, id: string, props: RepositoryAttributes): IRepository { return new ImportedRepository(parent, id, props); } @@ -166,12 +171,7 @@ export abstract class RepositoryBase extends cdk.Construct implements IRepositor /** * Export this repository from the stack */ - public export(): ImportRepositoryProps { - return { - repositoryArn: new cdk.Output(this, 'RepositoryArn', { value: this.repositoryArn }).makeImportValue().toString(), - repositoryName: new cdk.Output(this, 'RepositoryName', { value: this.repositoryName }).makeImportValue().toString() - }; - } + public abstract export(): RepositoryAttributes; public addToPipeline(stage: codepipeline.IStage, name: string, props: CommonPipelineSourceActionProps = {}): PipelineSourceAction { @@ -254,7 +254,7 @@ class ImportedRepository extends RepositoryBase { public readonly repositoryName: string; public readonly repositoryArn: string; - constructor(parent: cdk.Construct, id: string, props: ImportRepositoryProps) { + constructor(parent: cdk.Construct, id: string, props: RepositoryAttributes) { super(parent, id); if (props.repositoryArn) { @@ -282,6 +282,13 @@ class ImportedRepository extends RepositoryBase { } } + public export(): RepositoryAttributes { + return { + repositoryArn: this.repositoryArn, + repositoryName: this.repositoryName + }; + } + public addToResourcePolicy(_statement: iam.PolicyStatement) { // FIXME: Add annotation about policy we dropped on the floor } diff --git a/packages/@aws-cdk/aws-ecr/lib/repository.ts b/packages/@aws-cdk/aws-ecr/lib/repository.ts index ee624946368d5..bb905fe6229d5 100644 --- a/packages/@aws-cdk/aws-ecr/lib/repository.ts +++ b/packages/@aws-cdk/aws-ecr/lib/repository.ts @@ -2,7 +2,7 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { CfnRepository } from './ecr.generated'; import { CountType, LifecycleRule, TagStatus } from './lifecycle'; -import { RepositoryBase } from "./repository-ref"; +import { RepositoryAttributes, RepositoryBase } from "./repository-ref"; export interface RepositoryProps { /** @@ -71,6 +71,16 @@ export class Repository extends RepositoryBase { this.repositoryArn = resource.repositoryArn; } + /** + * Export this repository from the stack + */ + public export(): RepositoryAttributes { + return { + repositoryArn: new cdk.Output(this, 'RepositoryArn', { value: this.repositoryArn }).makeImportValue().toString(), + repositoryName: new cdk.Output(this, 'RepositoryName', { value: this.repositoryName }).makeImportValue().toString() + }; + } + public addToResourcePolicy(statement: iam.PolicyStatement) { if (this.policyDocument === undefined) { this.policyDocument = new iam.PolicyDocument(); diff --git a/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts b/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts index abd1ae07fcbdb..de987d2f1decf 100644 --- a/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts @@ -183,7 +183,7 @@ export abstract class BaseService extends cdk.Construct * Set up AWSVPC networking for this construct */ // tslint:disable-next-line:max-line-length - protected configureAwsVpcNetworking(vpc: ec2.VpcNetworkRef, assignPublicIp?: boolean, vpcPlacement?: ec2.VpcPlacementStrategy, securityGroup?: ec2.SecurityGroupRef) { + protected configureAwsVpcNetworking(vpc: ec2.IVpcNetwork, assignPublicIp?: boolean, vpcPlacement?: ec2.VpcPlacementStrategy, securityGroup?: ec2.ISecurityGroup) { if (vpcPlacement === undefined) { vpcPlacement = { subnetsToUse: assignPublicIp ? ec2.SubnetType.Public : ec2.SubnetType.Private }; } diff --git a/packages/@aws-cdk/aws-ecs/lib/cluster.ts b/packages/@aws-cdk/aws-ecs/lib/cluster.ts index faa7288f26c05..e739aa73e05a0 100644 --- a/packages/@aws-cdk/aws-ecs/lib/cluster.ts +++ b/packages/@aws-cdk/aws-ecs/lib/cluster.ts @@ -20,7 +20,7 @@ export interface ClusterProps { /** * The VPC where your ECS instances will be running or your ENIs will be deployed */ - vpc: ec2.VpcNetworkRef; + vpc: ec2.IVpcNetwork; } /** @@ -30,7 +30,7 @@ export class Cluster extends cdk.Construct implements ICluster { /** * Import an existing cluster */ - public static import(parent: cdk.Construct, name: string, props: ImportedClusterProps): ICluster { + public static import(parent: cdk.Construct, name: string, props: ClusterAttributes): ICluster { return new ImportedCluster(parent, name, props); } @@ -42,7 +42,7 @@ export class Cluster extends cdk.Construct implements ICluster { /** * The VPC this cluster was created in. */ - public readonly vpc: ec2.VpcNetworkRef; + public readonly vpc: ec2.IVpcNetwork; /** * The ARN of this cluster @@ -144,7 +144,7 @@ export class Cluster extends cdk.Construct implements ICluster { /** * Export the Cluster */ - public export(): ImportedClusterProps { + public export(): ClusterAttributes { return { clusterName: new cdk.Output(this, 'ClusterName', { value: this.clusterName }).makeImportValue().toString(), vpc: this.vpc.export(), @@ -217,7 +217,7 @@ export interface ICluster { /** * VPC that the cluster instances are running in */ - readonly vpc: ec2.VpcNetworkRef; + readonly vpc: ec2.IVpcNetwork; /** * Connections manager of the cluster instances @@ -228,12 +228,17 @@ export interface ICluster { * Whether the cluster has EC2 capacity associated with it */ readonly hasEc2Capacity: boolean; + + /** + * Export the Cluster + */ + export(): ClusterAttributes; } /** * Properties to import an ECS cluster */ -export interface ImportedClusterProps { +export interface ClusterAttributes { /** * Name of the cluster */ @@ -242,12 +247,12 @@ export interface ImportedClusterProps { /** * VPC that the cluster instances are running in */ - vpc: ec2.VpcNetworkRefProps; + vpc: ec2.VpcNetworkAttributes; /** * Security group of the cluster instances */ - securityGroups: ec2.SecurityGroupRefProps[]; + securityGroups: ec2.SecurityGroupAttributes[]; /** * Whether the given cluster has EC2 capacity @@ -269,7 +274,7 @@ class ImportedCluster extends cdk.Construct implements ICluster { /** * VPC that the cluster instances are running in */ - public readonly vpc: ec2.VpcNetworkRef; + public readonly vpc: ec2.IVpcNetwork; /** * Security group of the cluster instances @@ -281,18 +286,22 @@ class ImportedCluster extends cdk.Construct implements ICluster { */ public readonly hasEc2Capacity: boolean; - constructor(parent: cdk.Construct, name: string, props: ImportedClusterProps) { + constructor(parent: cdk.Construct, name: string, private readonly props: ClusterAttributes) { super(parent, name); this.clusterName = props.clusterName; - this.vpc = ec2.VpcNetworkRef.import(this, "vpc", props.vpc); + this.vpc = ec2.VpcNetwork.import(this, "vpc", props.vpc); this.hasEc2Capacity = props.hasEc2Capacity !== false; let i = 1; for (const sgProps of props.securityGroups) { - this.connections.addSecurityGroup(ec2.SecurityGroupRef.import(this, `SecurityGroup${i}`, sgProps)); + this.connections.addSecurityGroup(ec2.SecurityGroup.import(this, `SecurityGroup${i}`, sgProps)); i++; } } + + public export() { + return this.props; + } } /** diff --git a/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts b/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts index d28def8fcaf5f..de8bbac1be357 100644 --- a/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts @@ -38,7 +38,7 @@ export interface Ec2ServiceProps extends BaseServiceProps { * * @default A new security group is created */ - securityGroup?: ec2.SecurityGroupRef; + securityGroup?: ec2.ISecurityGroup; /** * Whether to start services on distinct instances diff --git a/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts b/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts index c3caf6ef09971..409c360d0a49d 100644 --- a/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts @@ -38,7 +38,7 @@ export interface FargateServiceProps extends BaseServiceProps { * * @default A new security group is created */ - securityGroup?: ec2.SecurityGroupRef; + securityGroup?: ec2.ISecurityGroup; /** * Fargate platform version to run this service on diff --git a/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service-applet.ts b/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service-applet.ts index 4fe86ab5e1d45..af5937804d9d4 100644 --- a/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service-applet.ts +++ b/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service-applet.ts @@ -1,4 +1,4 @@ -import { CertificateRef } from '@aws-cdk/aws-certificatemanager'; +import { Certificate } from '@aws-cdk/aws-certificatemanager'; import { VpcNetwork } from '@aws-cdk/aws-ec2'; import { HostedZoneProvider } from '@aws-cdk/aws-route53'; import cdk = require('@aws-cdk/cdk'); @@ -114,7 +114,7 @@ export class LoadBalancedFargateServiceApplet extends cdk.Stack { } let certificate; if (props.certificate) { - certificate = CertificateRef.import(this, 'Cert', { certificateArn: props.certificate }); + certificate = Certificate.import(this, 'Cert', { certificateArn: props.certificate }); } // Instantiate Fargate Service with just cluster and image diff --git a/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service.ts b/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service.ts index 1336d79b1b3e0..722829eac58f7 100644 --- a/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service.ts @@ -1,6 +1,6 @@ -import { CertificateRef } from '@aws-cdk/aws-certificatemanager'; +import { ICertificate } from '@aws-cdk/aws-certificatemanager'; import elbv2 = require('@aws-cdk/aws-elasticloadbalancingv2'); -import { AliasRecord, HostedZoneRef } from '@aws-cdk/aws-route53'; +import { AliasRecord, IHostedZone } from '@aws-cdk/aws-route53'; import cdk = require('@aws-cdk/cdk'); import { ICluster } from './cluster'; import { IContainerImage } from './container-image'; @@ -95,13 +95,13 @@ export interface LoadBalancedFargateServiceProps { /** * Route53 hosted zone for the domain, e.g. "example.com." */ - domainZone?: HostedZoneRef; + domainZone?: IHostedZone; /** * Certificate Manager certificate to associate with the load balancer. * Setting this option will set the load balancer port to 443. */ - certificate?: CertificateRef; + certificate?: ICertificate; /** * Whether to create an AWS log driver * @@ -179,7 +179,8 @@ export class LoadBalancedFargateService extends cdk.Construct { throw new Error('A Route53 hosted domain zone name is required to configure the specified domain name'); } - new AliasRecord(props.domainZone, "DNS", { + new AliasRecord(this, "DNS", { + zone: props.domainZone, recordName: props.domainName, target: lb }); diff --git a/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts b/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts index 5e43f5549fa50..434748d6755bb 100644 --- a/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts +++ b/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts @@ -25,7 +25,7 @@ export interface AwsLogDriverProps { * * @default A log group is automatically created */ - logGroup?: logs.LogGroupRef; + logGroup?: logs.ILogGroup; /** * This option defines a multiline start pattern in Python strftime format. @@ -53,7 +53,7 @@ export class AwsLogDriver extends LogDriver { /** * The log group that the logs will be sent to */ - public readonly logGroup: logs.LogGroupRef; + public readonly logGroup: logs.ILogGroup; constructor(parent: cdk.Construct, id: string, private readonly props: AwsLogDriverProps) { super(parent, id); diff --git a/packages/@aws-cdk/aws-ecs/test/test.l3s.ts b/packages/@aws-cdk/aws-ecs/test/test.l3s.ts index a8386d462b652..df6d3957837a8 100644 --- a/packages/@aws-cdk/aws-ecs/test/test.l3s.ts +++ b/packages/@aws-cdk/aws-ecs/test/test.l3s.ts @@ -1,5 +1,5 @@ import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert'; -import { CertificateRef } from '@aws-cdk/aws-certificatemanager'; +import { Certificate } from '@aws-cdk/aws-certificatemanager'; import ec2 = require('@aws-cdk/aws-ec2'); import { PublicHostedZone } from '@aws-cdk/aws-route53'; import cdk = require('@aws-cdk/cdk'); @@ -120,7 +120,7 @@ export = { image: ecs.ContainerImage.fromDockerHub('test'), domainName: 'api.example.com', domainZone: zone, - certificate: CertificateRef.import(stack, 'Cert', { certificateArn: 'helloworld' }) + certificate: Certificate.import(stack, 'Cert', { certificateArn: 'helloworld' }) }); // THEN - stack contains a load balancer and a service diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts index 72573fc92697c..186d524ac6c99 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts @@ -1,6 +1,7 @@ import codedeploy = require('@aws-cdk/aws-codedeploy-api'); -import { AnyIPv4, Connections, IConnectable, IPortRange, SecurityGroup, SecurityGroupRef, - TcpPort, VpcNetworkRef, VpcSubnetRef } from '@aws-cdk/aws-ec2'; +import { + AnyIPv4, Connections, IConnectable, IPortRange, ISecurityGroup, + IVpcNetwork, IVpcSubnet, SecurityGroup, TcpPort } from '@aws-cdk/aws-ec2'; import cdk = require('@aws-cdk/cdk'); import { CfnLoadBalancer } from './elasticloadbalancing.generated'; @@ -11,7 +12,7 @@ export interface LoadBalancerProps { /** * VPC network of the fleet instances */ - vpc: VpcNetworkRef; + vpc: IVpcNetwork; /** * Whether this is an internet-facing Load Balancer @@ -211,7 +212,7 @@ export class LoadBalancer extends cdk.Construct implements IConnectable, codedep this.connections = new Connections({ securityGroups: [this.securityGroup] }); // Depending on whether the ELB has public or internal IPs, pick the right backend subnets - const subnets: VpcSubnetRef[] = props.internetFacing ? props.vpc.publicSubnets : props.vpc.privateSubnets; + const subnets: IVpcSubnet[] = props.internetFacing ? props.vpc.publicSubnets : props.vpc.privateSubnets; this.elb = new CfnLoadBalancer(this, 'Resource', { securityGroups: [ this.securityGroup.securityGroupId ], @@ -344,7 +345,7 @@ export class LoadBalancer extends cdk.Construct implements IConnectable, codedep export class ListenerPort implements IConnectable { public readonly connections: Connections; - constructor(securityGroup: SecurityGroupRef, defaultPortRange: IPortRange) { + constructor(securityGroup: ISecurityGroup, defaultPortRange: IPortRange) { this.connections = new Connections({ securityGroups: [securityGroup] , defaultPortRange }); } } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts index 4d080c9277ac4..a096cb4d71747 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts @@ -79,7 +79,7 @@ export class ApplicationListener extends BaseListener implements IApplicationLis /** * Import an existing listener */ - public static import(parent: cdk.Construct, id: string, props: ApplicationListenerRefProps): IApplicationListener { + public static import(parent: cdk.Construct, id: string, props: ApplicationListenerAttributes): IApplicationListener { return new ImportedApplicationListener(parent, id, props); } @@ -238,7 +238,7 @@ export class ApplicationListener extends BaseListener implements IApplicationLis /** * Export this listener */ - public export(): ApplicationListenerRefProps { + public export(): ApplicationListenerAttributes { return { listenerArn: new cdk.Output(this, 'ListenerArn', { value: this.listenerArn }).makeImportValue().toString(), securityGroupId: this.connections.securityGroups[0]!.export().securityGroupId, @@ -296,12 +296,17 @@ export interface IApplicationListener extends ec2.IConnectable, cdk.IDependable * Don't call this directly. It is called by ApplicationTargetGroup. */ registerConnectable(connectable: ec2.IConnectable, portRange: ec2.IPortRange): void; + + /** + * Export this listener + */ + export(): ApplicationListenerAttributes; } /** * Properties to reference an existing listener */ -export interface ApplicationListenerRefProps { +export interface ApplicationListenerAttributes { /** * ARN of the listener */ @@ -327,7 +332,7 @@ class ImportedApplicationListener extends cdk.Construct implements IApplicationL */ public readonly listenerArn: string; - constructor(parent: cdk.Construct, id: string, props: ApplicationListenerRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: ApplicationListenerAttributes) { super(parent, id); this.listenerArn = props.listenerArn; @@ -335,11 +340,15 @@ class ImportedApplicationListener extends cdk.Construct implements IApplicationL const defaultPortRange = props.defaultPort !== undefined ? new ec2.TcpPortFromAttribute(props.defaultPort) : undefined; this.connections = new ec2.Connections({ - securityGroups: [ec2.SecurityGroupRef.import(this, 'SecurityGroup', { securityGroupId: props.securityGroupId })], + securityGroups: [ec2.SecurityGroup.import(this, 'SecurityGroup', { securityGroupId: props.securityGroupId })], defaultPortRange, }); } + public export() { + return this.props; + } + /** * Add one or more certificates to this listener. */ diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts index 8fe575d0bcc9e..14f460a57b184 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts @@ -16,7 +16,7 @@ export interface ApplicationLoadBalancerProps extends BaseLoadBalancerProps { * * @default A security group is created */ - securityGroup?: ec2.SecurityGroupRef; + securityGroup?: ec2.ISecurityGroup; /** * The type of IP addresses to use @@ -49,12 +49,12 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic /** * Import an existing Application Load Balancer */ - public static import(parent: cdk.Construct, id: string, props: ApplicationLoadBalancerRefProps): IApplicationLoadBalancer { + public static import(parent: cdk.Construct, id: string, props: ApplicationLoadBalancerAttributes): IApplicationLoadBalancer { return new ImportedApplicationLoadBalancer(parent, id, props); } public readonly connections: ec2.Connections; - private readonly securityGroup: ec2.SecurityGroupRef; + private readonly securityGroup: ec2.ISecurityGroup; constructor(parent: cdk.Construct, id: string, props: ApplicationLoadBalancerProps) { super(parent, id, props, { @@ -77,7 +77,7 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic /** * Enable access logging for this load balancer */ - public logAccessLogs(bucket: s3.BucketRef, prefix?: string) { + public logAccessLogs(bucket: s3.IBucket, prefix?: string) { this.setAttribute('access_logs.s3.enabled', 'true'); this.setAttribute('access_logs.s3.bucket', bucket.bucketName.toString()); this.setAttribute('access_logs.s3.prefix', prefix); @@ -110,7 +110,7 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic /** * Export this load balancer */ - public export(): ApplicationLoadBalancerRefProps { + public export(): ApplicationLoadBalancerAttributes { return { loadBalancerArn: new cdk.Output(this, 'LoadBalancerArn', { value: this.loadBalancerArn }).makeImportValue().toString(), securityGroupId: this.securityGroup.export().securityGroupId, @@ -485,18 +485,23 @@ export interface IApplicationLoadBalancer extends ec2.IConnectable { /** * The VPC this load balancer has been created in (if available) */ - readonly vpc?: ec2.VpcNetworkRef; + readonly vpc?: ec2.IVpcNetwork; /** * Add a new listener to this load balancer */ addListener(id: string, props: BaseApplicationListenerProps): ApplicationListener; + + /** + * Export this load balancer + */ + export(): ApplicationLoadBalancerAttributes; } /** * Properties to reference an existing load balancer */ -export interface ApplicationLoadBalancerRefProps { +export interface ApplicationLoadBalancerAttributes { /** * ARN of the load balancer */ @@ -534,7 +539,7 @@ const ELBV2_ACCOUNTS: {[region: string]: string } = { /** * An ApplicationLoadBalancer that has been defined elsewhere */ -class ImportedApplicationLoadBalancer extends cdk.Construct implements IApplicationLoadBalancer, ec2.IConnectable { +class ImportedApplicationLoadBalancer extends cdk.Construct implements IApplicationLoadBalancer { /** * Manage connections for this load balancer */ @@ -550,17 +555,21 @@ class ImportedApplicationLoadBalancer extends cdk.Construct implements IApplicat * * Always undefined. */ - public readonly vpc?: ec2.VpcNetworkRef; + public readonly vpc?: ec2.IVpcNetwork; - constructor(parent: cdk.Construct, id: string, props: ApplicationLoadBalancerRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: ApplicationLoadBalancerAttributes) { super(parent, id); this.loadBalancerArn = props.loadBalancerArn; this.connections = new ec2.Connections({ - securityGroups: [ec2.SecurityGroupRef.import(this, 'SecurityGroup', { securityGroupId: props.securityGroupId })] + securityGroups: [ec2.SecurityGroup.import(this, 'SecurityGroup', { securityGroupId: props.securityGroupId })] }); } + public export() { + return this.props; + } + public addListener(id: string, props: BaseApplicationListenerProps): ApplicationListener { return new ApplicationListener(this, id, { loadBalancer: this, diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts index d579fab83d5a6..885fe252cc5b1 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts @@ -1,10 +1,10 @@ import cloudwatch = require('@aws-cdk/aws-cloudwatch'); import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); -import { BaseTargetGroup, BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, - LoadBalancerTargetProps, TargetGroupRefProps } from '../shared/base-target-group'; +import { BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, LoadBalancerTargetProps, + TargetGroupAttributes, TargetGroupBase } from '../shared/base-target-group'; import { ApplicationProtocol } from '../shared/enums'; -import { BaseImportedTargetGroup } from '../shared/imported'; +import { ImportedTargetGroupBase } from '../shared/imported'; import { determineProtocolAndPort, LazyDependable } from '../shared/util'; import { IApplicationListener } from './application-listener'; import { HttpCodeTarget } from './application-load-balancer'; @@ -62,11 +62,11 @@ export interface ApplicationTargetGroupProps extends BaseTargetGroupProps { /** * Define an Application Target Group */ -export class ApplicationTargetGroup extends BaseTargetGroup { +export class ApplicationTargetGroup extends TargetGroupBase { /** * Import an existing target group */ - public static import(parent: cdk.Construct, id: string, props: TargetGroupRefProps): IApplicationTargetGroup { + public static import(parent: cdk.Construct, id: string, props: TargetGroupAttributes): IApplicationTargetGroup { return new ImportedApplicationTargetGroup(parent, id, props); } @@ -330,7 +330,7 @@ export interface IApplicationTargetGroup extends ITargetGroup { /** * An imported application target group */ -class ImportedApplicationTargetGroup extends BaseImportedTargetGroup implements IApplicationTargetGroup { +class ImportedApplicationTargetGroup extends ImportedTargetGroupBase implements IApplicationTargetGroup { public registerListener(_listener: IApplicationListener, _dependable?: cdk.IDependable) { // Nothing to do, we know nothing of our members } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts index cb3ef4787cf99..83d078d1ddbfe 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts @@ -39,7 +39,7 @@ export class NetworkListener extends BaseListener implements INetworkListener { /** * Import an existing listener */ - public static import(parent: cdk.Construct, id: string, props: NetworkListenerRefProps): INetworkListener { + public static import(parent: cdk.Construct, id: string, props: NetworkListenerAttributes): INetworkListener { return new ImportedNetworkListener(parent, id, props); } @@ -103,7 +103,7 @@ export class NetworkListener extends BaseListener implements INetworkListener { /** * Export this listener */ - public export(): NetworkListenerRefProps { + public export(): NetworkListenerAttributes { return { listenerArn: new cdk.Output(this, 'ListenerArn', { value: this.listenerArn }).makeImportValue().toString() }; @@ -119,12 +119,17 @@ export interface INetworkListener extends cdk.IDependable { * ARN of the listener */ readonly listenerArn: string; + + /** + * Export this listener + */ + export(): NetworkListenerAttributes; } /** * Properties to reference an existing listener */ -export interface NetworkListenerRefProps { +export interface NetworkListenerAttributes { /** * ARN of the listener */ @@ -142,11 +147,15 @@ class ImportedNetworkListener extends cdk.Construct implements INetworkListener */ public readonly listenerArn: string; - constructor(parent: cdk.Construct, id: string, props: NetworkListenerRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: NetworkListenerAttributes) { super(parent, id); this.listenerArn = props.listenerArn; } + + public export() { + return this.props; + } } /** diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts index 17ff56bd4af91..b842a4562e777 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts @@ -20,7 +20,7 @@ export interface NetworkLoadBalancerProps extends BaseLoadBalancerProps { * Define a new network load balancer */ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoadBalancer { - public static import(parent: cdk.Construct, id: string, props: NetworkLoadBalancerRefProps): INetworkLoadBalancer { + public static import(parent: cdk.Construct, id: string, props: NetworkLoadBalancerAttributes): INetworkLoadBalancer { return new ImportedNetworkLoadBalancer(parent, id, props); } @@ -47,7 +47,7 @@ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoa /** * Export this load balancer */ - public export(): NetworkLoadBalancerRefProps { + public export(): NetworkLoadBalancerAttributes { return { loadBalancerArn: new cdk.Output(this, 'LoadBalancerArn', { value: this.loadBalancerArn }).makeImportValue().toString() }; @@ -196,7 +196,7 @@ export interface INetworkLoadBalancer { /** * The VPC this load balancer has been created in (if available) */ - readonly vpc?: ec2.VpcNetworkRef; + readonly vpc?: ec2.IVpcNetwork; /** * Add a listener to this load balancer @@ -204,12 +204,17 @@ export interface INetworkLoadBalancer { * @returns The newly created listener */ addListener(id: string, props: BaseNetworkListenerProps): NetworkListener; + + /** + * Export this load balancer + */ + export(): NetworkLoadBalancerAttributes; } /** * Properties to reference an existing load balancer */ -export interface NetworkLoadBalancerRefProps { +export interface NetworkLoadBalancerAttributes { /** * ARN of the load balancer */ @@ -230,14 +235,18 @@ class ImportedNetworkLoadBalancer extends cdk.Construct implements INetworkLoadB * * Always undefined. */ - public readonly vpc?: ec2.VpcNetworkRef; + public readonly vpc?: ec2.IVpcNetwork; - constructor(parent: cdk.Construct, id: string, props: NetworkLoadBalancerRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: NetworkLoadBalancerAttributes) { super(parent, id); this.loadBalancerArn = props.loadBalancerArn; } + public export() { + return this.props; + } + /** * Add a listener to this load balancer * diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts index 4f9dfd2251591..d8ea34606ea40 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts @@ -1,8 +1,8 @@ import cdk = require('@aws-cdk/cdk'); -import { BaseTargetGroup, BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, - LoadBalancerTargetProps, TargetGroupRefProps } from '../shared/base-target-group'; +import { BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, LoadBalancerTargetProps, + TargetGroupAttributes, TargetGroupBase } from '../shared/base-target-group'; import { Protocol } from '../shared/enums'; -import { BaseImportedTargetGroup } from '../shared/imported'; +import { ImportedTargetGroupBase } from '../shared/imported'; import { LazyDependable } from '../shared/util'; import { INetworkListener } from './network-listener'; @@ -35,11 +35,11 @@ export interface NetworkTargetGroupProps extends BaseTargetGroupProps { /** * Define a Network Target Group */ -export class NetworkTargetGroup extends BaseTargetGroup { +export class NetworkTargetGroup extends TargetGroupBase { /** * Import an existing listener */ - public static import(parent: cdk.Construct, id: string, props: TargetGroupRefProps): INetworkTargetGroup { + public static import(parent: cdk.Construct, id: string, props: TargetGroupAttributes): INetworkTargetGroup { return new ImportedNetworkTargetGroup(parent, id, props); } @@ -107,7 +107,7 @@ export interface INetworkTargetGroup extends ITargetGroup { /** * An imported network target group */ -class ImportedNetworkTargetGroup extends BaseImportedTargetGroup implements INetworkTargetGroup { +class ImportedNetworkTargetGroup extends ImportedTargetGroupBase implements INetworkTargetGroup { public registerListener(_listener: INetworkListener) { // Nothing to do, we know nothing of our members } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts index e36b003896456..6d2fdc138bd85 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts @@ -18,7 +18,7 @@ export interface BaseLoadBalancerProps { /** * The VPC network to place the load balancer in */ - vpc: ec2.VpcNetworkRef; + vpc: ec2.IVpcNetwork; /** * Whether the load balancer has an internet-routable address @@ -86,7 +86,7 @@ export abstract class BaseLoadBalancer extends cdk.Construct implements route53. * * If the Load Balancer was imported, the VPC is not available. */ - public readonly vpc?: ec2.VpcNetworkRef; + public readonly vpc?: ec2.IVpcNetwork; /** * Attributes set on this load balancer diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts index 0a50e3dfe13ee..fcd44c120ca21 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts @@ -23,7 +23,7 @@ export interface BaseTargetGroupProps { /** * The virtual private cloud (VPC). */ - vpc: ec2.VpcNetworkRef; + vpc: ec2.IVpcNetwork; /** * The amount of time for Elastic Load Balancing to wait before deregistering a target. @@ -131,7 +131,7 @@ export interface HealthCheck { /** * Define the target of a load balancer */ -export abstract class BaseTargetGroup extends cdk.Construct implements ITargetGroup, codedeploy.ILoadBalancer { +export abstract class TargetGroupBase extends cdk.Construct implements ITargetGroup, codedeploy.ILoadBalancer { /** * The ARN of the target group */ @@ -261,7 +261,7 @@ export abstract class BaseTargetGroup extends cdk.Construct implements ITargetGr /** * Export this target group */ - public export(): TargetGroupRefProps { + public export(): TargetGroupAttributes { return { targetGroupArn: new cdk.Output(this, 'TargetGroupArn', { value: this.targetGroupArn }).makeImportValue().toString(), defaultPort: new cdk.Output(this, 'Port', { value: this.defaultPort }).makeImportValue().toString(), @@ -307,7 +307,7 @@ export abstract class BaseTargetGroup extends cdk.Construct implements ITargetGr /** * Properties to reference an existing target group */ -export interface TargetGroupRefProps { +export interface TargetGroupAttributes { /** * ARN of the target group */ @@ -342,6 +342,12 @@ export interface ITargetGroup { * Return an object to depend on the listeners added to this target group */ loadBalancerDependency(): cdk.IDependable; + + /** + * Export this target group + */ + export(): TargetGroupAttributes; + } /** diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts index e16b7b56cb9c4..ca06419a47704 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts @@ -1,10 +1,10 @@ import cdk = require('@aws-cdk/cdk'); -import { TargetGroupRefProps } from './base-target-group'; +import { ITargetGroup, TargetGroupAttributes } from './base-target-group'; /** - * Base class for existing target groups + * Base internal class for existing target groups */ -export class BaseImportedTargetGroup extends cdk.Construct { +export abstract class ImportedTargetGroupBase extends cdk.Construct implements ITargetGroup { /** * ARN of the target group */ @@ -15,10 +15,19 @@ export class BaseImportedTargetGroup extends cdk.Construct { */ public readonly loadBalancerArns: string; - constructor(parent: cdk.Construct, id: string, props: TargetGroupRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: TargetGroupAttributes) { super(parent, id); this.targetGroupArn = props.targetGroupArn; this.loadBalancerArns = props.loadBalancerArns || cdk.Aws.noValue; } + + /** + * Return an object to depend on the listeners added to this target group + */ + public abstract loadBalancerDependency(): cdk.IDependable; + + public export() { + return this.props; + } } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts index 1226af9be4d55..b23f7715d68aa 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts @@ -18,7 +18,8 @@ const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' }); -new route53.AliasRecord(zone, 'Alias', { +new route53.AliasRecord(stack, 'Alias', { + zone, recordName: '_foo', target: lb }); diff --git a/packages/@aws-cdk/aws-events/lib/rule-ref.ts b/packages/@aws-cdk/aws-events/lib/rule-ref.ts index 2a6b50b6b6fb8..155fff989e3bf 100644 --- a/packages/@aws-cdk/aws-events/lib/rule-ref.ts +++ b/packages/@aws-cdk/aws-events/lib/rule-ref.ts @@ -1,6 +1,4 @@ -import { Construct, Output } from '@aws-cdk/cdk'; - -export interface EventRuleRefProps { +export interface EventRuleAttributes { /** * The value of the event rule Amazon Resource Name (ARN), such as * arn:aws:events:us-east-2:123456789012:rule/example. @@ -8,37 +6,15 @@ export interface EventRuleRefProps { eventRuleArn: string; } -export abstract class EventRuleRef extends Construct { - - /** - * Imports a rule by ARN into this stack. - */ - public static import(parent: Construct, name: string, props: EventRuleRefProps): EventRuleRef { - return new ImportedEventRule(parent, name, props); - } - +export interface IEventRule { /** * The value of the event rule Amazon Resource Name (ARN), such as * arn:aws:events:us-east-2:123456789012:rule/example. */ - public abstract readonly ruleArn: string; + readonly ruleArn: string; /** * Exports this rule resource from this stack and returns an import token. */ - public export(): EventRuleRefProps { - return { - eventRuleArn: new Output(this, 'RuleArn', { value: this.ruleArn }).makeImportValue().toString() - }; - } -} - -class ImportedEventRule extends EventRuleRef { - public readonly ruleArn: string; - - constructor(parent: Construct, name: string, props: EventRuleRefProps) { - super(parent, name); - - this.ruleArn = props.eventRuleArn; - } + export(): EventRuleAttributes; } diff --git a/packages/@aws-cdk/aws-events/lib/rule.ts b/packages/@aws-cdk/aws-events/lib/rule.ts index 3a2eaf5a0f3a5..6925f194a3b8c 100644 --- a/packages/@aws-cdk/aws-events/lib/rule.ts +++ b/packages/@aws-cdk/aws-events/lib/rule.ts @@ -1,8 +1,9 @@ -import { Construct, Token } from '@aws-cdk/cdk'; +import { Construct, Output, Token } from '@aws-cdk/cdk'; import { EventPattern } from './event-pattern'; import { CfnRule } from './events.generated'; import { TargetInputTemplate } from './input-options'; -import { EventRuleRef } from './rule-ref'; +import { ImportedEventRule } from './rule-import'; +import { EventRuleAttributes, IEventRule } from './rule-ref'; import { IEventRuleTarget } from './target'; import { mergeEventPattern } from './util'; @@ -63,7 +64,14 @@ export interface EventRuleProps { /** * Defines a CloudWatch Event Rule in this stack. */ -export class EventRule extends EventRuleRef { +export class EventRule extends Construct implements IEventRule { + /** + * Imports a rule by ARN into this stack. + */ + public static import(parent: Construct, name: string, props: EventRuleAttributes): IEventRule { + return new ImportedEventRule(parent, name, props); + } + public readonly ruleArn: string; private readonly targets = new Array(); @@ -92,6 +100,15 @@ export class EventRule extends EventRuleRef { } } + /** + * Exports this rule resource from this stack and returns an import token. + */ + public export(): EventRuleAttributes { + return { + eventRuleArn: new Output(this, 'RuleArn', { value: this.ruleArn }).makeImportValue().toString() + }; + } + /** * Adds a target to the rule. The abstract class RuleTarget can be extended to define new * targets. diff --git a/packages/@aws-cdk/aws-kinesis/lib/stream.ts b/packages/@aws-cdk/aws-kinesis/lib/stream.ts index 2fa21ca8bbc6a..5d9d6808c174e 100644 --- a/packages/@aws-cdk/aws-kinesis/lib/stream.ts +++ b/packages/@aws-cdk/aws-kinesis/lib/stream.ts @@ -4,12 +4,61 @@ import logs = require('@aws-cdk/aws-logs'); import cdk = require('@aws-cdk/cdk'); import { CfnStream } from './kinesis.generated'; +export interface IStream extends logs.ILogSubscriptionDestination { + /** + * The ARN of the stream. + */ + readonly streamArn: string; + + /** + * The name of the stream + */ + readonly streamName: string; + + /** + * Optional KMS encryption key associated with this stream. + */ + readonly encryptionKey?: kms.IEncryptionKey; + + /** + * Exports this stream from the stack. + */ + export(): StreamAttributes; + + /** + * Grant read permissions for this stream and its contents to an IAM + * principal (Role/Group/User). + * + * If an encryption key is used, permission to ues the key to decrypt the + * contents of the stream will also be granted. + */ + grantRead(identity?: iam.IPrincipal): void; + + /** + * Grant write permissions for this stream and its contents to an IAM + * principal (Role/Group/User). + * + * If an encryption key is used, permission to ues the key to encrypt the + * contents of the stream will also be granted. + */ + grantWrite(identity?: iam.IPrincipal): void; + + /** + * Grants read/write permissions for this stream and its contents to an IAM + * principal (Role/Group/User). + * + * If an encryption key is used, permission to use the key for + * encrypt/decrypt will also be granted. + */ + grantReadWrite(identity?: iam.IPrincipal): void; +} + /** * A reference to a stream. The easiest way to instantiate is to call * `stream.export()`. Then, the consumer can use `Stream.import(this, ref)` and * get a `Stream`. */ -export interface StreamRefProps { +export interface StreamAttributes { /** * The ARN of the stream. */ @@ -18,7 +67,7 @@ export interface StreamRefProps { /** * The KMS key securing the contents of the stream if encryption is enabled. */ - encryptionKey?: kms.EncryptionKeyRefProps; + encryptionKey?: kms.EncryptionKeyAttributes; } /** @@ -30,27 +79,15 @@ export interface StreamRefProps { * * Or imported from an existing stream: * - * StreamRef.import(this, 'MyImportedStream', { streamArn: ... }); + * Stream.import(this, 'MyImportedStream', { streamArn: ... }); * * You can also export a stream and import it into another stack: * * const ref = myStream.export(); - * StreamRef.import(this, 'MyImportedStream', ref); + * Stream.import(this, 'MyImportedStream', ref); * */ -export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscriptionDestination { - /** - * Creates a Stream construct that represents an external stream. - * - * @param parent The parent creating construct (usually `this`). - * @param name The construct's name. - * @param ref A StreamRefProps object. Can be obtained from a call to - * `stream.export()`. - */ - public static import(parent: cdk.Construct, name: string, props: StreamRefProps): StreamRef { - return new ImportedStreamRef(parent, name, props); - } - +export abstract class StreamBase extends cdk.Construct implements IStream { /** * The ARN of the stream. */ @@ -64,22 +101,14 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr /** * Optional KMS encryption key associated with this stream. */ - public abstract readonly encryptionKey?: kms.EncryptionKeyRef; + public abstract readonly encryptionKey?: kms.IEncryptionKey; /** * The role that can be used by CloudWatch logs to write to this stream */ private cloudWatchLogsRole?: iam.Role; - /** - * Exports this stream from the stack. - */ - public export(): StreamRefProps { - return { - streamArn: new cdk.Output(this, 'StreamArn', { value: this.streamArn }).makeImportValue().toString(), - encryptionKey: this.encryptionKey ? this.encryptionKey.export() : undefined, - }; - } + public abstract export(): StreamAttributes; /** * Grant write permissions for this stream and its contents to an IAM @@ -165,7 +194,7 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr ); } - public logSubscriptionDestination(sourceLogGroup: logs.LogGroupRef): logs.LogSubscriptionDestination { + public logSubscriptionDestination(sourceLogGroup: logs.ILogGroup): logs.LogSubscriptionDestination { // Following example from https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#DestinationKinesisExample if (!this.cloudWatchLogsRole) { // Create a role to be assumed by CWL that can write to this stream and pass itself. @@ -178,7 +207,7 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr // We've now made it possible for CloudWatch events to write to us. In case the LogGroup is in a // different account, we must add a Destination in between as well. - const sourceStack = cdk.Stack.find(sourceLogGroup); + const sourceStack = cdk.Stack.find(sourceLogGroup as any); const thisStack = cdk.Stack.find(this); // Case considered: if both accounts are undefined, we can't make any assumptions. Better @@ -195,8 +224,9 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr /** * Generate a CloudWatch Logs Destination and return the properties in the form o a subscription destination */ - private crossAccountLogSubscriptionDestination(sourceLogGroup: logs.LogGroupRef): logs.LogSubscriptionDestination { - const sourceStack = cdk.Stack.find(sourceLogGroup); + private crossAccountLogSubscriptionDestination(sourceLogGroup: logs.ILogGroup): logs.LogSubscriptionDestination { + const sourceLogGroupConstruct: cdk.Construct = sourceLogGroup as any; + const sourceStack = cdk.Stack.find(sourceLogGroupConstruct); const thisStack = cdk.Stack.find(this); if (!sourceStack.env.account || !thisStack.env.account) { @@ -205,7 +235,7 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr // Take some effort to construct a unique ID for the destination that is unique to the // combination of (stream, loggroup). - const uniqueId = new cdk.HashedAddressingScheme().allocateAddress([sourceLogGroup.path.replace('/', ''), sourceStack.env.account!]); + const uniqueId = new cdk.HashedAddressingScheme().allocateAddress([sourceLogGroupConstruct.path.replace('/', ''), sourceStack.env.account!]); // The destination lives in the target account const dest = new logs.CrossAccountDestination(this, `CWLDestination${uniqueId}`, { @@ -272,16 +302,28 @@ export interface StreamProps { * @default If encryption is set to "Kms" and this property is undefined, a * new KMS key will be created and associated with this stream. */ - encryptionKey?: kms.EncryptionKeyRef; + encryptionKey?: kms.IEncryptionKey; } /** * A Kinesis stream. Can be encrypted with a KMS key. */ -export class Stream extends StreamRef { +export class Stream extends StreamBase { + /** + * Creates a Stream construct that represents an external stream. + * + * @param parent The parent creating construct (usually `this`). + * @param name The construct's name. + * @param ref A `StreamAttributes` object. Can be obtained from a call to + * `stream.export()`. + */ + public static import(parent: cdk.Construct, name: string, props: StreamAttributes): IStream { + return new ImportedStream(parent, name, props); + } + public readonly streamArn: string; public readonly streamName: string; - public readonly encryptionKey?: kms.EncryptionKeyRef; + public readonly encryptionKey?: kms.IEncryptionKey; private readonly stream: CfnStream; @@ -309,13 +351,23 @@ export class Stream extends StreamRef { if (props.streamName) { this.addMetadata('aws:cdk:hasPhysicalName', props.streamName); } } + /** + * Exports this stream from the stack. + */ + public export(): StreamAttributes { + return { + streamArn: new cdk.Output(this, 'StreamArn', { value: this.streamArn }).makeImportValue().toString(), + encryptionKey: this.encryptionKey ? this.encryptionKey.export() : undefined, + }; + } + /** * Set up key properties and return the Stream encryption property from the * user's configuration. */ private parseEncryption(props: StreamProps): { streamEncryption?: CfnStream.StreamEncryptionProperty, - encryptionKey?: kms.EncryptionKeyRef + encryptionKey?: kms.IEncryptionKey } { // default to unencrypted. @@ -362,12 +414,12 @@ export enum StreamEncryption { Kms = 'KMS', } -class ImportedStreamRef extends StreamRef { +class ImportedStream extends StreamBase { public readonly streamArn: string; public readonly streamName: string; - public readonly encryptionKey?: kms.EncryptionKeyRef; + public readonly encryptionKey?: kms.IEncryptionKey; - constructor(parent: cdk.Construct, name: string, props: StreamRefProps) { + constructor(parent: cdk.Construct, name: string, private readonly props: StreamAttributes) { super(parent, name); this.streamArn = props.streamArn; @@ -376,9 +428,13 @@ class ImportedStreamRef extends StreamRef { this.streamName = cdk.ArnUtils.parse(props.streamArn).resourceName!; if (props.encryptionKey) { - this.encryptionKey = kms.EncryptionKeyRef.import(parent, 'Key', props.encryptionKey); + this.encryptionKey = kms.EncryptionKey.import(parent, 'Key', props.encryptionKey); } else { this.encryptionKey = undefined; } } + + public export() { + return this.props; + } } diff --git a/packages/@aws-cdk/aws-kms/lib/alias.ts b/packages/@aws-cdk/aws-kms/lib/alias.ts index 9f05844243d13..dcb810b32de2c 100644 --- a/packages/@aws-cdk/aws-kms/lib/alias.ts +++ b/packages/@aws-cdk/aws-kms/lib/alias.ts @@ -1,5 +1,5 @@ import { Construct } from '@aws-cdk/cdk'; -import { EncryptionKeyRef } from './key'; +import { IEncryptionKey } from './key'; import { CfnAlias } from './kms.generated'; const REQUIRED_ALIAS_PREFIX = 'alias/'; @@ -18,7 +18,7 @@ export interface EncryptionKeyAliasProps { * globally unique identifier or Amazon Resource Name (ARN). You can't * specify another alias. */ - key: EncryptionKeyRef; + key: IEncryptionKey; } /** diff --git a/packages/@aws-cdk/aws-kms/lib/key.ts b/packages/@aws-cdk/aws-kms/lib/key.ts index 999b69ce7e10d..ea79638384236 100644 --- a/packages/@aws-cdk/aws-kms/lib/key.ts +++ b/packages/@aws-cdk/aws-kms/lib/key.ts @@ -3,36 +3,41 @@ import { Construct, DeletionPolicy, Output, resolve } from '@aws-cdk/cdk'; import { EncryptionKeyAlias } from './alias'; import { CfnKey } from './kms.generated'; -export interface EncryptionKeyRefProps { +export interface IEncryptionKey { /** - * The ARN of the external KMS key. + * The ARN of the key. */ - keyArn: string; + readonly keyArn: string; + + /** + * Defines a new alias for the key. + */ + addAlias(alias: string): EncryptionKeyAlias; + + /** + * Adds a statement to the KMS key resource policy. + * @param statement The policy statement to add + * @param allowNoOp If this is set to `false` and there is no policy + * defined (i.e. external key), the operation will fail. Otherwise, it will + * no-op. + */ + addToResourcePolicy(statement: PolicyStatement, allowNoOp?: boolean): void; + + /** + * Exports this key from the current stack. + * @returns a key ref which can be used in a call to `EncryptionKey.import(ref)`. + */ + export(): EncryptionKeyAttributes; } -export abstract class EncryptionKeyRef extends Construct { +export interface EncryptionKeyAttributes { /** - * Defines an imported encryption key. - * - * `ref` can be obtained either via a call to `key.export()` or using - * literals. - * - * For example: - * - * const keyRefProps = key.export(); - * const keyRef1 = EncryptionKeyRef.import(this, 'MyImportedKey1', keyRefProps); - * const keyRef2 = EncryptionKeyRef.import(this, 'MyImportedKey2', { - * keyArn: new KeyArn('arn:aws:kms:...') - * }); - * - * @param parent The parent construct. - * @param name The name of the construct. - * @param props The key reference. + * The ARN of the external KMS key. */ - public static import(parent: Construct, name: string, props: EncryptionKeyRefProps): EncryptionKeyRef { - return new EncryptionKeyRefImport(parent, name, props); - } + keyArn: string; +} +export abstract class EncryptionKeyBase extends Construct { /** * The ARN of the key. */ @@ -69,15 +74,7 @@ export abstract class EncryptionKeyRef extends Construct { this.policy.addStatement(statement); } - /** - * Exports this key from the current stack. - * @returns a key ref which can be used in a call to `EncryptionKey.import(ref)`. - */ - public export(): EncryptionKeyRefProps { - return { - keyArn: new Output(this, 'KeyArn', { value: this.keyArn }).makeImportValue().toString() - }; - } + public abstract export(): EncryptionKeyAttributes; } /** @@ -114,7 +111,29 @@ export interface EncryptionKeyProps { /** * Defines a KMS key. */ -export class EncryptionKey extends EncryptionKeyRef { +export class EncryptionKey extends EncryptionKeyBase { + /** + * Defines an imported encryption key. + * + * `ref` can be obtained either via a call to `key.export()` or using + * literals. + * + * For example: + * + * const keyAttr = key.export(); + * const keyRef1 = EncryptionKey.import(this, 'MyImportedKey1', keyAttr); + * const keyRef2 = EncryptionKey.import(this, 'MyImportedKey2', { + * keyArn: new KeyArn('arn:aws:kms:...') + * }); + * + * @param parent The parent construct. + * @param name The name of the construct. + * @param props The key reference. + */ + public static import(parent: Construct, name: string, props: EncryptionKeyAttributes): IEncryptionKey { + return new ImportedEncryptionKey(parent, name, props); + } + public readonly keyArn: string; protected readonly policy?: PolicyDocument; @@ -139,6 +158,16 @@ export class EncryptionKey extends EncryptionKeyRef { resource.options.deletionPolicy = DeletionPolicy.Retain; } + /** + * Exports this key from the current stack. + * @returns a key ref which can be used in a call to `EncryptionKey.import(ref)`. + */ + public export(): EncryptionKeyAttributes { + return { + keyArn: new Output(this, 'KeyArn', { value: this.keyArn }).makeImportValue().toString() + }; + } + /** * Let users from this account admin this key. * @link https://aws.amazon.com/premiumsupport/knowledge-center/update-key-policy-future/ @@ -166,13 +195,17 @@ export class EncryptionKey extends EncryptionKeyRef { } } -class EncryptionKeyRefImport extends EncryptionKeyRef { +class ImportedEncryptionKey extends EncryptionKeyBase { public readonly keyArn: string; protected readonly policy = undefined; // no policy associated with an imported key - constructor(parent: Construct, name: string, props: EncryptionKeyRefProps) { + constructor(parent: Construct, name: string, private readonly props: EncryptionKeyAttributes) { super(parent, name); this.keyArn = props.keyArn; } + + public export() { + return this.props; + } } diff --git a/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts b/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts index 5682f91fc9bf9..df46051841a4a 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts @@ -24,7 +24,7 @@ export class S3EventSource implements lambda.IEventSource { } - public bind(target: lambda.FunctionRef) { + public bind(target: lambda.IFunction) { const filters = this.props.filters || []; for (const event of this.props.events) { this.bucket.onEvent(event, target, ...filters); diff --git a/packages/@aws-cdk/aws-lambda-event-sources/lib/sns.ts b/packages/@aws-cdk/aws-lambda-event-sources/lib/sns.ts index 093bfd8a37d76..d2c40c1b4b47b 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/lib/sns.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/lib/sns.ts @@ -5,10 +5,10 @@ import sns = require('@aws-cdk/aws-sns'); * Use an Amazon SNS topic as an event source for AWS Lambda. */ export class SnsEventSource implements lambda.IEventSource { - constructor(readonly topic: sns.TopicRef) { + constructor(readonly topic: sns.ITopic) { } - public bind(target: lambda.FunctionRef) { + public bind(target: lambda.IFunction) { this.topic.subscribeLambda(target); } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-event-sources/lib/sqs.ts b/packages/@aws-cdk/aws-lambda-event-sources/lib/sqs.ts index 3cb3273ae6146..faf7576047f68 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/lib/sqs.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/lib/sqs.ts @@ -18,13 +18,13 @@ export interface SqsEventSourceProps { * Use an Amazon SQS queue as an event source for AWS Lambda. */ export class SqsEventSource implements lambda.IEventSource { - constructor(readonly queue: sqs.QueueRef, private readonly props: SqsEventSourceProps = { }) { + constructor(readonly queue: sqs.IQueue, private readonly props: SqsEventSourceProps = { }) { if (this.props.batchSize !== undefined && (this.props.batchSize < 1 || this.props.batchSize > 10)) { throw new Error(`Maximum batch size must be between 1 and 10 inclusive (given ${this.props.batchSize})`); } } - public bind(target: lambda.FunctionRef) { + public bind(target: lambda.FunctionBase) { new lambda.EventSourceMapping(target, `SqsEventSource:${this.queue.uniqueId}`, { target, batchSize: this.props.batchSize, diff --git a/packages/@aws-cdk/aws-lambda/lib/alias.ts b/packages/@aws-cdk/aws-lambda/lib/alias.ts index 3170a95bc2f4b..a173d30ed5437 100644 --- a/packages/@aws-cdk/aws-lambda/lib/alias.ts +++ b/packages/@aws-cdk/aws-lambda/lib/alias.ts @@ -1,6 +1,6 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { FunctionRef } from './lambda-ref'; +import { FunctionAttributes, FunctionBase, IFunction } from './lambda-ref'; import { FunctionVersion } from './lambda-version'; import { CfnAlias } from './lambda.generated'; import { Permission } from './permission'; @@ -51,7 +51,7 @@ export interface AliasProps { /** * A new alias to a particular version of a Lambda function. */ -export class Alias extends FunctionRef { +export class Alias extends FunctionBase { /** * ARN of this alias * @@ -78,7 +78,7 @@ export class Alias extends FunctionRef { /** * The actual Lambda function object that this Alias is pointing to */ - private readonly underlyingLambda: FunctionRef; + private readonly underlyingLambda: IFunction; constructor(parent: cdk.Construct, name: string, props: AliasProps) { super(parent, name); @@ -99,6 +99,12 @@ export class Alias extends FunctionRef { this.functionArn = alias.aliasArn; } + public export(): FunctionAttributes { + return { + functionArn: new cdk.Output(this, 'AliasArn', { value: this.functionArn }).makeImportValue().toString() + }; + } + public addPermission(name: string, permission: Permission) { // Forward addPermission() to the underlying Lambda object this.underlyingLambda.addPermission(name, permission); diff --git a/packages/@aws-cdk/aws-lambda/lib/code.ts b/packages/@aws-cdk/aws-lambda/lib/code.ts index 22237682d22ea..ba9b6769d4e37 100644 --- a/packages/@aws-cdk/aws-lambda/lib/code.ts +++ b/packages/@aws-cdk/aws-lambda/lib/code.ts @@ -11,7 +11,7 @@ export abstract class Code { * @param key The object key * @param objectVersion Optional S3 object version */ - public static bucket(bucket: s3.BucketRef, key: string, objectVersion?: string) { + public static bucket(bucket: s3.IBucket, key: string, objectVersion?: string) { return new S3Code(bucket, key, objectVersion); } @@ -71,7 +71,7 @@ export abstract class Code { export class S3Code extends Code { private bucketName: string; - constructor(bucket: s3.BucketRef, private key: string, private objectVersion?: string) { + constructor(bucket: s3.IBucket, private key: string, private objectVersion?: string) { super(); if (!bucket.bucketName) { diff --git a/packages/@aws-cdk/aws-lambda/lib/event-source-mapping.ts b/packages/@aws-cdk/aws-lambda/lib/event-source-mapping.ts index 481658dda5853..784777c1218f7 100644 --- a/packages/@aws-cdk/aws-lambda/lib/event-source-mapping.ts +++ b/packages/@aws-cdk/aws-lambda/lib/event-source-mapping.ts @@ -1,5 +1,5 @@ import cdk = require('@aws-cdk/cdk'); -import { FunctionRef } from './lambda-ref'; +import { IFunction } from './lambda-ref'; import { CfnEventSourceMapping } from './lambda.generated'; export interface EventSourceMappingProps { @@ -12,7 +12,7 @@ export interface EventSourceMappingProps { /** * The target AWS Lambda function. */ - target: FunctionRef; + target: IFunction; /** * The largest number of records that AWS Lambda will retrieve from your event diff --git a/packages/@aws-cdk/aws-lambda/lib/event-source.ts b/packages/@aws-cdk/aws-lambda/lib/event-source.ts index 76aa56311e05e..10b0937a6cfca 100644 --- a/packages/@aws-cdk/aws-lambda/lib/event-source.ts +++ b/packages/@aws-cdk/aws-lambda/lib/event-source.ts @@ -1,4 +1,4 @@ -import { FunctionRef } from './lambda-ref'; +import { FunctionBase } from './lambda-ref'; /** * An abstract class which represents an AWS Lambda event source. @@ -9,5 +9,5 @@ export interface IEventSource { * function. * @param target That lambda function to bind to. */ - bind(target: FunctionRef): void; + bind(target: FunctionBase): void; } diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts index 4bafd28ce8933..7de93ab2784de 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts @@ -12,121 +12,136 @@ import { CfnPermission } from './lambda.generated'; import { Permission } from './permission'; import { CommonPipelineInvokeActionProps, PipelineInvokeAction } from './pipeline-action'; -/** - * Represents a Lambda function defined outside of this stack. - */ -export interface FunctionRefProps { +export interface IFunction extends events.IEventRuleTarget, logs.ILogSubscriptionDestination, + s3n.IBucketNotificationDestination, ec2.IConnectable, stepfunctions.IStepFunctionsTaskResource { + /** - * The ARN of the Lambda function. - * - * Format: arn::lambda:::function: + * Logical ID of this Function. */ - functionArn: string; + readonly id: string; /** - * The IAM execution role associated with this function. + * The name of the function. + */ + readonly functionName: string; + + /** + * The ARN fo the function. + */ + readonly functionArn: string; + + /** + * The IAM role associated with this function. + */ + readonly role?: iam.Role; + + /** + * Access the Connections object * - * If the role is not specified, any role-related operations will no-op. + * Will fail if not a VPC-enabled Lambda Function */ - role?: iam.Role; + readonly connections: ec2.Connections; /** - * Id of the securityGroup for this Lambda, if in a VPC. + * Whether or not this Lambda function was bound to a VPC * - * This needs to be given in order to support allowing connections - * to this Lambda. + * If this is is `false`, trying to access the `connections` object will fail. */ - securityGroupId?: string; -} + readonly isBoundToVpc: boolean; -export abstract class FunctionRef extends cdk.Construct - implements events.IEventRuleTarget, logs.ILogSubscriptionDestination, s3n.IBucketNotificationDestination, - ec2.IConnectable, stepfunctions.IStepFunctionsTaskResource { + /** + * Adds a permission to the Lambda resource policy. + * @param id The id ƒor the permission construct + */ + addPermission(id: string, permission: Permission): void; /** - * Creates a Lambda function object which represents a function not defined - * within this stack. - * - * Lambda.import(this, 'MyImportedFunction', { lambdaArn: new LambdaArn('arn:aws:...') }); + * Convenience method for creating a new {@link PipelineInvokeAction}, + * and adding it to the given Stage. * - * @param parent The parent construct - * @param name The name of the lambda construct - * @param ref A reference to a Lambda function. Can be created manually (see - * example above) or obtained through a call to `lambda.export()`. + * @param stage the Pipeline Stage to add the new Action to + * @param name the name of the newly created Action + * @param props the properties of the new Action + * @returns the newly created {@link PipelineInvokeAction} */ - public static import(parent: cdk.Construct, name: string, ref: FunctionRefProps): FunctionRef { - return new LambdaRefImport(parent, name, ref); - } + addToPipeline(stage: codepipeline.IStage, name: string, props?: CommonPipelineInvokeActionProps): PipelineInvokeAction; + + addToRolePolicy(statement: iam.PolicyStatement): void; + + /** + * Grant the given identity permissions to invoke this Lambda + */ + grantInvoke(identity?: iam.IPrincipal): void; /** * Return the given named metric for this Lambda */ - public static metricAll(metricName: string, props?: cloudwatch.MetricCustomization): cloudwatch.Metric { - return new cloudwatch.Metric({ - namespace: 'AWS/Lambda', - metricName, - ...props - }); - } + metric(metricName: string, props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + /** - * Metric for the number of Errors executing all Lambdas + * Metric for the Errors executing this Lambda * * @default sum over 5 minutes */ - public static metricAllErrors(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { - return FunctionRef.metricAll('Errors', { statistic: 'sum', ...props }); - } + metricErrors(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; /** - * Metric for the Duration executing all Lambdas + * Metric for the Duration of this Lambda * * @default average over 5 minutes */ - public static metricAllDuration(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { - return FunctionRef.metricAll('Duration', props); - } + metricDuration(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; /** - * Metric for the number of invocations of all Lambdas + * Metric for the number of invocations of this Lambda * * @default sum over 5 minutes */ - public static metricAllInvocations(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { - return FunctionRef.metricAll('Invocations', { statistic: 'sum', ...props }); - } + metricInvocations(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; /** - * Metric for the number of throttled invocations of all Lambdas + * Metric for the number of throttled invocations of this Lambda * * @default sum over 5 minutes */ - public static metricAllThrottles(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { - return FunctionRef.metricAll('Throttles', { statistic: 'sum', ...props }); - } + metricThrottles(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + + /** + * Export this Function (without the role) + */ + export(): FunctionAttributes; + + addEventSource(source: IEventSource): void; +} +/** + * Represents a Lambda function defined outside of this stack. + */ +export interface FunctionAttributes { /** - * Metric for the number of concurrent executions across all Lambdas + * The ARN of the Lambda function. * - * @default max over 5 minutes - */ - public static metricAllConcurrentExecutions(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { - // Mini-FAQ: why max? This metric is a gauge that is emitted every - // minute, so either max or avg or a percentile make sense (but sum - // doesn't). Max is more sensitive to spiky load changes which is - // probably what you're interested in if you're looking at this metric - // (Load spikes may lead to concurrent execution errors that would - // otherwise not be visible in the avg) - return FunctionRef.metricAll('ConcurrentExecutions', { statistic: 'max', ...props }); - } + * Format: arn::lambda:::function: + */ + functionArn: string; /** - * Metric for the number of unreserved concurrent executions across all Lambdas + * The IAM execution role associated with this function. * - * @default max over 5 minutes + * If the role is not specified, any role-related operations will no-op. */ - public static metricAllUnreservedConcurrentExecutions(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { - return FunctionRef.metricAll('UnreservedConcurrentExecutions', { statistic: 'max', ...props }); - } + role?: iam.Role; + + /** + * Id of the securityGroup for this Lambda, if in a VPC. + * + * This needs to be given in order to support allowing connections + * to this Lambda. + */ + securityGroupId?: string; +} + +export abstract class FunctionBase extends cdk.Construct implements IFunction { /** * The name of the function. @@ -311,7 +326,7 @@ export abstract class FunctionRef extends cdk.Construct return this.metric('Throttles', { statistic: 'sum', ...props }); } - public logSubscriptionDestination(sourceLogGroup: logs.LogGroupRef): logs.LogSubscriptionDestination { + public logSubscriptionDestination(sourceLogGroup: logs.ILogGroup): logs.LogSubscriptionDestination { const arn = sourceLogGroup.logGroupArn; if (this.logSubscriptionDestinationPolicyAddedFor.indexOf(arn) === -1) { @@ -331,14 +346,7 @@ export abstract class FunctionRef extends cdk.Construct /** * Export this Function (without the role) */ - public export(): FunctionRefProps { - return { - functionArn: new cdk.Output(this, 'FunctionArn', { value: this.functionArn }).makeImportValue().toString(), - securityGroupId: this._connections && this._connections.securityGroups[0] - ? new cdk.Output(this, 'SecurityGroupId', { value: this._connections.securityGroups[0].securityGroupId }).makeImportValue().toString() - : undefined - }; - } + public abstract export(): FunctionAttributes; /** * Allows this Lambda to be used as a destination for bucket notifications. @@ -413,44 +421,3 @@ export abstract class FunctionRef extends cdk.Construct 'Supported: AccountPrincipal, ServicePrincipal'); } } - -class LambdaRefImport extends FunctionRef { - public readonly functionName: string; - public readonly functionArn: string; - public readonly role?: iam.Role; - - protected readonly canCreatePermissions = false; - - constructor(parent: cdk.Construct, name: string, props: FunctionRefProps) { - super(parent, name); - - this.functionArn = props.functionArn; - this.functionName = this.extractNameFromArn(props.functionArn); - this.role = props.role; - - if (props.securityGroupId) { - this._connections = new ec2.Connections({ - securityGroups: [ec2.SecurityGroupRef.import(this, 'SecurityGroup', { - securityGroupId: props.securityGroupId - })] - }); - } - } - - /** - * Given an opaque (token) ARN, returns a CloudFormation expression that extracts the function - * name from the ARN. - * - * Function ARNs look like this: - * - * arn:aws:lambda:region:account-id:function:function-name - * - * ..which means that in order to extract the `function-name` component from the ARN, we can - * split the ARN using ":" and select the component in index 6. - * - * @returns `FnSelect(6, FnSplit(':', arn))` - */ - private extractNameFromArn(arn: string) { - return cdk.Fn.select(6, cdk.Fn.split(':', arn)).toString(); - } -} diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-version.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-version.ts index d2e058e3d7729..e046ac67fd931 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-version.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-version.ts @@ -1,5 +1,5 @@ import { Construct } from '@aws-cdk/cdk'; -import { FunctionRef } from './lambda-ref'; +import { IFunction } from './lambda-ref'; import { CfnVersion } from './lambda.generated'; /** @@ -25,7 +25,7 @@ export interface FunctionVersionProps { /** * Function to get the value of */ - lambda: FunctionRef; + lambda: IFunction; } /** @@ -53,7 +53,7 @@ export class FunctionVersion extends Construct { /** * Lambda object this version is associated with */ - public readonly lambda: FunctionRef; + public readonly lambda: IFunction; constructor(parent: Construct, name: string, props: FunctionVersionProps) { super(parent, name); diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda.ts b/packages/@aws-cdk/aws-lambda/lib/lambda.ts index 237e8a9e6b4e0..38429e5acd990 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda.ts @@ -1,9 +1,11 @@ +import cloudwatch = require('@aws-cdk/aws-cloudwatch'); import ec2 = require('@aws-cdk/aws-ec2'); import iam = require('@aws-cdk/aws-iam'); import sqs = require('@aws-cdk/aws-sqs'); import cdk = require('@aws-cdk/cdk'); import { Code } from './code'; -import { FunctionRef } from './lambda-ref'; +import { ImportedFunction } from './lambda-import'; +import { FunctionAttributes, FunctionBase, IFunction } from './lambda-ref'; import { FunctionVersion } from './lambda-version'; import { CfnFunction } from './lambda.generated'; import { Runtime } from './runtime'; @@ -117,7 +119,7 @@ export interface FunctionProps { * * Specify this if the Lambda function needs to access resources in a VPC. */ - vpc?: ec2.VpcNetworkRef; + vpc?: ec2.IVpcNetwork; /** * Where to place the network interfaces within the VPC. @@ -138,7 +140,7 @@ export interface FunctionProps { * not specified, a dedicated security group will be created for this * function. */ - securityGroup?: ec2.SecurityGroupRef; + securityGroup?: ec2.ISecurityGroup; /** * Whether to allow the Lambda to send all network traffic @@ -163,7 +165,7 @@ export interface FunctionProps { * * @default SQS queue with 14 day retention period if `deadLetterQueueEnabled` is `true` */ - deadLetterQueue?: sqs.QueueRef; + deadLetterQueue?: sqs.IQueue; /** * Enable AWS X-Ray Tracing for Lambda Function. @@ -184,7 +186,92 @@ export interface FunctionProps { * This construct does not yet reproduce all features from the underlying resource * library. */ -export class Function extends FunctionRef { +export class Function extends FunctionBase { + /** + * Creates a Lambda function object which represents a function not defined + * within this stack. + * + * Lambda.import(this, 'MyImportedFunction', { lambdaArn: new LambdaArn('arn:aws:...') }); + * + * @param parent The parent construct + * @param name The name of the lambda construct + * @param ref A reference to a Lambda function. Can be created manually (see + * example above) or obtained through a call to `lambda.export()`. + */ + public static import(parent: cdk.Construct, name: string, ref: FunctionAttributes): IFunction { + return new ImportedFunction(parent, name, ref); + } + + /** + * Return the given named metric for this Lambda + */ + public static metricAll(metricName: string, props?: cloudwatch.MetricCustomization): cloudwatch.Metric { + return new cloudwatch.Metric({ + namespace: 'AWS/Lambda', + metricName, + ...props + }); + } + /** + * Metric for the number of Errors executing all Lambdas + * + * @default sum over 5 minutes + */ + public static metricAllErrors(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { + return this.metricAll('Errors', { statistic: 'sum', ...props }); + } + + /** + * Metric for the Duration executing all Lambdas + * + * @default average over 5 minutes + */ + public static metricAllDuration(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { + return this.metricAll('Duration', props); + } + + /** + * Metric for the number of invocations of all Lambdas + * + * @default sum over 5 minutes + */ + public static metricAllInvocations(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { + return this.metricAll('Invocations', { statistic: 'sum', ...props }); + } + + /** + * Metric for the number of throttled invocations of all Lambdas + * + * @default sum over 5 minutes + */ + public static metricAllThrottles(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { + return this.metricAll('Throttles', { statistic: 'sum', ...props }); + } + + /** + * Metric for the number of concurrent executions across all Lambdas + * + * @default max over 5 minutes + */ + public static metricAllConcurrentExecutions(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { + // Mini-FAQ: why max? This metric is a gauge that is emitted every + // minute, so either max or avg or a percentile make sense (but sum + // doesn't). Max is more sensitive to spiky load changes which is + // probably what you're interested in if you're looking at this metric + // (Load spikes may lead to concurrent execution errors that would + // otherwise not be visible in the avg) + return this.metricAll('ConcurrentExecutions', { statistic: 'max', ...props }); + } + + /** + * Metric for the number of unreserved concurrent executions across all Lambdas + * + * @default max over 5 minutes + */ + public static metricAllUnreservedConcurrentExecutions(props?: cloudwatch.MetricCustomization): cloudwatch.Metric { + return this.metricAll('UnreservedConcurrentExecutions', { statistic: 'max', ...props }); + } + /** * Name of this function */ @@ -267,6 +354,18 @@ export class Function extends FunctionRef { props.code.bind(this); } + /** + * Export this Function (without the role) + */ + public export(): FunctionAttributes { + return { + functionArn: new cdk.Output(this, 'FunctionArn', { value: this.functionArn }).makeImportValue().toString(), + securityGroupId: this._connections && this._connections.securityGroups[0] + ? new cdk.Output(this, 'SecurityGroupId', { value: this._connections.securityGroups[0].securityGroupId }).makeImportValue().toString() + : undefined + }; + } + /** * Adds an environment variable to this Lambda function. * If this is a ref to a Lambda function, this operation results in a no-op. diff --git a/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts b/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts index a5a930c355ed4..31737445b1412 100644 --- a/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts @@ -1,7 +1,7 @@ import codepipeline = require('@aws-cdk/aws-codepipeline-api'); import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { FunctionRef } from './lambda-ref'; +import { IFunction } from './lambda-ref'; /** * Common properties for creating a {@link PipelineInvokeAction} - @@ -72,7 +72,7 @@ export interface PipelineInvokeActionProps extends CommonPipelineInvokeActionPro /** * The lambda function to invoke. */ - lambda: FunctionRef; + lambda: IFunction; } /** diff --git a/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts b/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts index 026dc3b5676b3..3c21862adb900 100644 --- a/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts +++ b/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts @@ -1,7 +1,7 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { Function as LambdaFunction, FunctionProps } from './lambda'; -import { FunctionRef } from './lambda-ref'; +import { FunctionAttributes, FunctionBase, IFunction } from './lambda-ref'; import { Permission } from './permission'; /** @@ -34,12 +34,12 @@ export interface SingletonFunctionProps extends FunctionProps { * The lambda is identified using the value of 'uuid'. Run 'uuidgen' * for every SingletonLambda you create. */ -export class SingletonFunction extends FunctionRef { +export class SingletonFunction extends FunctionBase { public readonly functionName: string; public readonly functionArn: string; public readonly role?: iam.Role | undefined; protected readonly canCreatePermissions: boolean; - private lambdaFunction: FunctionRef; + private lambdaFunction: IFunction; constructor(parent: cdk.Construct, name: string, props: SingletonFunctionProps) { super(parent, name); @@ -53,17 +53,21 @@ export class SingletonFunction extends FunctionRef { this.canCreatePermissions = true; // Doesn't matter, addPermission is overriden anyway } + public export(): FunctionAttributes { + return this.lambdaFunction.export(); + } + public addPermission(name: string, permission: Permission) { return this.lambdaFunction.addPermission(name, permission); } - private ensureLambda(props: SingletonFunctionProps): FunctionRef { + private ensureLambda(props: SingletonFunctionProps): IFunction { const constructName = (props.lambdaPurpose || 'SingletonLambda') + slugify(props.uuid); const stack = cdk.Stack.find(this); const existing = stack.tryFindChild(constructName); if (existing) { // Just assume this is true - return existing as FunctionRef; + return existing as FunctionBase; } return new LambdaFunction(stack, constructName, props); diff --git a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts index 1241cfd5ba89c..93f498529fc3d 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts @@ -242,7 +242,7 @@ export = { // WHEN const props = fn.export(); - const imported = lambda.FunctionRef.import(stack2, 'Imported', props); + const imported = lambda.Function.import(stack2, 'Imported', props); // Can call addPermission() but it won't do anything imported.addPermission('Hello', { @@ -1076,7 +1076,7 @@ export = { let bindTarget; class EventSourceMock implements lambda.IEventSource { - public bind(target: lambda.FunctionRef) { + public bind(target: lambda.IFunction) { bindTarget = target; } } diff --git a/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts index cebff1fcf4272..46ba08766c520 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts @@ -81,7 +81,7 @@ export = { const somethingConnectable = new SomethingConnectable(new ec2.Connections({ securityGroups: [securityGroup] })); // WHEN - const importedLambda = lambda.FunctionRef.import(stack2, 'Lambda', this.lambda.export()); + const importedLambda = lambda.Function.import(stack2, 'Lambda', this.lambda.export()); importedLambda.connections.allowTo(somethingConnectable, new ec2.TcpAllPorts(), 'Lambda can call connectable'); // THEN: SomeSecurityGroup accepts connections from Lambda diff --git a/packages/@aws-cdk/aws-logs/lib/cross-account-destination.ts b/packages/@aws-cdk/aws-logs/lib/cross-account-destination.ts index 46e4adbf5dfd8..230775ab598a3 100644 --- a/packages/@aws-cdk/aws-logs/lib/cross-account-destination.ts +++ b/packages/@aws-cdk/aws-logs/lib/cross-account-destination.ts @@ -1,6 +1,6 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { LogGroupRef } from './log-group'; +import { ILogGroup } from './log-group'; import { CfnDestination } from './logs.generated'; import { ILogSubscriptionDestination, LogSubscriptionDestination } from './subscription-filter'; @@ -78,7 +78,7 @@ export class CrossAccountDestination extends cdk.Construct implements ILogSubscr this.policyDocument.addStatement(statement); } - public logSubscriptionDestination(_sourceLogGroup: LogGroupRef): LogSubscriptionDestination { + public logSubscriptionDestination(_sourceLogGroup: ILogGroup): LogSubscriptionDestination { return { arn: this.destinationArn }; } diff --git a/packages/@aws-cdk/aws-logs/lib/log-group.ts b/packages/@aws-cdk/aws-logs/lib/log-group.ts index bf27df4338963..9da3bb3132bb6 100644 --- a/packages/@aws-cdk/aws-logs/lib/log-group.ts +++ b/packages/@aws-cdk/aws-logs/lib/log-group.ts @@ -7,24 +7,87 @@ import { MetricFilter } from './metric-filter'; import { FilterPattern, IFilterPattern } from './pattern'; import { ILogSubscriptionDestination, SubscriptionFilter } from './subscription-filter'; +export interface ILogGroup { + /** + * The ARN of this log group + */ + readonly logGroupArn: string; + + /** + * The name of this log group + */ + readonly logGroupName: string; + + /** + * Create a new Log Stream for this Log Group + * + * @param parent Parent construct + * @param id Unique identifier for the construct in its parent + * @param props Properties for creating the LogStream + */ + newStream(parent: cdk.Construct, id: string, props?: NewLogStreamProps): LogStream; + + /** + * Create a new Subscription Filter on this Log Group + * + * @param parent Parent construct + * @param id Unique identifier for the construct in its parent + * @param props Properties for creating the SubscriptionFilter + */ + newSubscriptionFilter(parent: cdk.Construct, id: string, props: NewSubscriptionFilterProps): SubscriptionFilter; + + /** + * Create a new Metric Filter on this Log Group + * + * @param parent Parent construct + * @param id Unique identifier for the construct in its parent + * @param props Properties for creating the MetricFilter + */ + newMetricFilter(parent: cdk.Construct, id: string, props: NewMetricFilterProps): MetricFilter; + + /** + * Export this LogGroup + */ + export(): LogGroupAttributes; + + /** + * Extract a metric from structured log events in the LogGroup + * + * Creates a MetricFilter on this LogGroup that will extract the value + * of the indicated JSON field in all records where it occurs. + * + * The metric will be available in CloudWatch Metrics under the + * indicated namespace and name. + * + * @param jsonField JSON field to extract (example: '$.myfield') + * @param metricNamespace Namespace to emit the metric under + * @param metricName Name to emit the metric under + * @returns A Metric object representing the extracted metric + */ + extractMetric(jsonField: string, metricNamespace: string, metricName: string): cloudwatch.Metric; + + /** + * Give permissions to write to create and write to streams in this log group + */ + grantWrite(principal?: iam.IPrincipal): void; + + /** + * Give the indicated permissions on this log group and all streams + */ + grant(principal?: iam.IPrincipal, ...actions: string[]): void; +} + /** * Properties for importing a LogGroup */ -export interface LogGroupRefProps { +export interface LogGroupAttributes { logGroupArn: string; } /** * An CloudWatch Log Group */ -export abstract class LogGroupRef extends cdk.Construct { - /** - * Import an existing LogGroup - */ - public static import(parent: cdk.Construct, id: string, props: LogGroupRefProps): LogGroupRef { - return new ImportedLogGroup(parent, id, props); - } - +export abstract class LogGroupBase extends cdk.Construct implements ILogGroup { /** * The ARN of this log group */ @@ -77,14 +140,7 @@ export abstract class LogGroupRef extends cdk.Construct { }); } - /** - * Export this LogGroup - */ - public export(): LogGroupRefProps { - return { - logGroupArn: new cdk.Output(this, 'LogGroupArn', { value: this.logGroupArn }).makeImportValue().toString() - }; - } + public abstract export(): LogGroupAttributes; /** * Extract a metric from structured log events in the LogGroup @@ -169,7 +225,14 @@ export interface LogGroupProps { /** * Define a CloudWatch Log Group */ -export class LogGroup extends LogGroupRef { +export class LogGroup extends LogGroupBase { + /** + * Import an existing LogGroup + */ + public static import(parent: cdk.Construct, id: string, props: LogGroupAttributes): ILogGroup { + return new ImportedLogGroup(parent, id, props); + } + /** * The ARN of this log group */ @@ -203,12 +266,21 @@ export class LogGroup extends LogGroupRef { this.logGroupArn = resource.logGroupArn; this.logGroupName = resource.logGroupName; } + + /** + * Export this LogGroup + */ + public export(): LogGroupAttributes { + return { + logGroupArn: new cdk.Output(this, 'LogGroupArn', { value: this.logGroupArn }).makeImportValue().toString() + }; + } } /** * An imported CloudWatch Log Group */ -class ImportedLogGroup extends LogGroupRef { +class ImportedLogGroup extends LogGroupBase { /** * The ARN of this log group */ @@ -219,12 +291,19 @@ class ImportedLogGroup extends LogGroupRef { */ public readonly logGroupName: string; - constructor(parent: cdk.Construct, id: string, props: LogGroupRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: LogGroupAttributes) { super(parent, id); this.logGroupArn = props.logGroupArn; this.logGroupName = cdk.ArnUtils.resourceNameComponent(props.logGroupArn, ':'); } + + /** + * Export this LogGroup + */ + public export() { + return this.props; + } } /** diff --git a/packages/@aws-cdk/aws-logs/lib/log-stream.ts b/packages/@aws-cdk/aws-logs/lib/log-stream.ts index 6387bad4e9e45..59991c0740dfe 100644 --- a/packages/@aws-cdk/aws-logs/lib/log-stream.ts +++ b/packages/@aws-cdk/aws-logs/lib/log-stream.ts @@ -1,38 +1,24 @@ import cdk = require('@aws-cdk/cdk'); -import { LogGroupRef } from './log-group'; +import { ILogGroup } from './log-group'; import { CfnLogStream } from './logs.generated'; -/** - * Properties for importing a LogStream - */ -export interface LogStreamRefProps { - logStreamName: string; -} - -/** - * A Log Stream in a Log Group - */ -export abstract class LogStreamRef extends cdk.Construct { - /** - * Import an existing LogGroup - */ - public static import(parent: cdk.Construct, id: string, props: LogStreamRefProps): LogStreamRef { - return new ImportedLogStream(parent, id, props); - } - +export interface ILogStream { /** * The name of this log stream */ - public abstract readonly logStreamName: string; + readonly logStreamName: string; /** * Export this LogStream */ - public export(): LogStreamRefProps { - return { - logStreamName: new cdk.Output(this, 'LogStreamName', { value: this.logStreamName }).makeImportValue().toString() - }; - } + export(): LogStreamAttributes; +} + +/** + * Properties for importing a LogStream + */ +export interface LogStreamAttributes { + logStreamName: string; } /** @@ -42,7 +28,7 @@ export interface LogStreamProps { /** * The log group to create a log stream for. */ - logGroup: LogGroupRef; + logGroup: ILogGroup; /** * The name of the log stream to create. @@ -70,7 +56,14 @@ export interface LogStreamProps { /** * Define a Log Stream in a Log Group */ -export class LogStream extends LogStreamRef { +export class LogStream extends cdk.Construct implements ILogStream { + /** + * Import an existing LogGroup + */ + public static import(parent: cdk.Construct, id: string, props: LogStreamAttributes): ILogStream { + return new ImportedLogStream(parent, id, props); + } + /** * The name of this log stream */ @@ -90,20 +83,33 @@ export class LogStream extends LogStreamRef { this.logStreamName = resource.logStreamName; } + + /** + * Export this LogStream + */ + public export(): LogStreamAttributes { + return { + logStreamName: new cdk.Output(this, 'LogStreamName', { value: this.logStreamName }).makeImportValue().toString() + }; + } } /** * An imported LogStream */ -class ImportedLogStream extends LogStreamRef { +class ImportedLogStream extends cdk.Construct implements ILogStream { /** * The name of this log stream */ public readonly logStreamName: string; - constructor(parent: cdk.Construct, id: string, props: LogStreamRefProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: LogStreamAttributes) { super(parent, id); this.logStreamName = props.logStreamName; } + + public export() { + return this.props; + } } diff --git a/packages/@aws-cdk/aws-logs/lib/metric-filter.ts b/packages/@aws-cdk/aws-logs/lib/metric-filter.ts index 9e3881df94b54..797273e241613 100644 --- a/packages/@aws-cdk/aws-logs/lib/metric-filter.ts +++ b/packages/@aws-cdk/aws-logs/lib/metric-filter.ts @@ -1,5 +1,5 @@ import cdk = require('@aws-cdk/cdk'); -import { LogGroupRef } from './log-group'; +import { ILogGroup } from './log-group'; import { CfnMetricFilter } from './logs.generated'; import { IFilterPattern } from './pattern'; @@ -10,7 +10,7 @@ export interface MetricFilterProps { /** * The log group to create the filter on. */ - logGroup: LogGroupRef; + logGroup: ILogGroup; /** * Pattern to search for log events. diff --git a/packages/@aws-cdk/aws-logs/lib/subscription-filter.ts b/packages/@aws-cdk/aws-logs/lib/subscription-filter.ts index c5f7850807ce0..e85ee7986076c 100644 --- a/packages/@aws-cdk/aws-logs/lib/subscription-filter.ts +++ b/packages/@aws-cdk/aws-logs/lib/subscription-filter.ts @@ -1,6 +1,6 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { LogGroupRef } from './log-group'; +import { ILogGroup } from './log-group'; import { CfnSubscriptionFilter } from './logs.generated'; import { IFilterPattern } from './pattern'; @@ -18,7 +18,7 @@ export interface ILogSubscriptionDestination { * The destination may reconfigure its own permissions in response to this * function call. */ - logSubscriptionDestination(sourceLogGroup: LogGroupRef): LogSubscriptionDestination; + logSubscriptionDestination(sourceLogGroup: ILogGroup): LogSubscriptionDestination; } /** @@ -45,7 +45,7 @@ export interface SubscriptionFilterProps { /** * The log group to create the subscription on. */ - logGroup: LogGroupRef; + logGroup: ILogGroup; /** * The destination to send the filtered events to. diff --git a/packages/@aws-cdk/aws-logs/test/test.loggroup.ts b/packages/@aws-cdk/aws-logs/test/test.loggroup.ts index bbfb3c88970b7..f23d3b16f8002 100644 --- a/packages/@aws-cdk/aws-logs/test/test.loggroup.ts +++ b/packages/@aws-cdk/aws-logs/test/test.loggroup.ts @@ -2,7 +2,7 @@ import { expect, haveResource, matchTemplate } from '@aws-cdk/assert'; import iam = require('@aws-cdk/aws-iam'); import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { LogGroup, LogGroupRef } from '../lib'; +import { LogGroup } from '../lib'; export = { 'fixed retention'(test: Test) { @@ -86,7 +86,7 @@ export = { const stack2 = new Stack(); // WHEN - const imported = LogGroupRef.import(stack2, 'Import', lg.export()); + const imported = LogGroup.import(stack2, 'Import', lg.export()); imported.newStream(stack2, 'MakeMeAStream'); // THEN diff --git a/packages/@aws-cdk/aws-logs/test/test.subscriptionfilter.ts b/packages/@aws-cdk/aws-logs/test/test.subscriptionfilter.ts index 2eea9d0b37ba6..6002b3681d452 100644 --- a/packages/@aws-cdk/aws-logs/test/test.subscriptionfilter.ts +++ b/packages/@aws-cdk/aws-logs/test/test.subscriptionfilter.ts @@ -1,7 +1,7 @@ import { expect, haveResource } from '@aws-cdk/assert'; import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { FilterPattern, ILogSubscriptionDestination, LogGroup, LogGroupRef, SubscriptionFilter } from '../lib'; +import { FilterPattern, ILogGroup, ILogSubscriptionDestination, LogGroup, SubscriptionFilter } from '../lib'; export = { 'trivial instantiation'(test: Test) { @@ -28,7 +28,7 @@ export = { }; class FakeDestination implements ILogSubscriptionDestination { - public logSubscriptionDestination(_sourceLogGroup: LogGroupRef) { + public logSubscriptionDestination(_sourceLogGroup: ILogGroup) { return { arn: 'arn:bogus', }; diff --git a/packages/@aws-cdk/aws-quickstarts/lib/database.ts b/packages/@aws-cdk/aws-quickstarts/lib/database.ts index 7ef5ef5a04e46..03c7c8e4aa788 100644 --- a/packages/@aws-cdk/aws-quickstarts/lib/database.ts +++ b/packages/@aws-cdk/aws-quickstarts/lib/database.ts @@ -10,7 +10,7 @@ export interface SqlServerProps { masterUsername: string; masterPassword: string; allocatedStorage?: number; - vpc: ec2.VpcNetworkRef; + vpc: ec2.IVpcNetwork; } /** diff --git a/packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts b/packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts index e1832d83fb9b5..0855618af1117 100644 --- a/packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts +++ b/packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts @@ -4,7 +4,7 @@ import cdk = require('@aws-cdk/cdk'); export interface RemoteDesktopGatewayProps { rdgwCIDR: string; - vpc: ec2.VpcNetworkRef; + vpc: ec2.IVpcNetwork; keyPairName: string; adminPassword: string; @@ -47,7 +47,7 @@ export class RemoteDesktopGateway extends cdk.Construct implements ec2.IConnecta parameters: params }); - const securityGroup = ec2.SecurityGroupRef.import(this, 'SecurityGroup', { + const securityGroup = ec2.SecurityGroup.import(this, 'SecurityGroup', { securityGroupId: nestedStack.getAtt('Outputs.RemoteDesktopGatewaySGID').toString() }); diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group-ref.ts b/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group-ref.ts deleted file mode 100644 index 5d6cc27131c50..0000000000000 --- a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group-ref.ts +++ /dev/null @@ -1,46 +0,0 @@ -import cdk = require('@aws-cdk/cdk'); - -/** - * A cluster parameter group - */ -export abstract class ClusterParameterGroupRef extends cdk.Construct { - /** - * Import a parameter group - */ - public static import(parent: cdk.Construct, id: string, props: ClusterParameterGroupRefProps): ClusterParameterGroupRef { - return new ImportedClusterParameterGroup(parent, id, props); - } - - /** - * Name of this parameter group - */ - public abstract readonly parameterGroupName: string; - - /** - * Export this parameter group - */ - public export(): ClusterParameterGroupRefProps { - return { - parameterGroupName: new cdk.Output(this, 'ParameterGroupName', { value: this.parameterGroupName }).makeImportValue().toString() - }; - } -} - -/** - * Properties to reference a cluster parameter group - */ -export interface ClusterParameterGroupRefProps { - parameterGroupName: string; -} - -/** - * An imported cluster parameter group - */ -class ImportedClusterParameterGroup extends ClusterParameterGroupRef { - public readonly parameterGroupName: string; - - constructor(parent: cdk.Construct, id: string, props: ClusterParameterGroupRefProps) { - super(parent, id); - this.parameterGroupName = props.parameterGroupName; - } -} diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts b/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts index 0b59400fc5c5c..ae17339a1a768 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts @@ -1,8 +1,29 @@ import cdk = require('@aws-cdk/cdk'); -import { ClusterParameterGroupRef } from './cluster-parameter-group-ref'; import { Parameters } from './props'; import { CfnDBClusterParameterGroup } from './rds.generated'; +/** + * A cluster parameter group + */ +export interface IClusterParameterGroup { + /** + * Name of this parameter group + */ + readonly parameterGroupName: string; + + /** + * Export this parameter group + */ + export(): ClusterParameterGroupAttributes; +} + +/** + * Properties to reference a cluster parameter group + */ +export interface ClusterParameterGroupAttributes { + parameterGroupName: string; +} + /** * Properties for a cluster parameter group */ @@ -26,7 +47,14 @@ export interface ClusterParameterGroupProps { /** * Defina a cluster parameter group */ -export class ClusterParameterGroup extends ClusterParameterGroupRef { +export class ClusterParameterGroup extends cdk.Construct implements IClusterParameterGroup { + /** + * Import a parameter group + */ + public static import(parent: cdk.Construct, id: string, props: ClusterParameterGroupAttributes): IClusterParameterGroup { + return new ImportedClusterParameterGroup(parent, id, props); + } + public readonly parameterGroupName: string; private readonly parameters: Parameters = {}; @@ -46,6 +74,15 @@ export class ClusterParameterGroup extends ClusterParameterGroupRef { this.parameterGroupName = resource.ref; } + /** + * Export this parameter group + */ + public export(): ClusterParameterGroupAttributes { + return { + parameterGroupName: new cdk.Output(this, 'ParameterGroupName', { value: this.parameterGroupName }).makeImportValue().toString() + }; + } + /** * Set a single parameter in this parameter group */ @@ -75,3 +112,19 @@ export class ClusterParameterGroup extends ClusterParameterGroupRef { return []; } } + +/** + * An imported cluster parameter group + */ +class ImportedClusterParameterGroup extends cdk.Construct implements IClusterParameterGroup { + public readonly parameterGroupName: string; + + constructor(parent: cdk.Construct, id: string, private readonly props: ClusterParameterGroupAttributes) { + super(parent, id); + this.parameterGroupName = props.parameterGroupName; + } + + public export() { + return this.props; + } +} diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts index 5f7d6409a87ee..6b2195d6198e2 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts @@ -1,74 +1,54 @@ import ec2 = require('@aws-cdk/aws-ec2'); -import cdk = require('@aws-cdk/cdk'); /** * Create a clustered database with a given number of instances. */ -export abstract class DatabaseClusterRef extends cdk.Construct implements ec2.IConnectable { - /** - * Import an existing DatabaseCluster from properties - */ - public static import(parent: cdk.Construct, name: string, props: DatabaseClusterRefProps): DatabaseClusterRef { - return new ImportedDatabaseCluster(parent, name, props); - } - +export interface IDatabaseCluster extends ec2.IConnectable { /** * Access to the network connections */ - public abstract readonly connections: ec2.Connections; + readonly connections: ec2.Connections; /** * Identifier of the cluster */ - public abstract readonly clusterIdentifier: string; + readonly clusterIdentifier: string; /** * Identifiers of the replicas */ - public abstract readonly instanceIdentifiers: string[] = []; + readonly instanceIdentifiers: string[]; /** * The endpoint to use for read/write operations */ - public abstract readonly clusterEndpoint: Endpoint; + readonly clusterEndpoint: Endpoint; /** * Endpoint to use for load-balanced read-only operations. */ - public abstract readonly readerEndpoint: Endpoint; + readonly readerEndpoint: Endpoint; /** * Endpoints which address each individual replica. */ - public abstract readonly instanceEndpoints: Endpoint[] = []; + readonly instanceEndpoints: Endpoint[]; /** * The security group for this database cluster */ - protected abstract readonly securityGroupId: string; + readonly securityGroupId: string; /** * Export a Database Cluster for importing in another stack */ - public export(): DatabaseClusterRefProps { - // tslint:disable:max-line-length - return { - port: new cdk.Output(this, 'Port', { value: this.clusterEndpoint.port, }).makeImportValue().toString(), - securityGroupId: new cdk.Output(this, 'SecurityGroupId', { value: this.securityGroupId, }).makeImportValue().toString(), - clusterIdentifier: new cdk.Output(this, 'ClusterIdentifier', { value: this.clusterIdentifier, }).makeImportValue().toString(), - instanceIdentifiers: new cdk.StringListOutput(this, 'InstanceIdentifiers', { values: this.instanceIdentifiers }).makeImportValues().map(x => x.toString()), - clusterEndpointAddress: new cdk.Output(this, 'ClusterEndpointAddress', { value: this.clusterEndpoint.hostname, }).makeImportValue().toString(), - readerEndpointAddress: new cdk.Output(this, 'ReaderEndpointAddress', { value: this.readerEndpoint.hostname, }).makeImportValue().toString(), - instanceEndpointAddresses: new cdk.StringListOutput(this, 'InstanceEndpointAddresses', { values: this.instanceEndpoints.map(e => e.hostname) }).makeImportValues().map(x => x.toString()), - }; - // tslint:enable:max-line-length - } + export(): DatabaseClusterAttributes; } /** * Properties that describe an existing cluster instance */ -export interface DatabaseClusterRefProps { +export interface DatabaseClusterAttributes { /** * The database port */ @@ -106,66 +86,6 @@ export interface DatabaseClusterRefProps { instanceEndpointAddresses: string[]; } -/** - * An imported Database Cluster - */ -class ImportedDatabaseCluster extends DatabaseClusterRef { - /** - * Default port to connect to this database - */ - public readonly defaultPortRange: ec2.IPortRange; - - /** - * Access to the network connections - */ - public readonly connections: ec2.Connections; - - /** - * Identifier of the cluster - */ - public readonly clusterIdentifier: string; - - /** - * Identifiers of the replicas - */ - public readonly instanceIdentifiers: string[] = []; - - /** - * The endpoint to use for read/write operations - */ - public readonly clusterEndpoint: Endpoint; - - /** - * Endpoint to use for load-balanced read-only operations. - */ - public readonly readerEndpoint: Endpoint; - - /** - * Endpoints which address each individual replica. - */ - public readonly instanceEndpoints: Endpoint[] = []; - - /** - * Security group identifier of this database - */ - protected readonly securityGroupId: string; - - constructor(parent: cdk.Construct, name: string, props: DatabaseClusterRefProps) { - super(parent, name); - - this.securityGroupId = props.securityGroupId; - this.defaultPortRange = new ec2.TcpPortFromAttribute(props.port); - this.connections = new ec2.Connections({ - securityGroups: [ec2.SecurityGroupRef.import(this, 'SecurityGroup', props)], - defaultPortRange: this.defaultPortRange - }); - this.clusterIdentifier = props.clusterIdentifier; - this.clusterEndpoint = new Endpoint(props.clusterEndpointAddress, props.port); - this.readerEndpoint = new Endpoint(props.readerEndpointAddress, props.port); - this.instanceEndpoints = props.instanceEndpointAddresses.map(a => new Endpoint(a, props.port)); - } -} - /** * Connection endpoint of a database cluster or instance * diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index 7d2d357ee096d..705a9370cc222 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -1,7 +1,7 @@ import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); -import { ClusterParameterGroupRef } from './cluster-parameter-group-ref'; -import { DatabaseClusterRef, Endpoint } from './cluster-ref'; +import { IClusterParameterGroup } from './cluster-parameter-group'; +import { DatabaseClusterAttributes, Endpoint, IDatabaseCluster } from './cluster-ref'; import { BackupProps, DatabaseClusterEngine, InstanceProps, Login } from './props'; import { CfnDBCluster, CfnDBInstance, CfnDBSubnetGroup } from './rds.generated'; @@ -87,13 +87,20 @@ export interface DatabaseClusterProps { * * @default No parameter group */ - parameterGroup?: ClusterParameterGroupRef; + parameterGroup?: IClusterParameterGroup; } /** * Create a clustered database with a given number of instances. */ -export class DatabaseCluster extends DatabaseClusterRef { +export class DatabaseCluster extends cdk.Construct implements IDatabaseCluster { + /** + * Import an existing DatabaseCluster from properties + */ + public static import(parent: cdk.Construct, name: string, props: DatabaseClusterAttributes): IDatabaseCluster { + return new ImportedDatabaseCluster(parent, name, props); + } + /** * Identifier of the cluster */ @@ -127,7 +134,7 @@ export class DatabaseCluster extends DatabaseClusterRef { /** * Security group identifier of this database */ - protected readonly securityGroupId: string; + public readonly securityGroupId: string; constructor(parent: cdk.Construct, name: string, props: DatabaseClusterProps) { super(parent, name); @@ -215,6 +222,23 @@ export class DatabaseCluster extends DatabaseClusterRef { const defaultPortRange = new ec2.TcpPortFromAttribute(this.clusterEndpoint.port); this.connections = new ec2.Connections({ securityGroups: [securityGroup], defaultPortRange }); } + + /** + * Export a Database Cluster for importing in another stack + */ + public export(): DatabaseClusterAttributes { + // tslint:disable:max-line-length + return { + port: new cdk.Output(this, 'Port', { value: this.clusterEndpoint.port, }).makeImportValue().toString(), + securityGroupId: new cdk.Output(this, 'SecurityGroupId', { value: this.securityGroupId, }).makeImportValue().toString(), + clusterIdentifier: new cdk.Output(this, 'ClusterIdentifier', { value: this.clusterIdentifier, }).makeImportValue().toString(), + instanceIdentifiers: new cdk.StringListOutput(this, 'InstanceIdentifiers', { values: this.instanceIdentifiers }).makeImportValues().map(x => x.toString()), + clusterEndpointAddress: new cdk.Output(this, 'ClusterEndpointAddress', { value: this.clusterEndpoint.hostname, }).makeImportValue().toString(), + readerEndpointAddress: new cdk.Output(this, 'ReaderEndpointAddress', { value: this.readerEndpoint.hostname, }).makeImportValue().toString(), + instanceEndpointAddresses: new cdk.StringListOutput(this, 'InstanceEndpointAddresses', { values: this.instanceEndpoints.map(e => e.hostname) }).makeImportValues().map(x => x.toString()), + }; + // tslint:enable:max-line-length + } } /** @@ -223,3 +247,67 @@ export class DatabaseCluster extends DatabaseClusterRef { function databaseInstanceType(instanceType: ec2.InstanceType) { return 'db.' + instanceType.toString(); } + +/** + * An imported Database Cluster + */ +class ImportedDatabaseCluster extends cdk.Construct implements IDatabaseCluster { + /** + * Default port to connect to this database + */ + public readonly defaultPortRange: ec2.IPortRange; + + /** + * Access to the network connections + */ + public readonly connections: ec2.Connections; + + /** + * Identifier of the cluster + */ + public readonly clusterIdentifier: string; + + /** + * Identifiers of the replicas + */ + public readonly instanceIdentifiers: string[] = []; + + /** + * The endpoint to use for read/write operations + */ + public readonly clusterEndpoint: Endpoint; + + /** + * Endpoint to use for load-balanced read-only operations. + */ + public readonly readerEndpoint: Endpoint; + + /** + * Endpoints which address each individual replica. + */ + public readonly instanceEndpoints: Endpoint[] = []; + + /** + * Security group identifier of this database + */ + public readonly securityGroupId: string; + + constructor(parent: cdk.Construct, name: string, private readonly props: DatabaseClusterAttributes) { + super(parent, name); + + this.securityGroupId = props.securityGroupId; + this.defaultPortRange = new ec2.TcpPortFromAttribute(props.port); + this.connections = new ec2.Connections({ + securityGroups: [ec2.SecurityGroup.import(this, 'SecurityGroup', props)], + defaultPortRange: this.defaultPortRange + }); + this.clusterIdentifier = props.clusterIdentifier; + this.clusterEndpoint = new Endpoint(props.clusterEndpointAddress, props.port); + this.readerEndpoint = new Endpoint(props.readerEndpointAddress, props.port); + this.instanceEndpoints = props.instanceEndpointAddresses.map(a => new Endpoint(a, props.port)); + } + + public export() { + return this.props; + } +} diff --git a/packages/@aws-cdk/aws-rds/lib/index.ts b/packages/@aws-cdk/aws-rds/lib/index.ts index abd9739d1f8f1..4a0f2ed04ee88 100644 --- a/packages/@aws-cdk/aws-rds/lib/index.ts +++ b/packages/@aws-cdk/aws-rds/lib/index.ts @@ -3,7 +3,6 @@ export * from './cluster-ref'; export * from './instance'; export * from './props'; export * from './cluster-parameter-group'; -export * from './cluster-parameter-group-ref'; // AWS::RDS CloudFormation Resources: export * from './rds.generated'; diff --git a/packages/@aws-cdk/aws-rds/lib/props.ts b/packages/@aws-cdk/aws-rds/lib/props.ts index 16a6fb0460a22..f36afe4521cc6 100644 --- a/packages/@aws-cdk/aws-rds/lib/props.ts +++ b/packages/@aws-cdk/aws-rds/lib/props.ts @@ -24,7 +24,7 @@ export interface InstanceProps { * * Must be at least 2 subnets in two different AZs. */ - vpc: ec2.VpcNetworkRef; + vpc: ec2.IVpcNetwork; /** * Where to place the instances within the VPC diff --git a/packages/@aws-cdk/aws-rds/test/test.cluster.ts b/packages/@aws-cdk/aws-rds/test/test.cluster.ts index afd49e94d6da3..fad6e775c460a 100644 --- a/packages/@aws-cdk/aws-rds/test/test.cluster.ts +++ b/packages/@aws-cdk/aws-rds/test/test.cluster.ts @@ -2,7 +2,7 @@ import { expect, haveResource } from '@aws-cdk/assert'; import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); import { Test } from 'nodeunit'; -import { ClusterParameterGroup, DatabaseCluster, DatabaseClusterEngine, DatabaseClusterRef } from '../lib'; +import { ClusterParameterGroup, DatabaseCluster, DatabaseClusterEngine } from '../lib'; export = { 'check that instantiation works'(test: Test) { @@ -52,7 +52,7 @@ export = { }); // WHEN - DatabaseClusterRef.import(stack2, 'Database', cluster.export()); + DatabaseCluster.import(stack2, 'Database', cluster.export()); // THEN: No error diff --git a/packages/@aws-cdk/aws-route53/README.md b/packages/@aws-cdk/aws-route53/README.md index 2501ba578e22e..6476432160805 100644 --- a/packages/@aws-cdk/aws-route53/README.md +++ b/packages/@aws-cdk/aws-route53/README.md @@ -49,7 +49,7 @@ new route53.TXTRecord(zone, 'TXTRecord', { If you know the ID and Name of a Hosted Zone, you can import it directly: ```ts -const zone = HostedZoneRef.import(this, 'MyZone', { +const zone = HostedZone.import(this, 'MyZone', { zoneName: 'example.com', hostedZoneId: 'ZOJJZC49E0EPZ', }); diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts index fc3d01bf88e2f..19bddd9a95fd8 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts @@ -1,6 +1,7 @@ import cdk = require('@aws-cdk/cdk'); import cxapi = require('@aws-cdk/cx-api'); -import { HostedZoneRef, HostedZoneRefProps } from './hosted-zone-ref'; +import { HostedZone } from './hosted-zone'; +import { HostedZoneAttributes, IHostedZone } from './hosted-zone-ref'; /** * Zone properties for looking up the Hosted Zone @@ -39,13 +40,13 @@ export class HostedZoneProvider { /** * This method calls `findHostedZone` and returns the imported `HostedZoneRef` */ - public findAndImport(parent: cdk.Construct, id: string): HostedZoneRef { - return HostedZoneRef.import(parent, id, this.findHostedZone()); + public findAndImport(parent: cdk.Construct, id: string): IHostedZone { + return HostedZone.import(parent, id, this.findHostedZone()); } /** * Return the hosted zone meeting the filter */ - public findHostedZone(): HostedZoneRefProps { + public findHostedZone(): HostedZoneAttributes { const zone = this.provider.getValue(DEFAULT_HOSTED_ZONE) as HostedZoneContextResponse; // CDK handles the '.' at the end, so remove it here if (zone.Name.endsWith('.')) { diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts index 4810d5572c3ec..807a66fd776d1 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts @@ -1,38 +1,27 @@ -import { Construct, Output } from "@aws-cdk/cdk"; - /** * Imported or created hosted zone */ -export abstract class HostedZoneRef extends Construct { - public static import(parent: Construct, name: string, props: HostedZoneRefProps): HostedZoneRef { - return new ImportedHostedZone(parent, name, props); - } - +export interface IHostedZone { /** * ID of this hosted zone */ - public abstract readonly hostedZoneId: string; + readonly hostedZoneId: string; /** * FQDN of this hosted zone */ - public abstract readonly zoneName: string; + readonly zoneName: string; /** * Export the hosted zone */ - public export(): HostedZoneRefProps { - return { - hostedZoneId: new Output(this, 'HostedZoneId', { value: this.hostedZoneId }).makeImportValue().toString(), - zoneName: this.zoneName, - }; - } + export(): HostedZoneAttributes; } /** * Reference to a hosted zone */ -export interface HostedZoneRefProps { +export interface HostedZoneAttributes { /** * Identifier of the hosted zone */ @@ -43,19 +32,3 @@ export interface HostedZoneRefProps { */ zoneName: string; } - -/** - * Imported hosted zone - */ -export class ImportedHostedZone extends HostedZoneRef { - public readonly hostedZoneId: string; - - public readonly zoneName: string; - - constructor(parent: Construct, name: string, props: HostedZoneRefProps) { - super(parent, name); - - this.hostedZoneId = props.hostedZoneId; - this.zoneName = props.zoneName; - } -} diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index 4a5a76aa59bb2..edfaa6ac0d929 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts @@ -1,6 +1,6 @@ import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); -import { HostedZoneRef } from './hosted-zone-ref'; +import { HostedZoneAttributes, IHostedZone } from './hosted-zone-ref'; import { CfnHostedZone, HostedZoneNameServers } from './route53.generated'; import { validateZoneName } from './util'; @@ -28,10 +28,26 @@ export interface PublicHostedZoneProps { queryLogsLogGroupArn?: string; } +export abstract class HostedZone extends cdk.Construct implements IHostedZone { + public static import(parent: cdk.Construct, name: string, props: HostedZoneAttributes): IHostedZone { + return new ImportedHostedZone(parent, name, props); + } + + public abstract hostedZoneId: string; + public abstract zoneName: string; + + public export(): HostedZoneAttributes { + return { + hostedZoneId: new cdk.Output(this, 'HostedZoneId', { value: this.hostedZoneId }).makeImportValue().toString(), + zoneName: this.zoneName, + }; + } +} + /** * Create a Route53 public hosted zone. */ -export class PublicHostedZone extends HostedZoneRef { +export class PublicHostedZone extends HostedZone { /** * Identifier of this hosted zone */ @@ -69,7 +85,7 @@ export interface PrivateHostedZoneProps extends PublicHostedZoneProps { /** * One VPC that you want to associate with this hosted zone. */ - vpc: ec2.VpcNetworkRef; + vpc: ec2.IVpcNetwork; } /** @@ -78,7 +94,7 @@ export interface PrivateHostedZoneProps extends PublicHostedZoneProps { * Note that `enableDnsHostnames` and `enableDnsSupport` must have been enabled * for the VPC you're configuring for private hosted zones. */ -export class PrivateHostedZone extends HostedZoneRef { +export class PrivateHostedZone extends HostedZone { /** * Identifier of this hosted zone */ @@ -115,12 +131,12 @@ export class PrivateHostedZone extends HostedZoneRef { * * @param vpc the other VPC to add. */ - public addVpc(vpc: ec2.VpcNetworkRef) { + public addVpc(vpc: ec2.IVpcNetwork) { this.vpcs.push(toVpcProperty(vpc)); } } -function toVpcProperty(vpc: ec2.VpcNetworkRef): CfnHostedZone.VPCProperty { +function toVpcProperty(vpc: ec2.IVpcNetwork): CfnHostedZone.VPCProperty { return { vpcId: vpc.vpcId, vpcRegion: cdk.Aws.region }; } @@ -131,3 +147,23 @@ function determineHostedZoneProps(props: PublicHostedZoneProps) { return { name, hostedZoneConfig, queryLoggingConfig }; } + +/** + * Imported hosted zone + */ +class ImportedHostedZone extends cdk.Construct implements IHostedZone { + public readonly hostedZoneId: string; + + public readonly zoneName: string; + + constructor(parent: cdk.Construct, name: string, private readonly props: HostedZoneAttributes) { + super(parent, name); + + this.hostedZoneId = props.hostedZoneId; + this.zoneName = props.zoneName; + } + + public export() { + return this.props; + } +} diff --git a/packages/@aws-cdk/aws-route53/lib/records/_util.ts b/packages/@aws-cdk/aws-route53/lib/records/_util.ts index 53747dece7848..b51a2f89620a8 100644 --- a/packages/@aws-cdk/aws-route53/lib/records/_util.ts +++ b/packages/@aws-cdk/aws-route53/lib/records/_util.ts @@ -1,4 +1,4 @@ -import { HostedZoneRef } from '../hosted-zone-ref'; +import { IHostedZone } from '../hosted-zone-ref'; /** * Route53 requires the record names are specified as fully qualified names, but this @@ -15,7 +15,7 @@ import { HostedZoneRef } from '../hosted-zone-ref'; *
  • Otherwise, append +.+, +zoneName+ and a trailing +.+
  • * */ -export function determineFullyQualifiedDomainName(providedName: string, hostedZone: HostedZoneRef): string { +export function determineFullyQualifiedDomainName(providedName: string, hostedZone: IHostedZone): string { if (providedName.endsWith('.')) { return providedName; } diff --git a/packages/@aws-cdk/aws-route53/lib/records/alias.ts b/packages/@aws-cdk/aws-route53/lib/records/alias.ts index 57ea706f43338..d861e8bd6caa0 100644 --- a/packages/@aws-cdk/aws-route53/lib/records/alias.ts +++ b/packages/@aws-cdk/aws-route53/lib/records/alias.ts @@ -1,5 +1,5 @@ import { Construct } from '@aws-cdk/cdk'; -import { HostedZoneRef } from '../hosted-zone-ref'; +import { IHostedZone } from '../hosted-zone-ref'; import { CfnRecordSet } from '../route53.generated'; import { determineFullyQualifiedDomainName } from './_util'; @@ -30,6 +30,10 @@ export interface AliasRecordTargetProps { } export interface AliasRecordProps { + /** + * The zone in which this alias should be defined. + */ + zone: IHostedZone; /** * Name for the record. This can be the FQDN for the record (foo.example.com) or * a subdomain of the parent hosted zone (foo, with example.com as the hosted zone). @@ -45,12 +49,12 @@ export interface AliasRecordProps { * A Route53 alias record */ export class AliasRecord extends Construct { - constructor(parent: HostedZoneRef, id: string, props: AliasRecordProps) { + constructor(parent: Construct, id: string, props: AliasRecordProps) { super(parent, id); new CfnRecordSet(this, 'Resource', { - hostedZoneId: parent.hostedZoneId, - name: determineFullyQualifiedDomainName(props.recordName, parent), + hostedZoneId: props.zone.hostedZoneId, + name: determineFullyQualifiedDomainName(props.recordName, props.zone), type: 'A', // ipv4 aliasTarget: props.target.asAliasRecordTarget() }); diff --git a/packages/@aws-cdk/aws-route53/lib/records/txt.ts b/packages/@aws-cdk/aws-route53/lib/records/txt.ts index 7c7c058d4ba73..731b94e3d883a 100644 --- a/packages/@aws-cdk/aws-route53/lib/records/txt.ts +++ b/packages/@aws-cdk/aws-route53/lib/records/txt.ts @@ -1,9 +1,10 @@ import { Construct } from '@aws-cdk/cdk'; -import { HostedZoneRef } from '../hosted-zone-ref'; +import { IHostedZone } from '../hosted-zone-ref'; import { CfnRecordSet } from '../route53.generated'; import { determineFullyQualifiedDomainName } from './_util'; export interface TXTRecordProps { + zone: IHostedZone; recordName: string; recordValue: string; /** @default 1800 seconds */ @@ -14,7 +15,7 @@ export interface TXTRecordProps { * A DNS TXT record */ export class TXTRecord extends Construct { - constructor(parent: HostedZoneRef, name: string, props: TXTRecordProps) { + constructor(parent: Construct, name: string, props: TXTRecordProps) { super(parent, name); // JSON.stringify conveniently wraps strings in " and escapes ". @@ -22,8 +23,8 @@ export class TXTRecord extends Construct { const ttl = props.ttl === undefined ? 1800 : props.ttl; new CfnRecordSet(this, 'Resource', { - hostedZoneId: parent.hostedZoneId, - name: determineFullyQualifiedDomainName(props.recordName, parent), + hostedZoneId: props.zone.hostedZoneId, + name: determineFullyQualifiedDomainName(props.recordName, props.zone), type: 'TXT', resourceRecords: [recordValue], ttl: ttl.toString() diff --git a/packages/@aws-cdk/aws-route53/lib/records/zone-delegation.ts b/packages/@aws-cdk/aws-route53/lib/records/zone-delegation.ts index df7fbcacf7e5b..2b634634005e9 100644 --- a/packages/@aws-cdk/aws-route53/lib/records/zone-delegation.ts +++ b/packages/@aws-cdk/aws-route53/lib/records/zone-delegation.ts @@ -1,9 +1,13 @@ import { Construct } from '@aws-cdk/cdk'; -import { HostedZoneRef } from '../hosted-zone-ref'; +import { IHostedZone } from '../hosted-zone-ref'; import { CfnRecordSet } from '../route53.generated'; import { determineFullyQualifiedDomainName } from './_util'; export interface ZoneDelegationRecordProps { + /** + * The zone in which this delegate is defined. + */ + zone: IHostedZone; /** * The name of the zone that delegation is made to. */ @@ -33,14 +37,14 @@ export interface ZoneDelegationRecordProps { * A record to delegate further lookups to a different set of name servers */ export class ZoneDelegationRecord extends Construct { - constructor(parent: HostedZoneRef, name: string, props: ZoneDelegationRecordProps) { + constructor(parent: Construct, name: string, props: ZoneDelegationRecordProps) { super(parent, name); const ttl = props.ttl === undefined ? 172_800 : props.ttl; new CfnRecordSet(this, 'Resource', { - hostedZoneId: parent.hostedZoneId, - name: determineFullyQualifiedDomainName(props.delegatedZoneName, parent), + hostedZoneId: props.zone.hostedZoneId, + name: determineFullyQualifiedDomainName(props.delegatedZoneName, props.zone), type: 'NS', ttl: ttl.toString(), comment: props.comment, diff --git a/packages/@aws-cdk/aws-route53/test/integ.route53.ts b/packages/@aws-cdk/aws-route53/test/integ.route53.ts index dd20866e2fb9a..f276d80e26aaa 100644 --- a/packages/@aws-cdk/aws-route53/test/integ.route53.ts +++ b/packages/@aws-cdk/aws-route53/test/integ.route53.ts @@ -17,6 +17,7 @@ const publicZone = new PublicHostedZone(stack, 'PublicZone', { }); new TXTRecord(privateZone, 'TXT', { + zone: privateZone, recordName: '_foo', recordValue: 'Bar!', ttl: 60 diff --git a/packages/@aws-cdk/aws-route53/test/test.alias-record.ts b/packages/@aws-cdk/aws-route53/test/test.alias-record.ts index f0eeeffa7bb38..e5344bdd50b87 100644 --- a/packages/@aws-cdk/aws-route53/test/test.alias-record.ts +++ b/packages/@aws-cdk/aws-route53/test/test.alias-record.ts @@ -20,6 +20,7 @@ export = { // WHEN new AliasRecord(zone, 'Alias', { + zone, recordName: '_foo', target }); diff --git a/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts b/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts index a26f57fe36449..4028dfcb9fc0a 100644 --- a/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts +++ b/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts @@ -1,6 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import { Test } from 'nodeunit'; -import { HostedZoneProvider, HostedZoneRef, HostedZoneRefProps } from '../lib'; +import { HostedZone, HostedZoneAttributes, HostedZoneProvider } from '../lib'; export = { 'Hosted Zone Provider': { @@ -24,12 +24,12 @@ export = { stack.setContext(key, fakeZone); - const cdkZoneProps: HostedZoneRefProps = { + const cdkZoneProps: HostedZoneAttributes = { hostedZoneId: fakeZone.Id, zoneName: 'example.com', }; - const cdkZone = HostedZoneRef.import(stack, 'MyZone', cdkZoneProps); + const cdkZone = HostedZone.import(stack, 'MyZone', cdkZoneProps); // WHEN const provider = new HostedZoneProvider(stack, filter); diff --git a/packages/@aws-cdk/aws-route53/test/test.route53.ts b/packages/@aws-cdk/aws-route53/test/test.route53.ts index e82d01b0e4dc5..7cb0c53c9c687 100644 --- a/packages/@aws-cdk/aws-route53/test/test.route53.ts +++ b/packages/@aws-cdk/aws-route53/test/test.route53.ts @@ -2,7 +2,7 @@ import { beASupersetOfTemplate, exactlyMatchTemplate, expect, haveResource } fro import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); import { Test } from 'nodeunit'; -import { HostedZoneRef, PrivateHostedZone, PublicHostedZone, TXTRecord } from '../lib'; +import { HostedZone, PrivateHostedZone, PublicHostedZone, TXTRecord } from '../lib'; export = { 'default properties': { @@ -78,8 +78,9 @@ export = { }); const zoneRef = zone.export(); - const importedZone = HostedZoneRef.import(stack2, 'Imported', zoneRef); - new TXTRecord(importedZone, 'Record', { + const importedZone = HostedZone.import(stack2, 'Imported', zoneRef); + new TXTRecord(importedZone as any, 'Record', { + zone: importedZone, recordName: 'lookHere', recordValue: 'SeeThere' }); diff --git a/packages/@aws-cdk/aws-route53/test/test.txt-record.ts b/packages/@aws-cdk/aws-route53/test/test.txt-record.ts index fd05091176d4b..54b2dc4418d82 100644 --- a/packages/@aws-cdk/aws-route53/test/test.txt-record.ts +++ b/packages/@aws-cdk/aws-route53/test/test.txt-record.ts @@ -8,7 +8,7 @@ export = { TXT(test: Test) { const app = new TestApp(); const zone = new PublicHostedZone(app.stack, 'HostedZone', { zoneName: 'test.public' }); - new TXTRecord(zone, 'TXT', { recordName: '_foo', recordValue: 'Bar!' }); + new TXTRecord(zone, 'TXT', { zone, recordName: '_foo', recordValue: 'Bar!' }); expect(app.synthesizeTemplate()).to(exactlyMatchTemplate({ Resources: { HostedZoneDB99F866: { diff --git a/packages/@aws-cdk/aws-route53/test/test.zone-delegation-record.ts b/packages/@aws-cdk/aws-route53/test/test.zone-delegation-record.ts index 9d49513cbd418..37c437a655f4a 100644 --- a/packages/@aws-cdk/aws-route53/test/test.zone-delegation-record.ts +++ b/packages/@aws-cdk/aws-route53/test/test.zone-delegation-record.ts @@ -9,6 +9,7 @@ export = { const app = new TestApp(); const zone = new PublicHostedZone(app.stack, 'HostedZone', { zoneName: 'test.public' }); new ZoneDelegationRecord(zone, 'NS', { + zone, delegatedZoneName: 'foo', nameServers: ['ns-1777.awsdns-30.co.uk'] }); diff --git a/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts b/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts index a438af1a8b682..2862c450b9cb5 100644 --- a/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts +++ b/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts @@ -16,7 +16,7 @@ export interface BucketDeploymentProps { /** * The S3 bucket to sync the contents of the zip file to. */ - destinationBucket: s3.BucketRef; + destinationBucket: s3.IBucket; /** * Key prefix in the destination bucket. diff --git a/packages/@aws-cdk/aws-s3-deployment/lib/source.ts b/packages/@aws-cdk/aws-s3-deployment/lib/source.ts index 9df095c59722f..61507865c4840 100644 --- a/packages/@aws-cdk/aws-s3-deployment/lib/source.ts +++ b/packages/@aws-cdk/aws-s3-deployment/lib/source.ts @@ -7,7 +7,7 @@ export interface SourceProps { /** * The source bucket to deploy from. */ - bucket: s3.BucketRef; + bucket: s3.IBucket; /** * An S3 object key in the source bucket that points to a zip file. @@ -42,7 +42,7 @@ export class Source { * @param bucket The S3 Bucket * @param zipObjectKey The S3 object key of the zip file with contents */ - public static bucket(bucket: s3.BucketRef, zipObjectKey: string): ISource { + public static bucket(bucket: s3.IBucket, zipObjectKey: string): ISource { return { bind: () => ({ bucket, zipObjectKey }) }; diff --git a/packages/@aws-cdk/aws-s3/lib/bucket-policy.ts b/packages/@aws-cdk/aws-s3/lib/bucket-policy.ts index 3e6e3a7273601..1f9a21a283c33 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket-policy.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket-policy.ts @@ -1,13 +1,13 @@ import { PolicyDocument } from '@aws-cdk/aws-iam'; import { Construct } from '@aws-cdk/cdk'; -import { BucketRef } from './bucket'; +import { IBucket } from './bucket'; import { CfnBucketPolicy } from './s3.generated'; export interface BucketPolicyProps { /** * The Amazon S3 bucket that the policy applies to. */ - bucket: BucketRef; + bucket: IBucket; } /** diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 2a654e7cde16d..8dff14decc9bb 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -11,12 +11,174 @@ import { LifecycleRule } from './rule'; import { CfnBucket } from './s3.generated'; import { parseBucketArn, parseBucketName } from './util'; +export interface IBucket { + /** + * The ARN of the bucket. + */ + readonly bucketArn: string; + + /** + * The name of the bucket. + */ + readonly bucketName: string; + + /** + * The domain of the bucket. + */ + readonly domainName: string; + + /** + * Optional KMS encryption key associated with this bucket. + */ + readonly encryptionKey?: kms.IEncryptionKey; + + /** + * The https:// URL of this bucket. + * @example https://s3.us-west-1.amazonaws.com/onlybucket + * Similar to calling `urlForObject` with no object key. + */ + readonly bucketUrl: string; + + /** + * The resource policy assoicated with this bucket. + * + * If `autoCreatePolicy` is true, a `BucketPolicy` will be created upon the + * first call to addToResourcePolicy(s). + */ + policy?: BucketPolicy; + + /** + * Exports this bucket from the stack. + */ + export(): BucketAttributes; + + /** + * Convenience method for creating a new {@link PipelineSourceAction}, + * and adding it to the given Stage. + * + * @param stage the Pipeline Stage to add the new Action to + * @param name the name of the newly created Action + * @param props the properties of the new Action + * @returns the newly created {@link PipelineSourceAction} + */ + addToPipeline(stage: actions.IStage, name: string, props: CommonPipelineSourceActionProps): PipelineSourceAction; + + /** + * Adds a statement to the resource policy for a principal (i.e. + * account/role/service) to perform actions on this bucket and/or it's + * contents. Use `bucketArn` and `arnForObjects(keys)` to obtain ARNs for + * this bucket or objects. + */ + addToResourcePolicy(permission: iam.PolicyStatement): void; + + /** + * The https URL of an S3 object. For example: + * @example https://s3.us-west-1.amazonaws.com/onlybucket + * @example https://s3.us-west-1.amazonaws.com/bucket/key + * @example https://s3.cn-north-1.amazonaws.com.cn/china-bucket/mykey + * @param key The S3 key of the object. If not specified, the URL of the + * bucket is returned. + * @returns an ObjectS3Url token + */ + urlForObject(key?: string): string; + + /** + * Returns an ARN that represents all objects within the bucket that match + * the key pattern specified. To represent all keys, specify ``"*"``. + * + * If you specify multiple components for keyPattern, they will be concatenated:: + * + * arnForObjects('home/', team, '/', user, '/*') + * + */ + arnForObjects(...keyPattern: string[]): string; + + /** + * Grant read permissions for this bucket and it's contents to an IAM + * principal (Role/Group/User). + * + * If encryption is used, permission to use the key to decrypt the contents + * of the bucket will also be granted to the same principal. + * + * @param identity The principal + * @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*') + */ + grantRead(identity?: iam.IPrincipal, objectsKeyPattern?: any): void; + + /** + * Grant write permissions to this bucket to an IAM principal. + * + * If encryption is used, permission to use the key to encrypt the contents + * of written files will also be granted to the same principal. + * + * @param identity The principal + * @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*') + */ + grantWrite(identity?: iam.IPrincipal, objectsKeyPattern?: any): void; + + /** + * Grants s3:PutObject* and s3:Abort* permissions for this bucket to an IAM principal. + * + * If encryption is used, permission to use the key to encrypt the contents + * of written files will also be granted to the same principal. + * @param identity The principal + * @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*') + */ + grantPut(identity?: iam.IPrincipal, objectsKeyPattern?: any): void; + + /** + * Grants s3:DeleteObject* permission to an IAM pricipal for objects + * in this bucket. + * + * @param identity The principal + * @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*') + */ + grantDelete(identity?: iam.IPrincipal, objectsKeyPattern?: any): void; + + /** + * Grants read/write permissions for this bucket and it's contents to an IAM + * principal (Role/Group/User). + * + * If an encryption key is used, permission to use the key for + * encrypt/decrypt will also be granted. + * + * @param identity The principal + * @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*') + */ + grantReadWrite(identity?: iam.IPrincipal, objectsKeyPattern?: any): void; + + /** + * Allows unrestricted access to objects from this bucket. + * + * IMPORTANT: This permission allows anyone to perform actions on S3 objects + * in this bucket, which is useful for when you configure your bucket as a + * website and want everyone to be able to read objects in the bucket without + * needing to authenticate. + * + * Without arguments, this method will grant read ("s3:GetObject") access to + * all objects ("*") in the bucket. + * + * The method returns the `iam.PolicyStatement` object, which can then be modified + * as needed. For example, you can add a condition that will restrict access only + * to an IPv4 range like this: + * + * const statement = bucket.grantPublicAccess(); + * statement.addCondition('IpAddress', { "aws:SourceIp": "54.240.143.0/24" }); + * + * + * @param keyPrefix the prefix of S3 object keys (e.g. `home/*`). Default is "*". + * @param allowedActions the set of S3 actions to allow. Default is "s3:GetObject". + * @returns The `iam.PolicyStatement` object, which can be used to apply e.g. conditions. + */ + grantPublicAccess(keyPrefix?: string, ...allowedActions: string[]): iam.PolicyStatement; +} + /** * A reference to a bucket. The easiest way to instantiate is to call * `bucket.export()`. Then, the consumer can use `Bucket.import(this, ref)` and * get a `Bucket`. */ -export interface BucketRefProps { +export interface BucketAttributes { /** * The ARN fo the bucket. At least one of bucketArn or bucketName must be * defined in order to initialize a bucket ref. @@ -48,27 +210,15 @@ export interface BucketRefProps { * * Or imported from an existing bucket: * - * BucketRef.import(this, 'MyImportedBucket', { bucketArn: ... }); + * Bucket.import(this, 'MyImportedBucket', { bucketArn: ... }); * * You can also export a bucket and import it into another stack: * * const ref = myBucket.export(); - * BucketRef.import(this, 'MyImportedBucket', ref); + * Bucket.import(this, 'MyImportedBucket', ref); * */ -export abstract class BucketRef extends cdk.Construct { - /** - * Creates a Bucket construct that represents an external bucket. - * - * @param parent The parent creating construct (usually `this`). - * @param name The construct's name. - * @param ref A BucketRefProps object. Can be obtained from a call to - * `bucket.export()`. - */ - public static import(parent: cdk.Construct, name: string, props: BucketRefProps): BucketRef { - return new ImportedBucketRef(parent, name, props); - } - +export abstract class BucketBase extends cdk.Construct implements IBucket { /** * The ARN of the bucket. */ @@ -87,7 +237,7 @@ export abstract class BucketRef extends cdk.Construct { /** * Optional KMS encryption key associated with this bucket. */ - public abstract readonly encryptionKey?: kms.EncryptionKeyRef; + public abstract readonly encryptionKey?: kms.IEncryptionKey; /** * The resource policy assoicated with this bucket. @@ -95,7 +245,7 @@ export abstract class BucketRef extends cdk.Construct { * If `autoCreatePolicy` is true, a `BucketPolicy` will be created upon the * first call to addToResourcePolicy(s). */ - protected abstract policy?: BucketPolicy; + public abstract policy?: BucketPolicy; /** * Indicates if a bucket resource policy should automatically created upon @@ -106,13 +256,7 @@ export abstract class BucketRef extends cdk.Construct { /** * Exports this bucket from the stack. */ - public export(): BucketRefProps { - return { - bucketArn: new cdk.Output(this, 'BucketArn', { value: this.bucketArn }).makeImportValue().toString(), - bucketName: new cdk.Output(this, 'BucketName', { value: this.bucketName }).makeImportValue().toString(), - bucketDomainName: new cdk.Output(this, 'DomainName', { value: this.domainName }).makeImportValue().toString(), - }; - } + public abstract export(): BucketAttributes; /** * Convenience method for creating a new {@link PipelineSourceAction}, @@ -355,7 +499,7 @@ export interface BucketProps { * @default If encryption is set to "Kms" and this property is undefined, a * new KMS key will be created and associated with this bucket. */ - encryptionKey?: kms.EncryptionKeyRef; + encryptionKey?: kms.IEncryptionKey; /** * Physical name of this bucket. @@ -410,13 +554,25 @@ export interface BucketProps { * This bucket does not yet have all features that exposed by the underlying * BucketResource. */ -export class Bucket extends BucketRef { +export class Bucket extends BucketBase { + /** + * Creates a Bucket construct that represents an external bucket. + * + * @param parent The parent creating construct (usually `this`). + * @param name The construct's name. + * @param ref A `BucketAttributes` object. Can be obtained from a call to + * `bucket.export()`. + */ + public static import(parent: cdk.Construct, name: string, props: BucketAttributes): IBucket { + return new ImportedBucket(parent, name, props); + } + public readonly bucketArn: string; public readonly bucketName: string; public readonly domainName: string; public readonly dualstackDomainName: string; - public readonly encryptionKey?: kms.EncryptionKeyRef; - protected policy?: BucketPolicy; + public readonly encryptionKey?: kms.IEncryptionKey; + public policy?: BucketPolicy; protected autoCreatePolicy = true; private readonly lifecycleRules: LifecycleRule[] = []; private readonly versioned?: boolean; @@ -456,6 +612,17 @@ export class Bucket extends BucketRef { } } + /** + * Exports this bucket from the stack. + */ + public export(): BucketAttributes { + return { + bucketArn: new cdk.Output(this, 'BucketArn', { value: this.bucketArn }).makeImportValue().toString(), + bucketName: new cdk.Output(this, 'BucketName', { value: this.bucketName }).makeImportValue().toString(), + bucketDomainName: new cdk.Output(this, 'DomainName', { value: this.domainName }).makeImportValue().toString(), + }; + } + /** * Add a lifecycle rule to the bucket * @@ -524,7 +691,7 @@ export class Bucket extends BucketRef { */ private parseEncryption(props: BucketProps): { bucketEncryption?: CfnBucket.BucketEncryptionProperty, - encryptionKey?: kms.EncryptionKeyRef + encryptionKey?: kms.IEncryptionKey } { // default to unencrypted. @@ -784,16 +951,16 @@ export interface NotificationKeyFilter { suffix?: string; } -class ImportedBucketRef extends BucketRef { +class ImportedBucket extends BucketBase { public readonly bucketArn: string; public readonly bucketName: string; public readonly domainName: string; public readonly encryptionKey?: kms.EncryptionKey; - protected policy?: BucketPolicy; + public policy?: BucketPolicy; protected autoCreatePolicy: boolean; - constructor(parent: cdk.Construct, name: string, props: BucketRefProps) { + constructor(parent: cdk.Construct, name: string, private readonly props: BucketAttributes) { super(parent, name); const bucketName = parseBucketName(props); @@ -808,6 +975,13 @@ class ImportedBucketRef extends BucketRef { this.policy = undefined; } + /** + * Exports this bucket from the stack. + */ + public export() { + return this.props; + } + private generateDomainName() { return `${this.bucketName}.s3.amazonaws.com`; } diff --git a/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts b/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts index a4f03b9c79be5..175bb442e9d8c 100644 --- a/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts @@ -1,6 +1,6 @@ import codepipeline = require('@aws-cdk/aws-codepipeline-api'); import cdk = require('@aws-cdk/cdk'); -import { BucketRef } from './bucket'; +import { IBucket } from './bucket'; /** * Common properties for creating {@link PipelineSourceAction} - @@ -40,7 +40,7 @@ export interface PipelineSourceActionProps extends CommonPipelineSourceActionPro /** * The Amazon S3 bucket that stores the source code */ - bucket: BucketRef; + bucket: IBucket; } /** diff --git a/packages/@aws-cdk/aws-s3/lib/util.ts b/packages/@aws-cdk/aws-s3/lib/util.ts index d75fc4008fd91..a700f63801de2 100644 --- a/packages/@aws-cdk/aws-s3/lib/util.ts +++ b/packages/@aws-cdk/aws-s3/lib/util.ts @@ -1,7 +1,7 @@ import cdk = require('@aws-cdk/cdk'); -import { BucketRefProps } from './bucket'; +import { BucketAttributes } from './bucket'; -export function parseBucketArn(props: BucketRefProps): string { +export function parseBucketArn(props: BucketAttributes): string { // if we have an explicit bucket ARN, use it. if (props.bucketArn) { @@ -22,7 +22,7 @@ export function parseBucketArn(props: BucketRefProps): string { throw new Error('Cannot determine bucket ARN. At least `bucketArn` or `bucketName` is needed'); } -export function parseBucketName(props: BucketRefProps): string | undefined { +export function parseBucketName(props: BucketAttributes): string | undefined { // if we have an explicit bucket name, use it. if (props.bucketName) { diff --git a/packages/@aws-cdk/aws-s3/test/demo.import-export.ts b/packages/@aws-cdk/aws-s3/test/demo.import-export.ts index e30ce772effcd..33d994206aa13 100644 --- a/packages/@aws-cdk/aws-s3/test/demo.import-export.ts +++ b/packages/@aws-cdk/aws-s3/test/demo.import-export.ts @@ -7,7 +7,7 @@ import s3 = require('../lib'); // `Bucket.import`. class Producer extends cdk.Stack { - public readonly myBucketRef: s3.BucketRefProps; + public readonly myBucketRef: s3.BucketAttributes; constructor(parent: cdk.App, name: string) { super(parent, name); @@ -18,7 +18,7 @@ class Producer extends cdk.Stack { } interface ConsumerConstructProps { - bucket: s3.BucketRef; + bucket: s3.IBucket; } class ConsumerConstruct extends cdk.Construct { @@ -35,7 +35,7 @@ class ConsumerConstruct extends cdk.Construct { // this bucket and contents. interface ConsumerProps { - userBucketRef: s3.BucketRefProps; + userBucketRef: s3.BucketAttributes; } class Consumer extends cdk.Stack { diff --git a/packages/@aws-cdk/aws-sns/lib/policy.ts b/packages/@aws-cdk/aws-sns/lib/policy.ts index c1be7dfdfe7b9..a3e0a27d014b5 100644 --- a/packages/@aws-cdk/aws-sns/lib/policy.ts +++ b/packages/@aws-cdk/aws-sns/lib/policy.ts @@ -1,13 +1,13 @@ import { PolicyDocument } from '@aws-cdk/aws-iam'; import { Construct, IDependable } from '@aws-cdk/cdk'; import { CfnTopicPolicy } from './sns.generated'; -import { TopicRef } from './topic-ref'; +import { ITopic } from './topic-ref'; export interface TopicPolicyProps { /** * The set of topics this policy applies to. */ - topics: TopicRef[]; + topics: ITopic[]; } /** diff --git a/packages/@aws-cdk/aws-sns/lib/subscription.ts b/packages/@aws-cdk/aws-sns/lib/subscription.ts index 7202191f13af7..a6043c9a42a24 100644 --- a/packages/@aws-cdk/aws-sns/lib/subscription.ts +++ b/packages/@aws-cdk/aws-sns/lib/subscription.ts @@ -1,6 +1,6 @@ import { Construct } from '@aws-cdk/cdk'; import { CfnSubscription } from './sns.generated'; -import { TopicRef } from './topic-ref'; +import { ITopic } from './topic-ref'; /** * Properties for creating a new subscription @@ -21,13 +21,13 @@ export interface SubscriptionProps { /** * The topic to subscribe to. */ - topic: TopicRef; + topic: ITopic; } /** * A new subscription. * - * Prefer to use the `TopicRef.subscribeXxx()` methods to creating instances of + * Prefer to use the `ITopic.subscribeXxx()` methods to creating instances of * this class. */ export class Subscription extends Construct { diff --git a/packages/@aws-cdk/aws-sns/lib/topic-ref.ts b/packages/@aws-cdk/aws-sns/lib/topic-ref.ts index 0074358b691e1..7f670afb5a756 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic-ref.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic-ref.ts @@ -9,23 +9,117 @@ import cdk = require('@aws-cdk/cdk'); import { TopicPolicy } from './policy'; import { Subscription, SubscriptionProtocol } from './subscription'; -/** - * Either a new or imported Topic - */ -export abstract class TopicRef extends cdk.Construct - implements - events.IEventRuleTarget, - cloudwatch.IAlarmAction, - s3n.IBucketNotificationDestination, - autoscaling_api.ILifecycleHookTarget { +export interface ITopic extends + events.IEventRuleTarget, + cloudwatch.IAlarmAction, + s3n.IBucketNotificationDestination, + autoscaling_api.ILifecycleHookTarget { + + readonly topicArn: string; + + readonly topicName: string; /** - * Import a Topic defined elsewhere + * Export this Topic */ - public static import(parent: cdk.Construct, name: string, props: TopicRefProps): TopicRef { - return new ImportedTopic(parent, name, props); - } + export(): TopicAttributes; + + /** + * Subscribe some endpoint to this topic + */ + subscribe(name: string, endpoint: string, protocol: SubscriptionProtocol): Subscription; + + /** + * Defines a subscription from this SNS topic to an SQS queue. + * + * The queue resource policy will be updated to allow this SNS topic to send + * messages to the queue. + * + * @param name The subscription name + * @param queue The target queue + */ + subscribeQueue(queue: sqs.IQueue): Subscription; + + /** + * Defines a subscription from this SNS Topic to a Lambda function. + * + * The Lambda's resource policy will be updated to allow this topic to + * invoke the function. + * + * @param name A name for the subscription + * @param lambdaFunction The Lambda function to invoke + */ + subscribeLambda(lambdaFunction: lambda.IFunction): Subscription; + + /** + * Defines a subscription from this SNS topic to an email address. + * + * @param name A name for the subscription + * @param emailAddress The email address to use. + * @param jsonFormat True if the email content should be in JSON format (default is false). + */ + subscribeEmail(name: string, emailAddress: string, options?: EmailSubscriptionOptions): Subscription; + + /** + * Defines a subscription from this SNS topic to an http:// or https:// URL. + * + * @param name A name for the subscription + * @param url The URL to invoke + */ + subscribeUrl(name: string, url: string): Subscription; + + /** + * Adds a statement to the IAM resource policy associated with this topic. + * + * If this topic was created in this stack (`new Topic`), a topic policy + * will be automatically created upon the first call to `addToPolicy`. If + * the topic is improted (`Topic.import`), then this is a no-op. + */ + addToResourcePolicy(statement: iam.PolicyStatement): void; + + /** + * Grant topic publishing permissions to the given identity + */ + grantPublish(identity?: iam.IPrincipal): void; + + /** + * Construct a Metric object for the current topic for the given metric + */ + metric(metricName: string, props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + + /** + * Metric for the size of messages published through this topic + * + * @default average over 5 minutes + */ + metricPublishSize(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + /** + * Metric for the number of messages published through this topic + * + * @default sum over 5 minutes + */ + metricNumberOfMessagesPublished(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + + /** + * Metric for the number of messages that failed to publish through this topic + * + * @default sum over 5 minutes + */ + metricNumberOfMessagesFailed(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; + + /** + * Metric for the number of messages that were successfully delivered through this topic + * + * @default sum over 5 minutes + */ + metricNumberOfMessagesDelivered(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; +} + +/** + * Either a new or imported Topic + */ +export abstract class TopicBase extends cdk.Construct implements ITopic { public abstract readonly topicArn: string; public abstract readonly topicName: string; @@ -51,18 +145,13 @@ export abstract class TopicRef extends cdk.Construct /** * Export this Topic */ - public export(): TopicRefProps { - return { - topicArn: new cdk.Output(this, 'TopicArn', { value: this.topicArn }).makeImportValue().toString(), - topicName: new cdk.Output(this, 'TopicName', { value: this.topicName }).makeImportValue().toString(), - }; - } + public abstract export(): TopicAttributes; /** * Subscribe some endpoint to this topic */ - public subscribe(name: string, endpoint: string, protocol: SubscriptionProtocol) { - new Subscription(this, name, { + public subscribe(name: string, endpoint: string, protocol: SubscriptionProtocol): Subscription { + return new Subscription(this, name, { topic: this, endpoint, protocol @@ -75,12 +164,10 @@ export abstract class TopicRef extends cdk.Construct * The queue resource policy will be updated to allow this SNS topic to send * messages to the queue. * - * TODO: change to QueueRef. - * * @param name The subscription name * @param queue The target queue */ - public subscribeQueue(queue: sqs.QueueRef) { + public subscribeQueue(queue: sqs.IQueue): Subscription { const subscriptionName = queue.id + 'Subscription'; if (this.tryFindChild(subscriptionName)) { throw new Error(`A subscription between the topic ${this.id} and the queue ${queue.id} already exists`); @@ -114,7 +201,7 @@ export abstract class TopicRef extends cdk.Construct * @param name A name for the subscription * @param lambdaFunction The Lambda function to invoke */ - public subscribeLambda(lambdaFunction: lambda.FunctionRef) { + public subscribeLambda(lambdaFunction: lambda.IFunction): Subscription { const subscriptionName = lambdaFunction.id + 'Subscription'; if (this.tryFindChild(subscriptionName)) { @@ -142,7 +229,7 @@ export abstract class TopicRef extends cdk.Construct * @param emailAddress The email address to use. * @param jsonFormat True if the email content should be in JSON format (default is false). */ - public subscribeEmail(name: string, emailAddress: string, options?: EmailSubscriptionOptions) { + public subscribeEmail(name: string, emailAddress: string, options?: EmailSubscriptionOptions): Subscription { const protocol = (options && options.json ? SubscriptionProtocol.EmailJson : SubscriptionProtocol.Email); return new Subscription(this, name, { @@ -158,7 +245,7 @@ export abstract class TopicRef extends cdk.Construct * @param name A name for the subscription * @param url The URL to invoke */ - public subscribeUrl(name: string, url: string) { + public subscribeUrl(name: string, url: string): Subscription { if (!url.startsWith('http://') && !url.startsWith('https://')) { throw new Error('URL must start with either http:// or https://'); } @@ -317,26 +404,10 @@ export abstract class TopicRef extends cdk.Construct } } -/** - * An imported topic - */ -class ImportedTopic extends TopicRef { - public readonly topicArn: string; - public readonly topicName: string; - - protected autoCreatePolicy: boolean = false; - - constructor(parent: cdk.Construct, name: string, props: TopicRefProps) { - super(parent, name); - this.topicArn = props.topicArn; - this.topicName = props.topicName; - } -} - /** * Reference to an external topic. */ -export interface TopicRefProps { +export interface TopicAttributes { topicArn: string; topicName: string; } diff --git a/packages/@aws-cdk/aws-sns/lib/topic.ts b/packages/@aws-cdk/aws-sns/lib/topic.ts index 476a2446c6c7d..c379221941341 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic.ts @@ -1,6 +1,6 @@ -import { Construct, } from '@aws-cdk/cdk'; +import { Construct, Output } from '@aws-cdk/cdk'; import { CfnTopic } from './sns.generated'; -import { TopicRef } from './topic-ref'; +import { ITopic, TopicAttributes, TopicBase } from './topic-ref'; /** * Properties for a new SNS topic @@ -28,7 +28,14 @@ export interface TopicProps { /** * A new SNS topic */ -export class Topic extends TopicRef { +export class Topic extends TopicBase { + /** + * Import a Topic defined elsewhere + */ + public static import(parent: Construct, name: string, props: TopicAttributes): ITopic { + return new ImportedTopic(parent, name, props); + } + public readonly topicArn: string; public readonly topicName: string; @@ -45,4 +52,34 @@ export class Topic extends TopicRef { this.topicArn = resource.ref; this.topicName = resource.topicName; } + + /** + * Export this Topic + */ + public export(): TopicAttributes { + return { + topicArn: new Output(this, 'TopicArn', { value: this.topicArn }).makeImportValue().toString(), + topicName: new Output(this, 'TopicName', { value: this.topicName }).makeImportValue().toString(), + }; + } +} + +/** + * An imported topic + */ +class ImportedTopic extends TopicBase { + public readonly topicArn: string; + public readonly topicName: string; + + protected autoCreatePolicy: boolean = false; + + constructor(parent: Construct, name: string, private readonly props: TopicAttributes) { + super(parent, name); + this.topicArn = props.topicArn; + this.topicName = props.topicName; + } + + public export(): TopicAttributes { + return this.props; + } } diff --git a/packages/@aws-cdk/aws-sns/test/test.sns.ts b/packages/@aws-cdk/aws-sns/test/test.sns.ts index 8a59d503cb0bd..9ca00798b18ad 100644 --- a/packages/@aws-cdk/aws-sns/test/test.sns.ts +++ b/packages/@aws-cdk/aws-sns/test/test.sns.ts @@ -677,7 +677,7 @@ export = { // WHEN const ref = topic.export(); - const imported = sns.TopicRef.import(stack2, 'Imported', ref); + const imported = sns.Topic.import(stack2, 'Imported', ref); imported.subscribeQueue(queue); // THEN diff --git a/packages/@aws-cdk/aws-sqs/lib/policy.ts b/packages/@aws-cdk/aws-sqs/lib/policy.ts index e0d7eec007c4d..ba8a69b821a66 100644 --- a/packages/@aws-cdk/aws-sqs/lib/policy.ts +++ b/packages/@aws-cdk/aws-sqs/lib/policy.ts @@ -1,13 +1,13 @@ import { PolicyDocument } from '@aws-cdk/aws-iam'; import { Construct, IDependable } from '@aws-cdk/cdk'; -import { QueueRef } from './queue-ref'; +import { IQueue } from './queue-ref'; import { CfnQueuePolicy } from './sqs.generated'; export interface QueuePolicyProps { /** * The set of queues this policy applies to. */ - queues: QueueRef[]; + queues: IQueue[]; } /** diff --git a/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts b/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts index 7ee4148c3a93c..bab407b81df53 100644 --- a/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts +++ b/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts @@ -5,16 +5,105 @@ import s3n = require('@aws-cdk/aws-s3-notifications'); import cdk = require('@aws-cdk/cdk'); import { QueuePolicy } from './policy'; +export interface IQueue extends s3n.IBucketNotificationDestination, autoscaling_api.ILifecycleHookTarget { + /** + * Local logical ID. + */ + readonly id: string; + + /** + * Unique logical ID. + */ + readonly uniqueId: string; + + /** + * The ARN of this queue + */ + readonly queueArn: string; + + /** + * The URL of this queue + */ + readonly queueUrl: string; + + /** + * If this queue is server-side encrypted, this is the KMS encryption key. + */ + readonly encryptionMasterKey?: kms.IEncryptionKey; + + /** + * Export a queue + */ + export(): QueueAttributes; + + /** + * Adds a statement to the IAM resource policy associated with this queue. + * + * If this queue was created in this stack (`new Queue`), a queue policy + * will be automatically created upon the first call to `addToPolicy`. If + * the queue is improted (`Queue.import`), then this is a no-op. + */ + addToResourcePolicy(statement: iam.PolicyStatement): void; + + /** + * Grant permissions to consume messages from a queue + * + * This will grant the following permissions: + * + * - sqs:ChangeMessageVisibility + * - sqs:ChangeMessageVisibilityBatch + * - sqs:DeleteMessage + * - sqs:ReceiveMessage + * - sqs:DeleteMessageBatch + * - sqs:GetQueueAttributes + * - sqs:GetQueueUrl + * + * @param identity Principal to grant consume rights to + */ + grantConsumeMessages(identity?: iam.IPrincipal): void; + + /** + * Grant access to send messages to a queue to the given identity. + * + * This will grant the following permissions: + * + * - sqs:SendMessage + * - sqs:SendMessageBatch + * - sqs:GetQueueAttributes + * - sqs:GetQueueUrl + * + * @param identity Principal to grant send rights to + */ + grantSendMessages(identity?: iam.IPrincipal): void; + + /** + * Grant an IAM principal permissions to purge all messages from the queue. + * + * This will grant the following permissions: + * + * - sqs:PurgeQueue + * - sqs:GetQueueAttributes + * - sqs:GetQueueUrl + * + * @param identity Principal to grant send rights to + * @param queueActions additional queue actions to allow + */ + grantPurge(identity?: iam.IPrincipal): void; + + /** + * Grant the actions defined in queueActions to the identity Principal given + * on this SQS queue resource. + * + * @param identity Principal to grant right to + * @param queueActions The actions to grant + */ + grant(identity?: iam.IPrincipal, ...queueActions: string[]): void; +} + /** * Reference to a new or existing Amazon SQS queue */ -export abstract class QueueRef extends cdk.Construct implements s3n.IBucketNotificationDestination, autoscaling_api.ILifecycleHookTarget { - /** - * Import an existing queue - */ - public static import(parent: cdk.Construct, name: string, props: QueueRefProps): QueueRef { - return new ImportedQueue(parent, name, props); - } +export abstract class QueueBase extends cdk.Construct implements IQueue { /** * The ARN of this queue @@ -29,7 +118,7 @@ export abstract class QueueRef extends cdk.Construct implements s3n.IBucketNotif /** * If this queue is server-side encrypted, this is the KMS encryption key. */ - public abstract readonly encryptionMasterKey?: kms.EncryptionKeyRef; + public abstract readonly encryptionMasterKey?: kms.IEncryptionKey; /** * Controls automatic creation of policy objects. @@ -48,15 +137,7 @@ export abstract class QueueRef extends cdk.Construct implements s3n.IBucketNotif /** * Export a queue */ - public export(): QueueRefProps { - return { - queueArn: new cdk.Output(this, 'QueueArn', { value: this.queueArn }).makeImportValue().toString(), - queueUrl: new cdk.Output(this, 'QueueUrl', { value: this.queueUrl }).makeImportValue().toString(), - keyArn: this.encryptionMasterKey - ? new cdk.Output(this, 'KeyArn', { value: this.encryptionMasterKey.keyArn }).makeImportValue().toString() - : undefined - }; - } + public abstract export(): QueueAttributes; /** * Adds a statement to the IAM resource policy associated with this queue. @@ -206,7 +287,7 @@ export abstract class QueueRef extends cdk.Construct implements s3n.IBucketNotif /** * Reference to a queue */ -export interface QueueRefProps { +export interface QueueAttributes { /** * The ARN of the queue. */ @@ -217,31 +298,14 @@ export interface QueueRefProps { */ queueUrl: string; + /** + * The name of the queue. + * @default if queue name is not specified, the name will be derived from the queue ARN + */ + queueName?: string; + /** * KMS encryption key, if this queue is server-side encrypted by a KMS key. */ keyArn?: string; } - -/** - * A queue that has been imported - */ -class ImportedQueue extends QueueRef { - public readonly queueArn: string; - public readonly queueUrl: string; - public readonly encryptionMasterKey?: kms.EncryptionKeyRef; - - protected readonly autoCreatePolicy = false; - - constructor(parent: cdk.Construct, name: string, props: QueueRefProps) { - super(parent, name); - this.queueArn = props.queueArn; - this.queueUrl = props.queueUrl; - - if (props.keyArn) { - this.encryptionMasterKey = kms.EncryptionKey.import(this, 'Key', { - keyArn: props.keyArn - }); - } - } -} diff --git a/packages/@aws-cdk/aws-sqs/lib/queue.ts b/packages/@aws-cdk/aws-sqs/lib/queue.ts index f6b633a3ab1fe..2ce032e379a6b 100644 --- a/packages/@aws-cdk/aws-sqs/lib/queue.ts +++ b/packages/@aws-cdk/aws-sqs/lib/queue.ts @@ -1,6 +1,6 @@ import kms = require('@aws-cdk/aws-kms'); import cdk = require('@aws-cdk/cdk'); -import { QueueRef } from './queue-ref'; +import { IQueue, QueueAttributes, QueueBase } from './queue-ref'; import { CfnQueue } from './sqs.generated'; import { validateProps } from './validate-props'; @@ -103,7 +103,7 @@ export interface QueueProps { * * @default If encryption is set to KMS and not specified, a key will be created. */ - encryptionMasterKey?: kms.EncryptionKeyRef; + encryptionMasterKey?: kms.IEncryptionKey; /** * The length of time that Amazon SQS reuses a data key before calling KMS again. @@ -146,7 +146,7 @@ export interface DeadLetterQueue { /** * The dead-letter queue to which Amazon SQS moves messages after the value of maxReceiveCount is exceeded. */ - queue: QueueRef; + queue: IQueue; /** * The number of times a message can be unsuccesfully dequeued before being moved to the dead-letter queue. @@ -179,7 +179,14 @@ export enum QueueEncryption { /** * A new Amazon SQS queue */ -export class Queue extends QueueRef { +export class Queue extends QueueBase { + /** + * Import an existing queue + */ + public static import(parent: cdk.Construct, name: string, props: QueueAttributes): IQueue { + return new ImportedQueue(parent, name, props); + } + /** * The ARN of this queue */ @@ -198,7 +205,7 @@ export class Queue extends QueueRef { /** * If this queue is encrypted, this is the KMS key. */ - public readonly encryptionMasterKey?: kms.EncryptionKeyRef; + public readonly encryptionMasterKey?: kms.IEncryptionKey; protected readonly autoCreatePolicy = true; @@ -232,7 +239,7 @@ export class Queue extends QueueRef { this.queueName = queue.queueName; this.queueUrl = queue.ref; - function _determineEncryptionProps(this: Queue): { encryptionProps: EncryptionProps, encryptionMasterKey?: kms.EncryptionKeyRef } { + function _determineEncryptionProps(this: Queue): { encryptionProps: EncryptionProps, encryptionMasterKey?: kms.IEncryptionKey } { let encryption = props.encryption || QueueEncryption.Unencrypted; if (encryption !== QueueEncryption.Kms && props.encryptionMasterKey) { @@ -275,6 +282,19 @@ export class Queue extends QueueRef { } } + /** + * Export a queue + */ + public export(): QueueAttributes { + return { + queueArn: new cdk.Output(this, 'QueueArn', { value: this.queueArn }).makeImportValue().toString(), + queueUrl: new cdk.Output(this, 'QueueUrl', { value: this.queueUrl }).makeImportValue().toString(), + keyArn: this.encryptionMasterKey + ? new cdk.Output(this, 'KeyArn', { value: this.encryptionMasterKey.keyArn }).makeImportValue().toString() + : undefined + }; + } + /** * Look at the props, see if the FIFO props agree, and return the correct subset of props */ @@ -314,3 +334,33 @@ interface EncryptionProps { readonly kmsMasterKeyId?: string; readonly kmsDataKeyReusePeriodSeconds?: number; } + +/** + * A queue that has been imported + */ +class ImportedQueue extends QueueBase { + public readonly queueArn: string; + public readonly queueUrl: string; + public readonly encryptionMasterKey?: kms.IEncryptionKey; + + protected readonly autoCreatePolicy = false; + + constructor(parent: cdk.Construct, name: string, private readonly props: QueueAttributes) { + super(parent, name); + this.queueArn = props.queueArn; + this.queueUrl = props.queueUrl; + + if (props.keyArn) { + this.encryptionMasterKey = kms.EncryptionKey.import(this, 'Key', { + keyArn: props.keyArn + }); + } + } + + /** + * Export a queue + */ + public export() { + return this.props; + } +} diff --git a/packages/@aws-cdk/aws-sqs/test/test.sqs.ts b/packages/@aws-cdk/aws-sqs/test/test.sqs.ts index d6481db432925..97dfbb399d17e 100644 --- a/packages/@aws-cdk/aws-sqs/test/test.sqs.ts +++ b/packages/@aws-cdk/aws-sqs/test/test.sqs.ts @@ -98,7 +98,7 @@ export = { // WHEN const ref = queue.export(); - const imports = sqs.QueueRef.import(stack, 'Imported', ref); + const imports = sqs.Queue.import(stack, 'Imported', ref); // THEN diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts index 7ac12dfcad853..04f6dcd078550 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts @@ -44,7 +44,7 @@ export class StateMachine extends cdk.Construct implements IStateMachine { /** * Import a state machine */ - public static import(parent: cdk.Construct, id: string, props: ImportedStateMachineProps): IStateMachine { + public static import(parent: cdk.Construct, id: string, props: StateMachineAttributes): IStateMachine { return new ImportedStateMachine(parent, id, props); } @@ -192,7 +192,7 @@ export class StateMachine extends cdk.Construct implements IStateMachine { /** * Export this state machine */ - public export(): ImportedStateMachineProps { + public export(): StateMachineAttributes { return { stateMachineArn: new cdk.Output(this, 'StateMachineArn', { value: this.stateMachineArn }).makeImportValue().toString(), }; @@ -207,12 +207,17 @@ export interface IStateMachine { * The ARN of the state machine */ readonly stateMachineArn: string; + + /** + * Export this state machine + */ + export(): StateMachineAttributes; } /** * Properties for an imported state machine */ -export interface ImportedStateMachineProps { +export interface StateMachineAttributes { /** * The ARN of the state machine */ @@ -221,8 +226,12 @@ export interface ImportedStateMachineProps { class ImportedStateMachine extends cdk.Construct implements IStateMachine { public readonly stateMachineArn: string; - constructor(parent: cdk.Construct, id: string, props: ImportedStateMachineProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: StateMachineAttributes) { super(parent, id); this.stateMachineArn = props.stateMachineArn; } + + public export() { + return this.props; + } } \ No newline at end of file From 7ad4d409cbe5238c63b2da1aaa064e8c4faf5427 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 26 Dec 2018 19:47:48 +0200 Subject: [PATCH 06/26] A few more lints --- design/imports-exports.md | 222 ------------------ packages/@aws-cdk/aws-lambda/lib/alias.ts | 10 +- .../@aws-cdk/aws-lambda/lib/lambda-version.ts | 8 +- packages/@aws-cdk/aws-lambda/lib/lambda.ts | 18 +- packages/@aws-cdk/aws-s3/lib/bucket.ts | 10 +- packages/@aws-cdk/aws-sns/lib/policy.ts | 4 +- packages/@aws-cdk/aws-sns/lib/subscription.ts | 4 +- packages/@aws-cdk/aws-sns/lib/topic.ts | 4 +- 8 files changed, 29 insertions(+), 251 deletions(-) delete mode 100644 design/imports-exports.md diff --git a/design/imports-exports.md b/design/imports-exports.md deleted file mode 100644 index 9bf6aa575c4fc..0000000000000 --- a/design/imports-exports.md +++ /dev/null @@ -1,222 +0,0 @@ -# AWS Construct Library Resource Design Guidelines - -The AWS Construct Library is a rich class library of CDK constructs which -represent all resources offered by the AWS Cloud. - -Resources are organized into modules based on their AWS service. For example, -the **Bucket** resource, which is offered by the Amazon S3 service will be -available under the **aws-s3** module. - -Module and resource names correspond to the AWS CloudFormation naming. For -example, the AWS CloudFormation resource **AWS::S3::Bucket** represents the -module name **S3** and the resource name **Bucket**. - -This document defines the design guidelines for AWS resource constructs. The -purpose of these guidelines is to provide a consistent developer experience -throughout the library. - -For the purpose of this document we will use "**Xxx**" to denote the name of the -resource (i.e. "Bucket", "Queue", "Topic", etc). - -## Resource Attributes - -Every AWS resource has a set of "physical" runtime attributes such as ARN, -physical names, URLs, etc. These attributes are commonly late-bound, which means -they can only be resolved when AWS CloudFormation actually provisions the -resource. - -Resource attributes almost always represent **string** values (URL, ARN, name). -Sometimes they might also represent a **list of strings**. - -Since we want -attributes can either be late-bound ("a promise to a string") or concrete ("a -string"), the AWS CDK has a mechanism called "tokens" which allows codifying -late-bound values into strings or string arrays. This approach was chosen in -order to dramatically simplify the type-system and ergonomics of CDK code. As -long as users treat these attributes as _opaque values_ (e.g. not try to parse -them or manipulate them), they can be used - - -One of the design tenets of the AWS CDK is to be strongly-typed. - -- Runtime attributes should be represented as readonly properties on the resource class. -- Runtime attributes should use a the `string` type if the attribute resolves - -## Resource Properties - - - -## Internal/External Polymorphism - - - - -The following patterns should be implemented by all resource classes in the AWS -Construct Library. - -Terminology: -- "Xxx": represents the CloudFormation resource name (). - -Let's start by defining an interface which represents a resource of the type -"Xxx" (e.g. `Bucket`, `Topic`, `Function`, etc). - -This interface should represent both resources defined within the same stack -(aka "internal", "owned") and existing resources that are defined in another -stack/app (aka "imported", "existing", "external" or "unowned"). Throughout this -document we shall refer to these two types of resources as **"internal"** and -**"external"**. Therefore, this is the recommended type to use in public APIs -that require this resource. - -The interface should include all methods and properties, and extend any other -interfaces that are applicable for both internal and external resources of this -type. - -Here's a template: - -```ts -// extends all interfaces that are applicable for both internal -// and external resources of this type -export interface IXxx extends IFoo, IGoo { - - // attributes - readonly xxxArn: string; - readonly xxxFoo: string; - readonly xxxBar: string; - - // security group connections (if applicable) - readonly connections: ec2.Connections; - - // permission grants (adds statements to the principal's policy) - grant(principal?: iam.IPrincipal, ...actions: string[]): void; - grantFoo(principal?: iam.IPrincipal): void; - grantBar(principal?: iam.IPrincipal): void; - - // resource policy (if applicable) - addToResourcePolicy(statement: iam.PolicyStatement): void; - - // role (if applicable) - addToRolePolicy(statement: iam.PolicyStatement): void; - - // pipeline (if applicable) - addToPipeline(stage: pipelineapi.IStage, name: string, props?: XxxActionProps): XxxAction; - - // metrics - metric(metricName: string, props?: cloudwatch.MetricCustomization): cloudwatch.Metric; - metricFoo(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; - metricBar(props?: cloudwatch.MetricCustomization): cloudwatch.Metric; - - // export - export(): XxxAttributes; - - // any other methods/properties that are applicable for both internal - // and external resources of this type. - // ... -} -``` - -As mentioned above, this is a polymorphic interface which represents both -internal and external resources of this type. When users wish to import an -external resource, they will the static method `Xxx.import(...)` which returns -an object that implements this interface. - -Since many of the methods above (such as metrics and grants) are applicable -for both internal and external resources, it's usually a good idea to implement -an abstract base class which can be used to reuse these implementations. - -The base class will likely be a `cdk.Construct` (since it is common for many -of these implementations to need to add constructs to the construct tree). -There are some implementations, such as `export` and the various attributes -which are likely to remain `abstract`, and will only become concrete when -we implement the actual resource and imported resource classes. - - -```ts -export abstract class XxxBase extends cdk.Construct implements IXxx { - - // attributes are usually still abstract at this level - public abstract readonly xxxArn: string; - public abstract readonly xxxBoo: string[]; - - // the "export" method is also still abstract - public abstract export(): XxxAttributes; - - // grants can usually be shared - public grantYyy(principal?: iam.IPrincipal) { - // ... - } - - // metrics can usually be shared - public metricFoo(...) { ... } -} -``` - -Now, let's define our main resource class: - -```ts -// extends the abstract base class and implement any interfaces that are not applicable -// for imported resources. This is quite rare usually, but can happen. -export class Xxx extends XxxBase implements IAnotherInterface { - - // the import method is always going to look like this. - public static import(parent: Construct, id: string, props: XxxAttributes): IXxx { - return new ImportedXxx(parent, id, props); - } - - // implement resource attributes as readonly properties - public readonly xxxArn: string; - - // ctor's 3rd argument is always XxxProps. It should be optional (`= { }`) in case - // there are no required properties. - constructor(parent: Construct, id: string, props: XxxProps) { - super(parent, id); - - // you would usually add a `CfnXxx` resource at this point. - const resource = new CfnXxx(this, 'Resource', { - // ... - }); - - // proxy resource properties - this.xxxArn = resource.xxxArn; - this.xxxFoo = resource.xxxFoo; - } - - // this is how export() should be implemented on internal resources - // they would produce a stack export and return the "Fn::ImportValue" token - // for them so they can be imported to another stack. - public export(): XxxAttributes { - return { - xxxArn: new cdk.Output(this, 'Arn', { value: this.xxxArn }).makeImportValue().toString(), - // ... - } - } -} -``` - -- It must have a method with the following signature: - -```ts -static import(parent: Construct, id: string, props: XxxAttributes): IXxx -``` - -### `interface XxxProps` - -The set of initialization properties for `Xxx`. - -### `interface XxxAttributes` - -An interface that can be used to import a resource of this type into the app. - -- Should have the minimum required properties, that is: if it is possible to - parse the resource name from the ARN (using `cdk.ArnUtils.parse`), then only - the ARN should be required. -- In cases where it is not possible to parse the ARN (e.g. if it is a token and - the resource name might have use "/" characters), both the ARN and the name - should be optional and runtime-checks should be performed to require that at - least one will be defined. See `ecr.RepositoryAttributes` for an example. - - - -A data interface with the set of attributes which represent an existing AWS -resource. Normally this would be something like `xxxArn`, `xxxName`, etc. This -class is used when "importing" an existing resource to an application. - diff --git a/packages/@aws-cdk/aws-lambda/lib/alias.ts b/packages/@aws-cdk/aws-lambda/lib/alias.ts index a173d30ed5437..7554c0f00a2c9 100644 --- a/packages/@aws-cdk/aws-lambda/lib/alias.ts +++ b/packages/@aws-cdk/aws-lambda/lib/alias.ts @@ -1,7 +1,7 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { FunctionAttributes, FunctionBase, IFunction } from './lambda-ref'; -import { FunctionVersion } from './lambda-version'; +import { Version } from './lambda-version'; import { CfnAlias } from './lambda.generated'; import { Permission } from './permission'; @@ -21,7 +21,7 @@ export interface AliasProps { * * Use lambda.addVersion() to obtain a new lambda version to refer to. */ - version: FunctionVersion; + version: Version; /** * Name of this alias @@ -80,8 +80,8 @@ export class Alias extends FunctionBase { */ private readonly underlyingLambda: IFunction; - constructor(parent: cdk.Construct, name: string, props: AliasProps) { - super(parent, name); + constructor(parent: cdk.Construct, id: string, props: AliasProps) { + super(parent, id); this.underlyingLambda = props.version.lambda; @@ -154,7 +154,7 @@ export interface VersionWeight { /** * The version to route traffic to */ - readonly version: FunctionVersion; + readonly version: Version; /** * How much weight to assign to this version (0..1) diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-version.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-version.ts index e046ac67fd931..652f91442e77d 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-version.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-version.ts @@ -5,7 +5,7 @@ import { CfnVersion } from './lambda.generated'; /** * Properties for a new Lambda version */ -export interface FunctionVersionProps { +export interface VersionProps { /** * SHA256 of the version of the Lambda source code * @@ -44,7 +44,7 @@ export interface FunctionVersionProps { * the right deployment, specify the `codeSha256` property while * creating the `Version. */ -export class FunctionVersion extends Construct { +export class Version extends Construct { /** * The most recently deployed version of this function. */ @@ -55,8 +55,8 @@ export class FunctionVersion extends Construct { */ public readonly lambda: IFunction; - constructor(parent: Construct, name: string, props: FunctionVersionProps) { - super(parent, name); + constructor(parent: Construct, id: string, props: VersionProps) { + super(parent, id); const version = new CfnVersion(this, 'Resource', { codeSha256: props.codeSha256, diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda.ts b/packages/@aws-cdk/aws-lambda/lib/lambda.ts index 38429e5acd990..44de542071b52 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda.ts @@ -6,7 +6,7 @@ import cdk = require('@aws-cdk/cdk'); import { Code } from './code'; import { ImportedFunction } from './lambda-import'; import { FunctionAttributes, FunctionBase, IFunction } from './lambda-ref'; -import { FunctionVersion } from './lambda-version'; +import { Version } from './lambda-version'; import { CfnFunction } from './lambda.generated'; import { Runtime } from './runtime'; @@ -194,12 +194,12 @@ export class Function extends FunctionBase { * Lambda.import(this, 'MyImportedFunction', { lambdaArn: new LambdaArn('arn:aws:...') }); * * @param parent The parent construct - * @param name The name of the lambda construct - * @param ref A reference to a Lambda function. Can be created manually (see + * @param id The name of the lambda construct + * @param attrs A reference to a Lambda function. Can be created manually (see * example above) or obtained through a call to `lambda.export()`. */ - public static import(parent: cdk.Construct, name: string, ref: FunctionAttributes): IFunction { - return new ImportedFunction(parent, name, ref); + public static import(parent: cdk.Construct, id: string, attrs: FunctionAttributes): IFunction { + return new ImportedFunction(parent, id, attrs); } /** @@ -304,8 +304,8 @@ export class Function extends FunctionBase { */ private readonly environment?: { [key: string]: any }; - constructor(parent: cdk.Construct, name: string, props: FunctionProps) { - super(parent, name); + constructor(parent: cdk.Construct, id: string, props: FunctionProps) { + super(parent, id); this.environment = props.environment || { }; @@ -396,8 +396,8 @@ export class Function extends FunctionBase { * @param description A description for this version. * @returns A new Version object. */ - public addVersion(name: string, codeSha256?: string, description?: string): FunctionVersion { - return new FunctionVersion(this, 'Version' + name, { + public addVersion(name: string, codeSha256?: string, description?: string): Version { + return new Version(this, 'Version' + name, { lambda: this, codeSha256, description, diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 8dff14decc9bb..8685b93d8a7db 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -559,12 +559,12 @@ export class Bucket extends BucketBase { * Creates a Bucket construct that represents an external bucket. * * @param parent The parent creating construct (usually `this`). - * @param name The construct's name. - * @param ref A `BucketAttributes` object. Can be obtained from a call to - * `bucket.export()`. + * @param id The construct's name. + * @param attrs A `BucketAttributes` object. Can be obtained from a call to + * `bucket.export()` or manually created. */ - public static import(parent: cdk.Construct, name: string, props: BucketAttributes): IBucket { - return new ImportedBucket(parent, name, props); + public static import(parent: cdk.Construct, id: string, attrs: BucketAttributes): IBucket { + return new ImportedBucket(parent, id, attrs); } public readonly bucketArn: string; diff --git a/packages/@aws-cdk/aws-sns/lib/policy.ts b/packages/@aws-cdk/aws-sns/lib/policy.ts index a3e0a27d014b5..07c2767d49ff4 100644 --- a/packages/@aws-cdk/aws-sns/lib/policy.ts +++ b/packages/@aws-cdk/aws-sns/lib/policy.ts @@ -24,8 +24,8 @@ export class TopicPolicy extends Construct implements IDependable { */ public readonly dependencyElements = new Array(); - constructor(parent: Construct, name: string, props: TopicPolicyProps) { - super(parent, name); + constructor(parent: Construct, id: string, props: TopicPolicyProps) { + super(parent, id); const resource = new CfnTopicPolicy(this, 'Resource', { policyDocument: this.document, diff --git a/packages/@aws-cdk/aws-sns/lib/subscription.ts b/packages/@aws-cdk/aws-sns/lib/subscription.ts index a6043c9a42a24..6a6d5d2d3b192 100644 --- a/packages/@aws-cdk/aws-sns/lib/subscription.ts +++ b/packages/@aws-cdk/aws-sns/lib/subscription.ts @@ -31,8 +31,8 @@ export interface SubscriptionProps { * this class. */ export class Subscription extends Construct { - constructor(parent: Construct, name: string, props: SubscriptionProps) { - super(parent, name); + constructor(parent: Construct, id: string, props: SubscriptionProps) { + super(parent, id); new CfnSubscription(this, 'Resource', { endpoint: props.endpoint, diff --git a/packages/@aws-cdk/aws-sns/lib/topic.ts b/packages/@aws-cdk/aws-sns/lib/topic.ts index c379221941341..3997d5f6d7ec5 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic.ts @@ -73,8 +73,8 @@ class ImportedTopic extends TopicBase { protected autoCreatePolicy: boolean = false; - constructor(parent: Construct, name: string, private readonly props: TopicAttributes) { - super(parent, name); + constructor(parent: Construct, id: string, private readonly props: TopicAttributes) { + super(parent, id); this.topicArn = props.topicArn; this.topicName = props.topicName; } From cf839e0a469644127839168f067aab4b073edd2c Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 11:46:03 +0200 Subject: [PATCH 07/26] CR fixes --- packages/@aws-cdk/aws-s3/lib/bucket.ts | 2 +- packages/@aws-cdk/cdk/test/cloudformation/test.fn.ts | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 2a654e7cde16d..c7b32071263ec 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -166,7 +166,7 @@ export abstract class BucketRef extends cdk.Construct { * @returns an ObjectS3Url token */ public urlForObject(key?: string): string { - const components = [ 'https://', 's3.', cdk.Aws.region, '.', cdk.Aws.urlSuffix, '/', this.bucketName ]; + const components = [ `https://s3.${cdk.Aws.region}.${cdk.Aws.urlSuffix}/${this.bucketName}` ]; if (key) { // trim prepending '/' if (typeof key === 'string' && key.startsWith('/')) { diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.fn.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.fn.ts index 649fb553a835d..afb247fbebd57 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.fn.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.fn.ts @@ -1,6 +1,7 @@ import fc = require('fast-check'); import _ = require('lodash'); import nodeunit = require('nodeunit'); +import { CloudFormationToken } from '../../lib'; import { Fn } from '../../lib/cloudformation/fn'; import { resolve } from '../../lib/core/tokens'; @@ -53,7 +54,7 @@ export = nodeunit.testCase({ fc.property( fc.string(), fc.array(nonEmptyString, 1, 3), tokenish, fc.array(nonEmptyString, 1, 3), (delimiter, prefix, obj, suffix) => - _.isEqual(resolve(Fn.join(delimiter, [...prefix, obj as any, ...suffix])), + _.isEqual(resolve(Fn.join(delimiter, [...prefix, stringToken(obj), ...suffix])), { 'Fn::Join': [delimiter, [prefix.join(delimiter), obj, suffix.join(delimiter)]] }) ), { verbose: true, seed: 1539874645005, path: "0:0:0:0:0:0:0:0:0" } @@ -82,7 +83,7 @@ export = nodeunit.testCase({ fc.array(anyValue, 3), (delimiter1, delimiter2, prefix, nested, suffix) => { fc.pre(delimiter1 !== delimiter2); - const join = Fn.join(delimiter1, [...prefix, Fn.join(delimiter2, nested as any), ...suffix]); + const join = Fn.join(delimiter1, [...prefix, Fn.join(delimiter2, stringListToken(nested)), ...suffix]); const resolved = resolve(join); return resolved['Fn::Join'][1].find((e: any) => typeof e === 'object' && ('Fn::Join' in e) @@ -94,3 +95,10 @@ export = nodeunit.testCase({ }), }, }); + +function stringListToken(o: any): string[] { + return new CloudFormationToken(o).toList(); +} +function stringToken(o: any): string { + return new CloudFormationToken(o).toString(); +} \ No newline at end of file From 603a46066383b50a466a68ea2214abb47581bc44 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 11:50:26 +0200 Subject: [PATCH 08/26] Revert "Pseudo parameters from new Aws.Xxx() to Aws.xxx" This reverts commit 69da340816ce21cefb2a72327fa28f404aed6c48. --- docs/src/cloudformation.rst | 4 +- docs/src/constructs.rst | 2 +- .../advanced-usage/index.ts | 18 +++--- packages/@aws-cdk/aws-apigateway/lib/stage.ts | 2 +- packages/@aws-cdk/aws-cloudtrail/lib/index.ts | 2 +- packages/@aws-cdk/aws-cloudwatch/lib/graph.ts | 8 +-- .../@aws-cdk/aws-codebuild/lib/project.ts | 2 +- .../@aws-cdk/aws-codecommit/lib/repository.ts | 2 +- .../aws-codedeploy/lib/deployment-group.ts | 4 +- .../aws-ecs/lib/log-drivers/aws-log-driver.ts | 2 +- .../lib/shared/imported.ts | 2 +- .../@aws-cdk/aws-iam/lib/policy-document.ts | 6 +- packages/@aws-cdk/aws-kinesis/lib/stream.ts | 2 +- packages/@aws-cdk/aws-kms/test/integ.key.ts | 4 +- .../@aws-cdk/aws-lambda/lib/lambda-ref.ts | 4 +- .../@aws-cdk/aws-lambda/test/test.lambda.ts | 2 +- .../@aws-cdk/aws-route53/lib/hosted-zone.ts | 2 +- packages/@aws-cdk/aws-s3/lib/bucket.ts | 2 +- .../aws-stepfunctions/lib/state-machine.ts | 2 +- .../@aws-cdk/cdk/lib/cloudformation/arn.ts | 8 +-- .../@aws-cdk/cdk/lib/cloudformation/pseudo.ts | 58 ++++--------------- .../cdk/test/cloudformation/test.arn.ts | 6 +- packages/@aws-cdk/runtime-values/lib/rtv.ts | 4 +- 23 files changed, 55 insertions(+), 93 deletions(-) diff --git a/docs/src/cloudformation.rst b/docs/src/cloudformation.rst index 8bf7ce6f708dc..70556fd1a0ad4 100644 --- a/docs/src/cloudformation.rst +++ b/docs/src/cloudformation.rst @@ -183,8 +183,8 @@ Pseudo Parameters .. code-block:: js - import { Aws } from '@aws-cdk/cdk'; - Aws.region + import cdk = require('@aws-cdk/cdk'); + new cdk.AwsRegion() .. Add a new topic in "Advanced Topics" about integrating cdk synch > mytemplate diff --git a/docs/src/constructs.rst b/docs/src/constructs.rst index b2594f00dacd8..f21c583119dd9 100644 --- a/docs/src/constructs.rst +++ b/docs/src/constructs.rst @@ -145,7 +145,7 @@ Construct IDs may be any string with the following caveats: * Path separators (``/``s) will be replaced by double-dashes ``--``. This means that if you are trying to look up a child construct that may have a path separator, you will need to manually replace it with ``--``. -* Construct IDs may not include unresolved tokens (such as `Aws.region`). This is +* Construct IDs may not include unresolved tokens (such as `new AwsRegion()`). This is because those tokens are only resolved during deployment, and therefore cannot be used to render a stable logical ID for any resources in this tree. diff --git a/examples/cdk-examples-typescript/advanced-usage/index.ts b/examples/cdk-examples-typescript/advanced-usage/index.ts index 579e326898dd2..233df2d25be1a 100644 --- a/examples/cdk-examples-typescript/advanced-usage/index.ts +++ b/examples/cdk-examples-typescript/advanced-usage/index.ts @@ -157,7 +157,7 @@ class CloudFormationExample extends cdk.Stack { // outputs are constructs the synthesize into the template's "Outputs" section new cdk.Output(this, 'Output', { description: 'This is an output of the template', - value: `${cdk.Aws.accountId}/${param.ref}` + value: `${new cdk.AwsAccountId()}/${param.ref}` }); // stack.templateOptions can be used to specify template-level options @@ -166,14 +166,14 @@ class CloudFormationExample extends cdk.Stack { // all CloudFormation's pseudo-parameters are supported via the `cdk.AwsXxx` classes PseudoParameters: [ - cdk.Aws.accountId, - cdk.Aws.domainSuffix, - cdk.Aws.notificationARNs, - cdk.Aws.noValue, - cdk.Aws.partition, - cdk.Aws.region, - cdk.Aws.stackId, - cdk.Aws.stackName, + new cdk.AwsAccountId(), + new cdk.AwsDomainSuffix(), + new cdk.AwsNotificationARNs(), + new cdk.AwsNoValue(), + new cdk.AwsPartition(), + new cdk.AwsRegion(), + new cdk.AwsStackId(), + new cdk.AwsStackName(), ], // all CloudFormation's intrinsic functions are supported via the `cdk.Fn.xxx` static methods. diff --git a/packages/@aws-cdk/aws-apigateway/lib/stage.ts b/packages/@aws-cdk/aws-apigateway/lib/stage.ts index 782dad780bcb5..a2bac5bf90e2b 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/stage.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/stage.ts @@ -173,7 +173,7 @@ export class Stage extends cdk.Construct implements cdk.IDependable { if (!path.startsWith('/')) { throw new Error(`Path must begin with "/": ${path}`); } - return `https://${this.restApi.restApiId}.execute-api.${cdk.Aws.region}.amazonaws.com/${this.stageName}${path}`; + return `https://${this.restApi.restApiId}.execute-api.${new cdk.AwsRegion()}.amazonaws.com/${this.stageName}${path}`; } private renderMethodSettings(props: StageProps): CfnStage.MethodSettingProperty[] | undefined { diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts index 75735e83c51a6..cdbe5749261cd 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts @@ -138,7 +138,7 @@ export class CloudTrail extends cdk.Construct { .addServicePrincipal(cloudTrailPrincipal)); s3bucket.addToResourcePolicy(new iam.PolicyStatement() - .addResource(s3bucket.arnForObjects(`AWSLogs/${cdk.Aws.accountId}/*`)) + .addResource(s3bucket.arnForObjects(`AWSLogs/${new cdk.AwsAccountId()}/*`)) .addActions("s3:PutObject") .addServicePrincipal(cloudTrailPrincipal) .setCondition("StringEquals", {'s3:x-amz-acl': "bucket-owner-full-control"})); diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts b/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts index 2fc2d2baf48a3..27dc9c4cb44b4 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts @@ -1,4 +1,4 @@ -import { Aws } from "@aws-cdk/cdk"; +import { AwsRegion } from "@aws-cdk/cdk"; import { Alarm } from "./alarm"; import { Metric } from "./metric"; import { parseStatistic } from './util.statistic'; @@ -73,7 +73,7 @@ export class AlarmWidget extends ConcreteWidget { properties: { view: 'timeSeries', title: this.props.title, - region: this.props.region || Aws.region, + region: this.props.region || new AwsRegion(), annotations: { alarms: [this.props.alarm.alarmArn] }, @@ -150,7 +150,7 @@ export class GraphWidget extends ConcreteWidget { properties: { view: 'timeSeries', title: this.props.title, - region: this.props.region || Aws.region, + region: this.props.region || new AwsRegion(), metrics: (this.props.left || []).map(m => metricJson(m, 'left')).concat( (this.props.right || []).map(m => metricJson(m, 'right'))), annotations: { @@ -197,7 +197,7 @@ export class SingleValueWidget extends ConcreteWidget { properties: { view: 'singleValue', title: this.props.title, - region: this.props.region || Aws.region, + region: this.props.region || new AwsRegion(), metrics: this.props.metrics.map(m => metricJson(m, 'left')) } }]; diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index d67b61250b31a..4ce51ac2412e0 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -495,7 +495,7 @@ export class Project extends ProjectRef { let cache: CfnProject.ProjectCacheProperty | undefined; if (props.cacheBucket) { - const cacheDir = props.cacheDir != null ? props.cacheDir : cdk.Aws.noValue; + const cacheDir = props.cacheDir != null ? props.cacheDir : new cdk.AwsNoValue().toString(); cache = { type: 'S3', location: cdk.Fn.join('/', [props.cacheBucket.bucketName, cacheDir]), diff --git a/packages/@aws-cdk/aws-codecommit/lib/repository.ts b/packages/@aws-cdk/aws-codecommit/lib/repository.ts index 22ea9737a3f44..c28be77131b21 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/repository.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/repository.ts @@ -196,7 +196,7 @@ class ImportedRepositoryRef extends RepositoryRef { } private repositoryCloneUrl(protocol: 'https' | 'ssh'): string { - return `${protocol}://git-codecommit.${cdk.Aws.region}.${cdk.Aws.urlSuffix}/v1/repos/${this.repositoryName}`; + return `${protocol}://git-codecommit.${new cdk.AwsRegion()}.${new cdk.AwsURLSuffix()}/v1/repos/${this.repositoryName}`; } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts index d5a1defffb1a7..95b3557ad70c7 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts @@ -304,7 +304,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef { this._autoScalingGroups = props.autoScalingGroups || []; this.installAgent = props.installAgent === undefined ? true : props.installAgent; - const region = (cdk.Aws.region).toString(); + const region = (new cdk.AwsRegion()).toString(); this.codeDeployBucket = s3.BucketRef.import(this, 'CodeDeployBucket', { bucketName: `aws-codedeploy-${region}`, }); @@ -371,7 +371,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef { this.codeDeployBucket.grantRead(asg.role, 'latest/*'); - const region = (cdk.Aws.region).toString(); + const region = (new cdk.AwsRegion()).toString(); switch (asg.osType) { case ec2.OperatingSystemType.Linux: asg.addUserData( diff --git a/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts b/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts index 5e43f5549fa50..0a5a445d7e5c0 100644 --- a/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts +++ b/packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts @@ -78,7 +78,7 @@ export class AwsLogDriver extends LogDriver { options: removeEmpty({ 'awslogs-group': this.logGroup.logGroupName, 'awslogs-stream-prefix': this.props.streamPrefix, - 'awslogs-region': cdk.Aws.region, + 'awslogs-region': `${new cdk.AwsRegion()}`, 'awslogs-datetime-format': this.props.datetimeFormat, 'awslogs-multiline-pattern': this.props.multilinePattern, }), diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts index e16b7b56cb9c4..fe989ed60a789 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts @@ -19,6 +19,6 @@ export class BaseImportedTargetGroup extends cdk.Construct { super(parent, id); this.targetGroupArn = props.targetGroupArn; - this.loadBalancerArns = props.loadBalancerArns || cdk.Aws.noValue; + this.loadBalancerArns = props.loadBalancerArns || new cdk.AwsNoValue().toString(); } } diff --git a/packages/@aws-cdk/aws-iam/lib/policy-document.ts b/packages/@aws-cdk/aws-iam/lib/policy-document.ts index 0f201f71f7c62..5022a6f7445ca 100644 --- a/packages/@aws-cdk/aws-iam/lib/policy-document.ts +++ b/packages/@aws-cdk/aws-iam/lib/policy-document.ts @@ -1,4 +1,4 @@ -import { Aws, Token } from '@aws-cdk/cdk'; +import { AwsAccountId, AwsPartition, Token } from '@aws-cdk/cdk'; export class PolicyDocument extends Token { private statements = new Array(); @@ -82,7 +82,7 @@ export class ArnPrincipal extends PolicyPrincipal { export class AccountPrincipal extends ArnPrincipal { constructor(public readonly accountId: any) { - super(`arn:${Aws.partition}:iam::${accountId}:root`); + super(`arn:${new AwsPartition()}:iam::${accountId}:root`); } } @@ -137,7 +137,7 @@ export class FederatedPrincipal extends PolicyPrincipal { export class AccountRootPrincipal extends AccountPrincipal { constructor() { - super(Aws.accountId); + super(new AwsAccountId()); } } diff --git a/packages/@aws-cdk/aws-kinesis/lib/stream.ts b/packages/@aws-cdk/aws-kinesis/lib/stream.ts index 2fa21ca8bbc6a..a7261a929c0bf 100644 --- a/packages/@aws-cdk/aws-kinesis/lib/stream.ts +++ b/packages/@aws-cdk/aws-kinesis/lib/stream.ts @@ -170,7 +170,7 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr if (!this.cloudWatchLogsRole) { // Create a role to be assumed by CWL that can write to this stream and pass itself. this.cloudWatchLogsRole = new iam.Role(this, 'CloudWatchLogsCanPutRecords', { - assumedBy: new iam.ServicePrincipal(`logs.${cdk.Aws.region}.amazonaws.com`) + assumedBy: new iam.ServicePrincipal(`logs.${new cdk.AwsRegion()}.amazonaws.com`) }); this.cloudWatchLogsRole.addToPolicy(new iam.PolicyStatement().addAction('kinesis:PutRecord').addResource(this.streamArn)); this.cloudWatchLogsRole.addToPolicy(new iam.PolicyStatement().addAction('iam:PassRole').addResource(this.cloudWatchLogsRole.roleArn)); diff --git a/packages/@aws-cdk/aws-kms/test/integ.key.ts b/packages/@aws-cdk/aws-kms/test/integ.key.ts index f9920bb406698..f682b1d19fe6e 100644 --- a/packages/@aws-cdk/aws-kms/test/integ.key.ts +++ b/packages/@aws-cdk/aws-kms/test/integ.key.ts @@ -1,5 +1,5 @@ import { PolicyStatement } from '@aws-cdk/aws-iam'; -import { App, Aws, Stack } from '@aws-cdk/cdk'; +import { App, AwsAccountId, Stack } from '@aws-cdk/cdk'; import { EncryptionKey } from '../lib'; const app = new App(); @@ -11,7 +11,7 @@ const key = new EncryptionKey(stack, 'MyKey'); key.addToResourcePolicy(new PolicyStatement() .addAllResources() .addAction('kms:encrypt') - .addAwsPrincipal(Aws.accountId)); + .addAwsPrincipal(new AwsAccountId().toString())); key.addAlias('alias/bar'); diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts index 4bafd28ce8933..2971dc26c76d8 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts @@ -320,7 +320,7 @@ export abstract class FunctionRef extends cdk.Construct // // (Wildcards in principals are unfortunately not supported. this.addPermission('InvokedByCloudWatchLogs', { - principal: new iam.ServicePrincipal(`logs.${cdk.Aws.region}.amazonaws.com`), + principal: new iam.ServicePrincipal(`logs.${new cdk.AwsRegion()}.amazonaws.com`), sourceArn: arn }); this.logSubscriptionDestinationPolicyAddedFor.push(arn); @@ -348,7 +348,7 @@ export abstract class FunctionRef extends cdk.Construct const permissionId = `AllowBucketNotificationsFrom${bucketId}`; if (!this.tryFindChild(permissionId)) { this.addPermission(permissionId, { - sourceAccount: cdk.Aws.accountId.toString(), + sourceAccount: new cdk.AwsAccountId().toString(), principal: new iam.ServicePrincipal('s3.amazonaws.com'), sourceArn: bucketArn, }); diff --git a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts index 1241cfd5ba89c..ebcca95f660e6 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts @@ -118,7 +118,7 @@ export = { fn.addPermission('S3Permission', { action: 'lambda:*', principal: new iam.ServicePrincipal('s3.amazonaws.com'), - sourceAccount: cdk.Aws.accountId, + sourceAccount: new cdk.AwsAccountId().toString(), sourceArn: 'arn:aws:s3:::my_bucket' }); diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index 4a5a76aa59bb2..4769734048bc1 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts @@ -121,7 +121,7 @@ export class PrivateHostedZone extends HostedZoneRef { } function toVpcProperty(vpc: ec2.VpcNetworkRef): CfnHostedZone.VPCProperty { - return { vpcId: vpc.vpcId, vpcRegion: cdk.Aws.region }; + return { vpcId: vpc.vpcId, vpcRegion: new cdk.AwsRegion() }; } function determineHostedZoneProps(props: PublicHostedZoneProps) { diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index c7b32071263ec..c289052722672 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -166,7 +166,7 @@ export abstract class BucketRef extends cdk.Construct { * @returns an ObjectS3Url token */ public urlForObject(key?: string): string { - const components = [ `https://s3.${cdk.Aws.region}.${cdk.Aws.urlSuffix}/${this.bucketName}` ]; + const components = [ `https://s3.${new cdk.AwsRegion()}.${new cdk.AwsURLSuffix()}/${this.bucketName}` ]; if (key) { // trim prepending '/' if (typeof key === 'string' && key.startsWith('/')) { diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts index 7ac12dfcad853..1368bc599f37a 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts @@ -72,7 +72,7 @@ export class StateMachine extends cdk.Construct implements IStateMachine { super(parent, id); this.role = props.role || new iam.Role(this, 'Role', { - assumedBy: new iam.ServicePrincipal(`states.${cdk.Aws.region}.amazonaws.com`) + assumedBy: new iam.ServicePrincipal(`states.${new cdk.AwsRegion()}.amazonaws.com`), }); const graph = new StateGraph(props.definition.startState, `State Machine ${id} definition`); diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts b/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts index 61670850f7336..52e2fb3a563a3 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/arn.ts @@ -1,4 +1,4 @@ -import { Aws } from '..'; +import { AwsAccountId, AwsPartition, AwsRegion } from '..'; import { Fn } from '../cloudformation/fn'; import { unresolved } from '../core/tokens'; @@ -23,13 +23,13 @@ export class ArnUtils { */ public static fromComponents(components: ArnComponents): string { const partition = components.partition == null - ? Aws.partition + ? new AwsPartition() : components.partition; const region = components.region == null - ? Aws.region + ? new AwsRegion() : components.region; const account = components.account == null - ? Aws.accountId + ? new AwsAccountId() : components.account; const values = [ 'arn', ':', partition, ':', components.service, ':', region, ':', account, ':', components.resource ]; diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/pseudo.ts b/packages/@aws-cdk/cdk/lib/cloudformation/pseudo.ts index c0121d2a07e9a..e576320655ec2 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/pseudo.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/pseudo.ts @@ -1,98 +1,60 @@ import { CloudFormationToken } from './cloudformation-token'; -export class Aws { - public static get accountId(): string { - return new AwsAccountId().toString(); - } - - public static get domainSuffix(): string { - return new AwsDomainSuffix().toString(); - } - - public static get urlSuffix(): string { - return new AwsURLSuffix().toString(); - } - - public static get notificationARNs(): string[] { - return new AwsNotificationARNs().toList(); - } - - public static get noValue(): string { - return new AwsNoValue().toString(); - } - - public static get partition(): string { - return new AwsPartition().toString(); - } - - public static get region(): string { - return new AwsRegion().toString(); - } - - public static get stackId(): string { - return new AwsStackId().toString(); - } - - public static get stackName(): string { - return new AwsStackName().toString(); - } -} - -class PseudoParameter extends CloudFormationToken { +export class PseudoParameter extends CloudFormationToken { constructor(name: string) { super({ Ref: name }, name); } } -class AwsAccountId extends PseudoParameter { +export class AwsAccountId extends PseudoParameter { constructor() { super('AWS::AccountId'); } } -class AwsDomainSuffix extends PseudoParameter { +export class AwsDomainSuffix extends PseudoParameter { constructor() { super('AWS::DomainSuffix'); } } -class AwsURLSuffix extends PseudoParameter { +export class AwsURLSuffix extends PseudoParameter { constructor() { super('AWS::URLSuffix'); } } -class AwsNotificationARNs extends PseudoParameter { +export class AwsNotificationARNs extends PseudoParameter { constructor() { super('AWS::NotificationARNs'); } } -class AwsNoValue extends PseudoParameter { +export class AwsNoValue extends PseudoParameter { constructor() { super('AWS::NoValue'); } } -class AwsPartition extends PseudoParameter { +export class AwsPartition extends PseudoParameter { constructor() { super('AWS::Partition'); } } -class AwsRegion extends PseudoParameter { +export class AwsRegion extends PseudoParameter { constructor() { super('AWS::Region'); } } -class AwsStackId extends PseudoParameter { +export class AwsStackId extends PseudoParameter { constructor() { super('AWS::StackId'); } } -class AwsStackName extends PseudoParameter { +export class AwsStackName extends PseudoParameter { constructor() { super('AWS::StackName'); } diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts index 5869eb6eb00bd..18b90b460db69 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts @@ -1,5 +1,5 @@ import { Test } from 'nodeunit'; -import { ArnComponents, ArnUtils, Aws, resolve, Token } from '../../lib'; +import { ArnComponents, ArnUtils, AwsAccountId, AwsPartition, AwsRegion, resolve, Token } from '../../lib'; export = { 'create from components with defaults'(test: Test) { @@ -9,7 +9,7 @@ export = { }); test.deepEqual(resolve(arn), - resolve(`arn:${Aws.partition}:sqs:${Aws.region}:${Aws.accountId}:myqueuename`)); + resolve(`arn:${new AwsPartition()}:sqs:${new AwsRegion()}:${new AwsAccountId()}:myqueuename`)); test.done(); }, @@ -52,7 +52,7 @@ export = { }); test.deepEqual(resolve(arn), - resolve(`arn:${Aws.partition}:codedeploy:${Aws.region}:${Aws.accountId}:application:WordPress_App`)); + resolve(`arn:${new AwsPartition()}:codedeploy:${new AwsRegion()}:${new AwsAccountId()}:application:WordPress_App`)); test.done(); }, diff --git a/packages/@aws-cdk/runtime-values/lib/rtv.ts b/packages/@aws-cdk/runtime-values/lib/rtv.ts index 975170df63101..d909df03cf86c 100644 --- a/packages/@aws-cdk/runtime-values/lib/rtv.ts +++ b/packages/@aws-cdk/runtime-values/lib/rtv.ts @@ -30,7 +30,7 @@ export class RuntimeValue extends cdk.Construct { /** * The value to assign to the `RTV_STACK_NAME` environment variable. */ - public static readonly ENV_VALUE = cdk.Aws.stackName; + public static readonly ENV_VALUE = new cdk.AwsStackName(); /** * IAM actions needed to read a value from an SSM parameter. @@ -54,7 +54,7 @@ export class RuntimeValue extends cdk.Construct { constructor(parent: cdk.Construct, name: string, props: RuntimeValueProps) { super(parent, name); - this.parameterName = `/rtv/${cdk.Aws.stackName}/${props.package}/${name}`; + this.parameterName = `/rtv/${new cdk.AwsStackName()}/${props.package}/${name}`; new ssm.CfnParameter(this, 'Parameter', { name: this.parameterName, From 0130c762ca4cc64686682624b151776b49510f19 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 12:19:25 +0200 Subject: [PATCH 09/26] Do not use FnBase as an external base class --- packages/@aws-cdk/cdk/lib/cloudformation/fn.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts index 14fd3b61fcda7..11c9cf86105a9 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts @@ -460,8 +460,10 @@ class FnCidr extends FnBase { * conditions, you can define which resources are created and how they're configured for each * environment type. */ -export class FnCondition extends FnBase { - +export class FnCondition extends CloudFormationToken { + constructor(key: string, value: any) { + super({ [key]: value }); + } } /** From dbd80d99a94a5b40b2e630a1daa1ab824fae47ab Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 13:41:34 +0200 Subject: [PATCH 10/26] Remove merge error --- .../@aws-cdk/cdk/lib/cloudformation/fn.ts | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts index 11e5f4147853f..5e467ec1df0e8 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts @@ -442,31 +442,6 @@ class FnCidr extends FnBase { } } -/** -* You can use intrinsic functions, such as ``Fn::If``, ``Fn::Equals``, and ``Fn::Not``, to conditionally - * create stack resources. These conditions are evaluated based on input parameters that you - * declare when you create or update a stack. After you define all your conditions, you can - * associate them with resources or resource properties in the Resources and Outputs sections - * of a template. - * - * You define all conditions in the Conditions section of a template except for ``Fn::If`` conditions. - * You can use the ``Fn::If`` condition in the metadata attribute, update policy attribute, and property - * values in the Resources section and Outputs sections of a template. - * - * You might use conditions when you want to reuse a template that can create resources in different - * contexts, such as a test environment versus a production environment. In your template, you can - * add an EnvironmentType input parameter, which accepts either prod or test as inputs. For the - * production environment, you might include Amazon EC2 instances with certain capabilities; - * however, for the test environment, you want to use less capabilities to save costs. With - * conditions, you can define which resources are created and how they're configured for each - * environment type. - */ -export class FnCondition extends CloudFormationToken { - constructor(key: string, value: any) { - super({ [key]: value }); - } -} - /** * Returns true if all the specified conditions evaluate to true, or returns false if any one * of the conditions evaluates to false. ``Fn::And`` acts as an AND operator. The minimum number of From e967937e8296efde5fa8dfe16777a30c3ded9d32 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 15:38:17 +0200 Subject: [PATCH 11/26] Rename condition methods --- packages/@aws-cdk/cdk/lib/cloudformation/fn.ts | 16 ++++++++-------- .../cdk/test/cloudformation/test.resource.ts | 2 +- .../cdk/test/cloudformation/test.rule.ts | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts index 5e467ec1df0e8..44b0f440da057 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/fn.ts @@ -148,7 +148,7 @@ export class Fn { * @param conditions conditions to AND * @returns an FnCondition token */ - public static andCondition(...conditions: FnCondition[]): FnCondition { + public static conditionAnd(...conditions: FnCondition[]): FnCondition { return new FnAnd(...conditions); } @@ -159,7 +159,7 @@ export class Fn { * @param rhs A value of any type that you want to compare. * @returns an FnCondition token */ - public static equalsCondition(lhs: any, rhs: any): FnCondition { + public static conditionEquals(lhs: any, rhs: any): FnCondition { return new FnEquals(lhs, rhs); } @@ -178,7 +178,7 @@ export class Fn { * evaluates to false. * @returns an FnCondition token */ - public static ifCondition(conditionId: string, valueIfTrue: any, valueIfFalse: any): FnCondition { + public static conditionIf(conditionId: string, valueIfTrue: any, valueIfFalse: any): FnCondition { return new FnIf(conditionId, valueIfTrue, valueIfFalse); } @@ -189,7 +189,7 @@ export class Fn { * or false. * @returns an FnCondition token */ - public static notCondition(condition: FnCondition): FnCondition { + public static conditionNot(condition: FnCondition): FnCondition { return new FnNot(condition); } @@ -201,7 +201,7 @@ export class Fn { * @param conditions conditions that evaluates to true or false. * @returns an FnCondition token */ - public static orCondition(...conditions: FnCondition[]): FnCondition { + public static conditionOr(...conditions: FnCondition[]): FnCondition { return new FnOr(...conditions); } @@ -212,7 +212,7 @@ export class Fn { * @param value A string, such as "A", that you want to compare against a list of strings. * @returns an FnCondition token */ - public static containsCondition(listOfStrings: string[], value: string): FnCondition { + public static conditionContains(listOfStrings: string[], value: string): FnCondition { return new FnContains(listOfStrings, value); } @@ -223,7 +223,7 @@ export class Fn { * of strings. * @returns an FnCondition token */ - public eachMemberEqualsCondition(listOfStrings: string[], value: string): FnCondition { + public conditionEachMemberEquals(listOfStrings: string[], value: string): FnCondition { return new FnEachMemberEquals(listOfStrings, value); } @@ -238,7 +238,7 @@ export class Fn { * strings_to_check parameter. * @returns an FnCondition token */ - public eachMemberInCondition(stringsToCheck: string[], stringsToMatch: string): FnCondition { + public conditionEachMemberIn(stringsToCheck: string[], stringsToMatch: string): FnCondition { return new FnEachMemberIn(stringsToCheck, stringsToMatch); } diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts index 7678da5ad89df..c4feb2ee6d714 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts @@ -154,7 +154,7 @@ export = { 'conditions can be attached to a resource'(test: Test) { const stack = new Stack(); const r1 = new Resource(stack, 'Resource', { type: 'Type' }); - const cond = new Condition(stack, 'MyCondition', { expression: Fn.notCondition(Fn.equalsCondition('a', 'b')) }); + const cond = new Condition(stack, 'MyCondition', { expression: Fn.conditionNot(Fn.conditionEquals('a', 'b')) }); r1.options.condition = cond; test.deepEqual(stack.toCloudFormation(), { diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.rule.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.rule.ts index 6635bafa652f7..c4576dae703f2 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.rule.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.rule.ts @@ -6,8 +6,8 @@ export = { const stack = new Stack(); const rule = new Rule(stack, 'MyRule'); - rule.addAssertion(Fn.equalsCondition('lhs', 'rhs'), 'lhs equals rhs'); - rule.addAssertion(Fn.notCondition(Fn.andCondition(Fn.containsCondition([ 'hello', 'world' ], "world"))), 'some assertion'); + rule.addAssertion(Fn.conditionEquals('lhs', 'rhs'), 'lhs equals rhs'); + rule.addAssertion(Fn.conditionNot(Fn.conditionAnd(Fn.conditionContains([ 'hello', 'world' ], "world"))), 'some assertion'); test.deepEqual(stack.toCloudFormation(), { Rules: { From 757d793bb6ff17b57ad60fbea3be12693fd4b810 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 15:53:29 +0200 Subject: [PATCH 12/26] Add missing imported classes --- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 52 ++++++++++++++++++++-- packages/@aws-cdk/aws-events/lib/rule.ts | 15 ++++++- packages/@aws-cdk/aws-lambda/lib/lambda.ts | 45 ++++++++++++++++++- 3 files changed, 106 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 5a1997eeb7735..a210fb5a79a92 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -1,10 +1,8 @@ import cdk = require('@aws-cdk/cdk'); -import { Output } from '@aws-cdk/cdk'; import { CfnEIP, CfnInternetGateway, CfnNatGateway, CfnRoute } from './ec2.generated'; import { CfnRouteTable, CfnSubnet, CfnSubnetRouteTableAssociation, CfnVPC, CfnVPCGatewayAttachment } from './ec2.generated'; -import { ImportedVpcNetwork, ImportedVpcSubnet } from './imported-vpc'; import { NetworkBuilder } from './network-util'; -import { DEFAULT_SUBNET_NAME, ExportSubnetGroup, subnetId } from './util'; +import { DEFAULT_SUBNET_NAME, ExportSubnetGroup, ImportSubnetGroup, subnetId } from './util'; import { VpcNetworkProvider, VpcNetworkProviderProps } from './vpc-network-provider'; import { IVpcNetwork, IVpcSubnet, SubnetType, VpcNetworkAttributes, VpcNetworkBase, VpcPlacementStrategy, VpcSubnetAttributes } from './vpc-ref'; /** @@ -370,7 +368,7 @@ export class VpcNetwork extends VpcNetworkBase implements cdk.ITaggable { const iso = new ExportSubnetGroup(this, 'IsolatedSubnetIDs', this.isolatedSubnets, SubnetType.Isolated, this.availabilityZones.length); return { - vpcId: new Output(this, 'VpcId', { value: this.vpcId }).makeImportValue().toString(), + vpcId: new cdk.Output(this, 'VpcId', { value: this.vpcId }).makeImportValue().toString(), availabilityZones: this.availabilityZones, publicSubnetIds: pub.ids, publicSubnetNames: pub.names, @@ -665,3 +663,49 @@ export class VpcPrivateSubnet extends VpcSubnet { function ifUndefined(value: T | undefined, defaultValue: T): T { return value !== undefined ? value : defaultValue; } + +export class ImportedVpcNetwork extends VpcNetworkBase { + public readonly vpcId: string; + public readonly publicSubnets: IVpcSubnet[]; + public readonly privateSubnets: IVpcSubnet[]; + public readonly isolatedSubnets: IVpcSubnet[]; + public readonly availabilityZones: string[]; + + constructor(parent: cdk.Construct, id: string, private readonly props: VpcNetworkAttributes) { + super(parent, id); + + this.vpcId = props.vpcId; + this.availabilityZones = props.availabilityZones; + + // tslint:disable:max-line-length + const pub = new ImportSubnetGroup(props.publicSubnetIds, props.publicSubnetNames, SubnetType.Public, this.availabilityZones, 'publicSubnetIds', 'publicSubnetNames'); + const priv = new ImportSubnetGroup(props.privateSubnetIds, props.privateSubnetNames, SubnetType.Private, this.availabilityZones, 'privateSubnetIds', 'privateSubnetNames'); + const iso = new ImportSubnetGroup(props.isolatedSubnetIds, props.isolatedSubnetNames, SubnetType.Isolated, this.availabilityZones, 'isolatedSubnetIds', 'isolatedSubnetNames'); + // tslint:enable:max-line-length + + this.publicSubnets = pub.import(this); + this.privateSubnets = priv.import(this); + this.isolatedSubnets = iso.import(this); + } + + public export() { + return this.props; + } +} + +export class ImportedVpcSubnet extends cdk.Construct implements IVpcSubnet { + public readonly availabilityZone: string; + public readonly subnetId: string; + public readonly dependencyElements = new Array(); + + constructor(parent: cdk.Construct, id: string, private readonly props: VpcSubnetAttributes) { + super(parent, id); + + this.subnetId = props.subnetId; + this.availabilityZone = props.availabilityZone; + } + + public export() { + return this.props; + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events/lib/rule.ts b/packages/@aws-cdk/aws-events/lib/rule.ts index 6925f194a3b8c..842c06c533b1b 100644 --- a/packages/@aws-cdk/aws-events/lib/rule.ts +++ b/packages/@aws-cdk/aws-events/lib/rule.ts @@ -2,7 +2,6 @@ import { Construct, Output, Token } from '@aws-cdk/cdk'; import { EventPattern } from './event-pattern'; import { CfnRule } from './events.generated'; import { TargetInputTemplate } from './input-options'; -import { ImportedEventRule } from './rule-import'; import { EventRuleAttributes, IEventRule } from './rule-ref'; import { IEventRuleTarget } from './target'; import { mergeEventPattern } from './util'; @@ -236,3 +235,17 @@ export class EventRule extends Construct implements IEventRule { return out; } } + +class ImportedEventRule extends Construct implements IEventRule { + public readonly ruleArn: string; + + constructor(parent: Construct, id: string, private readonly props: EventRuleAttributes) { + super(parent, id); + + this.ruleArn = props.eventRuleArn; + } + + public export() { + return this.props; + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda.ts b/packages/@aws-cdk/aws-lambda/lib/lambda.ts index 44de542071b52..5b383877bf199 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda.ts @@ -4,7 +4,6 @@ import iam = require('@aws-cdk/aws-iam'); import sqs = require('@aws-cdk/aws-sqs'); import cdk = require('@aws-cdk/cdk'); import { Code } from './code'; -import { ImportedFunction } from './lambda-import'; import { FunctionAttributes, FunctionBase, IFunction } from './lambda-ref'; import { Version } from './lambda-version'; import { CfnFunction } from './lambda.generated'; @@ -489,5 +488,49 @@ export class Function extends FunctionBase { mode: Tracing[props.tracing] }; } +} + +export class ImportedFunction extends FunctionBase { + public readonly functionName: string; + public readonly functionArn: string; + public readonly role?: iam.Role; + + protected readonly canCreatePermissions = false; + + constructor(parent: cdk.Construct, id: string, private readonly props: FunctionAttributes) { + super(parent, id); + + this.functionArn = props.functionArn; + this.functionName = extractNameFromArn(props.functionArn); + this.role = props.role; + + if (props.securityGroupId) { + this._connections = new ec2.Connections({ + securityGroups: [ + ec2.SecurityGroup.import(this, 'SecurityGroup', { securityGroupId: props.securityGroupId }) + ] + }); + } + } + public export() { + return this.props; + } } + +/** + * Given an opaque (token) ARN, returns a CloudFormation expression that extracts the function + * name from the ARN. + * + * Function ARNs look like this: + * + * arn:aws:lambda:region:account-id:function:function-name + * + * ..which means that in order to extract the `function-name` component from the ARN, we can + * split the ARN using ":" and select the component in index 6. + * + * @returns `FnSelect(6, FnSplit(':', arn))` + */ +function extractNameFromArn(arn: string) { + return cdk.Fn.select(6, cdk.Fn.split(':', arn)); +} \ No newline at end of file From d4a30a58eaf81e483aeb3aaaf01ad134ae773255 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 16:04:04 +0200 Subject: [PATCH 13/26] Retain immutability of IHostedZone attributes --- packages/@aws-cdk/aws-route53/lib/hosted-zone.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index 5fc8a96d9e9ff..142ee507f29d6 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts @@ -33,8 +33,8 @@ export abstract class HostedZone extends cdk.Construct implements IHostedZone { return new ImportedHostedZone(parent, name, props); } - public abstract hostedZoneId: string; - public abstract zoneName: string; + public abstract readonly hostedZoneId: string; + public abstract readonly zoneName: string; public export(): HostedZoneAttributes { return { From 584b8bcae2890cfc12fc7e843d8e7b9d9ceab049 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 16:31:37 +0200 Subject: [PATCH 14/26] Fix event sources --- packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts | 2 +- packages/@aws-cdk/aws-lambda-event-sources/lib/sns.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts b/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts index df46051841a4a..49e4fe8e9d4a9 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts @@ -24,7 +24,7 @@ export class S3EventSource implements lambda.IEventSource { } - public bind(target: lambda.IFunction) { + public bind(target: lambda.FunctionBase) { const filters = this.props.filters || []; for (const event of this.props.events) { this.bucket.onEvent(event, target, ...filters); diff --git a/packages/@aws-cdk/aws-lambda-event-sources/lib/sns.ts b/packages/@aws-cdk/aws-lambda-event-sources/lib/sns.ts index d2c40c1b4b47b..f4f690f00dd7d 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/lib/sns.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/lib/sns.ts @@ -8,7 +8,7 @@ export class SnsEventSource implements lambda.IEventSource { constructor(readonly topic: sns.ITopic) { } - public bind(target: lambda.IFunction) { + public bind(target: lambda.FunctionBase) { this.topic.subscribeLambda(target); } } \ No newline at end of file From d341522607597f5a8dbff51f3c4967a6f0580384 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 16:50:43 +0200 Subject: [PATCH 15/26] fix linting error --- packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts index b9a2865eef7a1..4bba6a7f27631 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts @@ -421,4 +421,3 @@ export abstract class FunctionBase extends cdk.Construct implements IFunction { 'Supported: AccountPrincipal, ServicePrincipal'); } } - From eb6c2060425ad4351a799ff1ff68360fa14c85b1 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 17:43:04 +0200 Subject: [PATCH 16/26] Rename XxxAttributes to XxxImportProps --- .../bucket-import-export/index.ts | 4 ++-- examples/cdk-examples-typescript/ec2/index.ts | 2 +- packages/@aws-cdk/aws-apigateway/lib/restapi.ts | 10 +++++----- .../aws-certificatemanager/lib/certificate.ts | 10 +++++----- packages/@aws-cdk/aws-codebuild/lib/project.ts | 12 ++++++------ packages/@aws-cdk/aws-codecommit/lib/repository.ts | 12 ++++++------ .../@aws-cdk/aws-codedeploy/lib/application.ts | 10 +++++----- .../aws-codedeploy/lib/deployment-config.ts | 12 ++++++------ .../aws-codedeploy/lib/deployment-group.ts | 12 ++++++------ packages/@aws-cdk/aws-ec2/lib/security-group.ts | 12 ++++++------ .../@aws-cdk/aws-ec2/lib/vpc-network-provider.ts | 4 ++-- packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts | 10 +++++----- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 14 +++++++------- .../aws-ec2/test/example.share-vpcs.lit.ts | 4 ++-- packages/@aws-cdk/aws-ecr/lib/repository-ref.ts | 12 ++++++------ packages/@aws-cdk/aws-ecr/lib/repository.ts | 4 ++-- packages/@aws-cdk/aws-ecs/lib/cluster.ts | 14 +++++++------- .../lib/alb/application-listener.ts | 10 +++++----- .../lib/alb/application-load-balancer.ts | 10 +++++----- .../lib/alb/application-target-group.ts | 4 ++-- .../lib/nlb/network-listener.ts | 10 +++++----- .../lib/nlb/network-load-balancer.ts | 10 +++++----- .../lib/nlb/network-target-group.ts | 4 ++-- .../lib/shared/base-target-group.ts | 6 +++--- .../lib/shared/imported.ts | 4 ++-- packages/@aws-cdk/aws-events/lib/rule-ref.ts | 4 ++-- packages/@aws-cdk/aws-events/lib/rule.ts | 8 ++++---- packages/@aws-cdk/aws-kinesis/lib/stream.ts | 14 +++++++------- packages/@aws-cdk/aws-kms/lib/key.ts | 12 ++++++------ packages/@aws-cdk/aws-lambda/lib/alias.ts | 4 ++-- packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts | 6 +++--- packages/@aws-cdk/aws-lambda/lib/lambda.ts | 8 ++++---- .../@aws-cdk/aws-lambda/lib/singleton-lambda.ts | 4 ++-- packages/@aws-cdk/aws-logs/lib/log-group.ts | 12 ++++++------ packages/@aws-cdk/aws-logs/lib/log-stream.ts | 10 +++++----- .../aws-rds/lib/cluster-parameter-group.ts | 10 +++++----- packages/@aws-cdk/aws-rds/lib/cluster-ref.ts | 4 ++-- packages/@aws-cdk/aws-rds/lib/cluster.ts | 8 ++++---- .../aws-route53/lib/hosted-zone-provider.ts | 4 ++-- .../@aws-cdk/aws-route53/lib/hosted-zone-ref.ts | 4 ++-- packages/@aws-cdk/aws-route53/lib/hosted-zone.ts | 8 ++++---- .../aws-route53/test/test.hosted-zone-provider.ts | 4 ++-- packages/@aws-cdk/aws-s3/lib/bucket.ts | 12 ++++++------ packages/@aws-cdk/aws-s3/lib/util.ts | 6 +++--- .../@aws-cdk/aws-s3/test/demo.import-export.ts | 4 ++-- packages/@aws-cdk/aws-sns/lib/topic-ref.ts | 6 +++--- packages/@aws-cdk/aws-sns/lib/topic.ts | 10 +++++----- packages/@aws-cdk/aws-sqs/lib/queue-ref.ts | 6 +++--- packages/@aws-cdk/aws-sqs/lib/queue.ts | 8 ++++---- .../aws-stepfunctions/lib/state-machine.ts | 10 +++++----- 50 files changed, 201 insertions(+), 201 deletions(-) diff --git a/examples/cdk-examples-typescript/bucket-import-export/index.ts b/examples/cdk-examples-typescript/bucket-import-export/index.ts index 8f7109e8ae1a7..3ffd0f7a27e19 100644 --- a/examples/cdk-examples-typescript/bucket-import-export/index.ts +++ b/examples/cdk-examples-typescript/bucket-import-export/index.ts @@ -7,7 +7,7 @@ import cdk = require('@aws-cdk/cdk'); // `Bucket.import`. class Producer extends cdk.Stack { - public readonly myBucketRef: s3.BucketAttributes; + public readonly myBucketRef: s3.BucketImportProps; constructor(parent: cdk.App, name: string) { super(parent, name); @@ -35,7 +35,7 @@ class ConsumerConstruct extends cdk.Construct { // this bucket and contents. interface ConsumerProps { - userBucketRef: s3.BucketAttributes; + userBucketRef: s3.BucketImportProps; } class Consumer extends cdk.Stack { diff --git a/examples/cdk-examples-typescript/ec2/index.ts b/examples/cdk-examples-typescript/ec2/index.ts index 15d87ad5cda25..a94323c79e0af 100644 --- a/examples/cdk-examples-typescript/ec2/index.ts +++ b/examples/cdk-examples-typescript/ec2/index.ts @@ -52,7 +52,7 @@ class MyApp extends cdk.Stack { } class CommonInfrastructure extends cdk.Stack { - public vpc: ec2.VpcNetworkAttributes; + public vpc: ec2.VpcNetworkImportProps; constructor(parent: cdk.App, name: string, props?: cdk.StackProps) { super(parent, name, props); diff --git a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts index 053766791b0f8..35304e1b88766 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts @@ -7,7 +7,7 @@ import { Method, MethodOptions } from './method'; import { IRestApiResource, ProxyResource, Resource, ResourceOptions } from './resource'; import { Stage, StageOptions } from './stage'; -export interface RestApiAttributes { +export interface RestApiImportProps { /** * The REST API ID of an existing REST API resource. */ @@ -24,7 +24,7 @@ export interface IRestApi { * Exports a REST API resource from this stack. * @returns REST API props that can be imported to another stack. */ - export(): RestApiAttributes; + export(): RestApiImportProps; } export interface RestApiProps extends ResourceOptions { @@ -161,7 +161,7 @@ export class RestApi extends cdk.Construct implements cdk.IDependable, IRestApi * @param id Construct ID * @param props Imported rest API properties */ - public static import(parent: cdk.Construct, id: string, props: RestApiAttributes): IRestApi { + public static import(parent: cdk.Construct, id: string, props: RestApiImportProps): IRestApi { return new ImportedRestApi(parent, id, props); } @@ -257,7 +257,7 @@ export class RestApi extends cdk.Construct implements cdk.IDependable, IRestApi * Exports a REST API resource from this stack. * @returns REST API props that can be imported to another stack. */ - public export(): RestApiAttributes { + public export(): RestApiImportProps { return { restApiId: new cdk.Output(this, 'RestApiId', { value: this.restApiId }).makeImportValue().toString() }; @@ -409,7 +409,7 @@ export class RestApiUrl extends cdk.CloudFormationToken { } class ImportedRestApi extends cdk.Construct implements IRestApi { public restApiId: string; - constructor(parent: cdk.Construct, id: string, private readonly props: RestApiAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: RestApiImportProps) { super(parent, id); this.restApiId = props.restApiId; diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts b/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts index fb5f7f6bf5759..32acc34ae7cd0 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts +++ b/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts @@ -11,13 +11,13 @@ export interface ICertificate { /** * Export this certificate from the stack */ - export(): CertificateAttributes; + export(): CertificateImportProps; } /** * Reference to an existing Certificate */ -export interface CertificateAttributes { +export interface CertificateImportProps { /** * The certificate's ARN */ @@ -73,7 +73,7 @@ export class Certificate extends Construct implements ICertificate { /** * Import a certificate */ - public static import(parent: Construct, name: string, props: CertificateAttributes): ICertificate { + public static import(parent: Construct, name: string, props: CertificateImportProps): ICertificate { return new ImportedCertificate(parent, name, props); } @@ -112,7 +112,7 @@ export class Certificate extends Construct implements ICertificate { /** * Export this certificate from the stack */ - public export(): CertificateAttributes { + public export(): CertificateImportProps { return { certificateArn: new Output(this, 'Arn', { value: this.certificateArn }).makeImportValue().toString() }; @@ -125,7 +125,7 @@ export class Certificate extends Construct implements ICertificate { class ImportedCertificate extends Construct implements ICertificate { public readonly certificateArn: string; - constructor(parent: Construct, name: string, private readonly props: CertificateAttributes) { + constructor(parent: Construct, name: string, private readonly props: CertificateImportProps) { super(parent, name); this.certificateArn = props.certificateArn; diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index 9985890f3c4e6..a3021c83ae132 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -154,7 +154,7 @@ export interface IProject extends events.IEventRuleTarget { /** * Export this Project. Allows referencing this Project in a different CDK Stack. */ - export(): ProjectAttributes; + export(): ProjectImportProps; } /** @@ -163,7 +163,7 @@ export interface IProject extends events.IEventRuleTarget { * @see Project.import * @see Project.export */ -export interface ProjectAttributes { +export interface ProjectImportProps { /** * The human-readable name of the CodeBuild Project we're referencing. * The Project must be in the same account and region as the root Stack. @@ -194,7 +194,7 @@ export abstract class ProjectBase extends cdk.Construct implements IProject { /** A role used by CloudWatch events to trigger a build */ private eventsRole?: iam.Role; - public abstract export(): ProjectAttributes; + public abstract export(): ProjectImportProps; /** * Convenience method for creating a new {@link PipelineBuildAction} build Action, @@ -433,7 +433,7 @@ class ImportedProject extends ProjectBase { public readonly projectName: string; public readonly role?: iam.Role = undefined; - constructor(parent: cdk.Construct, name: string, private readonly props: ProjectAttributes) { + constructor(parent: cdk.Construct, name: string, private readonly props: ProjectImportProps) { super(parent, name); this.projectArn = cdk.ArnUtils.fromComponents({ @@ -592,7 +592,7 @@ export class Project extends ProjectBase { * @param props the properties of the referenced Project * @returns a reference to the existing Project */ - public static import(parent: cdk.Construct, name: string, props: ProjectAttributes): IProject { + public static import(parent: cdk.Construct, name: string, props: ProjectImportProps): IProject { return new ImportedProject(parent, name, props); } @@ -726,7 +726,7 @@ export class Project extends ProjectBase { /** * Export this Project. Allows referencing this Project in a different CDK Stack. */ - public export(): ProjectAttributes { + public export(): ProjectImportProps { return { projectName: new cdk.Output(this, 'ProjectName', { value: this.projectName }).makeImportValue().toString(), }; diff --git a/packages/@aws-cdk/aws-codecommit/lib/repository.ts b/packages/@aws-cdk/aws-codecommit/lib/repository.ts index 24c3e2b96413e..b1718363eb60b 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/repository.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/repository.ts @@ -85,13 +85,13 @@ export interface IRepository { * * @see import */ - export(): RepositoryAttributes; + export(): RepositoryImportProps; } /** * Properties for the {@link Repository.import} method. */ -export interface RepositoryAttributes { +export interface RepositoryImportProps { /** * The name of an existing CodeCommit Repository that we are referencing. * Must be in the same account and region as the root Stack. @@ -121,7 +121,7 @@ export abstract class RepositoryBase extends cdk.Construct implements IRepositor /** The SSH clone URL */ public abstract readonly repositoryCloneUrlSsh: string; - public abstract export(): RepositoryAttributes; + public abstract export(): RepositoryImportProps; /** * Convenience method for creating a new {@link PipelineSourceAction}, @@ -241,7 +241,7 @@ class ImportedRepository extends RepositoryBase { public readonly repositoryArn: string; public readonly repositoryName: string; - constructor(parent: cdk.Construct, name: string, private readonly props: RepositoryAttributes) { + constructor(parent: cdk.Construct, name: string, private readonly props: RepositoryImportProps) { super(parent, name); this.repositoryArn = cdk.ArnUtils.fromComponents({ @@ -294,7 +294,7 @@ export class Repository extends RepositoryBase { * @param props the properties used to identify the existing Repository * @returns a reference to the existing Repository */ - public static import(parent: cdk.Construct, name: string, props: RepositoryAttributes): IRepository { + public static import(parent: cdk.Construct, name: string, props: RepositoryImportProps): IRepository { return new ImportedRepository(parent, name, props); } @@ -332,7 +332,7 @@ export class Repository extends RepositoryBase { * * @see import */ - public export(): RepositoryAttributes { + public export(): RepositoryImportProps { return { repositoryName: new cdk.Output(this, 'RepositoryName', { value: this.repositoryName }).makeImportValue().toString() }; diff --git a/packages/@aws-cdk/aws-codedeploy/lib/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/application.ts index ac713ee15293b..d5442ee21f0e1 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/application.ts @@ -16,7 +16,7 @@ export interface IServerApplication { readonly applicationName: string; - export(): ServerApplicationAttributes; + export(): ServerApplicationImportProps; } /** @@ -25,7 +25,7 @@ export interface IServerApplication { * @see ServerApplication#import * @see ServerApplication#export */ -export interface ServerApplicationAttributes { +export interface ServerApplicationImportProps { /** * The physical, human-readable name of the CodeDeploy EC2/on-premise Application we're referencing. * The Application must be in the same account and region as the root Stack. @@ -37,7 +37,7 @@ class ImportedServerApplication extends cdk.Construct implements IServerApplicat public readonly applicationArn: string; public readonly applicationName: string; - constructor(parent: cdk.Construct, id: string, private readonly props: ServerApplicationAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: ServerApplicationImportProps) { super(parent, id); this.applicationName = props.applicationName; @@ -74,7 +74,7 @@ export class ServerApplication extends cdk.Construct implements IServerApplicati * @param props the properties of the referenced Application * @returns a Construct representing a reference to an existing Application */ - public static import(parent: cdk.Construct, id: string, props: ServerApplicationAttributes): IServerApplication { + public static import(parent: cdk.Construct, id: string, props: ServerApplicationImportProps): IServerApplication { return new ImportedServerApplication(parent, id, props); } @@ -93,7 +93,7 @@ export class ServerApplication extends cdk.Construct implements IServerApplicati this.applicationArn = applicationName2Arn(this.applicationName); } - public export(): ServerApplicationAttributes { + public export(): ServerApplicationImportProps { return { applicationName: new cdk.Output(this, 'ApplicationName', { value: this.applicationName }).makeImportValue().toString() }; diff --git a/packages/@aws-cdk/aws-codedeploy/lib/deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/deployment-config.ts index 3b61aa367fdc9..c71421e84a2e8 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/deployment-config.ts @@ -11,7 +11,7 @@ import { CfnDeploymentConfig } from './codedeploy.generated'; export interface IServerDeploymentConfig { readonly deploymentConfigName: string; readonly deploymentConfigArn: string; - export(): ServerDeploymentConfigAttributes; + export(): ServerDeploymentConfigImportProps; } /** @@ -20,7 +20,7 @@ export interface IServerDeploymentConfig { * @see ServerDeploymentConfig#import * @see ServerDeploymentConfig#export */ -export interface ServerDeploymentConfigAttributes { +export interface ServerDeploymentConfigImportProps { /** * The physical, human-readable name of the custom CodeDeploy EC2/on-premise Deployment Configuration * that we are referencing. @@ -32,7 +32,7 @@ class ImportedServerDeploymentConfig extends cdk.Construct implements IServerDep public readonly deploymentConfigName: string; public readonly deploymentConfigArn: string; - constructor(parent: cdk.Construct, id: string, private readonly props: ServerDeploymentConfigAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: ServerDeploymentConfigImportProps) { super(parent, id); this.deploymentConfigName = props.deploymentConfigName; @@ -53,7 +53,7 @@ class DefaultServerDeploymentConfig implements IServerDeploymentConfig { this.deploymentConfigArn = arnForDeploymentConfigName(this.deploymentConfigName); } - public export(): ServerDeploymentConfigAttributes { + public export(): ServerDeploymentConfigImportProps { return { deploymentConfigName: this.deploymentConfigName }; @@ -105,7 +105,7 @@ export class ServerDeploymentConfig extends cdk.Construct implements IServerDepl * @param props the properties of the referenced custom Deployment Configuration * @returns a Construct representing a reference to an existing custom Deployment Configuration */ - public static import(parent: cdk.Construct, id: string, props: ServerDeploymentConfigAttributes): IServerDeploymentConfig { + public static import(parent: cdk.Construct, id: string, props: ServerDeploymentConfigImportProps): IServerDeploymentConfig { return new ImportedServerDeploymentConfig(parent, id, props); } @@ -124,7 +124,7 @@ export class ServerDeploymentConfig extends cdk.Construct implements IServerDepl this.deploymentConfigArn = arnForDeploymentConfigName(this.deploymentConfigName); } - public export(): ServerDeploymentConfigAttributes { + public export(): ServerDeploymentConfigImportProps { return { deploymentConfigName: new cdk.Output(this, 'DeploymentConfigName', { value: this.deploymentConfigName, diff --git a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts index 5d84ebb9b8aac..5c3536c0de048 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts @@ -18,7 +18,7 @@ export interface IServerDeploymentGroup { readonly deploymentGroupArn: string; readonly deploymentConfig: IServerDeploymentConfig; readonly autoScalingGroups?: autoscaling.AutoScalingGroup[]; - export(): ServerDeploymentGroupAttributes; + export(): ServerDeploymentGroupImportProps; } /** @@ -27,7 +27,7 @@ export interface IServerDeploymentGroup { * @see ServerDeploymentGroupRef#import * @see ServerDeploymentGroupRef#export */ -export interface ServerDeploymentGroupAttributes { +export interface ServerDeploymentGroupImportProps { /** * The reference to the CodeDeploy EC2/on-premise Application * that this Deployment Group belongs to. @@ -71,7 +71,7 @@ export abstract class ServerDeploymentGroupBase extends cdk.Construct implements this.deploymentConfig = deploymentConfig || ServerDeploymentConfig.OneAtATime; } - public abstract export(): ServerDeploymentGroupAttributes; + public abstract export(): ServerDeploymentGroupImportProps; /** * Convenience method for creating a new {@link PipelineDeployAction} @@ -99,7 +99,7 @@ class ImportedServerDeploymentGroup extends ServerDeploymentGroupBase { public readonly deploymentGroupArn: string; public readonly autoScalingGroups?: autoscaling.AutoScalingGroup[] = undefined; - constructor(parent: cdk.Construct, id: string, private readonly props: ServerDeploymentGroupAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: ServerDeploymentGroupImportProps) { super(parent, id, props.deploymentConfig); this.application = props.application; @@ -284,7 +284,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase { * @param props the properties of the referenced Deployment Group * @returns a Construct representing a reference to an existing Deployment Group */ - public static import(parent: cdk.Construct, id: string, props: ServerDeploymentGroupAttributes): IServerDeploymentGroup { + public static import(parent: cdk.Construct, id: string, props: ServerDeploymentGroupImportProps): IServerDeploymentGroup { return new ImportedServerDeploymentGroup(parent, id, props); } @@ -347,7 +347,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase { this.deploymentGroupName); } - public export(): ServerDeploymentGroupAttributes { + public export(): ServerDeploymentGroupImportProps { return { application: this.application, deploymentGroupName: new cdk.Output(this, 'DeploymentGroupName', { diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index 1eeb1e8590104..a03cbfca68d27 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -8,10 +8,10 @@ export interface ISecurityGroup extends ISecurityGroupRule, IConnectable { readonly securityGroupId: string; addIngressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string): void; addEgressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string): void; - export(): SecurityGroupAttributes; + export(): SecurityGroupImportProps; } -export interface SecurityGroupAttributes { +export interface SecurityGroupImportProps { /** * ID of security group */ @@ -78,7 +78,7 @@ export abstract class SecurityGroupBase extends Construct implements ISecurityGr /** * Export this SecurityGroup for use in a different Stack */ - public abstract export(): SecurityGroupAttributes; + public abstract export(): SecurityGroupImportProps; } export interface SecurityGroupProps { @@ -134,7 +134,7 @@ export class SecurityGroup extends SecurityGroupBase implements ITaggable { /** * Import an existing SecurityGroup */ - public static import(parent: Construct, id: string, props: SecurityGroupAttributes): ISecurityGroup { + public static import(parent: Construct, id: string, props: SecurityGroupImportProps): ISecurityGroup { return new ImportedSecurityGroup(parent, id, props); } @@ -191,7 +191,7 @@ export class SecurityGroup extends SecurityGroupBase implements ITaggable { /** * Export this SecurityGroup for use in a different Stack */ - public export(): SecurityGroupAttributes { + public export(): SecurityGroupImportProps { return { securityGroupId: new Output(this, 'SecurityGroupId', { value: this.securityGroupId }).makeImportValue().toString() }; @@ -392,7 +392,7 @@ export interface ConnectionRule { class ImportedSecurityGroup extends SecurityGroupBase { public readonly securityGroupId: string; - constructor(parent: Construct, name: string, private readonly props: SecurityGroupAttributes) { + constructor(parent: Construct, name: string, private readonly props: SecurityGroupImportProps) { super(parent, name); this.securityGroupId = props.securityGroupId; diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts index e4f022ef0a4ff..29e8b42977f71 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts @@ -1,6 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import cxapi = require('@aws-cdk/cx-api'); -import { VpcNetworkAttributes } from './vpc-ref'; +import { VpcNetworkImportProps } from './vpc-ref'; /** * Properties for looking up an existing VPC. @@ -66,7 +66,7 @@ export class VpcNetworkProvider { /** * Return the VPC import props matching the filter */ - public get vpcProps(): VpcNetworkAttributes { + public get vpcProps(): VpcNetworkImportProps { const ret: cxapi.VpcContextResponse = this.provider.getValue(DUMMY_VPC_PROPS); return ret; } diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts index 49a4d0e88a6c0..3d0ce4dc6530b 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts @@ -25,7 +25,7 @@ export interface IVpcSubnet extends IDependable { /** * Exports this subnet to another stack. */ - export(): VpcSubnetAttributes; + export(): VpcSubnetImportProps; } export interface IVpcNetwork extends IDependable { @@ -82,7 +82,7 @@ export interface IVpcNetwork extends IDependable { /** * Exports this VPC so it can be consumed by another stack. */ - export(): VpcNetworkAttributes; + export(): VpcNetworkImportProps; } /** @@ -225,7 +225,7 @@ export abstract class VpcNetworkBase extends Construct implements IVpcNetwork { /** * Export this VPC from the stack */ - public abstract export(): VpcNetworkAttributes; + public abstract export(): VpcNetworkImportProps; /** * Return whether the given subnet is one of this VPC's public subnets. @@ -255,7 +255,7 @@ export abstract class VpcNetworkBase extends Construct implements IVpcNetwork { /** * Properties that reference an external VpcNetwork */ -export interface VpcNetworkAttributes { +export interface VpcNetworkImportProps { /** * VPC's identifier */ @@ -309,7 +309,7 @@ export interface VpcNetworkAttributes { isolatedSubnetNames?: string[]; } -export interface VpcSubnetAttributes { +export interface VpcSubnetImportProps { /** * The Availability Zone the subnet is located in */ diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index a210fb5a79a92..b1ade5e58448f 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -4,7 +4,7 @@ import { CfnRouteTable, CfnSubnet, CfnSubnetRouteTableAssociation, CfnVPC, CfnVP import { NetworkBuilder } from './network-util'; import { DEFAULT_SUBNET_NAME, ExportSubnetGroup, ImportSubnetGroup, subnetId } from './util'; import { VpcNetworkProvider, VpcNetworkProviderProps } from './vpc-network-provider'; -import { IVpcNetwork, IVpcSubnet, SubnetType, VpcNetworkAttributes, VpcNetworkBase, VpcPlacementStrategy, VpcSubnetAttributes } from './vpc-ref'; +import { IVpcNetwork, IVpcSubnet, SubnetType, VpcNetworkImportProps, VpcNetworkBase, VpcPlacementStrategy, VpcSubnetImportProps } from './vpc-ref'; /** * Name tag constant */ @@ -218,7 +218,7 @@ export class VpcNetwork extends VpcNetworkBase implements cdk.ITaggable { /** * Import an exported VPC */ - public static import(parent: cdk.Construct, name: string, props: VpcNetworkAttributes): IVpcNetwork { + public static import(parent: cdk.Construct, name: string, props: VpcNetworkImportProps): IVpcNetwork { return new ImportedVpcNetwork(parent, name, props); } @@ -362,7 +362,7 @@ export class VpcNetwork extends VpcNetworkBase implements cdk.ITaggable { /** * Export this VPC from the stack */ - public export(): VpcNetworkAttributes { + public export(): VpcNetworkImportProps { const pub = new ExportSubnetGroup(this, 'PublicSubnetIDs', this.publicSubnets, SubnetType.Public, this.availabilityZones.length); const priv = new ExportSubnetGroup(this, 'PrivateSubnetIDs', this.privateSubnets, SubnetType.Private, this.availabilityZones.length); const iso = new ExportSubnetGroup(this, 'IsolatedSubnetIDs', this.isolatedSubnets, SubnetType.Isolated, this.availabilityZones.length); @@ -519,7 +519,7 @@ export interface VpcSubnetProps { * Represents a new VPC subnet resource */ export class VpcSubnet extends cdk.Construct implements IVpcSubnet, cdk.ITaggable, cdk.IDependable { - public static import(parent: cdk.Construct, name: string, props: VpcSubnetAttributes): IVpcSubnet { + public static import(parent: cdk.Construct, name: string, props: VpcSubnetImportProps): IVpcSubnet { return new ImportedVpcSubnet(parent, name, props); } @@ -577,7 +577,7 @@ export class VpcSubnet extends cdk.Construct implements IVpcSubnet, cdk.ITaggabl this.dependencyElements.push(subnet, table, routeAssoc); } - public export(): VpcSubnetAttributes { + public export(): VpcSubnetImportProps { return { availabilityZone: new cdk.Output(this, 'AvailabilityZone', { value: this.availabilityZone }).makeImportValue().toString(), subnetId: new cdk.Output(this, 'VpcSubnetId', { value: this.subnetId }).makeImportValue().toString(), @@ -671,7 +671,7 @@ export class ImportedVpcNetwork extends VpcNetworkBase { public readonly isolatedSubnets: IVpcSubnet[]; public readonly availabilityZones: string[]; - constructor(parent: cdk.Construct, id: string, private readonly props: VpcNetworkAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: VpcNetworkImportProps) { super(parent, id); this.vpcId = props.vpcId; @@ -698,7 +698,7 @@ export class ImportedVpcSubnet extends cdk.Construct implements IVpcSubnet { public readonly subnetId: string; public readonly dependencyElements = new Array(); - constructor(parent: cdk.Construct, id: string, private readonly props: VpcSubnetAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: VpcSubnetImportProps) { super(parent, id); this.subnetId = props.subnetId; diff --git a/packages/@aws-cdk/aws-ec2/test/example.share-vpcs.lit.ts b/packages/@aws-cdk/aws-ec2/test/example.share-vpcs.lit.ts index b96d34371c5c4..c48f53f38fcd9 100644 --- a/packages/@aws-cdk/aws-ec2/test/example.share-vpcs.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/example.share-vpcs.lit.ts @@ -15,7 +15,7 @@ class ConstructThatTakesAVpc extends cdk.Construct { /// !show class Stack1 extends cdk.Stack { - public readonly vpcProps: ec2.VpcNetworkAttributes; + public readonly vpcProps: ec2.VpcNetworkImportProps; constructor(parent: cdk.App, id: string, props?: cdk.StackProps) { super(parent, id, props); @@ -28,7 +28,7 @@ class Stack1 extends cdk.Stack { } interface Stack2Props extends cdk.StackProps { - vpcProps: ec2.VpcNetworkAttributes; + vpcProps: ec2.VpcNetworkImportProps; } class Stack2 extends cdk.Stack { diff --git a/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts b/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts index a8d2286c530a9..95eec4a810151 100644 --- a/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts +++ b/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts @@ -79,10 +79,10 @@ export interface IRepository { /** * Export this repository from the stack */ - export(): RepositoryAttributes; + export(): RepositoryImportProps; } -export interface RepositoryAttributes { +export interface RepositoryImportProps { /** * The ARN of the repository to import. * @@ -114,7 +114,7 @@ export abstract class RepositoryBase extends cdk.Construct implements IRepositor /** * Import a repository */ - public static import(parent: cdk.Construct, id: string, props: RepositoryAttributes): IRepository { + public static import(parent: cdk.Construct, id: string, props: RepositoryImportProps): IRepository { return new ImportedRepository(parent, id, props); } @@ -171,7 +171,7 @@ export abstract class RepositoryBase extends cdk.Construct implements IRepositor /** * Export this repository from the stack */ - public abstract export(): RepositoryAttributes; + public abstract export(): RepositoryImportProps; public addToPipeline(stage: codepipeline.IStage, name: string, props: CommonPipelineSourceActionProps = {}): PipelineSourceAction { @@ -254,7 +254,7 @@ class ImportedRepository extends RepositoryBase { public readonly repositoryName: string; public readonly repositoryArn: string; - constructor(parent: cdk.Construct, id: string, props: RepositoryAttributes) { + constructor(parent: cdk.Construct, id: string, props: RepositoryImportProps) { super(parent, id); if (props.repositoryArn) { @@ -282,7 +282,7 @@ class ImportedRepository extends RepositoryBase { } } - public export(): RepositoryAttributes { + public export(): RepositoryImportProps { return { repositoryArn: this.repositoryArn, repositoryName: this.repositoryName diff --git a/packages/@aws-cdk/aws-ecr/lib/repository.ts b/packages/@aws-cdk/aws-ecr/lib/repository.ts index bb905fe6229d5..b4f92bfca0cff 100644 --- a/packages/@aws-cdk/aws-ecr/lib/repository.ts +++ b/packages/@aws-cdk/aws-ecr/lib/repository.ts @@ -2,7 +2,7 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { CfnRepository } from './ecr.generated'; import { CountType, LifecycleRule, TagStatus } from './lifecycle'; -import { RepositoryAttributes, RepositoryBase } from "./repository-ref"; +import { RepositoryImportProps, RepositoryBase } from "./repository-ref"; export interface RepositoryProps { /** @@ -74,7 +74,7 @@ export class Repository extends RepositoryBase { /** * Export this repository from the stack */ - public export(): RepositoryAttributes { + public export(): RepositoryImportProps { return { repositoryArn: new cdk.Output(this, 'RepositoryArn', { value: this.repositoryArn }).makeImportValue().toString(), repositoryName: new cdk.Output(this, 'RepositoryName', { value: this.repositoryName }).makeImportValue().toString() diff --git a/packages/@aws-cdk/aws-ecs/lib/cluster.ts b/packages/@aws-cdk/aws-ecs/lib/cluster.ts index e739aa73e05a0..db8ade9548d70 100644 --- a/packages/@aws-cdk/aws-ecs/lib/cluster.ts +++ b/packages/@aws-cdk/aws-ecs/lib/cluster.ts @@ -30,7 +30,7 @@ export class Cluster extends cdk.Construct implements ICluster { /** * Import an existing cluster */ - public static import(parent: cdk.Construct, name: string, props: ClusterAttributes): ICluster { + public static import(parent: cdk.Construct, name: string, props: ClusterImportProps): ICluster { return new ImportedCluster(parent, name, props); } @@ -144,7 +144,7 @@ export class Cluster extends cdk.Construct implements ICluster { /** * Export the Cluster */ - public export(): ClusterAttributes { + public export(): ClusterImportProps { return { clusterName: new cdk.Output(this, 'ClusterName', { value: this.clusterName }).makeImportValue().toString(), vpc: this.vpc.export(), @@ -232,13 +232,13 @@ export interface ICluster { /** * Export the Cluster */ - export(): ClusterAttributes; + export(): ClusterImportProps; } /** * Properties to import an ECS cluster */ -export interface ClusterAttributes { +export interface ClusterImportProps { /** * Name of the cluster */ @@ -247,12 +247,12 @@ export interface ClusterAttributes { /** * VPC that the cluster instances are running in */ - vpc: ec2.VpcNetworkAttributes; + vpc: ec2.VpcNetworkImportProps; /** * Security group of the cluster instances */ - securityGroups: ec2.SecurityGroupAttributes[]; + securityGroups: ec2.SecurityGroupImportProps[]; /** * Whether the given cluster has EC2 capacity @@ -286,7 +286,7 @@ class ImportedCluster extends cdk.Construct implements ICluster { */ public readonly hasEc2Capacity: boolean; - constructor(parent: cdk.Construct, name: string, private readonly props: ClusterAttributes) { + constructor(parent: cdk.Construct, name: string, private readonly props: ClusterImportProps) { super(parent, name); this.clusterName = props.clusterName; this.vpc = ec2.VpcNetwork.import(this, "vpc", props.vpc); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts index a096cb4d71747..7257af6e3e4da 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts @@ -79,7 +79,7 @@ export class ApplicationListener extends BaseListener implements IApplicationLis /** * Import an existing listener */ - public static import(parent: cdk.Construct, id: string, props: ApplicationListenerAttributes): IApplicationListener { + public static import(parent: cdk.Construct, id: string, props: ApplicationListenerImportProps): IApplicationListener { return new ImportedApplicationListener(parent, id, props); } @@ -238,7 +238,7 @@ export class ApplicationListener extends BaseListener implements IApplicationLis /** * Export this listener */ - public export(): ApplicationListenerAttributes { + public export(): ApplicationListenerImportProps { return { listenerArn: new cdk.Output(this, 'ListenerArn', { value: this.listenerArn }).makeImportValue().toString(), securityGroupId: this.connections.securityGroups[0]!.export().securityGroupId, @@ -300,13 +300,13 @@ export interface IApplicationListener extends ec2.IConnectable, cdk.IDependable /** * Export this listener */ - export(): ApplicationListenerAttributes; + export(): ApplicationListenerImportProps; } /** * Properties to reference an existing listener */ -export interface ApplicationListenerAttributes { +export interface ApplicationListenerImportProps { /** * ARN of the listener */ @@ -332,7 +332,7 @@ class ImportedApplicationListener extends cdk.Construct implements IApplicationL */ public readonly listenerArn: string; - constructor(parent: cdk.Construct, id: string, private readonly props: ApplicationListenerAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: ApplicationListenerImportProps) { super(parent, id); this.listenerArn = props.listenerArn; diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts index 14f460a57b184..f3d1076ac023f 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts @@ -49,7 +49,7 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic /** * Import an existing Application Load Balancer */ - public static import(parent: cdk.Construct, id: string, props: ApplicationLoadBalancerAttributes): IApplicationLoadBalancer { + public static import(parent: cdk.Construct, id: string, props: ApplicationLoadBalancerImportProps): IApplicationLoadBalancer { return new ImportedApplicationLoadBalancer(parent, id, props); } @@ -110,7 +110,7 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic /** * Export this load balancer */ - public export(): ApplicationLoadBalancerAttributes { + public export(): ApplicationLoadBalancerImportProps { return { loadBalancerArn: new cdk.Output(this, 'LoadBalancerArn', { value: this.loadBalancerArn }).makeImportValue().toString(), securityGroupId: this.securityGroup.export().securityGroupId, @@ -495,13 +495,13 @@ export interface IApplicationLoadBalancer extends ec2.IConnectable { /** * Export this load balancer */ - export(): ApplicationLoadBalancerAttributes; + export(): ApplicationLoadBalancerImportProps; } /** * Properties to reference an existing load balancer */ -export interface ApplicationLoadBalancerAttributes { +export interface ApplicationLoadBalancerImportProps { /** * ARN of the load balancer */ @@ -557,7 +557,7 @@ class ImportedApplicationLoadBalancer extends cdk.Construct implements IApplicat */ public readonly vpc?: ec2.IVpcNetwork; - constructor(parent: cdk.Construct, id: string, private readonly props: ApplicationLoadBalancerAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: ApplicationLoadBalancerImportProps) { super(parent, id); this.loadBalancerArn = props.loadBalancerArn; diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts index 885fe252cc5b1..88afbbd2e2e86 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts @@ -2,7 +2,7 @@ import cloudwatch = require('@aws-cdk/aws-cloudwatch'); import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); import { BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, LoadBalancerTargetProps, - TargetGroupAttributes, TargetGroupBase } from '../shared/base-target-group'; + TargetGroupImportProps, TargetGroupBase } from '../shared/base-target-group'; import { ApplicationProtocol } from '../shared/enums'; import { ImportedTargetGroupBase } from '../shared/imported'; import { determineProtocolAndPort, LazyDependable } from '../shared/util'; @@ -66,7 +66,7 @@ export class ApplicationTargetGroup extends TargetGroupBase { /** * Import an existing target group */ - public static import(parent: cdk.Construct, id: string, props: TargetGroupAttributes): IApplicationTargetGroup { + public static import(parent: cdk.Construct, id: string, props: TargetGroupImportProps): IApplicationTargetGroup { return new ImportedApplicationTargetGroup(parent, id, props); } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts index 83d078d1ddbfe..e6c5ecba109aa 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts @@ -39,7 +39,7 @@ export class NetworkListener extends BaseListener implements INetworkListener { /** * Import an existing listener */ - public static import(parent: cdk.Construct, id: string, props: NetworkListenerAttributes): INetworkListener { + public static import(parent: cdk.Construct, id: string, props: NetworkListenerImportProps): INetworkListener { return new ImportedNetworkListener(parent, id, props); } @@ -103,7 +103,7 @@ export class NetworkListener extends BaseListener implements INetworkListener { /** * Export this listener */ - public export(): NetworkListenerAttributes { + public export(): NetworkListenerImportProps { return { listenerArn: new cdk.Output(this, 'ListenerArn', { value: this.listenerArn }).makeImportValue().toString() }; @@ -123,13 +123,13 @@ export interface INetworkListener extends cdk.IDependable { /** * Export this listener */ - export(): NetworkListenerAttributes; + export(): NetworkListenerImportProps; } /** * Properties to reference an existing listener */ -export interface NetworkListenerAttributes { +export interface NetworkListenerImportProps { /** * ARN of the listener */ @@ -147,7 +147,7 @@ class ImportedNetworkListener extends cdk.Construct implements INetworkListener */ public readonly listenerArn: string; - constructor(parent: cdk.Construct, id: string, private readonly props: NetworkListenerAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: NetworkListenerImportProps) { super(parent, id); this.listenerArn = props.listenerArn; diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts index b842a4562e777..8979ae96939f3 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts @@ -20,7 +20,7 @@ export interface NetworkLoadBalancerProps extends BaseLoadBalancerProps { * Define a new network load balancer */ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoadBalancer { - public static import(parent: cdk.Construct, id: string, props: NetworkLoadBalancerAttributes): INetworkLoadBalancer { + public static import(parent: cdk.Construct, id: string, props: NetworkLoadBalancerImportProps): INetworkLoadBalancer { return new ImportedNetworkLoadBalancer(parent, id, props); } @@ -47,7 +47,7 @@ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoa /** * Export this load balancer */ - public export(): NetworkLoadBalancerAttributes { + public export(): NetworkLoadBalancerImportProps { return { loadBalancerArn: new cdk.Output(this, 'LoadBalancerArn', { value: this.loadBalancerArn }).makeImportValue().toString() }; @@ -208,13 +208,13 @@ export interface INetworkLoadBalancer { /** * Export this load balancer */ - export(): NetworkLoadBalancerAttributes; + export(): NetworkLoadBalancerImportProps; } /** * Properties to reference an existing load balancer */ -export interface NetworkLoadBalancerAttributes { +export interface NetworkLoadBalancerImportProps { /** * ARN of the load balancer */ @@ -237,7 +237,7 @@ class ImportedNetworkLoadBalancer extends cdk.Construct implements INetworkLoadB */ public readonly vpc?: ec2.IVpcNetwork; - constructor(parent: cdk.Construct, id: string, private readonly props: NetworkLoadBalancerAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: NetworkLoadBalancerImportProps) { super(parent, id); this.loadBalancerArn = props.loadBalancerArn; diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts index d8ea34606ea40..9f505e6e147ac 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts @@ -1,6 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import { BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, LoadBalancerTargetProps, - TargetGroupAttributes, TargetGroupBase } from '../shared/base-target-group'; + TargetGroupImportProps, TargetGroupBase } from '../shared/base-target-group'; import { Protocol } from '../shared/enums'; import { ImportedTargetGroupBase } from '../shared/imported'; import { LazyDependable } from '../shared/util'; @@ -39,7 +39,7 @@ export class NetworkTargetGroup extends TargetGroupBase { /** * Import an existing listener */ - public static import(parent: cdk.Construct, id: string, props: TargetGroupAttributes): INetworkTargetGroup { + public static import(parent: cdk.Construct, id: string, props: TargetGroupImportProps): INetworkTargetGroup { return new ImportedNetworkTargetGroup(parent, id, props); } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts index fcd44c120ca21..5dc46928649ff 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts @@ -261,7 +261,7 @@ export abstract class TargetGroupBase extends cdk.Construct implements ITargetGr /** * Export this target group */ - public export(): TargetGroupAttributes { + public export(): TargetGroupImportProps { return { targetGroupArn: new cdk.Output(this, 'TargetGroupArn', { value: this.targetGroupArn }).makeImportValue().toString(), defaultPort: new cdk.Output(this, 'Port', { value: this.defaultPort }).makeImportValue().toString(), @@ -307,7 +307,7 @@ export abstract class TargetGroupBase extends cdk.Construct implements ITargetGr /** * Properties to reference an existing target group */ -export interface TargetGroupAttributes { +export interface TargetGroupImportProps { /** * ARN of the target group */ @@ -346,7 +346,7 @@ export interface ITargetGroup { /** * Export this target group */ - export(): TargetGroupAttributes; + export(): TargetGroupImportProps; } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts index fdfa6dfca13c4..4449f667785c4 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts @@ -1,5 +1,5 @@ import cdk = require('@aws-cdk/cdk'); -import { ITargetGroup, TargetGroupAttributes } from './base-target-group'; +import { ITargetGroup, TargetGroupImportProps } from './base-target-group'; /** * Base internal class for existing target groups @@ -15,7 +15,7 @@ export abstract class ImportedTargetGroupBase extends cdk.Construct implements I */ public readonly loadBalancerArns: string; - constructor(parent: cdk.Construct, id: string, private readonly props: TargetGroupAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: TargetGroupImportProps) { super(parent, id); this.targetGroupArn = props.targetGroupArn; diff --git a/packages/@aws-cdk/aws-events/lib/rule-ref.ts b/packages/@aws-cdk/aws-events/lib/rule-ref.ts index 155fff989e3bf..4bc2ebcb27398 100644 --- a/packages/@aws-cdk/aws-events/lib/rule-ref.ts +++ b/packages/@aws-cdk/aws-events/lib/rule-ref.ts @@ -1,4 +1,4 @@ -export interface EventRuleAttributes { +export interface EventRuleImportProps { /** * The value of the event rule Amazon Resource Name (ARN), such as * arn:aws:events:us-east-2:123456789012:rule/example. @@ -16,5 +16,5 @@ export interface IEventRule { /** * Exports this rule resource from this stack and returns an import token. */ - export(): EventRuleAttributes; + export(): EventRuleImportProps; } diff --git a/packages/@aws-cdk/aws-events/lib/rule.ts b/packages/@aws-cdk/aws-events/lib/rule.ts index e68c30299566c..85a989fcf27c3 100644 --- a/packages/@aws-cdk/aws-events/lib/rule.ts +++ b/packages/@aws-cdk/aws-events/lib/rule.ts @@ -2,7 +2,7 @@ import { Construct, Output, Token } from '@aws-cdk/cdk'; import { EventPattern } from './event-pattern'; import { CfnRule } from './events.generated'; import { TargetInputTemplate } from './input-options'; -import { EventRuleAttributes, IEventRule } from './rule-ref'; +import { EventRuleImportProps, IEventRule } from './rule-ref'; import { IEventRuleTarget } from './target'; import { mergeEventPattern } from './util'; @@ -67,7 +67,7 @@ export class EventRule extends Construct implements IEventRule { /** * Imports a rule by ARN into this stack. */ - public static import(parent: Construct, name: string, props: EventRuleAttributes): IEventRule { + public static import(parent: Construct, name: string, props: EventRuleImportProps): IEventRule { return new ImportedEventRule(parent, name, props); } @@ -102,7 +102,7 @@ export class EventRule extends Construct implements IEventRule { /** * Exports this rule resource from this stack and returns an import token. */ - public export(): EventRuleAttributes { + public export(): EventRuleImportProps { return { eventRuleArn: new Output(this, 'RuleArn', { value: this.ruleArn }).makeImportValue().toString() }; @@ -239,7 +239,7 @@ export class EventRule extends Construct implements IEventRule { class ImportedEventRule extends Construct implements IEventRule { public readonly ruleArn: string; - constructor(parent: Construct, id: string, private readonly props: EventRuleAttributes) { + constructor(parent: Construct, id: string, private readonly props: EventRuleImportProps) { super(parent, id); this.ruleArn = props.eventRuleArn; diff --git a/packages/@aws-cdk/aws-kinesis/lib/stream.ts b/packages/@aws-cdk/aws-kinesis/lib/stream.ts index 29d872b9ccdfd..01d272cf24cb4 100644 --- a/packages/@aws-cdk/aws-kinesis/lib/stream.ts +++ b/packages/@aws-cdk/aws-kinesis/lib/stream.ts @@ -23,7 +23,7 @@ export interface IStream extends logs.ILogSubscriptionDestination { /** * Exports this stream from the stack. */ - export(): StreamAttributes; + export(): StreamImportProps; /** * Grant read permissions for this stream and its contents to an IAM @@ -58,7 +58,7 @@ export interface IStream extends logs.ILogSubscriptionDestination { * `stream.export()`. Then, the consumer can use `Stream.import(this, ref)` and * get a `Stream`. */ -export interface StreamAttributes { +export interface StreamImportProps { /** * The ARN of the stream. */ @@ -67,7 +67,7 @@ export interface StreamAttributes { /** * The KMS key securing the contents of the stream if encryption is enabled. */ - encryptionKey?: kms.EncryptionKeyAttributes; + encryptionKey?: kms.EncryptionKeyImportProps; } /** @@ -108,7 +108,7 @@ export abstract class StreamBase extends cdk.Construct implements IStream { */ private cloudWatchLogsRole?: iam.Role; - public abstract export(): StreamAttributes; + public abstract export(): StreamImportProps; /** * Grant write permissions for this stream and its contents to an IAM @@ -317,7 +317,7 @@ export class Stream extends StreamBase { * @param ref A `StreamAttributes` object. Can be obtained from a call to * `stream.export()`. */ - public static import(parent: cdk.Construct, name: string, props: StreamAttributes): IStream { + public static import(parent: cdk.Construct, name: string, props: StreamImportProps): IStream { return new ImportedStream(parent, name, props); } @@ -354,7 +354,7 @@ export class Stream extends StreamBase { /** * Exports this stream from the stack. */ - public export(): StreamAttributes { + public export(): StreamImportProps { return { streamArn: new cdk.Output(this, 'StreamArn', { value: this.streamArn }).makeImportValue().toString(), encryptionKey: this.encryptionKey ? this.encryptionKey.export() : undefined, @@ -419,7 +419,7 @@ class ImportedStream extends StreamBase { public readonly streamName: string; public readonly encryptionKey?: kms.IEncryptionKey; - constructor(parent: cdk.Construct, name: string, private readonly props: StreamAttributes) { + constructor(parent: cdk.Construct, name: string, private readonly props: StreamImportProps) { super(parent, name); this.streamArn = props.streamArn; diff --git a/packages/@aws-cdk/aws-kms/lib/key.ts b/packages/@aws-cdk/aws-kms/lib/key.ts index ea79638384236..5bd50a5d531a5 100644 --- a/packages/@aws-cdk/aws-kms/lib/key.ts +++ b/packages/@aws-cdk/aws-kms/lib/key.ts @@ -27,10 +27,10 @@ export interface IEncryptionKey { * Exports this key from the current stack. * @returns a key ref which can be used in a call to `EncryptionKey.import(ref)`. */ - export(): EncryptionKeyAttributes; + export(): EncryptionKeyImportProps; } -export interface EncryptionKeyAttributes { +export interface EncryptionKeyImportProps { /** * The ARN of the external KMS key. */ @@ -74,7 +74,7 @@ export abstract class EncryptionKeyBase extends Construct { this.policy.addStatement(statement); } - public abstract export(): EncryptionKeyAttributes; + public abstract export(): EncryptionKeyImportProps; } /** @@ -130,7 +130,7 @@ export class EncryptionKey extends EncryptionKeyBase { * @param name The name of the construct. * @param props The key reference. */ - public static import(parent: Construct, name: string, props: EncryptionKeyAttributes): IEncryptionKey { + public static import(parent: Construct, name: string, props: EncryptionKeyImportProps): IEncryptionKey { return new ImportedEncryptionKey(parent, name, props); } @@ -162,7 +162,7 @@ export class EncryptionKey extends EncryptionKeyBase { * Exports this key from the current stack. * @returns a key ref which can be used in a call to `EncryptionKey.import(ref)`. */ - public export(): EncryptionKeyAttributes { + public export(): EncryptionKeyImportProps { return { keyArn: new Output(this, 'KeyArn', { value: this.keyArn }).makeImportValue().toString() }; @@ -199,7 +199,7 @@ class ImportedEncryptionKey extends EncryptionKeyBase { public readonly keyArn: string; protected readonly policy = undefined; // no policy associated with an imported key - constructor(parent: Construct, name: string, private readonly props: EncryptionKeyAttributes) { + constructor(parent: Construct, name: string, private readonly props: EncryptionKeyImportProps) { super(parent, name); this.keyArn = props.keyArn; diff --git a/packages/@aws-cdk/aws-lambda/lib/alias.ts b/packages/@aws-cdk/aws-lambda/lib/alias.ts index 7554c0f00a2c9..2abc2ac0fc3c4 100644 --- a/packages/@aws-cdk/aws-lambda/lib/alias.ts +++ b/packages/@aws-cdk/aws-lambda/lib/alias.ts @@ -1,6 +1,6 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { FunctionAttributes, FunctionBase, IFunction } from './lambda-ref'; +import { FunctionImportProps, FunctionBase, IFunction } from './lambda-ref'; import { Version } from './lambda-version'; import { CfnAlias } from './lambda.generated'; import { Permission } from './permission'; @@ -99,7 +99,7 @@ export class Alias extends FunctionBase { this.functionArn = alias.aliasArn; } - public export(): FunctionAttributes { + public export(): FunctionImportProps { return { functionArn: new cdk.Output(this, 'AliasArn', { value: this.functionArn }).makeImportValue().toString() }; diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts index 4bba6a7f27631..980e5a4e550ad 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts @@ -109,7 +109,7 @@ export interface IFunction extends events.IEventRuleTarget, logs.ILogSubscriptio /** * Export this Function (without the role) */ - export(): FunctionAttributes; + export(): FunctionImportProps; addEventSource(source: IEventSource): void; } @@ -117,7 +117,7 @@ export interface IFunction extends events.IEventRuleTarget, logs.ILogSubscriptio /** * Represents a Lambda function defined outside of this stack. */ -export interface FunctionAttributes { +export interface FunctionImportProps { /** * The ARN of the Lambda function. * @@ -346,7 +346,7 @@ export abstract class FunctionBase extends cdk.Construct implements IFunction { /** * Export this Function (without the role) */ - public abstract export(): FunctionAttributes; + public abstract export(): FunctionImportProps; /** * Allows this Lambda to be used as a destination for bucket notifications. diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda.ts b/packages/@aws-cdk/aws-lambda/lib/lambda.ts index 5b383877bf199..24111719c2c8c 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda.ts @@ -4,7 +4,7 @@ import iam = require('@aws-cdk/aws-iam'); import sqs = require('@aws-cdk/aws-sqs'); import cdk = require('@aws-cdk/cdk'); import { Code } from './code'; -import { FunctionAttributes, FunctionBase, IFunction } from './lambda-ref'; +import { FunctionBase, FunctionImportProps, IFunction } from './lambda-ref'; import { Version } from './lambda-version'; import { CfnFunction } from './lambda.generated'; import { Runtime } from './runtime'; @@ -197,7 +197,7 @@ export class Function extends FunctionBase { * @param attrs A reference to a Lambda function. Can be created manually (see * example above) or obtained through a call to `lambda.export()`. */ - public static import(parent: cdk.Construct, id: string, attrs: FunctionAttributes): IFunction { + public static import(parent: cdk.Construct, id: string, attrs: FunctionImportProps): IFunction { return new ImportedFunction(parent, id, attrs); } @@ -356,7 +356,7 @@ export class Function extends FunctionBase { /** * Export this Function (without the role) */ - public export(): FunctionAttributes { + public export(): FunctionImportProps { return { functionArn: new cdk.Output(this, 'FunctionArn', { value: this.functionArn }).makeImportValue().toString(), securityGroupId: this._connections && this._connections.securityGroups[0] @@ -497,7 +497,7 @@ export class ImportedFunction extends FunctionBase { protected readonly canCreatePermissions = false; - constructor(parent: cdk.Construct, id: string, private readonly props: FunctionAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: FunctionImportProps) { super(parent, id); this.functionArn = props.functionArn; diff --git a/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts b/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts index 3c21862adb900..8f5abe4b9eb7e 100644 --- a/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts +++ b/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts @@ -1,7 +1,7 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { Function as LambdaFunction, FunctionProps } from './lambda'; -import { FunctionAttributes, FunctionBase, IFunction } from './lambda-ref'; +import { FunctionBase, FunctionImportProps, IFunction } from './lambda-ref'; import { Permission } from './permission'; /** @@ -53,7 +53,7 @@ export class SingletonFunction extends FunctionBase { this.canCreatePermissions = true; // Doesn't matter, addPermission is overriden anyway } - public export(): FunctionAttributes { + public export(): FunctionImportProps { return this.lambdaFunction.export(); } diff --git a/packages/@aws-cdk/aws-logs/lib/log-group.ts b/packages/@aws-cdk/aws-logs/lib/log-group.ts index 9da3bb3132bb6..29999317512dc 100644 --- a/packages/@aws-cdk/aws-logs/lib/log-group.ts +++ b/packages/@aws-cdk/aws-logs/lib/log-group.ts @@ -48,7 +48,7 @@ export interface ILogGroup { /** * Export this LogGroup */ - export(): LogGroupAttributes; + export(): LogGroupImportProps; /** * Extract a metric from structured log events in the LogGroup @@ -80,7 +80,7 @@ export interface ILogGroup { /** * Properties for importing a LogGroup */ -export interface LogGroupAttributes { +export interface LogGroupImportProps { logGroupArn: string; } @@ -140,7 +140,7 @@ export abstract class LogGroupBase extends cdk.Construct implements ILogGroup { }); } - public abstract export(): LogGroupAttributes; + public abstract export(): LogGroupImportProps; /** * Extract a metric from structured log events in the LogGroup @@ -229,7 +229,7 @@ export class LogGroup extends LogGroupBase { /** * Import an existing LogGroup */ - public static import(parent: cdk.Construct, id: string, props: LogGroupAttributes): ILogGroup { + public static import(parent: cdk.Construct, id: string, props: LogGroupImportProps): ILogGroup { return new ImportedLogGroup(parent, id, props); } @@ -270,7 +270,7 @@ export class LogGroup extends LogGroupBase { /** * Export this LogGroup */ - public export(): LogGroupAttributes { + public export(): LogGroupImportProps { return { logGroupArn: new cdk.Output(this, 'LogGroupArn', { value: this.logGroupArn }).makeImportValue().toString() }; @@ -291,7 +291,7 @@ class ImportedLogGroup extends LogGroupBase { */ public readonly logGroupName: string; - constructor(parent: cdk.Construct, id: string, private readonly props: LogGroupAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: LogGroupImportProps) { super(parent, id); this.logGroupArn = props.logGroupArn; diff --git a/packages/@aws-cdk/aws-logs/lib/log-stream.ts b/packages/@aws-cdk/aws-logs/lib/log-stream.ts index 59991c0740dfe..33d6b36688192 100644 --- a/packages/@aws-cdk/aws-logs/lib/log-stream.ts +++ b/packages/@aws-cdk/aws-logs/lib/log-stream.ts @@ -11,13 +11,13 @@ export interface ILogStream { /** * Export this LogStream */ - export(): LogStreamAttributes; + export(): LogStreamImportProps; } /** * Properties for importing a LogStream */ -export interface LogStreamAttributes { +export interface LogStreamImportProps { logStreamName: string; } @@ -60,7 +60,7 @@ export class LogStream extends cdk.Construct implements ILogStream { /** * Import an existing LogGroup */ - public static import(parent: cdk.Construct, id: string, props: LogStreamAttributes): ILogStream { + public static import(parent: cdk.Construct, id: string, props: LogStreamImportProps): ILogStream { return new ImportedLogStream(parent, id, props); } @@ -87,7 +87,7 @@ export class LogStream extends cdk.Construct implements ILogStream { /** * Export this LogStream */ - public export(): LogStreamAttributes { + public export(): LogStreamImportProps { return { logStreamName: new cdk.Output(this, 'LogStreamName', { value: this.logStreamName }).makeImportValue().toString() }; @@ -103,7 +103,7 @@ class ImportedLogStream extends cdk.Construct implements ILogStream { */ public readonly logStreamName: string; - constructor(parent: cdk.Construct, id: string, private readonly props: LogStreamAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: LogStreamImportProps) { super(parent, id); this.logStreamName = props.logStreamName; diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts b/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts index ae17339a1a768..d5b35b3553beb 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts @@ -14,13 +14,13 @@ export interface IClusterParameterGroup { /** * Export this parameter group */ - export(): ClusterParameterGroupAttributes; + export(): ClusterParameterGroupImportProps; } /** * Properties to reference a cluster parameter group */ -export interface ClusterParameterGroupAttributes { +export interface ClusterParameterGroupImportProps { parameterGroupName: string; } @@ -51,7 +51,7 @@ export class ClusterParameterGroup extends cdk.Construct implements IClusterPara /** * Import a parameter group */ - public static import(parent: cdk.Construct, id: string, props: ClusterParameterGroupAttributes): IClusterParameterGroup { + public static import(parent: cdk.Construct, id: string, props: ClusterParameterGroupImportProps): IClusterParameterGroup { return new ImportedClusterParameterGroup(parent, id, props); } @@ -77,7 +77,7 @@ export class ClusterParameterGroup extends cdk.Construct implements IClusterPara /** * Export this parameter group */ - public export(): ClusterParameterGroupAttributes { + public export(): ClusterParameterGroupImportProps { return { parameterGroupName: new cdk.Output(this, 'ParameterGroupName', { value: this.parameterGroupName }).makeImportValue().toString() }; @@ -119,7 +119,7 @@ export class ClusterParameterGroup extends cdk.Construct implements IClusterPara class ImportedClusterParameterGroup extends cdk.Construct implements IClusterParameterGroup { public readonly parameterGroupName: string; - constructor(parent: cdk.Construct, id: string, private readonly props: ClusterParameterGroupAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: ClusterParameterGroupImportProps) { super(parent, id); this.parameterGroupName = props.parameterGroupName; } diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts index 6b2195d6198e2..1d943743b3246 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts @@ -42,13 +42,13 @@ export interface IDatabaseCluster extends ec2.IConnectable { /** * Export a Database Cluster for importing in another stack */ - export(): DatabaseClusterAttributes; + export(): DatabaseClusterImportProps; } /** * Properties that describe an existing cluster instance */ -export interface DatabaseClusterAttributes { +export interface DatabaseClusterImportProps { /** * The database port */ diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index 705a9370cc222..0b92b2be67362 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -1,7 +1,7 @@ import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); import { IClusterParameterGroup } from './cluster-parameter-group'; -import { DatabaseClusterAttributes, Endpoint, IDatabaseCluster } from './cluster-ref'; +import { DatabaseClusterImportProps, Endpoint, IDatabaseCluster } from './cluster-ref'; import { BackupProps, DatabaseClusterEngine, InstanceProps, Login } from './props'; import { CfnDBCluster, CfnDBInstance, CfnDBSubnetGroup } from './rds.generated'; @@ -97,7 +97,7 @@ export class DatabaseCluster extends cdk.Construct implements IDatabaseCluster { /** * Import an existing DatabaseCluster from properties */ - public static import(parent: cdk.Construct, name: string, props: DatabaseClusterAttributes): IDatabaseCluster { + public static import(parent: cdk.Construct, name: string, props: DatabaseClusterImportProps): IDatabaseCluster { return new ImportedDatabaseCluster(parent, name, props); } @@ -226,7 +226,7 @@ export class DatabaseCluster extends cdk.Construct implements IDatabaseCluster { /** * Export a Database Cluster for importing in another stack */ - public export(): DatabaseClusterAttributes { + public export(): DatabaseClusterImportProps { // tslint:disable:max-line-length return { port: new cdk.Output(this, 'Port', { value: this.clusterEndpoint.port, }).makeImportValue().toString(), @@ -292,7 +292,7 @@ class ImportedDatabaseCluster extends cdk.Construct implements IDatabaseCluster */ public readonly securityGroupId: string; - constructor(parent: cdk.Construct, name: string, private readonly props: DatabaseClusterAttributes) { + constructor(parent: cdk.Construct, name: string, private readonly props: DatabaseClusterImportProps) { super(parent, name); this.securityGroupId = props.securityGroupId; diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts index 19bddd9a95fd8..47b1288080603 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts @@ -1,7 +1,7 @@ import cdk = require('@aws-cdk/cdk'); import cxapi = require('@aws-cdk/cx-api'); import { HostedZone } from './hosted-zone'; -import { HostedZoneAttributes, IHostedZone } from './hosted-zone-ref'; +import { HostedZoneImportProps, IHostedZone } from './hosted-zone-ref'; /** * Zone properties for looking up the Hosted Zone @@ -46,7 +46,7 @@ export class HostedZoneProvider { /** * Return the hosted zone meeting the filter */ - public findHostedZone(): HostedZoneAttributes { + public findHostedZone(): HostedZoneImportProps { const zone = this.provider.getValue(DEFAULT_HOSTED_ZONE) as HostedZoneContextResponse; // CDK handles the '.' at the end, so remove it here if (zone.Name.endsWith('.')) { diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts index 807a66fd776d1..25602d6132c05 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts @@ -15,13 +15,13 @@ export interface IHostedZone { /** * Export the hosted zone */ - export(): HostedZoneAttributes; + export(): HostedZoneImportProps; } /** * Reference to a hosted zone */ -export interface HostedZoneAttributes { +export interface HostedZoneImportProps { /** * Identifier of the hosted zone */ diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index 142ee507f29d6..d0c6579d9d907 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts @@ -1,6 +1,6 @@ import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); -import { HostedZoneAttributes, IHostedZone } from './hosted-zone-ref'; +import { HostedZoneImportProps, IHostedZone } from './hosted-zone-ref'; import { CfnHostedZone, HostedZoneNameServers } from './route53.generated'; import { validateZoneName } from './util'; @@ -29,14 +29,14 @@ export interface PublicHostedZoneProps { } export abstract class HostedZone extends cdk.Construct implements IHostedZone { - public static import(parent: cdk.Construct, name: string, props: HostedZoneAttributes): IHostedZone { + public static import(parent: cdk.Construct, name: string, props: HostedZoneImportProps): IHostedZone { return new ImportedHostedZone(parent, name, props); } public abstract readonly hostedZoneId: string; public abstract readonly zoneName: string; - public export(): HostedZoneAttributes { + public export(): HostedZoneImportProps { return { hostedZoneId: new cdk.Output(this, 'HostedZoneId', { value: this.hostedZoneId }).makeImportValue().toString(), zoneName: this.zoneName, @@ -156,7 +156,7 @@ class ImportedHostedZone extends cdk.Construct implements IHostedZone { public readonly zoneName: string; - constructor(parent: cdk.Construct, name: string, private readonly props: HostedZoneAttributes) { + constructor(parent: cdk.Construct, name: string, private readonly props: HostedZoneImportProps) { super(parent, name); this.hostedZoneId = props.hostedZoneId; diff --git a/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts b/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts index 4028dfcb9fc0a..202710d47b9ad 100644 --- a/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts +++ b/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts @@ -1,6 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import { Test } from 'nodeunit'; -import { HostedZone, HostedZoneAttributes, HostedZoneProvider } from '../lib'; +import { HostedZone, HostedZoneImportProps, HostedZoneProvider } from '../lib'; export = { 'Hosted Zone Provider': { @@ -24,7 +24,7 @@ export = { stack.setContext(key, fakeZone); - const cdkZoneProps: HostedZoneAttributes = { + const cdkZoneProps: HostedZoneImportProps = { hostedZoneId: fakeZone.Id, zoneName: 'example.com', }; diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 5ab8bda3b3f2b..efba50fde88fc 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -50,7 +50,7 @@ export interface IBucket { /** * Exports this bucket from the stack. */ - export(): BucketAttributes; + export(): BucketImportProps; /** * Convenience method for creating a new {@link PipelineSourceAction}, @@ -178,7 +178,7 @@ export interface IBucket { * `bucket.export()`. Then, the consumer can use `Bucket.import(this, ref)` and * get a `Bucket`. */ -export interface BucketAttributes { +export interface BucketImportProps { /** * The ARN fo the bucket. At least one of bucketArn or bucketName must be * defined in order to initialize a bucket ref. @@ -256,7 +256,7 @@ export abstract class BucketBase extends cdk.Construct implements IBucket { /** * Exports this bucket from the stack. */ - public abstract export(): BucketAttributes; + public abstract export(): BucketImportProps; /** * Convenience method for creating a new {@link PipelineSourceAction}, @@ -563,7 +563,7 @@ export class Bucket extends BucketBase { * @param attrs A `BucketAttributes` object. Can be obtained from a call to * `bucket.export()` or manually created. */ - public static import(parent: cdk.Construct, id: string, attrs: BucketAttributes): IBucket { + public static import(parent: cdk.Construct, id: string, attrs: BucketImportProps): IBucket { return new ImportedBucket(parent, id, attrs); } @@ -615,7 +615,7 @@ export class Bucket extends BucketBase { /** * Exports this bucket from the stack. */ - public export(): BucketAttributes { + public export(): BucketImportProps { return { bucketArn: new cdk.Output(this, 'BucketArn', { value: this.bucketArn }).makeImportValue().toString(), bucketName: new cdk.Output(this, 'BucketName', { value: this.bucketName }).makeImportValue().toString(), @@ -960,7 +960,7 @@ class ImportedBucket extends BucketBase { public policy?: BucketPolicy; protected autoCreatePolicy: boolean; - constructor(parent: cdk.Construct, name: string, private readonly props: BucketAttributes) { + constructor(parent: cdk.Construct, name: string, private readonly props: BucketImportProps) { super(parent, name); const bucketName = parseBucketName(props); diff --git a/packages/@aws-cdk/aws-s3/lib/util.ts b/packages/@aws-cdk/aws-s3/lib/util.ts index a700f63801de2..a6c9861829a15 100644 --- a/packages/@aws-cdk/aws-s3/lib/util.ts +++ b/packages/@aws-cdk/aws-s3/lib/util.ts @@ -1,7 +1,7 @@ import cdk = require('@aws-cdk/cdk'); -import { BucketAttributes } from './bucket'; +import { BucketImportProps } from './bucket'; -export function parseBucketArn(props: BucketAttributes): string { +export function parseBucketArn(props: BucketImportProps): string { // if we have an explicit bucket ARN, use it. if (props.bucketArn) { @@ -22,7 +22,7 @@ export function parseBucketArn(props: BucketAttributes): string { throw new Error('Cannot determine bucket ARN. At least `bucketArn` or `bucketName` is needed'); } -export function parseBucketName(props: BucketAttributes): string | undefined { +export function parseBucketName(props: BucketImportProps): string | undefined { // if we have an explicit bucket name, use it. if (props.bucketName) { diff --git a/packages/@aws-cdk/aws-s3/test/demo.import-export.ts b/packages/@aws-cdk/aws-s3/test/demo.import-export.ts index 33d994206aa13..1ca1631cb301e 100644 --- a/packages/@aws-cdk/aws-s3/test/demo.import-export.ts +++ b/packages/@aws-cdk/aws-s3/test/demo.import-export.ts @@ -7,7 +7,7 @@ import s3 = require('../lib'); // `Bucket.import`. class Producer extends cdk.Stack { - public readonly myBucketRef: s3.BucketAttributes; + public readonly myBucketRef: s3.BucketImportProps; constructor(parent: cdk.App, name: string) { super(parent, name); @@ -35,7 +35,7 @@ class ConsumerConstruct extends cdk.Construct { // this bucket and contents. interface ConsumerProps { - userBucketRef: s3.BucketAttributes; + userBucketRef: s3.BucketImportProps; } class Consumer extends cdk.Stack { diff --git a/packages/@aws-cdk/aws-sns/lib/topic-ref.ts b/packages/@aws-cdk/aws-sns/lib/topic-ref.ts index 7f670afb5a756..c8cd0f83875a4 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic-ref.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic-ref.ts @@ -22,7 +22,7 @@ export interface ITopic extends /** * Export this Topic */ - export(): TopicAttributes; + export(): TopicImportProps; /** * Subscribe some endpoint to this topic @@ -145,7 +145,7 @@ export abstract class TopicBase extends cdk.Construct implements ITopic { /** * Export this Topic */ - public abstract export(): TopicAttributes; + public abstract export(): TopicImportProps; /** * Subscribe some endpoint to this topic @@ -407,7 +407,7 @@ export abstract class TopicBase extends cdk.Construct implements ITopic { /** * Reference to an external topic. */ -export interface TopicAttributes { +export interface TopicImportProps { topicArn: string; topicName: string; } diff --git a/packages/@aws-cdk/aws-sns/lib/topic.ts b/packages/@aws-cdk/aws-sns/lib/topic.ts index 3997d5f6d7ec5..3c51e8717ef74 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic.ts @@ -1,6 +1,6 @@ import { Construct, Output } from '@aws-cdk/cdk'; import { CfnTopic } from './sns.generated'; -import { ITopic, TopicAttributes, TopicBase } from './topic-ref'; +import { ITopic, TopicBase, TopicImportProps } from './topic-ref'; /** * Properties for a new SNS topic @@ -32,7 +32,7 @@ export class Topic extends TopicBase { /** * Import a Topic defined elsewhere */ - public static import(parent: Construct, name: string, props: TopicAttributes): ITopic { + public static import(parent: Construct, name: string, props: TopicImportProps): ITopic { return new ImportedTopic(parent, name, props); } @@ -56,7 +56,7 @@ export class Topic extends TopicBase { /** * Export this Topic */ - public export(): TopicAttributes { + public export(): TopicImportProps { return { topicArn: new Output(this, 'TopicArn', { value: this.topicArn }).makeImportValue().toString(), topicName: new Output(this, 'TopicName', { value: this.topicName }).makeImportValue().toString(), @@ -73,13 +73,13 @@ class ImportedTopic extends TopicBase { protected autoCreatePolicy: boolean = false; - constructor(parent: Construct, id: string, private readonly props: TopicAttributes) { + constructor(parent: Construct, id: string, private readonly props: TopicImportProps) { super(parent, id); this.topicArn = props.topicArn; this.topicName = props.topicName; } - public export(): TopicAttributes { + public export(): TopicImportProps { return this.props; } } diff --git a/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts b/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts index bab407b81df53..84287c71f1dc6 100644 --- a/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts +++ b/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts @@ -34,7 +34,7 @@ export interface IQueue extends s3n.IBucketNotificationDestination, autoscaling_ /** * Export a queue */ - export(): QueueAttributes; + export(): QueueImportProps; /** * Adds a statement to the IAM resource policy associated with this queue. @@ -137,7 +137,7 @@ export abstract class QueueBase extends cdk.Construct implements IQueue { /** * Export a queue */ - public abstract export(): QueueAttributes; + public abstract export(): QueueImportProps; /** * Adds a statement to the IAM resource policy associated with this queue. @@ -287,7 +287,7 @@ export abstract class QueueBase extends cdk.Construct implements IQueue { /** * Reference to a queue */ -export interface QueueAttributes { +export interface QueueImportProps { /** * The ARN of the queue. */ diff --git a/packages/@aws-cdk/aws-sqs/lib/queue.ts b/packages/@aws-cdk/aws-sqs/lib/queue.ts index 2ce032e379a6b..e066040fc3efd 100644 --- a/packages/@aws-cdk/aws-sqs/lib/queue.ts +++ b/packages/@aws-cdk/aws-sqs/lib/queue.ts @@ -1,6 +1,6 @@ import kms = require('@aws-cdk/aws-kms'); import cdk = require('@aws-cdk/cdk'); -import { IQueue, QueueAttributes, QueueBase } from './queue-ref'; +import { IQueue, QueueBase, QueueImportProps } from './queue-ref'; import { CfnQueue } from './sqs.generated'; import { validateProps } from './validate-props'; @@ -183,7 +183,7 @@ export class Queue extends QueueBase { /** * Import an existing queue */ - public static import(parent: cdk.Construct, name: string, props: QueueAttributes): IQueue { + public static import(parent: cdk.Construct, name: string, props: QueueImportProps): IQueue { return new ImportedQueue(parent, name, props); } @@ -285,7 +285,7 @@ export class Queue extends QueueBase { /** * Export a queue */ - public export(): QueueAttributes { + public export(): QueueImportProps { return { queueArn: new cdk.Output(this, 'QueueArn', { value: this.queueArn }).makeImportValue().toString(), queueUrl: new cdk.Output(this, 'QueueUrl', { value: this.queueUrl }).makeImportValue().toString(), @@ -345,7 +345,7 @@ class ImportedQueue extends QueueBase { protected readonly autoCreatePolicy = false; - constructor(parent: cdk.Construct, name: string, private readonly props: QueueAttributes) { + constructor(parent: cdk.Construct, name: string, private readonly props: QueueImportProps) { super(parent, name); this.queueArn = props.queueArn; this.queueUrl = props.queueUrl; diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts index 6aa01c5369a73..ea016a18217f6 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts @@ -44,7 +44,7 @@ export class StateMachine extends cdk.Construct implements IStateMachine { /** * Import a state machine */ - public static import(parent: cdk.Construct, id: string, props: StateMachineAttributes): IStateMachine { + public static import(parent: cdk.Construct, id: string, props: StateMachineImportProps): IStateMachine { return new ImportedStateMachine(parent, id, props); } @@ -192,7 +192,7 @@ export class StateMachine extends cdk.Construct implements IStateMachine { /** * Export this state machine */ - public export(): StateMachineAttributes { + public export(): StateMachineImportProps { return { stateMachineArn: new cdk.Output(this, 'StateMachineArn', { value: this.stateMachineArn }).makeImportValue().toString(), }; @@ -211,13 +211,13 @@ export interface IStateMachine { /** * Export this state machine */ - export(): StateMachineAttributes; + export(): StateMachineImportProps; } /** * Properties for an imported state machine */ -export interface StateMachineAttributes { +export interface StateMachineImportProps { /** * The ARN of the state machine */ @@ -226,7 +226,7 @@ export interface StateMachineAttributes { class ImportedStateMachine extends cdk.Construct implements IStateMachine { public readonly stateMachineArn: string; - constructor(parent: cdk.Construct, id: string, private readonly props: StateMachineAttributes) { + constructor(parent: cdk.Construct, id: string, private readonly props: StateMachineImportProps) { super(parent, id); this.stateMachineArn = props.stateMachineArn; } From be2fcd0c58d52ef2c17772251cb5bcb20b17e43c Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 17:48:22 +0200 Subject: [PATCH 17/26] Renames in comments --- .../cdk-examples-typescript/bucket-import-export/index.ts | 6 +++--- examples/cdk-examples-typescript/chat-app/index.ts | 2 +- packages/@aws-cdk/aws-apigateway/lib/method.ts | 2 +- packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts | 2 +- packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts | 4 ++-- packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts | 2 +- packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts | 4 ++-- packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts | 2 +- packages/@aws-cdk/aws-ec2/lib/security-group.ts | 2 +- packages/@aws-cdk/aws-ecr/lib/pipeline-action.ts | 2 +- packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts | 2 +- packages/@aws-cdk/aws-lambda/test/test.lambda.ts | 2 +- packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts | 2 +- .../lib/notifications-resource/notifications-resource.ts | 2 +- packages/@aws-cdk/aws-s3/lib/pipeline-action.ts | 2 +- packages/@aws-cdk/aws-s3/test/demo.import-export.ts | 4 ++-- packages/@aws-cdk/aws-sqs/test/test.sqs.ts | 2 +- 17 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/cdk-examples-typescript/bucket-import-export/index.ts b/examples/cdk-examples-typescript/bucket-import-export/index.ts index 3ffd0f7a27e19..32ecea2465819 100644 --- a/examples/cdk-examples-typescript/bucket-import-export/index.ts +++ b/examples/cdk-examples-typescript/bucket-import-export/index.ts @@ -3,7 +3,7 @@ import s3 = require('@aws-cdk/aws-s3'); import cdk = require('@aws-cdk/cdk'); // Define a stack with an S3 bucket and export it using `bucket.export()`. -// bucket.export returns a `BucketRef` object which can later be used in +// bucket.export returns an `IBucket` object which can later be used in // `Bucket.import`. class Producer extends cdk.Stack { @@ -18,7 +18,7 @@ class Producer extends cdk.Stack { } interface ConsumerConstructProps { - bucket: s3.BucketRef; + bucket: s3.IBucket; } class ConsumerConstruct extends cdk.Construct { @@ -29,7 +29,7 @@ class ConsumerConstruct extends cdk.Construct { } } -// Define a stack that requires a BucketRef as an input and uses `Bucket.import` +// Define a stack that requires an IBucket as an input and uses `Bucket.import` // to create a `Bucket` object that represents this external bucket. Grant a // user principal created within this consuming stack read/write permissions to // this bucket and contents. diff --git a/examples/cdk-examples-typescript/chat-app/index.ts b/examples/cdk-examples-typescript/chat-app/index.ts index 2f1e1ef3e7e85..e2cad596456aa 100644 --- a/examples/cdk-examples-typescript/chat-app/index.ts +++ b/examples/cdk-examples-typescript/chat-app/index.ts @@ -69,7 +69,7 @@ class MyStack extends cdk.Stack { } interface ChatAppFuncProps { - bucket: s3.BucketRef; + bucket: s3.IBucket; zipFile: string; } diff --git a/packages/@aws-cdk/aws-apigateway/lib/method.ts b/packages/@aws-cdk/aws-apigateway/lib/method.ts index efc39df09f01d..711abf00c2d56 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/method.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/method.ts @@ -23,7 +23,7 @@ export interface MethodOptions { * If `authorizationType` is `Custom`, this specifies the ID of the method * authorizer resource. * - * NOTE: in the future this will be replaced with an `AuthorizerRef` + * NOTE: in the future this will be replaced with an `IAuthorizer` * construct. */ authorizerId?: string; diff --git a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts index ecd94ebb58b55..e1b926d6d240b 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -285,7 +285,7 @@ export class AutoScalingGroup extends cdk.Construct implements IAutoScalingGroup * Add the security group to all instances via the launch configuration * security groups array. * - * @param securityGroup: The SecurityGroupRef to add + * @param securityGroup: The security group to add */ public addSecurityGroup(securityGroup: ec2.ISecurityGroup): void { this.securityGroups.push(securityGroup); diff --git a/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts b/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts index de532a4f9db8a..721e402147dc0 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts @@ -23,7 +23,7 @@ export interface CommonCodeBuildActionProps { /** * Common properties for creating {@link PipelineBuildAction} - * either directly, through its constructor, - * or through {@link ProjectRef#addToPipeline}. + * or through {@link IProject#addToPipeline}. */ export interface CommonPipelineBuildActionProps extends CommonCodeBuildActionProps, codepipeline.CommonActionProps { @@ -109,7 +109,7 @@ export class PipelineBuildAction extends codepipeline.BuildAction { /** * Common properties for creating {@link PipelineTestAction} - * either directly, through its constructor, - * or through {@link ProjectRef#addToPipelineAsTest}. + * or through {@link IProject#addToPipelineAsTest}. */ export interface CommonPipelineTestActionProps extends CommonCodeBuildActionProps, codepipeline.CommonActionProps { diff --git a/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts b/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts index ff99ce394fdec..0fa65e3699bcd 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts @@ -6,7 +6,7 @@ import { IRepository } from './repository'; /** * Common properties for creating {@link PipelineSourceAction} - * either directly, through its constructor, - * or through {@link RepositoryRef#addToPipeline}. + * or through {@link IRepository#addToPipeline}. */ export interface CommonPipelineSourceActionProps extends codepipeline.CommonActionProps { /** diff --git a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts index 5c3536c0de048..8cd588b07bff6 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts @@ -24,8 +24,8 @@ export interface IServerDeploymentGroup { /** * Properties of a reference to a CodeDeploy EC2/on-premise Deployment Group. * - * @see ServerDeploymentGroupRef#import - * @see ServerDeploymentGroupRef#export + * @see ServerDeploymentGroup#import + * @see IServerDeploymentGroup#export */ export interface ServerDeploymentGroupImportProps { /** diff --git a/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts b/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts index a0f9e00c17d88..2a840e575385a 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts @@ -6,7 +6,7 @@ import { IServerDeploymentGroup } from './deployment-group'; /** * Common properties for creating a {@link PipelineDeployAction}, * either directly, through its constructor, - * or through {@link ServerDeploymentGroupRef#addToPipeline}. + * or through {@link IServerDeploymentGroup#addToPipeline}. */ export interface CommonPipelineDeployActionProps extends codepipeline.CommonActionProps { /** diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index a03cbfca68d27..001c3935b87f7 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -126,7 +126,7 @@ export interface SecurityGroupProps { /** * Creates an Amazon EC2 security group within a VPC. * - * This class has an additional optimization over SecurityGroupRef that it can also create + * This class has an additional optimization over imported security groups that it can also create * inline ingress and egress rule (which saves on the total number of resources inside * the template). */ diff --git a/packages/@aws-cdk/aws-ecr/lib/pipeline-action.ts b/packages/@aws-cdk/aws-ecr/lib/pipeline-action.ts index 7d5af0917560e..ec0fa6db438f9 100644 --- a/packages/@aws-cdk/aws-ecr/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-ecr/lib/pipeline-action.ts @@ -6,7 +6,7 @@ import { IRepository } from './repository-ref'; /** * Common properties for the {@link PipelineSourceAction CodePipeline source Action}, * whether creating it directly, - * or through the {@link RepositoryRef#addToPipeline} method. + * or through the {@link IRepository#addToPipeline} method. */ export interface CommonPipelineSourceActionProps extends codepipeline.CommonActionProps { /** diff --git a/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts b/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts index 31737445b1412..256c7c0d8f4d6 100644 --- a/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts @@ -6,7 +6,7 @@ import { IFunction } from './lambda-ref'; /** * Common properties for creating a {@link PipelineInvokeAction} - * either directly, through its constructor, - * or through {@link FunctionRef#addToPipeline}. + * or through {@link IFunction#addToPipeline}. */ export interface CommonPipelineInvokeActionProps extends codepipeline.CommonActionProps { // because of @see links diff --git a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts index 218d6c69aede9..38c6a81a4c21e 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts @@ -234,7 +234,7 @@ export = { }, 'import/export': { - 'lambda.export() can be used to add Outputs to the stack and returns a LambdaRef object'(test: Test) { + 'lambda.export() can be used to add Outputs to the stack and returns an IFunction object'(test: Test) { // GIVEN const stack1 = new cdk.Stack(); const stack2 = new cdk.Stack(); diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts index 47b1288080603..cb54ebe820ebf 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts @@ -38,7 +38,7 @@ export class HostedZoneProvider { } /** - * This method calls `findHostedZone` and returns the imported `HostedZoneRef` + * This method calls `findHostedZone` and returns the imported hosted zone */ public findAndImport(parent: cdk.Construct, id: string): IHostedZone { return HostedZone.import(parent, id, this.findHostedZone()); diff --git a/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource.ts b/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource.ts index 10ae2819085e2..4e824f7447920 100644 --- a/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource.ts +++ b/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource.ts @@ -7,7 +7,7 @@ interface NotificationsProps { /** * The bucket to manage notifications for. * - * This cannot be a `BucketRef` because the bucket maintains the 1:1 + * This cannot be an `IBucket` because the bucket maintains the 1:1 * relationship with this resource. */ bucket: Bucket; diff --git a/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts b/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts index 175bb442e9d8c..43aa1a94a836c 100644 --- a/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts @@ -5,7 +5,7 @@ import { IBucket } from './bucket'; /** * Common properties for creating {@link PipelineSourceAction} - * either directly, through its constructor, - * or through {@link BucketRef#addToPipeline}. + * or through {@link IBucket#addToPipeline}. */ export interface CommonPipelineSourceActionProps extends codepipeline.CommonActionProps { /** diff --git a/packages/@aws-cdk/aws-s3/test/demo.import-export.ts b/packages/@aws-cdk/aws-s3/test/demo.import-export.ts index 1ca1631cb301e..e05b9dc41eeda 100644 --- a/packages/@aws-cdk/aws-s3/test/demo.import-export.ts +++ b/packages/@aws-cdk/aws-s3/test/demo.import-export.ts @@ -3,7 +3,7 @@ import cdk = require('@aws-cdk/cdk'); import s3 = require('../lib'); // Define a stack with an S3 bucket and export it using `bucket.export()`. -// bucket.export returns a `BucketRef` object which can later be used in +// bucket.export returns an `IBucket` object which can later be used in // `Bucket.import`. class Producer extends cdk.Stack { @@ -29,7 +29,7 @@ class ConsumerConstruct extends cdk.Construct { } } -// Define a stack that requires a BucketRef as an input and uses `Bucket.import` +// Define a stack that requires an IBucket as an input and uses `Bucket.import` // to create a `Bucket` object that represents this external bucket. Grant a // user principal created within this consuming stack read/write permissions to // this bucket and contents. diff --git a/packages/@aws-cdk/aws-sqs/test/test.sqs.ts b/packages/@aws-cdk/aws-sqs/test/test.sqs.ts index 97dfbb399d17e..37e9faff6a5ff 100644 --- a/packages/@aws-cdk/aws-sqs/test/test.sqs.ts +++ b/packages/@aws-cdk/aws-sqs/test/test.sqs.ts @@ -102,7 +102,7 @@ export = { // THEN - // "import" returns a a QueueRef bound to `Fn::ImportValue`s. + // "import" returns an IQueue bound to `Fn::ImportValue`s. test.deepEqual(resolve(imports.queueArn), { 'Fn::ImportValue': 'QueueQueueArn8CF496D5' }); test.deepEqual(resolve(imports.queueUrl), { 'Fn::ImportValue': 'QueueQueueUrlC30FF916' }); From 546df1db3a594c687091825a42855a25cf997b2c Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 19:46:16 +0200 Subject: [PATCH 18/26] Fix linting error --- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index b1ade5e58448f..080c0ae8bb922 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -4,7 +4,7 @@ import { CfnRouteTable, CfnSubnet, CfnSubnetRouteTableAssociation, CfnVPC, CfnVP import { NetworkBuilder } from './network-util'; import { DEFAULT_SUBNET_NAME, ExportSubnetGroup, ImportSubnetGroup, subnetId } from './util'; import { VpcNetworkProvider, VpcNetworkProviderProps } from './vpc-network-provider'; -import { IVpcNetwork, IVpcSubnet, SubnetType, VpcNetworkImportProps, VpcNetworkBase, VpcPlacementStrategy, VpcSubnetImportProps } from './vpc-ref'; +import { IVpcNetwork, IVpcSubnet, SubnetType, VpcNetworkBase, VpcNetworkImportProps, VpcPlacementStrategy, VpcSubnetImportProps } from './vpc-ref'; /** * Name tag constant */ From 8f5fe1e241a8161a113742dba2eccffa42bbe9a9 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 20:04:46 +0200 Subject: [PATCH 19/26] yet another tslint error --- packages/@aws-cdk/aws-ecr/lib/repository.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-ecr/lib/repository.ts b/packages/@aws-cdk/aws-ecr/lib/repository.ts index b4f92bfca0cff..1d74accc18173 100644 --- a/packages/@aws-cdk/aws-ecr/lib/repository.ts +++ b/packages/@aws-cdk/aws-ecr/lib/repository.ts @@ -2,7 +2,7 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { CfnRepository } from './ecr.generated'; import { CountType, LifecycleRule, TagStatus } from './lifecycle'; -import { RepositoryImportProps, RepositoryBase } from "./repository-ref"; +import { RepositoryBase, RepositoryImportProps } from "./repository-ref"; export interface RepositoryProps { /** From 4ccd6f106ec7269a8c8bc6f92031614064ee056d Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 20:32:50 +0200 Subject: [PATCH 20/26] a few more linting --- .../lib/alb/application-target-group.ts | 2 +- .../aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts | 2 +- packages/@aws-cdk/aws-lambda/lib/alias.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts index 88afbbd2e2e86..d3786805de5db 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts @@ -2,7 +2,7 @@ import cloudwatch = require('@aws-cdk/aws-cloudwatch'); import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); import { BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, LoadBalancerTargetProps, - TargetGroupImportProps, TargetGroupBase } from '../shared/base-target-group'; + TargetGroupBase, TargetGroupImportProps } from '../shared/base-target-group'; import { ApplicationProtocol } from '../shared/enums'; import { ImportedTargetGroupBase } from '../shared/imported'; import { determineProtocolAndPort, LazyDependable } from '../shared/util'; diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts index 9f505e6e147ac..44ef15726bbd6 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts @@ -1,6 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import { BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, LoadBalancerTargetProps, - TargetGroupImportProps, TargetGroupBase } from '../shared/base-target-group'; + TargetGroupBase, TargetGroupImportProps } from '../shared/base-target-group'; import { Protocol } from '../shared/enums'; import { ImportedTargetGroupBase } from '../shared/imported'; import { LazyDependable } from '../shared/util'; diff --git a/packages/@aws-cdk/aws-lambda/lib/alias.ts b/packages/@aws-cdk/aws-lambda/lib/alias.ts index 2abc2ac0fc3c4..a1d728b3b87c3 100644 --- a/packages/@aws-cdk/aws-lambda/lib/alias.ts +++ b/packages/@aws-cdk/aws-lambda/lib/alias.ts @@ -1,6 +1,6 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { FunctionImportProps, FunctionBase, IFunction } from './lambda-ref'; +import { FunctionBase, FunctionImportProps, IFunction } from './lambda-ref'; import { Version } from './lambda-version'; import { CfnAlias } from './lambda.generated'; import { Permission } from './permission'; From 41888be89c7f055917f68a12d65dee1025989fee Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 21:16:01 +0200 Subject: [PATCH 21/26] Add coverge to rule import/export --- .../@aws-cdk/aws-events/test/test.rule.ts | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-events/test/test.rule.ts b/packages/@aws-cdk/aws-events/test/test.rule.ts index 72743367c59d0..dd638cd64e548 100644 --- a/packages/@aws-cdk/aws-events/test/test.rule.ts +++ b/packages/@aws-cdk/aws-events/test/test.rule.ts @@ -1,6 +1,6 @@ import { expect, haveResource } from '@aws-cdk/assert'; import cdk = require('@aws-cdk/cdk'); -import { resolve } from '@aws-cdk/cdk'; +import { resolve, Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; import { IEventRuleTarget } from '../lib'; import { EventRule } from '../lib/rule'; @@ -331,6 +331,25 @@ export = { test.deepEqual(resolve(receivedRuleArn), resolve(rule.ruleArn)); test.deepEqual(receivedRuleId, rule.uniqueId); + test.done(); + }, + + 'import/export rule'(test: Test) { + // GIVEN + const stack = new Stack(); + const myRule = new EventRule(stack, 'MyRule'); + + // WHEN + const exportedRule = myRule.export(); + + const importedRule = EventRule.import(stack, 'ImportedRule', { + eventRuleArn: 'arn:of:rule' + }); + + // THEN + test.deepEqual(cdk.resolve(exportedRule), { eventRuleArn: { 'Fn::ImportValue': 'MyRuleRuleArnDB13ADB1' } }); + test.deepEqual(importedRule.ruleArn, 'arn:of:rule'); + test.done(); } }; From 980a1da8dbf411b619d190700e86c8b4adde2917 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 21:51:36 +0200 Subject: [PATCH 22/26] Extend converage --- packages/@aws-cdk/aws-ecr/lib/repository-ref.ts | 7 ++----- packages/@aws-cdk/aws-ecr/test/test.repository.ts | 3 +++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts b/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts index 95eec4a810151..3c73b055a06e6 100644 --- a/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts +++ b/packages/@aws-cdk/aws-ecr/lib/repository-ref.ts @@ -254,7 +254,7 @@ class ImportedRepository extends RepositoryBase { public readonly repositoryName: string; public readonly repositoryArn: string; - constructor(parent: cdk.Construct, id: string, props: RepositoryImportProps) { + constructor(parent: cdk.Construct, id: string, private readonly props: RepositoryImportProps) { super(parent, id); if (props.repositoryArn) { @@ -283,10 +283,7 @@ class ImportedRepository extends RepositoryBase { } public export(): RepositoryImportProps { - return { - repositoryArn: this.repositoryArn, - repositoryName: this.repositoryName - }; + return this.props; } public addToResourcePolicy(_statement: iam.PolicyStatement) { diff --git a/packages/@aws-cdk/aws-ecr/test/test.repository.ts b/packages/@aws-cdk/aws-ecr/test/test.repository.ts index a9b58c486b04c..e3bfa4ffcc657 100644 --- a/packages/@aws-cdk/aws-ecr/test/test.repository.ts +++ b/packages/@aws-cdk/aws-ecr/test/test.repository.ts @@ -179,9 +179,12 @@ export = { repositoryArn: 'arn:aws:ecr:us-east-1:585695036304:repository/foo/bar/foo/fooo' }); + const exportImport = repo2.export(); + // THEN test.deepEqual(cdk.resolve(repo2.repositoryArn), 'arn:aws:ecr:us-east-1:585695036304:repository/foo/bar/foo/fooo'); test.deepEqual(cdk.resolve(repo2.repositoryName), 'foo/bar/foo/fooo'); + test.deepEqual(cdk.resolve(exportImport), { repositoryArn: 'arn:aws:ecr:us-east-1:585695036304:repository/foo/bar/foo/fooo' }); test.done(); }, From 66870813f238a75171e34020339506946a653528 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 22:16:45 +0200 Subject: [PATCH 23/26] Preserve logical id --- .../aws-cloudfront/test/integ.cloudfront-alias-target.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-alias-target.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-alias-target.ts index 83aed6458402c..f7629bdfe774a 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-alias-target.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-alias-target.ts @@ -24,7 +24,7 @@ const distribution = new cloudfront.CloudFrontWebDistribution(stack, 'MyDistribu ] }); -new route53.AliasRecord(stack, 'Alias', { +new route53.AliasRecord(zone, 'Alias', { zone, recordName: '_foo', target: distribution From b81a1fdb928e320ef87d0ab1ee02f72d8f4b337b Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 22:43:31 +0200 Subject: [PATCH 24/26] Fix another hosted zone logical id --- .../aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts index b23f7715d68aa..abde2b0edd6a4 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts @@ -18,7 +18,7 @@ const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' }); -new route53.AliasRecord(stack, 'Alias', { +new route53.AliasRecord(zone, 'Alias', { zone, recordName: '_foo', target: lb From dcde666eb2baf0846357e5aa5da45fc53b9b8bac Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 27 Dec 2018 23:26:23 +0200 Subject: [PATCH 25/26] fix .net issue --- packages/@aws-cdk/aws-rds/lib/cluster-ref.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts index 1d943743b3246..4e4c8a4766c39 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts @@ -4,11 +4,6 @@ import ec2 = require('@aws-cdk/aws-ec2'); * Create a clustered database with a given number of instances. */ export interface IDatabaseCluster extends ec2.IConnectable { - /** - * Access to the network connections - */ - readonly connections: ec2.Connections; - /** * Identifier of the cluster */ From ae2e27e149903ff028f237293bec1bb47b79ab83 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Fri, 28 Dec 2018 00:20:21 +0200 Subject: [PATCH 26/26] remove another inherited override --- packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts index 980e5a4e550ad..5f4f1f7d621a8 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts @@ -35,13 +35,6 @@ export interface IFunction extends events.IEventRuleTarget, logs.ILogSubscriptio */ readonly role?: iam.Role; - /** - * Access the Connections object - * - * Will fail if not a VPC-enabled Lambda Function - */ - readonly connections: ec2.Connections; - /** * Whether or not this Lambda function was bound to a VPC *