diff --git a/packages/@aws-cdk/aws-applicationautoscaling/lib/step-scaling-policy.ts b/packages/@aws-cdk/aws-applicationautoscaling/lib/step-scaling-policy.ts index 7ae93532ecde8..80cb19e90e620 100644 --- a/packages/@aws-cdk/aws-applicationautoscaling/lib/step-scaling-policy.ts +++ b/packages/@aws-cdk/aws-applicationautoscaling/lib/step-scaling-policy.ts @@ -108,7 +108,7 @@ export class StepScalingPolicy extends cdk.Construct { evaluationPeriods: 1, threshold, }); - this.lowerAlarm.addAlarmAction(this.lowerAction); + this.lowerAlarm.onAlarm(this.lowerAction); } if (alarms.upperAlarmIntervalIndex !== undefined) { @@ -138,7 +138,7 @@ export class StepScalingPolicy extends cdk.Construct { evaluationPeriods: 1, threshold, }); - this.upperAlarm.addAlarmAction(this.upperAction); + this.upperAlarm.onAlarm(this.upperAction); } } } 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 415e12e31bc95..238899b972c08 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -193,7 +193,7 @@ abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGrou /** * Send a message to either an SQS queue or SNS topic when instances launch or terminate */ - public addLifecycleHook(id: string, props: BasicLifecycleHookProps): LifecycleHook { + public onLifecycleTransition(id: string, props: BasicLifecycleHookProps): LifecycleHook { return new LifecycleHook(this, `LifecycleHook${id}`, { autoScalingGroup: this, ...props @@ -701,7 +701,7 @@ export interface IAutoScalingGroup extends IResource { /** * Send a message to either an SQS queue or SNS topic when instances launch or terminate */ - addLifecycleHook(id: string, props: BasicLifecycleHookProps): LifecycleHook; + onLifecycleTransition(id: string, props: BasicLifecycleHookProps): LifecycleHook; /** * Scale out or in based on time diff --git a/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-policy.ts b/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-policy.ts index 7fb1bb9c60f9c..e85e6f3546107 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-policy.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-policy.ts @@ -109,7 +109,7 @@ export class StepScalingPolicy extends cdk.Construct { evaluationPeriods: 1, threshold, }); - this.lowerAlarm.addAlarmAction(this.lowerAction); + this.lowerAlarm.onAlarm(this.lowerAction); } if (alarms.upperAlarmIntervalIndex !== undefined) { @@ -139,7 +139,7 @@ export class StepScalingPolicy extends cdk.Construct { evaluationPeriods: 1, threshold, }); - this.upperAlarm.addAlarmAction(this.upperAction); + this.upperAlarm.onAlarm(this.upperAction); } } } diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts b/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts index 276cc35e22fff..e680224545f96 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts @@ -18,7 +18,7 @@ export = { }); // WHEN - asg.addLifecycleHook('Transition', { + asg.onLifecycleTransition('Transition', { notificationTarget: new FakeNotificationTarget(), lifecycleTransition: autoscaling.LifecycleTransition.InstanceLaunching, defaultResult: autoscaling.DefaultResult.Abandon, diff --git a/packages/@aws-cdk/aws-cloudtrail/SAMPLE-EVENTS.md b/packages/@aws-cdk/aws-cloudtrail/SAMPLE-EVENTS.md deleted file mode 100644 index f729b5f8a0003..0000000000000 --- a/packages/@aws-cdk/aws-cloudtrail/SAMPLE-EVENTS.md +++ /dev/null @@ -1,68 +0,0 @@ -# Some sample CloudTrail events - -For reference. - - -## S3 - -PutObject - - { - "eventSource": "s3.amazonaws.com", - "resources": [ - { - "ARN": "arn:aws:s3:::BUCKETNAME/OBJECTKEY", - "type": "AWS::S3::Object" - }, - { - "accountId": "123456789012", - "ARN": "arn:aws:s3:::BUCKETNAME", - "type": "AWS::S3::Bucket" - } - ], - "eventTime": "2019-05-22T08:38:05Z", - "userAgent": "[aws-cli/1.16.96 Python/2.7.12 Linux/4.4.0-146-generic botocore/1.12.86]", - "readOnly": false, - "recipientAccountId": "123456789012", - "awsRegion": "eu-west-1", - "requestID": "CF9748DFDC5FB0A4", - "additionalEventData": { - "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", - "bytesTransferredOut": 0, - "AuthenticationMethod": "AuthHeader", - "x-amz-id-2": "hRJMAs5p4ALZIabP4ATIL53npWU61+N6LYWj02gdQtR0ymKSySzVXUSZx7ydv7tRJwk+XMaPerM=", - "bytesTransferredIn": 197, - "SignatureVersion": "SigV4" - }, - "eventType": "AwsApiCall", - "eventID": "3074546e-1bfa-4973-8502-b1bb4d0bda1a", - "eventVersion": "1.05", - "eventName": "PutObject", - "sourceIPAddress": "1.2.3.4", - "userIdentity": { - "accountId": "123456789012", - "type": "AssumedRole", - "principalId": "AROAJBNCAL3UTR5C42U4M:user-SomeRole", - "accessKeyId": "AZYCAIJERO6H7", - "sessionContext": { - "attributes": { - "mfaAuthenticated": "false", - "creationDate": "2019-05-22T08:10:21Z" - }, - "sessionIssuer": { - "accountId": "123456789012", - "type": "Role", - "principalId": "AROAJBNCAL3UTR5C42U4M", - "userName": "SomeRole", - "arn": "arn:aws:iam::123456789012:role/SomeRole" - } - }, - "arn": "arn:aws:sts::123456789012:assumed-role/SomeRole/user-SomeRole" - }, - "responseElements": null, - "requestParameters": { - "bucketName": "BUCKETNAME", - "Host": "BUCKETNAME.s3.eu-west-1.amazonaws.com", - "key": "OBJECTKEY" - } - } diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts index 6c8001a8712fa..da8ce991cfc86 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts @@ -222,16 +222,14 @@ export class Trail extends Resource { } /** - * Create an event rule for when an event is recorded by any Trail in the account. + * Create an event rule for when an event is recorded by any trail. * - * Note that the event doesn't necessarily have to come from this Trail, it can - * be captured from any one. - * - * Be sure to filter the event further down using an event pattern. + * Note that the event doesn't necessarily have to come from this + * trail. Be sure to filter the event properly using an event pattern. */ - public onCloudTrailEvent(id: string, options: events.OnEventOptions): events.Rule { - const rule = new events.Rule(this, id, options); - rule.addTarget(options.target); + public onEvent(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = new events.Rule(this, name, options); + rule.addTarget(target); rule.addEventPattern({ detailType: ['AWS API Call via CloudTrail'] }); diff --git a/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts b/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts index 605cc9f721033..facae5fe9003b 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts @@ -197,13 +197,11 @@ export = { const trail = new Trail(stack, 'MyAmazingCloudTrail', { managementEvents: ReadWriteType.WriteOnly }); // WHEN - trail.onCloudTrailEvent('DoEvents', { - target: { - bind: () => ({ - arn: 'arn', - id: 'myid' - }) - } + trail.onEvent('DoEvents', { + bind: () => ({ + arn: 'arn', + id: 'myid' + }) }); // THEN diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts b/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts index 923b43492c154..2f5929fc853d3 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts @@ -155,7 +155,7 @@ export class Alarm extends Resource implements IAlarm { * * Typically the ARN of an SNS topic or ARN of an AutoScaling policy. */ - public addAlarmAction(...actions: IAlarmAction[]) { + public onAlarm(...actions: IAlarmAction[]) { if (this.alarmActionArns === undefined) { this.alarmActionArns = []; } @@ -168,7 +168,7 @@ export class Alarm extends Resource implements IAlarm { * * Typically the ARN of an SNS topic or ARN of an AutoScaling policy. */ - public addInsufficientDataAction(...actions: IAlarmAction[]) { + public onInsufficientData(...actions: IAlarmAction[]) { if (this.insufficientDataActionArns === undefined) { this.insufficientDataActionArns = []; } @@ -181,7 +181,7 @@ export class Alarm extends Resource implements IAlarm { * * Typically the ARN of an SNS topic or ARN of an AutoScaling policy. */ - public addOkAction(...actions: IAlarmAction[]) { + public onOk(...actions: IAlarmAction[]) { if (this.okActionArns === undefined) { this.okActionArns = []; } diff --git a/packages/@aws-cdk/aws-cloudwatch/test/test.alarm.ts b/packages/@aws-cdk/aws-cloudwatch/test/test.alarm.ts index 0f5268b8b61b5..5ef3dfe2a4307 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/test.alarm.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/test.alarm.ts @@ -72,9 +72,9 @@ export = { evaluationPeriods: 2 }); - alarm.addAlarmAction(new TestAlarmAction('A')); - alarm.addInsufficientDataAction(new TestAlarmAction('B')); - alarm.addOkAction(new TestAlarmAction('C')); + alarm.onAlarm(new TestAlarmAction('A')); + alarm.onInsufficientData(new TestAlarmAction('B')); + alarm.onOk(new TestAlarmAction('C')); // THEN expect(stack).to(haveResource('AWS::CloudWatch::Alarm', { diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index b7535f8af7bb2..faebadbb2de75 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -32,13 +32,6 @@ export interface IProject extends IResource, iam.IGrantable { /** The IAM service Role of this Project. Undefined for imported Projects. */ readonly role?: iam.IRole; - /** - * Defines a CloudWatch event rule triggered when something happens with this project. - * - * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html - */ - onEvent(id: string, options: events.OnEventOptions): events.Rule; - /** * Defines a CloudWatch event rule triggered when the build project state * changes. You can filter specific build status events using an event @@ -64,7 +57,7 @@ export interface IProject extends IResource, iam.IGrantable { * * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html */ - onStateChange(id: string, options: events.OnEventOptions): events.Rule; + onStateChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines a CloudWatch event rule that triggers upon phase change of this @@ -72,22 +65,22 @@ export interface IProject extends IResource, iam.IGrantable { * * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html */ - onPhaseChange(id: string, options: events.OnEventOptions): events.Rule; + onPhaseChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines an event rule which triggers when a build starts. */ - onBuildStarted(id: string, options: events.OnEventOptions): events.Rule; + onBuildStarted(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines an event rule which triggers when a build fails. */ - onBuildFailed(id: string, options: events.OnEventOptions): events.Rule; + onBuildFailed(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines an event rule which triggers when a build completes successfully. */ - onBuildSucceeded(id: string, options: events.OnEventOptions): events.Rule; + onBuildSucceeded(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * @returns a CloudWatch metric associated with this build project. @@ -164,23 +157,6 @@ abstract class ProjectBase extends Resource implements IProject { /** The IAM service Role of this Project. */ public abstract readonly role?: iam.IRole; - /** - * Defines a CloudWatch event rule triggered when something happens with this project. - * - * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html - */ - public onEvent(id: string, options: events.OnEventOptions): events.Rule { - const rule = new events.Rule(this, id, options); - rule.addTarget(options.target); - rule.addEventPattern({ - source: ['aws.codebuild'], - detail: { - 'project-name': [this.projectName] - } - }); - return rule; - } - /** * Defines a CloudWatch event rule triggered when the build project state * changes. You can filter specific build status events using an event @@ -206,10 +182,17 @@ abstract class ProjectBase extends Resource implements IProject { * * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html */ - public onStateChange(id: string, options: events.OnEventOptions) { - const rule = this.onEvent(id, options); + public onStateChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = new events.Rule(this, name, options); + rule.addTarget(target); rule.addEventPattern({ + source: ['aws.codebuild'], detailType: ['CodeBuild Build State Change'], + detail: { + 'project-name': [ + this.projectName + ] + } }); return rule; } @@ -220,10 +203,17 @@ abstract class ProjectBase extends Resource implements IProject { * * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html */ - public onPhaseChange(id: string, options: events.OnEventOptions) { - const rule = this.onEvent(id, options); + public onPhaseChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = new events.Rule(this, name, options); + rule.addTarget(target); rule.addEventPattern({ + source: ['aws.codebuild'], detailType: ['CodeBuild Build Phase Change'], + detail: { + 'project-name': [ + this.projectName + ] + } }); return rule; } @@ -234,8 +224,8 @@ abstract class ProjectBase extends Resource implements IProject { * To access fields from the event in the event target input, * use the static fields on the `StateChangeEvent` class. */ - public onBuildStarted(id: string, options: events.OnEventOptions) { - const rule = this.onStateChange(id, options); + public onBuildStarted(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onStateChange(name, target, options); rule.addEventPattern({ detail: { 'build-status': ['IN_PROGRESS'] @@ -250,8 +240,8 @@ abstract class ProjectBase extends Resource implements IProject { * To access fields from the event in the event target input, * use the static fields on the `StateChangeEvent` class. */ - public onBuildFailed(id: string, options: events.OnEventOptions) { - const rule = this.onStateChange(id, options); + public onBuildFailed(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onStateChange(name, target, options); rule.addEventPattern({ detail: { 'build-status': ['FAILED'] @@ -266,8 +256,8 @@ abstract class ProjectBase extends Resource implements IProject { * To access fields from the event in the event target input, * use the static fields on the `StateChangeEvent` class. */ - public onBuildSucceeded(id: string, options: events.OnEventOptions) { - const rule = this.onStateChange(id, options); + public onBuildSucceeded(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onStateChange(name, target, options); rule.addEventPattern({ detail: { 'build-status': ['SUCCEEDED'] diff --git a/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts b/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts index bb4149c8ad9f4..7893113869115 100644 --- a/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts +++ b/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts @@ -973,11 +973,11 @@ export = { source: new codebuild.CodePipelineSource() }); - project.onBuildFailed('OnBuildFailed', { target: { bind: () => ({ arn: 'ARN', id: 'ID' }) }}); - project.onBuildSucceeded('OnBuildSucceeded', { target: { bind: () => ({ arn: 'ARN', id: 'ID' }) }}); - project.onPhaseChange('OnPhaseChange', { target: { bind: () => ({ arn: 'ARN', id: 'ID' }) }}); - project.onStateChange('OnStateChange', { target: { bind: () => ({ arn: 'ARN', id: 'ID' }) }}); - project.onBuildStarted('OnBuildStarted', { target: { bind: () => ({ arn: 'ARN', id: 'ID' }) }}); + project.onBuildFailed('OnBuildFailed'); + project.onBuildSucceeded('OnBuildSucceeded'); + project.onPhaseChange('OnPhaseChange'); + project.onStateChange('OnStateChange'); + project.onBuildStarted('OnBuildStarted'); expect(stack).to(haveResource('AWS::Events::Rule', { "EventPattern": { diff --git a/packages/@aws-cdk/aws-codecommit/lib/repository.ts b/packages/@aws-cdk/aws-codecommit/lib/repository.ts index 03e2372b5e7ba..518f6ffb0a8a6 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/repository.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/repository.ts @@ -31,64 +31,53 @@ export interface IRepository extends IResource { * Defines a CloudWatch event rule which triggers for repository events. Use * `rule.addEventPattern(pattern)` to specify a filter. */ - onEvent(id: string, options: events.OnEventOptions): events.Rule; + onEvent(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines a CloudWatch event rule which triggers when a "CodeCommit * Repository State Change" event occurs. */ - onStateChange(id: string, options: events.OnEventOptions): events.Rule; + onStateChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines a CloudWatch event rule which triggers when a reference is * created (i.e. a new branch/tag is created) to the repository. */ - onReferenceCreated(id: string, options: events.OnEventOptions): events.Rule; + onReferenceCreated(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * 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(id: string, options: events.OnEventOptions): events.Rule; + onReferenceUpdated(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines a CloudWatch event rule which triggers when a reference is * delete (i.e. a branch/tag is deleted) from the repository. */ - onReferenceDeleted(id: string, options: events.OnEventOptions): events.Rule; + onReferenceDeleted(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines a CloudWatch event rule which triggers when a pull request state is changed. */ - onPullRequestStateChange(id: string, options: events.OnEventOptions): events.Rule; + onPullRequestStateChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines a CloudWatch event rule which triggers when a comment is made on a pull request. */ - onCommentOnPullRequest(id: string, options: events.OnEventOptions): events.Rule; + onCommentOnPullRequest(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines a CloudWatch event rule which triggers when a comment is made on a commit. */ - onCommentOnCommit(id: string, options: events.OnEventOptions): events.Rule; + onCommentOnCommit(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * 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(id: string, options: OnCommitOptions): events.Rule; -} - -/** - * Options for the onCommit() method - */ -export interface OnCommitOptions extends events.OnEventOptions { - - /** - * The branch to monitor. - * - * @default - All branches - */ - readonly branches?: string[]; + onCommit(name: string, target?: events.IRuleTarget, branch?: string): events.Rule; } /** @@ -117,13 +106,13 @@ abstract class RepositoryBase extends Resource implements IRepository { * Defines a CloudWatch event rule which triggers for repository events. Use * `rule.addEventPattern(pattern)` to specify a filter. */ - public onEvent(id: string, options: events.OnEventOptions) { - const rule = new events.Rule(this, id, options); + public onEvent(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = new events.Rule(this, name, options); rule.addEventPattern({ source: [ 'aws.codecommit' ], resources: [ this.repositoryArn ] }); - rule.addTarget(options.target); + rule.addTarget(target); return rule; } @@ -131,8 +120,8 @@ abstract class RepositoryBase extends Resource implements IRepository { * Defines a CloudWatch event rule which triggers when a "CodeCommit * Repository State Change" event occurs. */ - public onStateChange(id: string, options: events.OnEventOptions) { - const rule = this.onEvent(id, options); + public onStateChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onEvent(name, target, options); rule.addEventPattern({ detailType: [ 'CodeCommit Repository State Change' ], }); @@ -143,8 +132,8 @@ abstract class RepositoryBase extends Resource implements IRepository { * Defines a CloudWatch event rule which triggers when a reference is * created (i.e. a new branch/tag is created) to the repository. */ - public onReferenceCreated(id: string, options: events.OnEventOptions) { - const rule = this.onStateChange(id, options); + public onReferenceCreated(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onStateChange(name, target, options); rule.addEventPattern({ detail: { event: [ 'referenceCreated' ] } }); return rule; } @@ -153,8 +142,8 @@ abstract class RepositoryBase extends Resource implements IRepository { * 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. */ - public onReferenceUpdated(id: string, options: events.OnEventOptions) { - const rule = this.onStateChange(id, options); + public onReferenceUpdated(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onStateChange(name, target, options); rule.addEventPattern({ detail: { event: [ 'referenceCreated', 'referenceUpdated' ] } }); return rule; } @@ -163,8 +152,8 @@ abstract class RepositoryBase extends Resource implements IRepository { * Defines a CloudWatch event rule which triggers when a reference is * delete (i.e. a branch/tag is deleted) from the repository. */ - public onReferenceDeleted(id: string, options: events.OnEventOptions) { - const rule = this.onStateChange(id, options); + public onReferenceDeleted(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onStateChange(name, target, options); rule.addEventPattern({ detail: { event: [ 'referenceDeleted' ] } }); return rule; } @@ -172,8 +161,8 @@ abstract class RepositoryBase extends Resource implements IRepository { /** * Defines a CloudWatch event rule which triggers when a pull request state is changed. */ - public onPullRequestStateChange(id: string, options: events.OnEventOptions) { - const rule = this.onEvent(id, options); + public onPullRequestStateChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onEvent(name, target, options); rule.addEventPattern({ detailType: [ 'CodeCommit Pull Request State Change' ] }); return rule; } @@ -181,8 +170,8 @@ abstract class RepositoryBase extends Resource implements IRepository { /** * Defines a CloudWatch event rule which triggers when a comment is made on a pull request. */ - public onCommentOnPullRequest(id: string, options: events.OnEventOptions) { - const rule = this.onEvent(id, options); + public onCommentOnPullRequest(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onEvent(name, target, options); rule.addEventPattern({ detailType: [ 'CodeCommit Comment on Pull Request' ] }); return rule; } @@ -190,19 +179,21 @@ abstract class RepositoryBase extends Resource implements IRepository { /** * Defines a CloudWatch event rule which triggers when a comment is made on a commit. */ - public onCommentOnCommit(id: string, options: events.OnEventOptions) { - const rule = this.onEvent(id, options); + public onCommentOnCommit(name: string, target?: events.IRuleTarget, options?: events.RuleProps) { + const rule = this.onEvent(name, target, options); rule.addEventPattern({ detailType: [ 'CodeCommit Comment on Commit' ] }); return rule; } /** * 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. */ - public onCommit(id: string, options: OnCommitOptions) { - const rule = this.onReferenceUpdated(id, options); - if (options.branches) { - rule.addEventPattern({ detail: { referenceName: options.branches }}); + public onCommit(name: string, target?: events.IRuleTarget, branch?: string) { + const rule = this.onReferenceUpdated(name, target); + if (branch) { + rule.addEventPattern({ detail: { referenceName: [ branch ] }}); } return rule; } diff --git a/packages/@aws-cdk/aws-codecommit/test/integ.codecommit-events.ts b/packages/@aws-cdk/aws-codecommit/test/integ.codecommit-events.ts index 654dde70c1684..b674b18656260 100644 --- a/packages/@aws-cdk/aws-codecommit/test/integ.codecommit-events.ts +++ b/packages/@aws-cdk/aws-codecommit/test/integ.codecommit-events.ts @@ -11,12 +11,10 @@ const topic = new sns.Topic(stack, 'MyTopic'); // we can't use @aws-cdk/aws-events-targets.SnsTopic here because it will // create a cyclic dependency with codebuild, so we just fake it repo.onReferenceCreated('OnReferenceCreated', { - target: { - bind: () => ({ - arn: topic.topicArn, - id: 'MyTopic' - }) - } + bind: () => ({ + arn: topic.topicArn, + id: 'MyTopic' + }) }); app.run(); diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts index eae6b45745927..379fcfa2b57cf 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts @@ -170,10 +170,10 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy this.deploymentGroupArn = arnForDeploymentGroup(this.application.applicationName, this.deploymentGroupName); if (props.preHook) { - this.addPreHook(props.preHook); + this.onPreHook(props.preHook); } if (props.postHook) { - this.addPostHook(props.postHook); + this.onPostHook(props.postHook); } (props.alias.node.findChild('Resource') as lambda.CfnAlias).options.updatePolicy = { @@ -200,7 +200,7 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy * @param preHook function to run before deployment beings * @throws an error if a pre-hook function is already configured */ - public addPreHook(preHook: lambda.IFunction): void { + public onPreHook(preHook: lambda.IFunction): void { if (this.preHook !== undefined) { throw new Error('A pre-hook function is already defined for this deployment group'); } @@ -214,7 +214,7 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy * @param postHook function to run after deployment completes * @throws an error if a post-hook function is already configured */ - public addPostHook(postHook: lambda.IFunction): void { + public onPostHook(postHook: lambda.IFunction): void { if (this.postHook !== undefined) { throw new Error('A post-hook function is already defined for this deployment group'); } diff --git a/packages/@aws-cdk/aws-codedeploy/test/lambda/test.deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/test/lambda/test.deployment-group.ts index ffe617c10d918..3a13c87e03121 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/lambda/test.deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/lambda/test.deployment-group.ts @@ -227,7 +227,7 @@ export = { preHook: mockFunction(stack, 'PreHook'), deploymentConfig: LambdaDeploymentConfig.AllAtOnce }); - test.throws(() => group.addPreHook(mockFunction(stack, 'PreHook2'))); + test.throws(() => group.onPreHook(mockFunction(stack, 'PreHook2'))); test.done(); }, "onPostHook throws error if post-hook already defined"(test: Test) { @@ -238,7 +238,7 @@ export = { postHook: mockFunction(stack, 'PostHook'), deploymentConfig: LambdaDeploymentConfig.AllAtOnce }); - test.throws(() => group.addPostHook(mockFunction(stack, 'PostHook2'))); + test.throws(() => group.onPostHook(mockFunction(stack, 'PostHook2'))); test.done(); }, "can run pre hook lambda function before deployment"(test: Test) { @@ -299,7 +299,7 @@ export = { alias, deploymentConfig: LambdaDeploymentConfig.AllAtOnce }); - group.addPreHook(mockFunction(stack, 'PreHook')); + group.onPreHook(mockFunction(stack, 'PreHook')); expect(stack).to(haveResourceLike('AWS::Lambda::Alias', { UpdatePolicy: { @@ -397,7 +397,7 @@ export = { alias, deploymentConfig: LambdaDeploymentConfig.AllAtOnce }); - group.addPostHook(mockFunction(stack, 'PostHook')); + group.onPostHook(mockFunction(stack, 'PostHook')); expect(stack).to(haveResourceLike('AWS::Lambda::Alias', { UpdatePolicy: { diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts index 3e96e368e710b..741a1478446ce 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts @@ -57,10 +57,8 @@ export class CodeCommitSourceAction extends codepipeline.Action { protected bind(info: codepipeline.ActionBind): void { if (!this.props.pollForSourceChanges) { - this.props.repository.onCommit(info.pipeline.node.uniqueId + 'EventRule', { - target: new targets.CodePipeline(info.pipeline), - branches: [this.props.branch || 'master'] - }); + this.props.repository.onCommit(info.pipeline.node.uniqueId + 'EventRule', + new targets.CodePipeline(info.pipeline), this.props.branch || 'master'); } // https://docs.aws.amazon.com/codecommit/latest/userguide/auth-and-access-control-permissions-reference.html#aa-acp diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts index 04f927719089e..e86c3bed59739 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts @@ -28,10 +28,6 @@ export interface EcrSourceActionProps extends codepipeline.CommonActionProps { /** * The ECR Repository source CodePipeline Action. - * - * Will trigger the pipeline as soon as the target tag in the repository - * changes, but only if there is a CloudTrail Trail in the account that - * captures the ECR event. */ export class EcrSourceAction extends codepipeline.Action { private readonly props: EcrSourceActionProps; @@ -59,9 +55,7 @@ export class EcrSourceAction extends codepipeline.Action { ) .addResource(this.props.repository.repositoryArn)); - this.props.repository.onCloudTrailImagePushed(info.pipeline.node.uniqueId + 'SourceEventRule', { - target: new targets.CodePipeline(info.pipeline), - imageTag: this.props.imageTag - }); + this.props.repository.onImagePushed(info.pipeline.node.uniqueId + 'SourceEventRule', + new targets.CodePipeline(info.pipeline), this.props.imageTag); } } diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts index eb4065cb0f3ff..88f003dd29732 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts @@ -38,9 +38,6 @@ export interface S3SourceActionProps extends codepipeline.CommonActionProps { /** * Source that is provided by a specific Amazon S3 object. - * - * Will trigger the pipeline as soon as the S3 object changes, but only if there is - * a CloudTrail Trail in the account that captures the S3 event. */ export class S3SourceAction extends codepipeline.Action { private readonly props: S3SourceActionProps; @@ -64,10 +61,8 @@ export class S3SourceAction extends codepipeline.Action { protected bind(info: codepipeline.ActionBind): void { if (this.props.pollForSourceChanges === false) { - this.props.bucket.onCloudTrailPutObject(info.pipeline.node.uniqueId + 'SourceEventRule', { - target: new targets.CodePipeline(info.pipeline), - paths: [this.props.bucketKey] - }); + this.props.bucket.onPutObject(info.pipeline.node.uniqueId + 'SourceEventRule', + new targets.CodePipeline(info.pipeline), this.props.bucketKey); } // pipeline needs permissions to read from the S3 bucket diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.pipeline-actions.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.pipeline-actions.ts index 028ed4a69fe57..656f96b26de24 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.pipeline-actions.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.pipeline-actions.ts @@ -324,13 +324,6 @@ class PipelineDouble extends cdk.Construct implements codepipeline.IPipeline { public grantBucketReadWrite(_identity?: iam.IGrantable): iam.Grant { throw new Error('grantBucketReadWrite() is unsupported in PipelineDouble'); } - - public onEvent(_id: string, _options: events.OnEventOptions): events.Rule { - throw new Error("Method not implemented."); - } - public onStateChange(_id: string, _options: events.OnEventOptions): events.Rule { - throw new Error("Method not implemented."); - } } class StageDouble implements codepipeline.IStage { diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.expected.json index 6878eb270286e..66b99d6d54d05 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.expected.json @@ -395,6 +395,9 @@ "AWS API Call via CloudTrail" ], "detail": { + "eventSource": [ + "s3.amazonaws.com" + ], "eventName": [ "PutObject" ], @@ -663,4 +666,4 @@ ] } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.expected.json index f7d21ee67d544..9c3df28286ac0 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.expected.json @@ -235,9 +235,6 @@ "source": [ "aws.ecr" ], - "detail-type": [ - "AWS API Call via CloudTrail" - ], "detail": { "eventName": [ "PutImage" @@ -289,4 +286,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.ts index 30b2ce6cb3b33..328bb6d6c293f 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.ts @@ -48,11 +48,9 @@ const topic = new sns.Topic(stack, 'MyTopic'); const eventPipeline = events.EventField.fromPath('$.detail.pipeline'); const eventState = events.EventField.fromPath('$.detail.state'); -pipeline.onStateChange('OnPipelineStateChange', { - target: new targets.SnsTopic(topic, { - message: events.RuleTargetInput.fromText(`Pipeline ${eventPipeline} changed state to ${eventState}`), - }) -}); +pipeline.onStateChange('OnPipelineStateChange').addTarget(new targets.SnsTopic(topic, { + message: events.RuleTargetInput.fromText(`Pipeline ${eventPipeline} changed state to ${eventState}`), +})); sourceStage.onStateChange('OnSourceStateChange', new targets.SnsTopic(topic)); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/test.pipeline.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/test.pipeline.ts index 3c4bb6a7fb70e..afe45b320f0bc 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/test.pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/test.pipeline.ts @@ -310,9 +310,9 @@ export = { ], }); - pipeline.onStateChange('OnStateChange', { - target: new targets.SnsTopic(topic), + pipeline.onStateChange('OnStateChange', new targets.SnsTopic(topic), { description: 'desc', + scheduleExpression: 'now', eventPattern: { detail: { state: [ 'FAILED' ] @@ -360,6 +360,7 @@ export = { } ] }, + "ScheduleExpression": "now", "State": "ENABLED", "Targets": [ { diff --git a/packages/@aws-cdk/aws-codepipeline/lib/action.ts b/packages/@aws-cdk/aws-codepipeline/lib/action.ts index a63caa198c5a5..e8dabace20812 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/action.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/action.ts @@ -86,23 +86,6 @@ export interface IPipeline extends IResource { * @param identity the IAM Identity to grant the permissions to */ grantBucketReadWrite(identity: iam.IGrantable): iam.Grant; - - /** - * Define an event rule triggered by this CodePipeline. - * - * @param id Identifier for this event handler. - * @param options Additional options to pass to the event rule. - */ - onEvent(id: string, options: events.OnEventOptions): events.Rule; - - /** - * Define an event rule triggered by the "CodePipeline Pipeline Execution - * State Change" event emitted from this pipeline. - * - * @param id Identifier for this event handler. - * @param options Additional options to pass to the event rule. - */ - onStateChange(id: string, options: events.OnEventOptions): events.Rule; } /** diff --git a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts index 03622bf4fe3e0..70e268badb771 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts @@ -118,37 +118,6 @@ abstract class PipelineBase extends Resource implements IPipeline { public abstract grantBucketRead(identity: iam.IGrantable): iam.Grant; public abstract grantBucketReadWrite(identity: iam.IGrantable): iam.Grant; - /** - * Defines an event rule triggered by this CodePipeline. - * - * @param id Identifier for this event handler. - * @param options Additional options to pass to the event rule. - */ - public onEvent(id: string, options: events.OnEventOptions): events.Rule { - const rule = new events.Rule(this, id, options); - rule.addTarget(options.target); - rule.addEventPattern({ - source: [ 'aws.codepipeline' ], - resources: [ this.pipelineArn ], - }); - return rule; - } - - /** - * Defines an event rule triggered by the "CodePipeline Pipeline Execution - * State Change" event emitted from this pipeline. - * - * @param id Identifier for this event handler. - * @param options Additional options to pass to the event rule. - */ - public onStateChange(id: string, options: events.OnEventOptions): events.Rule { - const rule = this.onEvent(id, options); - rule.addEventPattern({ - detailType: [ 'CodePipeline Pipeline Execution State Change' ], - }); - return rule; - } - } /** @@ -311,6 +280,31 @@ export class Pipeline extends PipelineBase { this.role.addToPolicy(statement); } + /** + * Defines an event rule triggered by the "CodePipeline Pipeline Execution + * State Change" event emitted from this pipeline. + * + * @param target Initial target to add to the event rule. You can also add + * targets and customize target inputs by calling `rule.addTarget(target[, + * options])` after the rule was created. + * + * @param options Additional options to pass to the event rule + * + * @param name The name of the event rule construct. If you wish to define + * more than a single onStateChange event, you will need to explicitly + * specify a name. + */ + public onStateChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule { + const rule = new events.Rule(this, name, options); + rule.addTarget(target); + rule.addEventPattern({ + detailType: [ 'CodePipeline Pipeline Execution State Change' ], + source: [ 'aws.codepipeline' ], + resources: [ this.pipelineArn ], + }); + return rule; + } + /** * Get the number of Stages in this Pipeline. */ diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts index ed478523bfa86..044bf87ec4693 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts @@ -407,7 +407,7 @@ export class UserPool extends Resource implements IUserPool { * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-create-auth-challenge.html * @param fn the lambda function to attach */ - public addCreateAuthChallengeTrigger(fn: lambda.IFunction): void { + public onCreateAuthChallenge(fn: lambda.IFunction): void { this.addLambdaPermission(fn, 'CreateAuthChallenge'); this.triggers = { ...this.triggers, createAuthChallenge: fn.functionArn }; } @@ -418,7 +418,7 @@ export class UserPool extends Resource implements IUserPool { * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-message.html * @param fn the lambda function to attach */ - public addCustomMessageTrigger(fn: lambda.IFunction): void { + public onCustomMessage(fn: lambda.IFunction): void { this.addLambdaPermission(fn, 'CustomMessage'); this.triggers = { ...this.triggers, customMessage: fn.functionArn }; } @@ -429,7 +429,7 @@ export class UserPool extends Resource implements IUserPool { * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-define-auth-challenge.html * @param fn the lambda function to attach */ - public addDefineAuthChallengeTrigger(fn: lambda.IFunction): void { + public onDefineAuthChallenge(fn: lambda.IFunction): void { this.addLambdaPermission(fn, 'DefineAuthChallenge'); this.triggers = { ...this.triggers, defineAuthChallenge: fn.functionArn }; } @@ -440,7 +440,7 @@ export class UserPool extends Resource implements IUserPool { * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-post-authentication.html * @param fn the lambda function to attach */ - public addPostAuthenticationTrigger(fn: lambda.IFunction): void { + public onPostAuthentication(fn: lambda.IFunction): void { this.addLambdaPermission(fn, 'PostAuthentication'); this.triggers = { ...this.triggers, postAuthentication: fn.functionArn }; } @@ -451,7 +451,7 @@ export class UserPool extends Resource implements IUserPool { * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-post-confirmation.html * @param fn the lambda function to attach */ - public addPostConfirmationTrigger(fn: lambda.IFunction): void { + public onPostConfirmation(fn: lambda.IFunction): void { this.addLambdaPermission(fn, 'PostConfirmation'); this.triggers = { ...this.triggers, postConfirmation: fn.functionArn }; } @@ -462,7 +462,7 @@ export class UserPool extends Resource implements IUserPool { * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-authentication.html * @param fn the lambda function to attach */ - public addPreAuthenticationTrigger(fn: lambda.IFunction): void { + public onPreAuthentication(fn: lambda.IFunction): void { this.addLambdaPermission(fn, 'PreAuthentication'); this.triggers = { ...this.triggers, preAuthentication: fn.functionArn }; } @@ -473,7 +473,7 @@ export class UserPool extends Resource implements IUserPool { * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-sign-up.html * @param fn the lambda function to attach */ - public addPreSignUpTrigger(fn: lambda.IFunction): void { + public onPreSignUp(fn: lambda.IFunction): void { this.addLambdaPermission(fn, 'PreSignUp'); this.triggers = { ...this.triggers, preSignUp: fn.functionArn }; } @@ -484,7 +484,7 @@ export class UserPool extends Resource implements IUserPool { * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-verify-auth-challenge-response.html * @param fn the lambda function to attach */ - public addVerifyAuthChallengeResponseTrigger(fn: lambda.IFunction): void { + public onVerifyAuthChallengeResponse(fn: lambda.IFunction): void { this.addLambdaPermission(fn, 'VerifyAuthChallengeResponse'); this.triggers = { ...this.triggers, verifyAuthChallengeResponse: fn.functionArn }; } diff --git a/packages/@aws-cdk/aws-cognito/test/test.user-pool.ts b/packages/@aws-cdk/aws-cognito/test/test.user-pool.ts index fb8c330b7e1a8..10b2fa45711f8 100644 --- a/packages/@aws-cdk/aws-cognito/test/test.user-pool.ts +++ b/packages/@aws-cdk/aws-cognito/test/test.user-pool.ts @@ -37,7 +37,7 @@ export = { preSignUp: fn } }); - pool.addCustomMessageTrigger(fn); + pool.onCustomMessage(fn); // THEN expect(stack).to(haveResourceLike('AWS::Cognito::UserPool', { @@ -61,14 +61,14 @@ export = { // WHEN const pool = new cognito.UserPool(stack, 'Pool', { }); - pool.addCreateAuthChallengeTrigger(fn); - pool.addCustomMessageTrigger(fn); - pool.addDefineAuthChallengeTrigger(fn); - pool.addPostAuthenticationTrigger(fn); - pool.addPostConfirmationTrigger(fn); - pool.addPreAuthenticationTrigger(fn); - pool.addPreSignUpTrigger(fn); - pool.addVerifyAuthChallengeResponseTrigger(fn); + pool.onCreateAuthChallenge(fn); + pool.onCustomMessage(fn); + pool.onDefineAuthChallenge(fn); + pool.onPostAuthentication(fn); + pool.onPostConfirmation(fn); + pool.onPreAuthentication(fn); + pool.onPreSignUp(fn); + pool.onVerifyAuthChallengeResponse(fn); // THEN expect(stack).to(haveResourceLike('AWS::Cognito::UserPool', { diff --git a/packages/@aws-cdk/aws-config/README.md b/packages/@aws-cdk/aws-config/README.md index d8e45ea18d38f..98c190ed0b719 100644 --- a/packages/@aws-cdk/aws-config/README.md +++ b/packages/@aws-cdk/aws-config/README.md @@ -63,9 +63,7 @@ To define Amazon CloudWatch event rules, use the `onComplianceChange()` or `onRe ```ts const rule = new CloudFormationStackDriftDetectionCheck(this, 'Drift'); -rule.onComplianceChange('TopicEvent', { - target: new targets.SnsTopic(topic)) -}); +rule.onComplianceChange(topic); ``` #### Example diff --git a/packages/@aws-cdk/aws-config/lib/rule.ts b/packages/@aws-cdk/aws-config/lib/rule.ts index 1ee8783db6f19..3d9b742763d88 100644 --- a/packages/@aws-cdk/aws-config/lib/rule.ts +++ b/packages/@aws-cdk/aws-config/lib/rule.ts @@ -19,17 +19,17 @@ export interface IRule extends IResource { * Defines a CloudWatch event rule which triggers for rule events. Use * `rule.addEventPattern(pattern)` to specify a filter. */ - onEvent(id: string, options: events.OnEventOptions): events.Rule; + onEvent(id: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines a CloudWatch event rule which triggers for rule compliance events. */ - onComplianceChange(id: string, options: events.OnEventOptions): events.Rule; + onComplianceChange(id: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; /** * Defines a CloudWatch event rule which triggers for rule re-evaluation status events. */ - onReEvaluationStatus(id: string, options: events.OnEventOptions): events.Rule; + onReEvaluationStatus(id: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule; } /** @@ -65,7 +65,7 @@ abstract class RuleBase extends Resource implements IRule { * Defines a CloudWatch event rule which triggers for rule events. Use * `rule.addEventPattern(pattern)` to specify a filter. */ - public onEvent(id: string, options: events.OnEventOptions) { + public onEvent(id: string, target?: events.IRuleTarget, options?: events.RuleProps) { const rule = new events.Rule(this, id, options); rule.addEventPattern({ source: ['aws.config'], @@ -73,15 +73,15 @@ abstract class RuleBase extends Resource implements IRule { configRuleName: [this.configRuleName] } }); - rule.addTarget(options.target); + rule.addTarget(target); return rule; } /** * Defines a CloudWatch event rule which triggers for rule compliance events. */ - public onComplianceChange(id: string, options: events.OnEventOptions): events.Rule { - const rule = this.onEvent(id, options); + public onComplianceChange(id: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule { + const rule = this.onEvent(id, target, options); rule.addEventPattern({ detailType: [ 'Config Rules Compliance Change' ], }); @@ -91,8 +91,8 @@ abstract class RuleBase extends Resource implements IRule { /** * Defines a CloudWatch event rule which triggers for rule re-evaluation status events. */ - public onReEvaluationStatus(id: string, options: events.OnEventOptions): events.Rule { - const rule = this.onEvent(id, options); + public onReEvaluationStatus(id: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule { + const rule = this.onEvent(id, target, options); rule.addEventPattern({ detailType: [ 'Config Rules Re-evaluation Status' ], }); diff --git a/packages/@aws-cdk/aws-config/test/integ.rule.lit.ts b/packages/@aws-cdk/aws-config/test/integ.rule.lit.ts index 0dc7480879ee0..db58cda3f4979 100644 --- a/packages/@aws-cdk/aws-config/test/integ.rule.lit.ts +++ b/packages/@aws-cdk/aws-config/test/integ.rule.lit.ts @@ -32,9 +32,7 @@ class ConfigStack extends cdk.Stack { const complianceTopic = new sns.Topic(this, 'ComplianceTopic'); // Send notification on compliance change - driftRule.onComplianceChange('ComplianceChange', { - target: new targets.SnsTopic(complianceTopic) - }); + driftRule.onComplianceChange('ComplianceChange', new targets.SnsTopic(complianceTopic)); /// !hide } } diff --git a/packages/@aws-cdk/aws-config/test/test.rule.ts b/packages/@aws-cdk/aws-config/test/test.rule.ts index 464a6960414b6..38d8c9b2099f0 100644 --- a/packages/@aws-cdk/aws-config/test/test.rule.ts +++ b/packages/@aws-cdk/aws-config/test/test.rule.ts @@ -256,9 +256,7 @@ export = { }); // WHEN - rule.onComplianceChange('ComplianceChange', { - target: new targets.LambdaFunction(fn) - }); + rule.onComplianceChange('ComplianceChange', new targets.LambdaFunction(fn)); expect(stack).to(haveResource('AWS::Events::Rule', { EventPattern: { diff --git a/packages/@aws-cdk/aws-ecr/lib/repository.ts b/packages/@aws-cdk/aws-ecr/lib/repository.ts index 1c8afe1a47171..658c87c15a876 100644 --- a/packages/@aws-cdk/aws-ecr/lib/repository.ts +++ b/packages/@aws-cdk/aws-ecr/lib/repository.ts @@ -58,28 +58,14 @@ export interface IRepository extends IResource { */ grantPullPush(grantee: iam.IGrantable): iam.Grant; - /** - * Define a CloudWatch event that triggers when something happens to this repository - * - * Requires that there exists at least one CloudTrail Trail in your account - * that captures the event. This method will not create the Trail. - * - * @param id The id of the rule - * @param options Options for adding the rule - */ - onCloudTrailEvent(id: string, options: events.OnEventOptions): events.Rule; - /** * Defines an AWS CloudWatch event rule that can trigger a target when an image is pushed to this * repository. - * - * Requires that there exists at least one CloudTrail Trail in your account - * that captures the event. This method will not create the Trail. - * - * @param id The id of the rule - * @param options Options for adding the rule + * @param name The name of the rule + * @param target An IRuleTarget to invoke when this event happens (you can add more targets using `addTarget`) + * @param imageTag Only trigger on the specific image tag */ - onCloudTrailImagePushed(id: string, options: OnCloudTrailImagePushedOptions): events.Rule; + onImagePushed(name: string, target?: events.IRuleTarget, imageTag?: string): events.Rule; } /** @@ -124,51 +110,31 @@ export abstract class RepositoryBase extends Resource implements IRepository { return `${parts.account}.dkr.ecr.${parts.region}.amazonaws.com/${this.repositoryName}${tagSuffix}`; } - /** - * Define a CloudWatch event that triggers when something happens to this repository - * - * Requires that there exists at least one CloudTrail Trail in your account - * that captures the event. This method will not create the Trail. - * - * @param id The id of the rule - * @param options Options for adding the rule - */ - public onCloudTrailEvent(id: string, options: events.OnEventOptions): events.Rule { - const rule = new events.Rule(this, id, options); - rule.addTarget(options.target); - rule.addEventPattern({ - source: ['aws.ecr'], - detailType: ['AWS API Call via CloudTrail'], - detail: { - requestParameters: { - repositoryName: [this.repositoryName], - } - } - }); - return rule; - } - /** * Defines an AWS CloudWatch event rule that can trigger a target when an image is pushed to this * repository. - * - * Requires that there exists at least one CloudTrail Trail in your account - * that captures the event. This method will not create the Trail. - * - * @param id The id of the rule - * @param options Options for adding the rule + * @param name The name of the rule + * @param target An IRuleTarget to invoke when this event happens (you can add more targets using `addTarget`) + * @param imageTag Only trigger on the specific image tag */ - public onCloudTrailImagePushed(id: string, options: OnCloudTrailImagePushedOptions): events.Rule { - const rule = this.onCloudTrailEvent(id, options); - rule.addEventPattern({ - detail: { - eventName: ['PutImage'], - requestParameters: { - imageTag: options.imageTag ? [options.imageTag] : undefined, + public onImagePushed(name: string, target?: events.IRuleTarget, imageTag?: string): events.Rule { + return new events.Rule(this, name, { + targets: target ? [target] : undefined, + eventPattern: { + source: ['aws.ecr'], + detail: { + eventName: [ + 'PutImage', + ], + requestParameters: { + repositoryName: [ + this.repositoryName, + ], + imageTag: imageTag ? [imageTag] : undefined, + }, }, }, }); - return rule; } /** @@ -212,18 +178,6 @@ export abstract class RepositoryBase extends Resource implements IRepository { } } -/** - * Options for the onCloudTrailImagePushed method - */ -export interface OnCloudTrailImagePushedOptions extends events.OnEventOptions { - /** - * Only watch changes to this image tag - * - * @default - Watch changes to all tags - */ - readonly imageTag?: string; -} - export interface RepositoryProps { /** * Name for this repository diff --git a/packages/@aws-cdk/aws-ecr/test/test.repository.ts b/packages/@aws-cdk/aws-ecr/test/test.repository.ts index 76b9865efae30..e83eeefd26704 100644 --- a/packages/@aws-cdk/aws-ecr/test/test.repository.ts +++ b/packages/@aws-cdk/aws-ecr/test/test.repository.ts @@ -285,15 +285,11 @@ export = { }, 'events': { - 'onImagePushed without imageTag creates the correct event'(test: Test) { + 'onImagePushed without target or imageTag creates the correct event'(test: Test) { const stack = new cdk.Stack(); const repo = new ecr.Repository(stack, 'Repo'); - repo.onCloudTrailImagePushed('EventRule', { - target: { - bind: () => ({ arn: 'ARN', id: 'ID' }) - } - }); + repo.onImagePushed('EventRule'); expect(stack).to(haveResourceLike('AWS::Events::Rule', { "EventPattern": { @@ -307,8 +303,7 @@ export = { "requestParameters": { "repositoryName": [ { - "Ref": "Repo02AC86CF" - } + }, ], }, }, diff --git a/packages/@aws-cdk/aws-ecs/lib/drain-hook/instance-drain-hook.ts b/packages/@aws-cdk/aws-ecs/lib/drain-hook/instance-drain-hook.ts index c5eecb95735f2..9605f66bf0af9 100644 --- a/packages/@aws-cdk/aws-ecs/lib/drain-hook/instance-drain-hook.ts +++ b/packages/@aws-cdk/aws-ecs/lib/drain-hook/instance-drain-hook.ts @@ -63,7 +63,7 @@ export class InstanceDrainHook extends cdk.Construct { }); // Hook everything up: ASG -> Topic, Topic -> Lambda - props.autoScalingGroup.addLifecycleHook('DrainHook', { + props.autoScalingGroup.onLifecycleTransition('DrainHook', { lifecycleTransition: autoscaling.LifecycleTransition.InstanceTerminating, defaultResult: autoscaling.DefaultResult.Continue, notificationTarget: topic, diff --git a/packages/@aws-cdk/aws-events-targets/test/codebuild/integ.project-events.ts b/packages/@aws-cdk/aws-events-targets/test/codebuild/integ.project-events.ts index 06b0231f42b6e..357a3c592ffe0 100644 --- a/packages/@aws-cdk/aws-events-targets/test/codebuild/integ.project-events.ts +++ b/packages/@aws-cdk/aws-events-targets/test/codebuild/integ.project-events.ts @@ -23,23 +23,17 @@ topic.subscribeQueue(queue); // this will send an email with the JSON event for every state change of this // build project. -project.onStateChange('StateChange', { target: new targets.SnsTopic(topic) }); +project.onStateChange('StateChange', new targets.SnsTopic(topic)); // this will send an email with the message "Build phase changed to ". // The phase will be extracted from the "completed-phase" field of the event // details. -project.onPhaseChange('PhaseChange', { - target: new targets.SnsTopic(topic, { - message: events.RuleTargetInput.fromText(`Build phase changed to ${codebuild.PhaseChangeEvent.completedPhase}`) - }) -}); +project.onPhaseChange('PhaseChange').addTarget(new targets.SnsTopic(topic, { + message: events.RuleTargetInput.fromText(`Build phase changed to ${codebuild.PhaseChangeEvent.completedPhase}`) +})); // trigger a build when a commit is pushed to the repo -const onCommitRule = repo.onCommit('OnCommit', { - target: new targets.CodeBuildProject(project), - branches: ['master'] -}); - +const onCommitRule = repo.onCommit('OnCommit', new targets.CodeBuildProject(project), 'master'); onCommitRule.addTarget(new targets.SnsTopic(topic, { message: events.RuleTargetInput.fromText( `A commit was pushed to the repository ${codecommit.ReferenceEvent.repositoryName} on branch ${codecommit.ReferenceEvent.referenceName}` diff --git a/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.expected.json b/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.expected.json deleted file mode 100644 index 5c4b2bf89391c..0000000000000 --- a/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.expected.json +++ /dev/null @@ -1,380 +0,0 @@ -{ - "Resources": { - "Repo02AC86CF": { - "Type": "AWS::CodeCommit::Repository", - "Properties": { - "RepositoryName": "TestRepository", - "Triggers": [] - } - }, - "PipelineArtifactsBucketEncryptionKey01D58D69": { - "Type": "AWS::KMS::Key", - "Properties": { - "KeyPolicy": { - "Statement": [ - { - "Action": [ - "kms:Create*", - "kms:Describe*", - "kms:Enable*", - "kms:List*", - "kms:Put*", - "kms:Update*", - "kms:Revoke*", - "kms:Disable*", - "kms:Get*", - "kms:Delete*", - "kms:ScheduleKeyDeletion", - "kms:CancelKeyDeletion" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" - ] - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:Decrypt", - "kms:DescribeKey", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::GetAtt": [ - "PipelineRoleD68726F7", - "Arn" - ] - } - }, - "Resource": "*" - } - ], - "Version": "2012-10-17" - } - }, - "DeletionPolicy": "Retain" - }, - "PipelineArtifactsBucket22248F97": { - "Type": "AWS::S3::Bucket", - "Properties": { - "BucketEncryption": { - "ServerSideEncryptionConfiguration": [ - { - "ServerSideEncryptionByDefault": { - "KMSMasterKeyID": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] - }, - "SSEAlgorithm": "aws:kms" - } - } - ] - } - }, - "DeletionPolicy": "Retain" - }, - "PipelineRoleD68726F7": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": { - "Fn::Join": [ - "", - [ - "codepipeline.", - { - "Ref": "AWS::URLSuffix" - } - ] - ] - } - } - } - ], - "Version": "2012-10-17" - } - } - }, - "PipelineRoleDefaultPolicyC7A05455": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*", - "s3:DeleteObject*", - "s3:PutObject*", - "s3:Abort*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "PipelineArtifactsBucket22248F97", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "PipelineArtifactsBucket22248F97", - "Arn" - ] - }, - "/*" - ] - ] - } - ] - }, - { - "Action": [ - "kms:Decrypt", - "kms:DescribeKey", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "PipelineRoleDefaultPolicyC7A05455", - "Roles": [ - { - "Ref": "PipelineRoleD68726F7" - } - ] - } - }, - "PipelineC660917D": { - "Type": "AWS::CodePipeline::Pipeline", - "Properties": { - "RoleArn": { - "Fn::GetAtt": [ - "PipelineRoleD68726F7", - "Arn" - ] - }, - "Stages": [ - { - "Actions": [ - { - "ActionTypeId": { - "Category": "Source", - "Owner": "AWS", - "Provider": "CodeCommit", - "Version": "1" - }, - "Configuration": { - "RepositoryName": { - "Fn::GetAtt": [ - "Repo02AC86CF", - "Name" - ] - }, - "BranchName": "master" - }, - "InputArtifacts": [], - "Name": "CodeCommit", - "OutputArtifacts": [ - { - "Name": "Src" - } - ], - "RunOrder": 1 - } - ], - "Name": "Source" - }, - { - "Actions": [ - { - "ActionTypeId": { - "Category": "Approval", - "Owner": "AWS", - "Provider": "Manual", - "Version": "1" - }, - "InputArtifacts": [], - "Name": "Hello", - "OutputArtifacts": [], - "RunOrder": 1 - } - ], - "Name": "Build" - } - ], - "ArtifactStore": { - "EncryptionKey": { - "Id": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] - }, - "Type": "KMS" - }, - "Location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "Type": "S3" - } - }, - "DependsOn": [ - "PipelineRoleDefaultPolicyC7A05455", - "PipelineRoleD68726F7" - ] - }, - "PipelineEventsRole46BEEA7C": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": { - "Fn::Join": [ - "", - [ - "events.", - { - "Ref": "AWS::URLSuffix" - } - ] - ] - } - } - } - ], - "Version": "2012-10-17" - } - } - }, - "PipelineEventsRoleDefaultPolicyFF4FCCE0": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "codepipeline:StartPipelineExecution", - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":codepipeline:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":", - { - "Ref": "PipelineC660917D" - } - ] - ] - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "PipelineEventsRoleDefaultPolicyFF4FCCE0", - "Roles": [ - { - "Ref": "PipelineEventsRole46BEEA7C" - } - ] - } - }, - "ruleF2C1DCDC": { - "Type": "AWS::Events::Rule", - "Properties": { - "ScheduleExpression": "rate(1 minute)", - "State": "ENABLED", - "Targets": [ - { - "Arn": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":codepipeline:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":", - { - "Ref": "PipelineC660917D" - } - ] - ] - }, - "Id": "Pipeline", - "RoleArn": { - "Fn::GetAtt": [ - "PipelineEventsRole46BEEA7C", - "Arn" - ] - } - } - ] - } - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.ts b/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.ts deleted file mode 100644 index 36c15e999eedf..0000000000000 --- a/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.ts +++ /dev/null @@ -1,50 +0,0 @@ -import codecommit = require('@aws-cdk/aws-codecommit'); -import codepipeline = require('@aws-cdk/aws-codepipeline'); -import events = require('@aws-cdk/aws-events'); -import cdk = require('@aws-cdk/cdk'); -import targets = require('../../lib'); - -class MockAction extends codepipeline.Action { - protected bind(_info: codepipeline.ActionBind): void { - // void - } -} - -const app = new cdk.App(); -const stack = new cdk.Stack(app, 'pipeline-events'); - -const repo = new codecommit.Repository(stack, 'Repo', { - repositoryName: 'TestRepository' -}); - -const pipeline = new codepipeline.Pipeline(stack, 'Pipeline'); - -const srcArtifact = new codepipeline.Artifact('Src'); -pipeline.addStage({ - name: 'Source', - actions: [new MockAction({ - actionName: 'CodeCommit', - category: codepipeline.ActionCategory.Source, - provider: 'CodeCommit', - artifactBounds: { minInputs: 0, maxInputs: 0 , minOutputs: 1, maxOutputs: 1, }, - configuration: { - RepositoryName: repo.repositoryName, - BranchName: 'master', - }, - outputs: [srcArtifact]})] -}); -pipeline.addStage({ - name: 'Build', - actions: [new MockAction({ - actionName: 'Hello', - category: codepipeline.ActionCategory.Approval, - provider: 'Manual', - artifactBounds: { minInputs: 0, maxInputs: 0 , minOutputs: 0, maxOutputs: 0, }})] -}); - -new events.Rule(stack, 'rule', { - scheduleExpression: 'rate(1 minute)', - targets: [new targets.CodePipeline(pipeline)] -}); - -app.run(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events/lib/index.ts b/packages/@aws-cdk/aws-events/lib/index.ts index 0409be7ae29d5..81e2633f09a6f 100644 --- a/packages/@aws-cdk/aws-events/lib/index.ts +++ b/packages/@aws-cdk/aws-events/lib/index.ts @@ -3,7 +3,6 @@ export * from './rule'; export * from './rule-ref'; export * from './target'; export * from './event-pattern'; -export * from './on-event-options'; // AWS::Events CloudFormation Resources: export * from './events.generated'; diff --git a/packages/@aws-cdk/aws-events/lib/on-event-options.ts b/packages/@aws-cdk/aws-events/lib/on-event-options.ts deleted file mode 100644 index 047722cb35ab7..0000000000000 --- a/packages/@aws-cdk/aws-events/lib/on-event-options.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { EventPattern } from "./event-pattern"; -import { IRuleTarget } from "./target"; - -/** - * Standard set of options for `onXxx` event handlers on construct - */ -export interface OnEventOptions { - /** - * The target to register for the event - */ - readonly target: IRuleTarget; - - /** - * A description of the rule's purpose. - */ - readonly description?: string; - - /** - * A name for the rule. - * - * @default AWS CloudFormation generates a unique physical ID. - */ - readonly ruleName?: string; - - /** - * Additional restrictions for the event to route to the specified target - * - * The method that generates the rule probably imposes some type of event - * filtering. The filtering implied by what you pass here is added - * on top of that filtering. - * - * @see - * http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CloudWatchEventsandEventPatterns.html - */ - readonly eventPattern?: EventPattern; -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events/lib/util.ts b/packages/@aws-cdk/aws-events/lib/util.ts index 1b1c860d7850d..99b26f9e19493 100644 --- a/packages/@aws-cdk/aws-events/lib/util.ts +++ b/packages/@aws-cdk/aws-events/lib/util.ts @@ -21,14 +21,12 @@ export function mergeEventPattern(dest: any, src: any) { const srcValue = srcObj[field]; const destValue = destObj[field]; - if (srcValue === undefined) { continue; } - if (typeof(srcValue) !== 'object') { throw new Error(`Invalid event pattern field { ${field}: ${JSON.stringify(srcValue)} }. All fields must be arrays`); } // dest doesn't have this field - if (destObj[field] === undefined) { + if (!(field in destObj)) { destObj[field] = srcValue; continue; } 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 7bb2726f2b4ff..3b669ad26a0f2 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/lib/s3.ts @@ -27,7 +27,7 @@ export class S3EventSource implements lambda.IEventSource { public bind(target: lambda.IFunction) { const filters = this.props.filters || []; for (const event of this.props.events) { - this.bucket.addEventNotification(event, target, ...filters); + this.bucket.onEvent(event, target, ...filters); } } } diff --git a/packages/@aws-cdk/aws-lambda/test/integ.bucket-notifications.ts b/packages/@aws-cdk/aws-lambda/test/integ.bucket-notifications.ts index 663175eec774a..eeb14db4809f1 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.bucket-notifications.ts +++ b/packages/@aws-cdk/aws-lambda/test/integ.bucket-notifications.ts @@ -20,8 +20,8 @@ const bucketB = new s3.Bucket(stack, 'YourBucket', { removalPolicy: cdk.RemovalPolicy.Destroy }); -bucketA.addObjectCreatedNotification(fn, { suffix: '.png' }); -bucketB.addEventNotification(s3.EventType.ObjectRemoved, fn); +bucketA.onObjectCreated(fn, { suffix: '.png' }); +bucketB.onEvent(s3.EventType.ObjectRemoved, fn); app.run(); diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 9da3738645841..9166020e24a43 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -166,27 +166,14 @@ export interface IBucket extends IResource { grantPublicAccess(keyPrefix?: string, ...allowedActions: string[]): iam.Grant; /** - * Define a CloudWatch event that triggers when something happens to this repository + * Defines a CloudWatch Event Rule that triggers upon putting an object into the Bucket. * - * Requires that there exists at least one CloudTrail Trail in your account - * that captures the event. This method will not create the Trail. - * - * @param id The id of the rule - * @param options Options for adding the rule - */ - onCloudTrailEvent(id: string, options: OnCloudTrailBucketEventOptions): events.Rule; - - /** - * Defines an AWS CloudWatch event rule that can trigger a target when an image is pushed to this - * repository. - * - * Requires that there exists at least one CloudTrail Trail in your account - * that captures the event. This method will not create the Trail. - * - * @param id The id of the rule - * @param options Options for adding the rule + * @param name the logical ID of the newly created Event Rule + * @param target the optional target of the Event Rule + * @param path the optional path inside the Bucket that will be watched for changes + * @returns a new {@link events.Rule} instance */ - onCloudTrailPutObject(id: string, options: OnCloudTrailBucketEventOptions): events.Rule; + onPutObject(name: string, target?: events.IRuleTarget, path?: string): events.Rule; } /** @@ -291,48 +278,32 @@ abstract class BucketBase extends Resource implements IBucket { */ protected abstract disallowPublicAccess?: boolean; - /** - * Define a CloudWatch event that triggers when something happens to this repository - * - * Requires that there exists at least one CloudTrail Trail in your account - * that captures the event. This method will not create the Trail. - * - * @param id The id of the rule - * @param options Options for adding the rule - */ - public onCloudTrailEvent(id: string, options: OnCloudTrailBucketEventOptions): events.Rule { - const rule = new events.Rule(this, id, options); - rule.addTarget(options.target); - rule.addEventPattern({ - source: ['aws.s3'], - detailType: ['AWS API Call via CloudTrail'], - detail: { - resources: { - ARN: options.paths ? options.paths.map(p => this.arnForObjects(p)) : [this.bucketArn], + public onPutObject(name: string, target?: events.IRuleTarget, path?: string): events.Rule { + const eventRule = new events.Rule(this, name, { + eventPattern: { + source: [ + 'aws.s3', + ], + detailType: [ + 'AWS API Call via CloudTrail', + ], + detail: { + eventSource: [ + 's3.amazonaws.com', + ], + eventName: [ + 'PutObject', + ], + resources: { + ARN: [ + path ? this.arnForObjects(path) : this.bucketArn, + ], + }, }, - } - }); - return rule; - } - - /** - * Defines an AWS CloudWatch event rule that can trigger a target when an image is pushed to this - * repository. - * - * Requires that there exists at least one CloudTrail Trail in your account - * that captures the event. This method will not create the Trail. - * - * @param id The id of the rule - * @param options Options for adding the rule - */ - public onCloudTrailPutObject(id: string, options: OnCloudTrailBucketEventOptions): events.Rule { - const rule = this.onCloudTrailEvent(id, options); - rule.addEventPattern({ - detail: { - eventName: ['PutObject'], }, }); - return rule; + eventRule.addTarget(target); + return eventRule; } /** @@ -858,12 +829,12 @@ export class Bucket extends BucketBase { * * @example * - * bucket.addEventNotification(EventType.OnObjectCreated, myLambda, 'home/myusername/*') + * bucket.onEvent(EventType.OnObjectCreated, myLambda, 'home/myusername/*') * * @see * https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html */ - public addEventNotification(event: EventType, dest: IBucketNotificationDestination, ...filters: NotificationKeyFilter[]) { + public onEvent(event: EventType, dest: IBucketNotificationDestination, ...filters: NotificationKeyFilter[]) { this.notifications.addNotification(event, dest, ...filters); } @@ -875,8 +846,8 @@ export class Bucket extends BucketBase { * @param dest The notification destination (see onEvent) * @param filters Filters (see onEvent) */ - public addObjectCreatedNotification(dest: IBucketNotificationDestination, ...filters: NotificationKeyFilter[]) { - return this.addEventNotification(EventType.ObjectCreated, dest, ...filters); + public onObjectCreated(dest: IBucketNotificationDestination, ...filters: NotificationKeyFilter[]) { + return this.onEvent(EventType.ObjectCreated, dest, ...filters); } /** @@ -887,8 +858,8 @@ export class Bucket extends BucketBase { * @param dest The notification destination (see onEvent) * @param filters Filters (see onEvent) */ - public addObjectRemovedNotification(dest: IBucketNotificationDestination, ...filters: NotificationKeyFilter[]) { - return this.addEventNotification(EventType.ObjectRemoved, dest, ...filters); + public onObjectRemoved(dest: IBucketNotificationDestination, ...filters: NotificationKeyFilter[]) { + return this.onEvent(EventType.ObjectRemoved, dest, ...filters); } private validateBucketName(bucketName: string) { @@ -1210,15 +1181,3 @@ export interface NotificationKeyFilter { */ readonly suffix?: string; } - -/** - * Options for the onCloudTrailPutObject method - */ -export interface OnCloudTrailBucketEventOptions extends events.OnEventOptions { - /** - * Only watch changes to these object paths - * - * @default - Watch changes to all objects - */ - readonly paths?: string[]; -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-s3/test/integ.notifications.ts b/packages/@aws-cdk/aws-s3/test/integ.notifications.ts index 67e5714ce7939..cdc989fe4e90a 100644 --- a/packages/@aws-cdk/aws-s3/test/integ.notifications.ts +++ b/packages/@aws-cdk/aws-s3/test/integ.notifications.ts @@ -13,12 +13,12 @@ const bucket = new s3.Bucket(stack, 'Bucket', { const topic = new Topic(stack, 'Topic'); const topic3 = new Topic(stack, 'Topic3'); -bucket.addEventNotification(s3.EventType.ObjectCreatedPut, topic); -bucket.addEventNotification(s3.EventType.ObjectRemoved, topic3, { prefix: 'home/myusername/' }); +bucket.onEvent(s3.EventType.ObjectCreatedPut, topic); +bucket.onEvent(s3.EventType.ObjectRemoved, topic3, { prefix: 'home/myusername/' }); const bucket2 = new s3.Bucket(stack, 'Bucket2', { removalPolicy: cdk.RemovalPolicy.Destroy }); -bucket2.addObjectRemovedNotification(topic3, { prefix: 'foo' }, { suffix: 'foo/bar' }); +bucket2.onObjectRemoved(topic3, { prefix: 'foo' }, { suffix: 'foo/bar' }); app.run(); diff --git a/packages/@aws-cdk/aws-s3/test/test.notifications.ts b/packages/@aws-cdk/aws-s3/test/test.notifications.ts index 74e35aac97091..c495f3e7f3aee 100644 --- a/packages/@aws-cdk/aws-s3/test/test.notifications.ts +++ b/packages/@aws-cdk/aws-s3/test/test.notifications.ts @@ -34,7 +34,7 @@ export = { const topic = new Topic(stack, 'MyTopic'); - bucket.addEventNotification(s3.EventType.ObjectCreated, topic); + bucket.onEvent(s3.EventType.ObjectCreated, topic); expect(stack).to(haveResource('AWS::S3::Bucket')); expect(stack).to(haveResource('AWS::Lambda::Function', { Description: 'AWS CloudFormation handler for "Custom::S3BucketNotifications" resources (@aws-cdk/aws-s3)' })); @@ -50,7 +50,7 @@ export = { const topic = new Topic(stack, 'MyTopic'); - bucket.addEventNotification(s3.EventType.ObjectCreated, topic); + bucket.onEvent(s3.EventType.ObjectCreated, topic); expect(stack).to(haveResource('AWS::S3::Bucket')); expect(stack).to(haveResource('AWS::Lambda::Function', { @@ -70,7 +70,7 @@ export = { const topic = new Topic(stack, 'Topic'); const bucket = new s3.Bucket(stack, 'MyBucket'); - bucket.addObjectCreatedNotification(topic); + bucket.onObjectCreated(topic); expect(stack).to(haveResource('AWS::SNS::TopicPolicy', { "Topics": [ @@ -135,9 +135,9 @@ export = { }) }; - bucket.addEventNotification(s3.EventType.ObjectCreated, queueTarget); - bucket.addEventNotification(s3.EventType.ObjectCreated, lambdaTarget); - bucket.addObjectRemovedNotification(topicTarget, { prefix: 'prefix' }); + bucket.onEvent(s3.EventType.ObjectCreated, queueTarget); + bucket.onEvent(s3.EventType.ObjectCreated, lambdaTarget); + bucket.onObjectRemoved(topicTarget, { prefix: 'prefix' }); expect(stack).to(haveResource('Custom::S3BucketNotifications', { "ServiceToken": { @@ -195,14 +195,14 @@ export = { const bucket = new s3.Bucket(stack, 'TestBucket'); - bucket.addEventNotification(s3.EventType.ObjectRemovedDelete, { + bucket.onEvent(s3.EventType.ObjectRemovedDelete, { asBucketNotificationDestination: _ => ({ type: s3n.BucketNotificationDestinationType.Queue, arn: 'arn:aws:sqs:...:queue1' }) }); - bucket.addEventNotification(s3.EventType.ObjectRemovedDelete, { + bucket.onEvent(s3.EventType.ObjectRemovedDelete, { asBucketNotificationDestination: _ => ({ type: s3n.BucketNotificationDestinationType.Queue, arn: 'arn:aws:sqs:...:queue2' @@ -250,7 +250,7 @@ export = { arn: 'arn:aws:sqs:...' }; - bucket.addEventNotification(s3.EventType.ObjectRemovedDelete, { asBucketNotificationDestination: _ => bucketNotificationTarget }, { prefix: 'images/', suffix: '.jpg' }); + bucket.onEvent(s3.EventType.ObjectRemovedDelete, { asBucketNotificationDestination: _ => bucketNotificationTarget }, { prefix: 'images/', suffix: '.jpg' }); expect(stack).to(haveResource('Custom::S3BucketNotifications', { "ServiceToken": { @@ -304,7 +304,7 @@ export = { }) }; - bucket.addObjectCreatedNotification(dest); + bucket.onObjectCreated(dest); stack.node.prepareTree(); test.deepEqual(SynthUtils.toCloudFormation(stack).Resources.BucketNotifications8F2E257D, { @@ -326,11 +326,7 @@ export = { const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', { bucketName: 'MyBucket', }); - bucket.onCloudTrailPutObject('PutRule', { - target: { - bind: () => ({ arn: 'ARN', id: 'ID' }) - } - }); + bucket.onPutObject('PutRule'); expect(stack).to(haveResourceLike('AWS::Events::Rule', { "EventPattern": { @@ -338,6 +334,9 @@ export = { "aws.s3", ], "detail": { + "eventSource": [ + "s3.amazonaws.com", + ], "eventName": [ "PutObject", ], @@ -370,12 +369,7 @@ export = { const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', { bucketName: 'MyBucket', }); - bucket.onCloudTrailPutObject('PutRule', { - target: { - bind: () => ({ arn: 'ARN', id: 'ID' }) - }, - paths: ['my/path.zip'] - }); + bucket.onPutObject('PutRule', undefined, 'my/path.zip'); expect(stack).to(haveResourceLike('AWS::Events::Rule', { "EventPattern": { @@ -383,6 +377,9 @@ export = { "aws.s3", ], "detail": { + "eventSource": [ + "s3.amazonaws.com", + ], "eventName": [ "PutObject", ], diff --git a/packages/@aws-cdk/aws-sns/test/integ.sns-bucket-notifications.ts b/packages/@aws-cdk/aws-sns/test/integ.sns-bucket-notifications.ts index db1527730f93a..1a702b4b89d52 100644 --- a/packages/@aws-cdk/aws-sns/test/integ.sns-bucket-notifications.ts +++ b/packages/@aws-cdk/aws-sns/test/integ.sns-bucket-notifications.ts @@ -12,8 +12,8 @@ class MyStack extends cdk.Stack { removalPolicy: cdk.RemovalPolicy.Destroy }); - bucket.addObjectCreatedNotification(objectCreateTopic); - bucket.addObjectRemovedNotification(objectRemovedTopic, { prefix: 'foo/', suffix: '.txt' }); + bucket.onObjectCreated(objectCreateTopic); + bucket.onObjectRemoved(objectRemovedTopic, { prefix: 'foo/', suffix: '.txt' }); } } diff --git a/packages/@aws-cdk/aws-sqs/test/integ.bucket-notifications.ts b/packages/@aws-cdk/aws-sqs/test/integ.bucket-notifications.ts index e807defac5165..8310efec49c50 100644 --- a/packages/@aws-cdk/aws-sqs/test/integ.bucket-notifications.ts +++ b/packages/@aws-cdk/aws-sqs/test/integ.bucket-notifications.ts @@ -11,14 +11,14 @@ const bucket1 = new s3.Bucket(stack, 'Bucket1', { }); const queue = new sqs.Queue(stack, 'MyQueue'); -bucket1.addObjectCreatedNotification(queue); +bucket1.onObjectCreated(queue); const bucket2 = new s3.Bucket(stack, 'Bucket2', { removalPolicy: cdk.RemovalPolicy.Destroy }); -bucket2.addObjectCreatedNotification(queue, { suffix: '.png' }); +bucket2.onObjectCreated(queue, { suffix: '.png' }); const encryptedQueue = new sqs.Queue(stack, 'EncryptedQueue', { encryption: sqs.QueueEncryption.Kms }); -bucket1.addObjectRemovedNotification(encryptedQueue); +bucket1.onObjectRemoved(encryptedQueue); app.run(); diff --git a/packages/@aws-cdk/aws-sqs/test/test.sqs.ts b/packages/@aws-cdk/aws-sqs/test/test.sqs.ts index fe0c6fd0fc7e2..12b230a283a94 100644 --- a/packages/@aws-cdk/aws-sqs/test/test.sqs.ts +++ b/packages/@aws-cdk/aws-sqs/test/test.sqs.ts @@ -240,7 +240,7 @@ export = { const queue = new sqs.Queue(stack, 'Queue'); const bucket = new s3.Bucket(stack, 'Bucket'); - bucket.addObjectRemovedNotification(queue); + bucket.onObjectRemoved(queue); expect(stack).to(haveResource('AWS::SQS::QueuePolicy', { "PolicyDocument": { @@ -314,7 +314,7 @@ export = { const bucket = new s3.Bucket(stack, 'Bucket'); const queue = new sqs.Queue(stack, 'Queue', { encryption: sqs.QueueEncryption.Kms }); - bucket.addObjectCreatedNotification(queue); + bucket.onObjectCreated(queue); expect(stack).to(haveResource('AWS::KMS::Key', { "KeyPolicy": { @@ -381,7 +381,7 @@ export = { const stack = new Stack(); const queue = new sqs.Queue(stack, 'Queue', { encryption: sqs.QueueEncryption.KmsManaged }); const bucket = new s3.Bucket(stack, 'Bucket'); - test.throws(() => bucket.addObjectRemovedNotification(queue), 'Unable to add statement to IAM resource policy for KMS key: "alias/aws/sqs"'); + test.throws(() => bucket.onObjectRemoved(queue), 'Unable to add statement to IAM resource policy for KMS key: "alias/aws/sqs"'); test.done(); } diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts index 5dce6925b53d7..02158a9c443a0 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts @@ -188,7 +188,7 @@ export abstract class State extends cdk.Construct implements IChainable { * Register this state as part of the given graph * * Don't call this. It will be called automatically when you work - * with states normally. + * states normally. */ public bindToGraph(graph: StateGraph) { if (this.containingGraph === graph) { return; } @@ -199,7 +199,7 @@ export abstract class State extends cdk.Construct implements IChainable { } this.containingGraph = graph; - this.whenBoundToGraph(graph); + this.onBindToGraph(graph); for (const incoming of this.incomingStates) { incoming.bindToGraph(graph); @@ -349,7 +349,7 @@ export abstract class State extends cdk.Construct implements IChainable { * * Can be overridden by subclasses. */ - protected whenBoundToGraph(graph: StateGraph) { + protected onBindToGraph(graph: StateGraph) { graph.registerState(this); } diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/task.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/task.ts index d0a0bbf820334..dd524d03fdbac 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/task.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/task.ts @@ -229,8 +229,8 @@ export class Task extends State implements INextable { return this.taskMetric(this.taskProps.metricPrefixPlural, 'HeartbeatTimedOut', props); } - protected whenBoundToGraph(graph: StateGraph) { - super.whenBoundToGraph(graph); + protected onBindToGraph(graph: StateGraph) { + super.onBindToGraph(graph); for (const policyStatement of this.taskProps.policyStatements || []) { graph.registerPolicyStatement(policyStatement); } diff --git a/tools/awslint/bin/awslint.ts b/tools/awslint/bin/awslint.ts index 32a3c6c362363..236393580ce33 100644 --- a/tools/awslint/bin/awslint.ts +++ b/tools/awslint/bin/awslint.ts @@ -5,8 +5,7 @@ import fs = require('fs-extra'); import reflect = require('jsii-reflect'); import path = require('path'); import yargs = require('yargs'); -import { AggregateLinter, apiLinter, attributesLinter, cfnResourceLinter, constructLinter, DiagnosticLevel, eventsLinter, exportsLinter, importsLinter, - moduleLinter, resourceLinter } from '../lib'; +import { AggregateLinter, apiLinter, attributesLinter, cfnResourceLinter, constructLinter, DiagnosticLevel, importsLinter, moduleLinter, resourceLinter, exportsLinter } from '../lib'; const linter = new AggregateLinter( moduleLinter, @@ -16,8 +15,7 @@ const linter = new AggregateLinter( apiLinter, importsLinter, attributesLinter, - exportsLinter, - eventsLinter + exportsLinter ); let stackTrace = false; diff --git a/tools/awslint/lib/linter.ts b/tools/awslint/lib/linter.ts index 8ce53d42c1093..fa84010818b81 100644 --- a/tools/awslint/lib/linter.ts +++ b/tools/awslint/lib/linter.ts @@ -117,6 +117,7 @@ export class Evaluation { } public assert(condition: any, scope: string, extra?: string): condition is true { + // deduplicate: skip if this specific assertion ("rule:scope") was already examined if (this.diagnostics.find(d => d.rule.code === this.curr.code && d.scope === scope)) { return condition; @@ -125,19 +126,11 @@ export class Evaluation { const include = this.shouldEvaluate(this.curr.code, scope); const message = util.format(this.curr.message, extra || ''); - // Don't add a "Success" diagnostic. It will break if we run a compound - // linter rule which consists of 3 checks with the same scope (such - // as for example `assertSignature()`). If the first check fails, we would - // add a "Success" diagnostic and all other diagnostics would be skipped because - // of the deduplication check above. Changing the scope makes it worse, since - // the scope is also the ignore pattern and they're all conceptually the same rule. - // - // Simplest solution is to not record successes -- why do we even need them? - if (include && condition) { return condition; } - let level: DiagnosticLevel; if (!include) { level = DiagnosticLevel.Skipped; + } else if (condition) { + level = DiagnosticLevel.Success; } else if (this.curr.warning) { level = DiagnosticLevel.Warning; } else { @@ -166,12 +159,6 @@ export class Evaluation { return this.assert(a.toString() === e.toString(), scope, ` (expected="${e}",actual="${a}")`); } - public assertTypesAssignable(ts: reflect.TypeSystem, actual: TypeSpecifier, expected: TypeSpecifier, scope: string) { - const a = typeReferenceFrom(ts, actual); - const e = typeReferenceFrom(ts, expected); - return this.assert(a.toString() === e.toString() || (a.fqn && e.fqn && a.type!.extends(e.type!)), scope, ` ("${a}" not assignable to "${e}")`); - } - public assertSignature(method: reflect.Callable, expectations: MethodSignatureExpectations) { const scope = method.parentType.fqn + '.' + method.name; if (expectations.returns && reflect.Method.isMethod(method)) { @@ -192,11 +179,7 @@ export class Evaluation { this.assertEquals(actualName, expectedName, pscope); } if (expect.type) { - if (expect.subtypeAllowed) { - this.assertTypesAssignable(method.system, actual.type, expect.type, pscope); - } else { - this.assertTypesEqual(method.system, actual.type, expect.type, pscope); - } + this.assertTypesEqual(method.system, actual.type, expect.type, pscope); } } } @@ -271,7 +254,6 @@ export type TypeSpecifier = reflect.TypeReference | reflect.Type | string; export interface MethodSignatureParameterExpectation { name?: string; type?: TypeSpecifier; - subtypeAllowed?: boolean; /** should this param be optional? */ optional?: boolean; diff --git a/tools/awslint/lib/rules/cloudwatch-events.ts b/tools/awslint/lib/rules/cloudwatch-events.ts deleted file mode 100644 index 57dcbbb52923a..0000000000000 --- a/tools/awslint/lib/rules/cloudwatch-events.ts +++ /dev/null @@ -1,71 +0,0 @@ -import reflect = require('jsii-reflect'); -import { Linter } from '../linter'; -import { ConstructReflection } from './construct'; -import { CoreTypes } from './core-types'; - -export const eventsLinter = new Linter(assembly => assembly.classes - .filter(t => CoreTypes.isConstructClass(t)) - .map(construct => new EventsReflection(construct))); - -export class EventsReflection extends ConstructReflection { - public get directEventMethods() { - return this.classType.allMethods.filter(isDirectEventMethod); - } - - public get cloudTrailEventMethods() { - return this.classType.allMethods.filter(isCloudTrailEventMethod); - } -} - -const ON_EVENT_OPTIONS_FQN = '@aws-cdk/aws-events.OnEventOptions'; -const EVENT_RULE_FQN = '@aws-cdk/aws-events.Rule'; - -eventsLinter.add({ - code: 'events-in-interface', - message: `'onXxx()' methods should also be defined on construct interface`, - eval: e => { - for (const method of e.ctx.directEventMethods.concat(e.ctx.cloudTrailEventMethods)) { - e.assert(!e.ctx.interfaceType || e.ctx.interfaceType.allMethods.some(m => m.name === method.name), `${e.ctx.fqn}.${method.name}`); - } - } -}); - -eventsLinter.add({ - code: 'events-generic', - message: `if there are specific 'onXxx()' methods, there should also be a generic 'onEvent()' method`, - eval: e => { - e.assert(e.ctx.directEventMethods.length === 0 || e.ctx.classType.allMethods.some(m => m.name === 'onEvent'), e.ctx.fqn); - } -}); - -eventsLinter.add({ - code: 'events-generic-cloudtrail', - message: `if there are specific 'onCloudTrailXxx()' methods, there should also be a generic 'onCloudTrailEvent()' method`, - eval: e => { - e.assert(e.ctx.cloudTrailEventMethods.length === 0 || e.ctx.classType.allMethods.some(m => m.name === 'onCloudTrailEvent'), e.ctx.fqn); - } -}); - -eventsLinter.add({ - code: 'events-method-signature', - message: `all 'onXxx()' methods should have the CloudWatch Events signature (id: string, options: events.OnEventOptions) => events.Rule`, - eval: e => { - for (const method of e.ctx.directEventMethods) { - e.assertSignature(method, { - parameters: [ - { type: 'string' }, - { type: ON_EVENT_OPTIONS_FQN, subtypeAllowed: true }, - ], - returns: EVENT_RULE_FQN - }); - } - } -}); - -function isDirectEventMethod(m: reflect.Method) { - return m.name.startsWith('on') && ! m.name.startsWith('onCloudTrail'); -} - -function isCloudTrailEventMethod(m: reflect.Method) { - return m.name.startsWith('onCloudTrail'); -} \ No newline at end of file diff --git a/tools/awslint/lib/rules/index.ts b/tools/awslint/lib/rules/index.ts index 31b837a8c9d62..2f8db16866e8e 100644 --- a/tools/awslint/lib/rules/index.ts +++ b/tools/awslint/lib/rules/index.ts @@ -6,4 +6,3 @@ export * from './cfn-resource'; export * from './attributes'; export * from './api'; export * from './exports'; -export * from './cloudwatch-events';