Skip to content

Commit

Permalink
feat: aws resource api linting (breaking changes) (#1434)
Browse files Browse the repository at this point in the history
Fixes #742 
Built on top of #1428 

BREAKING CHANGE: AWS resource-related classes have been changed to conform to API guidelines:

  - `XxxRef` abstract classes are now `IXxx` interfaces
  - `XxxRefProps` are now `XxxImportProps`
  - `XxxRef.import(...)` are now `Xxx.import(...)` accept `XxxImportProps` and return `IXxx`
  - `export(): XxxImportProps` is now defined in `IXxx` and implemented by imported resources
  - Lambda's static "metric" methods moved from `lambda.FunctionRef` to `lambda.Function`.
  - Route53 record classes now require a `zone` when created (not assuming zone is the parent construct).
  • Loading branch information
Elad Ben-Israel committed Dec 28, 2018
1 parent 0d2b633 commit 8c17ca7
Show file tree
Hide file tree
Showing 142 changed files with 2,540 additions and 1,360 deletions.
15 changes: 9 additions & 6 deletions docs/src/aws-construct-lib.rst
Expand Up @@ -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.
Expand All @@ -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>`
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down
12 changes: 6 additions & 6 deletions docs/src/passing-in-data.rst
Expand Up @@ -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();
}
}
Expand All @@ -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
Expand All @@ -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
}
Expand All @@ -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();
Expand Down
10 changes: 5 additions & 5 deletions examples/cdk-examples-typescript/bucket-import-export/index.ts
Expand Up @@ -3,11 +3,11 @@ 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 {
public readonly myBucketRef: s3.BucketRefProps;
public readonly myBucketRef: s3.BucketImportProps;

constructor(parent: cdk.App, name: string) {
super(parent, name);
Expand All @@ -18,7 +18,7 @@ class Producer extends cdk.Stack {
}

interface ConsumerConstructProps {
bucket: s3.BucketRef;
bucket: s3.IBucket;
}

class ConsumerConstruct extends cdk.Construct {
Expand All @@ -29,13 +29,13 @@ 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.

interface ConsumerProps {
userBucketRef: s3.BucketRefProps;
userBucketRef: s3.BucketImportProps;
}

class Consumer extends cdk.Stack {
Expand Down
4 changes: 2 additions & 2 deletions examples/cdk-examples-typescript/chat-app/index.ts
Expand Up @@ -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'
});

Expand Down Expand Up @@ -69,7 +69,7 @@ class MyStack extends cdk.Stack {
}

interface ChatAppFuncProps {
bucket: s3.BucketRef;
bucket: s3.IBucket;
zipFile: string;
}

Expand Down
2 changes: 1 addition & 1 deletion examples/cdk-examples-typescript/ec2/index.ts
Expand Up @@ -52,7 +52,7 @@ class MyApp extends cdk.Stack {
}

class CommonInfrastructure extends cdk.Stack {
public vpc: ec2.VpcNetworkRefProps;
public vpc: ec2.VpcNetworkImportProps;

constructor(parent: cdk.App, name: string, props?: cdk.StackProps) {
super(parent, name, props);
Expand Down
Expand Up @@ -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,
Expand Down
9 changes: 8 additions & 1 deletion packages/@aws-cdk/assets-docker/lib/adopted-repository.ts
Expand Up @@ -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', {
Expand Down Expand Up @@ -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.
*
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/assets/lib/asset.ts
Expand Up @@ -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
Expand Down Expand Up @@ -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
});

Expand Down
6 changes: 3 additions & 3 deletions 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.
Expand Down Expand Up @@ -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.
Expand Down
1 change: 0 additions & 1 deletion 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';
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts
Expand Up @@ -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({
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-apigateway/lib/method.ts
Expand Up @@ -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;
Expand Down
46 changes: 0 additions & 46 deletions 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;
}
}

0 comments on commit 8c17ca7

Please sign in to comment.