Skip to content

Commit 027fd4a

Browse files
committed
feat: oss resource definition
Signed-off-by: seven <[email protected]>
1 parent 473188e commit 027fd4a

File tree

7 files changed

+198
-18
lines changed

7 files changed

+198
-18
lines changed

src/parser/bucketParser.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { BucketDomain, BucketRaw } from '../types';
2+
3+
export const parseBucket = (buckets: {
4+
[key: string]: BucketRaw;
5+
}): Array<BucketDomain> | undefined => {
6+
if (!buckets) {
7+
return undefined;
8+
}
9+
return Object.entries(buckets).map(([key, bucket]) => ({
10+
key,
11+
name: bucket.name,
12+
storage: bucket.storage,
13+
versioning: bucket.versioning,
14+
security: bucket.security
15+
? {
16+
force_delete: bucket.security.force_delete ?? false,
17+
sse_algorithm: bucket.security.sse_algorithm,
18+
sse_kms_master_key_id: bucket.security.sse_kms_master_key_id,
19+
}
20+
: undefined,
21+
22+
website: bucket.website
23+
? {
24+
index: bucket.website.index ?? 'index.html',
25+
error_page: bucket.website.error_page ?? '404.html',
26+
error_code: bucket.website.error_code ?? 404,
27+
}
28+
: undefined,
29+
}));
30+
};

src/stack/rosStack/bucket.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
1-
import { ActionContext, DatabaseDomain } from '../../types';
1+
import { ActionContext, BucketDomain } from '../../types';
22
import * as oss from '@alicloud/ros-cdk-oss';
33
import * as ros from '@alicloud/ros-cdk-core';
44
import { replaceReference } from '../../common';
55

66
export const resolveBuckets = (
77
scope: ros.Construct,
8-
buckets: Array<DatabaseDomain> | undefined,
8+
buckets: Array<BucketDomain> | undefined,
99
context: ActionContext,
1010
) => {
1111
if (!buckets) {
1212
return undefined;
1313
}
1414
buckets.forEach((bucket) => {
1515
new oss.Bucket(scope, replaceReference(bucket.key, context), {
16-
bucketName: bucket.name,
16+
bucketName: replaceReference(bucket.name, context),
17+
websiteConfigurationV2: bucket.website
18+
? {
19+
indexDocument: {
20+
type: '0',
21+
suffix: replaceReference(bucket.website.index, context),
22+
supportSubDir: 'true',
23+
},
24+
errorDocument: {
25+
httpStatus: `${replaceReference(bucket.website.error_code, context)}`,
26+
key: replaceReference(bucket.website.error_page, context),
27+
},
28+
}
29+
: undefined,
1730
});
1831
});
1932
};

src/stack/rosStack/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { resolveStages } from './stage';
77
import { resloveVars } from './vars';
88
import { resolveDatabases } from './database';
99
import { resolveEvents } from './event';
10+
import { resolveBuckets } from './bucket';
1011

1112
export * from './bootstrap';
1213

@@ -32,5 +33,7 @@ export class RosStack extends ros.Stack {
3233
resolveEvents(this, iac.events, iac.tags, context, this.service);
3334
// Define Databases
3435
resolveDatabases(this, iac.databases, context);
36+
// Define Buckets
37+
resolveBuckets(this, iac.buckets, context);
3538
}
3639
}

