Skip to content

Commit 03876ac

Browse files
committed
fix(cynosdb): support serverless
1 parent 4c6d6bf commit 03876ac

File tree

5 files changed

+352
-116
lines changed

5 files changed

+352
-116
lines changed

__tests__/cynos.test.js

Lines changed: 0 additions & 67 deletions
This file was deleted.

__tests__/cynosdb.test.js

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
const { Cynosdb } = require('../src');
2+
const {
3+
getClusterDetail,
4+
sleep,
5+
generatePwd,
6+
offlineCluster,
7+
PWD_CHARS,
8+
} = require('../src/modules/cynosdb/utils');
9+
10+
const pwdReg = new RegExp(`[${PWD_CHARS}]{8,64}`);
11+
12+
describe('Cynosdb', () => {
13+
jest.setTimeout(600000);
14+
const credentials = {
15+
SecretId: process.env.TENCENT_SECRET_ID,
16+
SecretKey: process.env.TENCENT_SECRET_KEY,
17+
};
18+
const region = 'ap-shanghai';
19+
const client = new Cynosdb(credentials, region);
20+
21+
const inputs = {
22+
region,
23+
zone: 'ap-shanghai-2',
24+
vpcConfig: {
25+
vpcId: 'vpc-mshegdk6',
26+
subnetId: 'subnet-3la82w45',
27+
},
28+
};
29+
30+
let clusterId;
31+
32+
test('[generatePwd] should get random password with default length 8', () => {
33+
const res = generatePwd();
34+
expect(typeof res).toBe('string');
35+
expect(res.length).toBe(8);
36+
});
37+
38+
test('[generatePwd] should get random password with customize length 6', () => {
39+
const res = generatePwd(6);
40+
expect(typeof res).toBe('string');
41+
expect(res.length).toBe(6);
42+
});
43+
44+
test('[NORMAL] deploy', async () => {
45+
const res = await client.deploy(inputs);
46+
expect(res).toEqual({
47+
dbMode: 'NORMAL',
48+
region: inputs.region,
49+
region: inputs.region,
50+
zone: inputs.zone,
51+
vpcConfig: inputs.vpcConfig,
52+
instanceCount: 2,
53+
adminPassword: expect.stringMatching(pwdReg),
54+
clusterId: expect.stringContaining('cynosdbmysql-'),
55+
connection: {
56+
ip: expect.any(String),
57+
port: 3306,
58+
readList: [
59+
{
60+
ip: expect.any(String),
61+
port: 3306,
62+
},
63+
],
64+
},
65+
});
66+
67+
({ clusterId } = res);
68+
});
69+
70+
test('[NORMAL] remove', async () => {
71+
await sleep(300);
72+
const res = await client.remove({ clusterId });
73+
74+
const detail = await getClusterDetail(client.capi, clusterId);
75+
expect(res).toEqual(true);
76+
expect(detail.Status).toBe('isolated');
77+
});
78+
test('[NORMAL] offline', async () => {
79+
await sleep(300);
80+
const res = await offlineCluster(client.capi, clusterId);
81+
expect(res).toBeUndefined();
82+
});
83+
84+
test('[SERVERLESS] deploy', async () => {
85+
inputs.dbMode = 'SERVERLESS';
86+
87+
const res = await client.deploy(inputs);
88+
expect(res).toEqual({
89+
dbMode: 'SERVERLESS',
90+
region: inputs.region,
91+
zone: inputs.zone,
92+
vpcConfig: inputs.vpcConfig,
93+
instanceCount: 1,
94+
adminPassword: expect.stringMatching(pwdReg),
95+
clusterId: expect.stringContaining('cynosdbmysql-'),
96+
minCpu: 0.5,
97+
maxCpu: 2,
98+
connection: {
99+
ip: expect.any(String),
100+
port: 3306,
101+
readList: expect.any(Array),
102+
},
103+
});
104+
105+
({ clusterId } = res);
106+
});
107+
108+
test('[SERVERLESS] remove', async () => {
109+
await sleep(300);
110+
const res = await client.remove({ clusterId });
111+
112+
const detail = await getClusterDetail(client.capi, clusterId);
113+
expect(res).toEqual(true);
114+
expect(detail.Status).toBe('isolated');
115+
});
116+
117+
test('[SERVERLESS] offline', async () => {
118+
await sleep(300);
119+
const res = await offlineCluster(client.capi, clusterId);
120+
expect(res).toBeUndefined();
121+
});
122+
123+
test('[SERVERLESS with minCpu and maxCpu] deploy', async () => {
124+
inputs.dbMode = 'SERVERLESS';
125+
inputs.minCpu = 2;
126+
inputs.maxCpu = 4;
127+
128+
const res = await client.deploy(inputs);
129+
expect(res).toEqual({
130+
dbMode: 'SERVERLESS',
131+
region: inputs.region,
132+
zone: inputs.zone,
133+
vpcConfig: inputs.vpcConfig,
134+
instanceCount: 1,
135+
adminPassword: expect.stringMatching(pwdReg),
136+
clusterId: expect.stringContaining('cynosdbmysql-'),
137+
minCpu: 2,
138+
maxCpu: 4,
139+
connection: {
140+
ip: expect.any(String),
141+
port: 3306,
142+
readList: expect.any(Array),
143+
},
144+
});
145+
146+
({ clusterId } = res);
147+
});
148+
149+
test('[SERVERLESS with minCpu and maxCpu] remove', async () => {
150+
await sleep(300);
151+
const res = await client.remove({ clusterId });
152+
153+
const detail = await getClusterDetail(client.capi, clusterId);
154+
expect(res).toEqual(true);
155+
expect(detail.Status).toBe('isolated');
156+
});
157+
158+
test('[SERVERLESS with minCpu and maxCpu] offline', async () => {
159+
await sleep(300);
160+
const res = await offlineCluster(client.capi, clusterId);
161+
expect(res).toBeUndefined();
162+
});
163+
});

