Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(aws-apigateway): add support for UsagePlan, ApiKey, UsagePlanKey #2564

Merged
merged 30 commits into from
May 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a0aee19
feat(aws-apigateway): add support for UsagePlan, ApiKey, UsagePlanKey…
Nov 20, 2018
9c1bdf4
Update ts documentation for low-level cfn props
Nov 22, 2018
832d09d
replace UsagePlanKey with UsagPlan.addApiKey
Nov 27, 2018
1656684
feat(bootstrap): allow specifying the toolkit staging bucket name
May 1, 2019
6e47171
pulled upstream master
May 7, 2019
68c93e1
Merge branch 'master' of https://github.com/awslabs/aws-cdk
May 10, 2019
75aab2a
update with upstream, add lerna clean
May 10, 2019
dbd636f
Merge branch 'master' of https://github.com/awslabs/aws-cdk
May 11, 2019
13f1575
pulled in upstream
May 11, 2019
d11c8ca
fix TS9999: JSII errors
May 11, 2019
090da64
continued working on this PR..
May 16, 2019
7cc5435
- specify keys in UsagePlanProps
May 17, 2019
aa9a03a
specify keys in UsagePlanProps
May 17, 2019
d1f8bab
refactoring
May 17, 2019
4d656b0
Merge branch 'master' of https://github.com/awslabs/aws-cdk
May 17, 2019
4d066ef
Merge branch 'master' into orangewise/usage-723
May 17, 2019
070578e
make TS happy
May 17, 2019
6931471
remove empty object
May 18, 2019
93dfcd1
fix some linting issues
May 19, 2019
c965274
let build succeed
May 19, 2019
fd5ff1e
export ApiKey
May 20, 2019
b488719
pulled in upstream
May 20, 2019
c7b8871
merge upstream
May 20, 2019
360f933
Delete ln
orangewise May 20, 2019
057df82
Merge branch 'orangewise/usage-723' of https://github.com/cloudchefs/…
May 20, 2019
f65c6fd
implemented addApiStage
May 21, 2019
94e9bb5
Docstrings
May 21, 2019
6c69a29
document
May 21, 2019
431d731
pull upstream
May 24, 2019
663458d
Merge branch 'master' into orangewise/usage-723
May 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ npm ci --global-style
export PATH=node_modules/.bin:$PATH

echo "============================================================================================="
echo "bootstrapping..."
echo "cleanup and start bootstrapping..."
lerna clean --yes
lerna bootstrap --reject-cycles --ci
36 changes: 36 additions & 0 deletions packages/@aws-cdk/aws-apigateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,42 @@ book.addMethod('GET', getBookIntegration, {
});
```

The following example shows how to use an API Key with a usage plan:

```ts
const hello = new lambda.Function(this, 'hello', {
runtime: lambda.Runtime.NodeJS810,
handler: 'hello.handler',
code: lambda.Code.asset('lambda')
});

const api = new apigateway.RestApi(this, 'hello-api', { });
const integration = new apigateway.LambdaIntegration(hello);

const v1 = api.root.addResource('v1');
const echo = v1.addResource('echo');
const echoMethod = echo.addMethod('GET', integration, { apiKeyRequired: true });
const key = api.addApiKey('ApiKey');

const plan = api.addUsagePlan('UsagePlan', {
name: 'Easy',
apiKey: key
});