src/types/domains/bucket.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,42 @@
1-
export type BucketDomain = {
1+
export type BucketRaw = {
22
name: string;
3-
storage: {
3+
storage?: {
44
class: string;
55
};
6-
versioning: {
6+
versioning?: {
77
status: string;
88
};
9-
lifecycle: {
10-
rule: {
11-
id: string;
12-
};
9+
10+
security?: {
11+
force_delete?: boolean;
12+
sse_algorithm?: string;
13+
sse_kms_master_key_id?: string;
14+
};
15+
website?: {
16+
index?: string;
17+
error_page?: string;
18+
error_code?: number;
19+
};
20+
};
21+
22+
export type BucketDomain = {
23+
key: string;
24+
name: string;
25+
storage?: {
26+
class: string;
27+
};
28+
versioning?: {
1329
status: string;
14-
expiration: {
15-
days: number;
16-
};
1730
};
1831

19-
security: {
32+
security?: {
2033
force_delete: boolean;
21-
sse_algorithm: string;
22-
sse_kms_master_key_id: string;
34+
sse_algorithm?: string;
35+
sse_kms_master_key_id?: string;
2336
};
24-
website: {
37+
website?: {
2538
index: string;
26-
error: string;
39+
error_page: string;
40+
error_code: number;
2741
};
2842
};

src/types/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { EventDomain, EventRaw } from './domains/event';
44
import { DatabaseDomain, DatabaseRaw } from './domains/database';
55
import { FunctionDomain, FunctionRaw } from './domains/function';
66
import { Provider } from './domains/provider';
7+
import { BucketDomain, BucketRaw } from './domains/bucket';
78

89
export * from './domains/database';
910
export * from './domains/event';
@@ -24,6 +25,7 @@ export type ServerlessIacRaw = {
2425
functions: { [key: string]: FunctionRaw };
2526
events: { [key: string]: EventRaw };
2627
databases: { [key: string]: DatabaseRaw };
28+
buckets: { [key: string]: BucketRaw };
2729
};
2830

2931
export type ServerlessIac = {
@@ -36,4 +38,5 @@ export type ServerlessIac = {
3638
functions?: Array<FunctionDomain>;
3739
events?: Array<EventDomain>;
3840
databases?: Array<DatabaseDomain>;
41+
buckets?: Array<BucketDomain>;
3942
};

tests/fixtures/deployFixture.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,3 +1242,86 @@ export const esServerlessMinimumRos = {
12421242
},
12431243
},
12441244
};
1245+
1246+
export const bucketMinimumIac = {
1247+
version: '0.0.1',
1248+
provider: {
1249+
name: 'aliyun',
1250+
region: 'cn-hangzhou',
1251+
},
1252+
service: 'my-bucket-service',
1253+
buckets: [
1254+
{
1255+
key: 'my_bucket',
1256+
name: 'my-bucket',
1257+
},
1258+
],
1259+
} as unknown as ServerlessIac;
1260+
1261+
export const bucketMinimumRos = {
1262+
Description: 'my-bucket-service stack',
1263+
Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } },
1264+
ROSTemplateFormatVersion: '2015-09-01',
1265+
Resources: {
1266+
my_bucket: {
1267+
Properties: {
1268+
BucketName: 'my-bucket',
1269+
AccessControl: 'private',
1270+
DeletionForce: false,
1271+
EnableOssHdfsService: false,
1272+
RedundancyType: 'LRS',
1273+
},
1274+
Type: 'ALIYUN::OSS::Bucket',
1275+
},
1276+
},
1277+
};
1278+
1279+
export const bucketWithWebsiteIac = {
1280+
version: '0.0.1',
1281+
provider: {
1282+
name: 'aliyun',
1283+
region: 'cn-hangzhou',
1284+
},
1285+
service: 'my-bucket-service',
1286+
buckets: [
1287+
{
1288+
key: 'my_bucket',
1289+
name: 'my-bucket',
1290+
website: {
1291+
index: 'index.html',
1292+
error_page: '404.html',
1293+
error_code: 404,
1294+
},
1295+
},
1296+
],
1297+
} as ServerlessIac;
1298+
1299+
export const bucketWithWebsiteRos = {
1300+
Description: 'my-bucket-service stack',
1301+
Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } },
1302+
ROSTemplateFormatVersion: '2015-09-01',
1303+
Resources: {
1304+
my_bucket: {
1305+
Properties: {
1306+
BucketName: 'my-bucket',
1307+
AccessControl: 'private',
1308+
DeletionForce: false,
1309+
EnableOssHdfsService: false,
1310+
RedundancyType: 'LRS',
1311+
1312+
WebsiteConfigurationV2: {
1313+
ErrorDocument: {
1314+
HttpStatus: '404',
1315+
Key: '404.html',
1316+
},
1317+
IndexDocument: {
1318+
Suffix: 'index.html',
1319+
SupportSubDir: 'true',
1320+
Type: '0',
1321+
},
1322+
},
1323+
},
1324+
Type: 'ALIYUN::OSS::Bucket',
1325+
},
1326+
},
1327+
};

tests/stack/deploy.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { deployStack } from '../../src/stack';
22
import { ActionContext } from '../../src/types';
33
import {
4+
bucketMinimumIac,
5+
bucketMinimumRos,
6+
bucketWithWebsiteIac,
7+
bucketWithWebsiteRos,
48
esServerlessMinimumIac,
59
esServerlessMinimumRos,
610
largeCodeRos,
@@ -177,4 +181,34 @@ describe('Unit tests for stack deployment', () => {
177181
]);
178182
});
179183
});
184+
185+
describe('unit test for deploy of buckets', () => {
186+
it('should deploy bucket when minimum fields provided', async () => {
187+
const stackName = 'my-demo-bucket-stack';
188+
mockedRosStackDeploy.mockResolvedValue(stackName);
189+
190+
await deployStack(stackName, bucketMinimumIac, { stackName } as ActionContext);
191+
192+
expect(mockedRosStackDeploy).toHaveBeenCalledTimes(2);
193+
expect(mockedRosStackDeploy.mock.calls[1]).toEqual([
194+
stackName,
195+
bucketMinimumRos,
196+
{ stackName },
197+
]);
198+
});
199+
200+
it('should deploy bucket as a website when website field is provided', async () => {
201+
const stackName = 'my-website-bucket-stack';
202+
mockedRosStackDeploy.mockResolvedValue(stackName);
203+
204+
await deployStack(stackName, bucketWithWebsiteIac, { stackName } as ActionContext);
205+
206+
expect(mockedRosStackDeploy).toHaveBeenCalledTimes(2);
207+
expect(mockedRosStackDeploy.mock.calls[1]).toEqual([
208+
stackName,
209+
bucketWithWebsiteRos,
210+
{ stackName },
211+
]);
212+
});
213+
});
180214
});

0 commit comments

Comments
 (0)