src/modules/cynosdb/apis.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@ const ACTIONS = [
44
'CreateClusters',
55
'DescribeClusterDetail',
66
'IsolateCluster',
7+
'OfflineCluster',
8+
'OfflineInstance',
9+
'DescribeInstances',
10+
'DescribeInstanceDetail',
711
'DescribeAccounts',
812
'ResetAccountPassword',
13+
'DescribeClusters',
14+
'DescribeServerlessInstanceSpecs',
915
];
1016

1117
const APIS = ApiFactory({

src/modules/cynosdb/index.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const { Capi } = require('@tencent-sdk/capi');
22
const {
33
createCluster,
44
getClusterDetail,
5-
deleteCluster,
5+
isolateCluster,
66
generatePwd,
77
formatConnectOutput,
88
resetPwd,
@@ -41,13 +41,20 @@ class Cynosdb {
4141
timeSpan = 1,
4242
timeUnit = 'm',
4343
autoVoucher = 1,
44+
dbMode = 'NORMAL',
45+
minCpu = 0.5,
46+
maxCpu = 2,
47+
autoPause = 'yes',
48+
autoPauseDelay = 3600, // default 1h
4449
} = inputs;
4550

4651
const outputs = {
52+
dbMode,
4753
region: region,
4854
zone: zone,
4955
vpcConfig: vpcConfig,
5056
instanceCount,
57+
dbMode,
5158
};
5259

5360
let isExisted = false;
@@ -84,13 +91,25 @@ class Cynosdb {
8491
VpcId: vpcConfig.vpcId,
8592
SubnetId: vpcConfig.subnetId,
8693
AdminPassword: adminPassword || generatePwd(),
94+
DbMode: dbMode,
8795
};
8896
// prepay need set timespan 1month
8997
if (payMode === 1) {
9098
dbInputs.TimeSpan = timeSpan;
9199
dbInputs.TimeUnit = timeUnit;
92100
}
93101

102+
if (dbMode === 'SERVERLESS') {
103+
dbInputs.MinCpu = minCpu;
104+
dbInputs.MaxCpu = maxCpu;
105+
dbInputs.AutoPause = autoPause;
106+
dbInputs.AutoPauseDelay = autoPauseDelay;
107+
108+
outputs.minCpu = minCpu;
109+
outputs.maxCpu = maxCpu;
110+
outputs.instanceCount = 1;
111+
}
112+
94113
clusterDetail = await createCluster(this.capi, dbInputs);
95114
outputs.clusterId = clusterDetail.ClusterId;
96115

@@ -108,7 +127,7 @@ class Cynosdb {
108127
const clusterDetail = await getClusterDetail(this.capi, clusterId);
109128
if (clusterDetail && clusterDetail.ClusterId) {
110129
// need circle for deleting, after host status is 6, then we can delete it
111-
await deleteCluster(this.capi, clusterId);
130+
await isolateCluster(this.capi, clusterId);
112131
}
113132
return true;
114133
}

0 commit comments

Comments
 (0)