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(s3): onCloudTrailWriteObject matches all update events #4723

Merged
merged 9 commits into from
Oct 30, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@
"Version": "2012-10-17"
}
},
"DeletionPolicy": "Delete",
"UpdateReplacePolicy": "Delete"
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"PipelineArtifactsBucket22248F97": {
"Type": "AWS::S3::Bucket",
Expand All @@ -104,8 +104,8 @@
]
}
},
"DeletionPolicy": "Retain",
"UpdateReplacePolicy": "Retain"
"UpdateReplacePolicy": "Retain",
"DeletionPolicy": "Retain"
},
"PipelineArtifactsBucketEncryptionKeyAlias5C510EEE": {
"Type": "AWS::KMS::Alias",
Expand All @@ -118,8 +118,8 @@
]
}
},
"DeletionPolicy": "Delete",
"UpdateReplacePolicy": "Delete"
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"PipelineRoleD68726F7": {
"Type": "AWS::IAM::Role",
Expand Down Expand Up @@ -381,7 +381,6 @@
}
]
},

{
"Action": [
"s3:DeleteObject*",
Expand Down Expand Up @@ -567,8 +566,8 @@
"Status": "Enabled"
}
},
"DeletionPolicy": "Delete",
"UpdateReplacePolicy": "Delete"
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"PipelineBucketawscdkcodepipelinelambdaPipeline87A4B3D3SourceEventRulekey23D3C004": {
"Type": "AWS::Events::Rule",
Expand Down Expand Up @@ -600,8 +599,20 @@
]
},
"eventName": [
"CompleteMultipartUpload",
"CopyObject",
"PutObject"
]
],
"requestParameters": {
"bucketName": [
{
"Ref": "PipelineBucketB967BD35"
}
],
"key": [
"key"
]
}
}
},
"State": "ENABLED",
Expand Down Expand Up @@ -643,8 +654,8 @@
},
"CloudTrailS310CD22F2": {
"Type": "AWS::S3::Bucket",
"DeletionPolicy": "Retain",
"UpdateReplacePolicy": "Retain"
"UpdateReplacePolicy": "Retain",
"DeletionPolicy": "Retain"
},
"CloudTrailS3PolicyEA49A03E": {
"Type": "AWS::S3::BucketPolicy",
Expand Down Expand Up @@ -820,4 +831,4 @@
]
}
}
}
}
92 changes: 87 additions & 5 deletions packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ test('a notification destination can specify a set of dependencies that must be
});

describe('CloudWatch Events', () => {
test('onPutItem contains the Bucket ARN itself when path is undefined', () => {
test('onCloudTrailPutObject matches on CompleteMultipartUpload, CopyObject, and PutObject', () => {
const stack = new cdk.Stack();
const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
bucketName: 'MyBucket',
Expand All @@ -323,8 +323,33 @@ describe('CloudWatch Events', () => {
],
"detail": {
"eventName": [
"CompleteMultipartUpload",
"CopyObject",
"PutObject",
],
},
},
"State": "ENABLED",
});
});

test('onCloudTrailPutObject contains the Bucket ARN itself when path is undefined', () => {
const stack = new cdk.Stack();
const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
bucketName: 'MyBucket',
});
bucket.onCloudTrailPutObject('PutRule', {
target: {
bind: () => ({ arn: 'ARN', id: '' })
}
});

expect(stack).toHaveResourceLike('AWS::Events::Rule', {
"EventPattern": {
"source": [
"aws.s3",
],
"detail": {
"resources": {
"ARN": [
{
Expand All @@ -347,7 +372,7 @@ describe('CloudWatch Events', () => {
});
});

test("onPutItem contains the path when it's provided", () => {
test("onCloudTrailPutObject contains the path when it's provided", () => {
const stack = new cdk.Stack();
const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
bucketName: 'MyBucket',
Expand All @@ -365,9 +390,6 @@ describe('CloudWatch Events', () => {
"aws.s3",
],
"detail": {
"eventName": [
eladb marked this conversation as resolved.
Show resolved Hide resolved
"PutObject",
],
"resources": {
"ARN": [
{
Expand All @@ -389,4 +411,64 @@ describe('CloudWatch Events', () => {
"State": "ENABLED",
});
});

test("onCloudTrailPutObject matches on the requestParameter bucketName when the path is not provided", () => {
const stack = new cdk.Stack();
const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
bucketName: 'MyBucket',
});
bucket.onCloudTrailPutObject('PutRule', {
target: {
bind: () => ({ arn: 'ARN', id: '' })
},
});

expect(stack).toHaveResourceLike('AWS::Events::Rule', {
"EventPattern": {
"source": [
"aws.s3",
],
"detail": {
"requestParameters": {
"bucketName": [
bucket.bucketName,
],
},
},
},
"State": "ENABLED",
});
});

test("onCloudTrailPutObject matches on the requestParameters bucketName and key when the path is provided", () => {
const stack = new cdk.Stack();
const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
bucketName: 'MyBucket',
});
bucket.onCloudTrailPutObject('PutRule', {
target: {
bind: () => ({ arn: 'ARN', id: '' })
},
paths: ['my/path.zip']
});

expect(stack).toHaveResourceLike('AWS::Events::Rule', {
"EventPattern": {
"source": [
"aws.s3",
],
"detail": {
"requestParameters": {
"bucketName": [
bucket.bucketName,
],
"key": [
"my/path.zip",
],
},
},
},
"State": "ENABLED",
});
});
});
22 changes: 16 additions & 6 deletions packages/@aws-cdk/aws-s3/lib/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export interface IBucket extends IResource {
grantPublicAccess(keyPrefix?: string, ...allowedActions: string[]): iam.Grant;

/**
* Define a CloudWatch event that triggers when something happens to this repository
* Define a CloudWatch event that triggers when something happens to this bucket
*
* Requires that there exists at least one CloudTrail Trail in your account
* that captures the event. This method will not create the Trail.
Expand All @@ -183,8 +183,9 @@ export interface IBucket extends IResource {
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.
* Defines an AWS CloudWatch event rule that can trigger a target when the
* object at the specified key in this bucket is written to. This includes
* the events PutObject, CopyObject, and CompleteMultipartUpload.
*
* Requires that there exists at least one CloudTrail Trail in your account
* that captures the event. This method will not create the Trail.
Expand Down Expand Up @@ -325,8 +326,9 @@ abstract class BucketBase extends Resource implements IBucket {
}

/**
* Defines an AWS CloudWatch event rule that can trigger a target when an image is pushed to this
* repository.
* Defines an AWS CloudWatch event rule that can trigger a target when the
* object at the specified key in this bucket is written to. This includes
* the events PutObject, CopyObject, and CompleteMultipartUpload.
*
* Requires that there exists at least one CloudTrail Trail in your account
* that captures the event. This method will not create the Trail.
Expand All @@ -338,7 +340,15 @@ abstract class BucketBase extends Resource implements IBucket {
const rule = this.onCloudTrailEvent(id, options);
rule.addEventPattern({
detail: {
eventName: ['PutObject'],
eventName: [
'CompleteMultipartUpload',
'CopyObject',
'PutObject'
],
requestParameters: {
bucketName: [ this.bucketName ],
key: options.paths,
},
},
});
return rule;
Expand Down