-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
s3-file.ts
103 lines (89 loc) · 2.85 KB
/
s3-file.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import * as path from 'path';
import * as iam from '@aws-cdk/aws-iam';
import * as lambda from '@aws-cdk/aws-lambda';
import * as s3 from '@aws-cdk/aws-s3';
import { CustomResource, Stack } from '@aws-cdk/core';
import { Construct, Node } from 'constructs';
import * as cr from '../../../lib';
import * as api from './s3-file-handler/api';
// v2 - keep this import as a separate section to reduce merge conflict when forward merging with the v2 branch.
// eslint-disable-next-line
import { Construct as CoreConstruct } from '@aws-cdk/core';
interface S3FileProps {
/**
* The bucket in which the file will be created.
*/
readonly bucket: s3.IBucket;
/**
* The object key.
*
* @default - automatically-generated
*/
readonly objectKey?: string;
/**
* The contents of the file.
*/
readonly contents: string;
/**
* Indicates if this file should have public-read permissions.
*
* @default false
*/
readonly public?: boolean;
}
export class S3File extends CoreConstruct {
public readonly objectKey: string;
public readonly url: string;
public readonly etag: string;
constructor(scope: Construct, id: string, props: S3FileProps) {
super(scope, id);
const resource = new CustomResource(this, 'Resource', {
serviceToken: S3FileProvider.getOrCreate(this),
resourceType: 'Custom::S3File',
properties: {
[api.PROP_BUCKET_NAME]: props.bucket.bucketName,
[api.PROP_CONTENTS]: props.contents,
[api.PROP_OBJECT_KEY]: props.objectKey,
[api.PROP_PUBLIC]: props.public,
},
});
this.objectKey = resource.getAttString(api.ATTR_OBJECT_KEY);
this.url = resource.getAttString(api.ATTR_URL);
this.etag = resource.getAttString(api.ATTR_ETAG);
}
}
class S3FileProvider extends CoreConstruct {
/**
* Returns the singleton provider.
*/
public static getOrCreate(scope: Construct) {
const stack = Stack.of(scope);
const id = 'com.amazonaws.cdk.custom-resources.s3file-provider';
const x = Node.of(stack).tryFindChild(id) as S3FileProvider || new S3FileProvider(stack, id);
return x.provider.serviceToken;
}
private readonly provider: cr.Provider;
constructor(scope: Construct, id: string) {
super(scope, id);
this.provider = new cr.Provider(this, 's3file-provider', {
onEventHandler: new lambda.Function(this, 's3file-on-event', {
code: lambda.Code.fromAsset(path.join(__dirname, 's3-file-handler')),
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'index.onEvent',
initialPolicy: [
new iam.PolicyStatement({
resources: ['*'],
actions: [
's3:GetObject*',
's3:GetBucket*',
's3:List*',
's3:DeleteObject*',
's3:PutObject*',
's3:Abort*',
],
}),
],
}),
});
}
}