plan.addApiStage({
stage: api.deploymentStage,
throttle: [
{
method: echoMethod,
throttle: {
rateLimit: 10,
burstLimit: 2
}
}
]
});
```

#### Default Integration and Method Options

The `defaultIntegration` and `defaultMethodOptions` properties can be used to
Expand Down
112 changes: 112 additions & 0 deletions packages/@aws-cdk/aws-apigateway/lib/api-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Construct, IResource as IResourceBase, Resource } from '@aws-cdk/cdk';
import { CfnApiKey } from './apigateway.generated';
import { ResourceOptions } from "./resource";
import { RestApi } from './restapi';

/**
* API keys are alphanumeric string values that you distribute to
* app developer customers to grant access to your API
*/
export interface ApiKeyAttributes {
orangewise marked this conversation as resolved.
Show resolved Hide resolved
/**
* The API key ID.
* @attribute
*/
readonly keyId: string;
}

/**
* API keys are alphanumeric string values that you distribute to
* app developer customers to grant access to your API
*/
export interface IApiKey extends IResourceBase {
orangewise marked this conversation as resolved.
Show resolved Hide resolved
/**
* The API key ID.
* @attribute
*/
readonly keyId: string;
}

/**
* ApiKey Properties.
*/
export interface ApiKeyProps extends ResourceOptions {
orangewise marked this conversation as resolved.
Show resolved Hide resolved
/**
* A list of resources this api key is associated with.
* @default none
*/
readonly resources?: RestApi[];

/**
* An AWS Marketplace customer identifier to use when integrating with the AWS SaaS Marketplace.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-customerid
* @default none
*/
readonly customerId?: string;

/**
* A description of the purpose of the API key.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-description
* @default none
*/
readonly description?: string;

/**
* Indicates whether the API key can be used by clients.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-enabled
* @default true
*/
readonly enabled?: boolean;

/**
* Specifies whether the key identifier is distinct from the created API key value.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-generatedistinctid
* @default false
*/
readonly generateDistinctId?: boolean;

/**
* A name for the API key. If you don't specify a name, AWS CloudFormation generates a unique physical ID and uses that ID for the API key name.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-name
* @default automically generated name
*/
readonly name?: string;
}

/**
* An API Gateway ApiKey.
*
* An ApiKey can be distributed to API clients that are executing requests
* for Method resources that require an Api Key.
*/
export class ApiKey extends Resource implements IApiKey {
public readonly keyId: string;

constructor(scope: Construct, id: string, props: ApiKeyProps = { }) {
super(scope, id);

const resource = new CfnApiKey(this, 'Resource', {
customerId: props.customerId,
description: props.description,
enabled: props.enabled || true,
generateDistinctId: props.generateDistinctId,
name: props.name,
stageKeys: this.renderStageKeys(props.resources)
});

this.keyId = resource.ref;
}

private renderStageKeys(resources: RestApi[] | undefined): CfnApiKey.StageKeyProperty[] | undefined {
if (!resources) {
return undefined;
}

return resources.map((resource: RestApi) => {
const restApi = resource;
const restApiId = restApi.restApiId;
const stageName = restApi.deploymentStage!.stageName.toString();
return { restApiId, stageName };
});
}
}
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-apigateway/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export * from './deployment';
export * from './stage';
export * from './integrations';
export * from './lambda-api';
export * from './api-key';
export * from './usage-plan';
export * from './vpc-link';
export * from './methodresponse';
export * from './model';
Expand Down
18 changes: 18 additions & 0 deletions packages/@aws-cdk/aws-apigateway/lib/restapi.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import iam = require('@aws-cdk/aws-iam');
import { CfnOutput, Construct, IResource as IResourceBase, Resource } from '@aws-cdk/cdk';
import { ApiKey, IApiKey } from './api-key';
import { CfnAccount, CfnRestApi } from './apigateway.generated';
import { Deployment } from './deployment';
import { Integration } from './integration';
import { Method, MethodOptions } from './method';
import { IResource, ResourceBase, ResourceOptions } from './resource';
import { Stage, StageOptions } from './stage';
import { UsagePlan, UsagePlanProps } from './usage-plan';

export interface IRestApi extends IResourceBase {
/**
Expand Down Expand Up @@ -249,6 +251,22 @@ export class RestApi extends Resource implements IRestApi {
return this.deploymentStage.urlForPath(path);
}

/**
* Adds a usage plan.
*/
public addUsagePlan(id: string, props: UsagePlanProps): UsagePlan {
return new UsagePlan(this, id, props);
}

/**
* Add an ApiKey
*/
public addApiKey(id: string): IApiKey {
return new ApiKey(this, id, {
resources: [this]
});
}

/**
* @returns The "execute-api" ARN.
* @default "*" returns the execute API ARN for all methods/resources in
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-apigateway/lib/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export class Stage extends Resource {
*/
public readonly stageName: string;

private readonly restApi: IRestApi;
public readonly restApi: IRestApi;
private enableCacheCluster?: boolean;

constructor(scope: Construct, id: string, props: StageProps) {
Expand Down
Loading