Skip to content

Commit 40ee1fa

Browse files
committed
feat(cfs): add cfs module
1 parent 65affaf commit 40ee1fa

File tree

4 files changed

+317
-0
lines changed

4 files changed

+317
-0
lines changed

src/modules/cfs/apis/apis.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
const { TypeError } = require('../../../utils/error');
2+
3+
function apiFactory(actions) {
4+
const apis = {};
5+
actions.forEach((action) => {
6+
apis[action] = async (capi, inputs) => {
7+
const data = {
8+
Version: '2019-07-19',
9+
Action: action,
10+
...inputs,
11+
};
12+
try {
13+
const { Response } = await capi.request(
14+
data,
15+
// this is preset options for capiateway
16+
{
17+
debug: false,
18+
ServiceType: 'cfs',
19+
// baseHost: 'tencentcloudapi.com'
20+
host: 'cfs.tencentcloudapi.com',
21+
},
22+
false,
23+
);
24+
25+
if (Response && Response.Error && Response.Error.Code) {
26+
throw new TypeError(
27+
`API_CFS_${action}`,
28+
Response.Error.Message,
29+
null,
30+
Response.RequestId,
31+
);
32+
}
33+
return Response;
34+
} catch (e) {
35+
throw new TypeError(`API_CFS_${action}`, e.message, e.stack, e.reqId);
36+
}
37+
};
38+
});
39+
40+
return apis;
41+
}
42+
43+
const ACTIONS = [
44+
'CreateCfsFileSystem',
45+
'DescribeCfsFileSystems',
46+
'UpdateCfsFileSystemName',
47+
'UpdateCfsFileSystemPGroup',
48+
'UpdateCfsFileSystemSizeLimit',
49+
'DeleteCfsFileSystem',
50+
'DescribeMountTargets',
51+
'DeleteMountTarget',
52+
];
53+
const APIS = apiFactory(ACTIONS);
54+
55+
module.exports = APIS;

src/modules/cfs/apis/index.js

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
const { waitResponse } = require('@ygkit/request');
2+
const { TypeError } = require('../../../utils/error');
3+
const {
4+
CreateCfsFileSystem,
5+
DescribeCfsFileSystems,
6+
UpdateCfsFileSystemName,
7+
UpdateCfsFileSystemPGroup,
8+
UpdateCfsFileSystemSizeLimit,
9+
DeleteCfsFileSystem,
10+
// DescribeMountTargets,
11+
DeleteMountTarget,
12+
} = require('./apis');
13+
14+
const TIMEOUT = 5 * 60 * 1000;
15+
16+
const apis = {
17+
async getCfs(capi, FileSystemId) {
18+
try {
19+
const {
20+
FileSystems: [detail],
21+
} = await DescribeCfsFileSystems(capi, {
22+
FileSystemId,
23+
});
24+
if (detail && detail.FileSystemId) {
25+
return detail;
26+
}
27+
} catch (e) {}
28+
return undefined;
29+
},
30+
31+
async createCfs(capi, params) {
32+
const res = await CreateCfsFileSystem(capi, params);
33+
34+
const detail = await waitResponse({
35+
callback: async () => this.getCfs(capi, res.FileSystemId),
36+
targetProp: 'LifeCycleState',
37+
targetResponse: 'available',
38+
timeout: TIMEOUT,
39+
});
40+
return detail;
41+
},
42+
43+
async deleteMountTarget(capi, FileSystemId, MountTargetId) {
44+
try {
45+
await DeleteMountTarget(capi, {
46+
FileSystemId,
47+
MountTargetId,
48+
});
49+
} catch (e) {
50+
throw new TypeError(
51+
'API_CFS_DeleteMountTarget',
52+
`Delete mouted target ${MountTargetId} for cfs ${FileSystemId} failed`,
53+
e.stack,
54+
e.reqId,
55+
);
56+
}
57+
},
58+
59+
async deleteCfs(capi, FileSystemId) {
60+
// TODO: now not support delete mount target
61+
// const { MountTargets } = await DescribeMountTargets(capi, {
62+
// FileSystemId,
63+
// });
64+
// console.log('MountTargets', MountTargets);
65+
// // 1. delete all mount target
66+
// if (MountTargets && MountTargets.length > 0) {
67+
// for (let i = 0; i < MountTargets.length; i++) {
68+
// await this.deleteMountTarget(capi, FileSystemId, MountTargets[i].MountTargetId);
69+
// }
70+
// }
71+
// 2. delete cfs and wait for it
72+
const { RequestId } = await DeleteCfsFileSystem(capi, {
73+
FileSystemId,
74+
});
75+
try {
76+
await waitResponse({
77+
callback: async () => this.getCfs(capi, FileSystemId),
78+
targetResponse: undefined,
79+
timeout: TIMEOUT,
80+
});
81+
} catch (e) {
82+
throw new TypeError(
83+
'API_CFS_DeleteCfsFileSystem',
84+
`Delete cfs ${FileSystemId} failed`,
85+
null,
86+
RequestId,
87+
);
88+
}
89+
},
90+
91+
async updateCfs(capi, FileSystemId, params) {
92+
// update fs name
93+
if (params.fsName) {
94+
await UpdateCfsFileSystemName(capi, {
95+
FileSystemId,
96+
FsName: params.fsName,
97+
});
98+
}
99+
// update priority group
100+
if (params.pGroupId) {
101+
await UpdateCfsFileSystemPGroup(capi, {
102+
FileSystemId,
103+
PGroupId: params.pGroupId,
104+
});
105+
106+
await waitResponse({
107+
callback: async () => this.getCfs(capi, FileSystemId),
108+
targetProp: 'LifeCycleState',
109+
targetResponse: 'available',
110+
timeout: TIMEOUT,
111+
});
112+
}
113+
// update fs storage limit
114+
if (params.fsLimit) {
115+
await UpdateCfsFileSystemSizeLimit(capi, {
116+
FileSystemId,
117+
FsLimit: params.fsLimit,
118+
});
119+
120+
await waitResponse({
121+
callback: async () => this.getCfs(capi, FileSystemId),
122+
targetProp: 'LifeCycleState',
123+
targetResponse: 'available',
124+
timeout: TIMEOUT,
125+
});
126+
}
127+
},
128+
};
129+
130+
module.exports = apis;

src/modules/cfs/index.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
const { Capi } = require('@tencent-sdk/capi');
2+
const apis = require('./apis');
3+
4+
class Layer {
5+
constructor(credentials = {}, region) {
6+
this.region = region || 'ap-guangzhou';
7+
this.credentials = credentials;
8+
this.capi = new Capi({
9+
Region: region,
10+
SecretId: credentials.SecretId,
11+
SecretKey: credentials.SecretKey,
12+
Token: credentials.Token,
13+
});
14+
}
15+
16+
async deploy(inputs = {}) {
17+
const cfsInputs = {
18+
Zone: inputs.zone,
19+
FsName: inputs.fsName,
20+
PGroupId: inputs.pGroupId || 'pgroupbasic',
21+
NetInterface: inputs.netInterface || 'VPC',
22+
Protocol: inputs.protocol || 'NFS',
23+
StorageType: inputs.storageType || 'SD',
24+
};
25+
26+
const outputs = {
27+
region: this.region,
28+
fsName: cfsInputs.FsName,
29+
pGroupId: cfsInputs.PGroupId,
30+
netInterface: cfsInputs.NetInterface,
31+
protocol: cfsInputs.Protocol,
32+
storageType: cfsInputs.StorageType,
33+
};
34+
35+
// check cfs existance
36+
let exist = false;
37+
if (inputs.fileSystemId) {
38+
const detail = await apis.getCfs(this.capi, inputs.fileSystemId);
39+
// update it
40+
if (detail) {
41+
exist = true;
42+
const updateParams = {};
43+
if (inputs.pGroupId !== detail.PGroup.PGroupId) {
44+
updateParams.pGroupId = inputs.pGroupId;
45+
}
46+
if (inputs.fsName && inputs.fsName !== detail.FsName) {
47+
updateParams.fsName = inputs.fsName;
48+
}
49+
if (inputs.fsLimit !== undefined && inputs.fsLimit !== detail.SizeLimit) {
50+
updateParams.fsLimit = inputs.fsLimit;
51+
}
52+
// update cfs
53+
if (Object.keys(updateParams).length > 0) {
54+
console.log(`Updating CFS id: ${inputs.fileSystemId}, name: ${inputs.fsName}`);
55+
await apis.updateCfs(this.capi, inputs.fileSystemId, updateParams);
56+
console.log(`Update CFS id: ${inputs.fileSystemId}, name: ${inputs.fsName} success.`);
57+
}
58+
59+
outputs.fileSystemId = inputs.fileSystemId;
60+
}
61+
}
62+
63+
// if not exist, create cfs
64+
if (!exist) {
65+
if (inputs.netInterface === 'VPC') {
66+
cfsInputs.VpcId = inputs.vpc.vpcId;
67+
cfsInputs.SubnetId = inputs.vpc.subnetId;
68+
69+
if (inputs.vpc.mountIP) {
70+
cfsInputs.MountIP = inputs.vpc.mountIP;
71+
}
72+
}
73+
74+
if (inputs.tags) {
75+
cfsInputs.ResourceTags = inputs.tags;
76+
}
77+
console.log(`Creating CFS ${inputs.fsName}`);
78+
const { FileSystemId } = await apis.createCfs(this.capi, cfsInputs);
79+
console.log(`Created CFS ${inputs.fsName}, id ${FileSystemId} successful`);
80+
outputs.fileSystemId = FileSystemId;
81+
}
82+
83+
return outputs;
84+
}
85+
86+
async remove(inputs = {}) {
87+
try {
88+
console.log(`Start removing CFS ${inputs.fsName}, id ${inputs.fileSystemId}...`);
89+
await apis.deleteCfs(this.capi, inputs.fileSystemId);
90+
console.log(`Remove CFS ${inputs.fsName}, id ${inputs.fileSystemId} successfully`);
91+
} catch (e) {
92+
console.log(e);
93+
}
94+
95+
return {};
96+
}
97+
}
98+
99+
module.exports = Layer;

src/modules/cfs/index.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const Client = require('./index');
2+
const { sleep } = require('@ygkit/request');
3+
4+
async function runTest() {
5+
const credentials = {
6+
SecretId: '',
7+
SecretKey: '',
8+
};
9+
10+
const inputs = {
11+
fileSystemId: 'cfs-lffp4e73',
12+
fsName: 'cfs-test',
13+
region: 'ap-guangzhou',
14+
zone: 'ap-guangzhou-3',
15+
netInterface: 'VPC',
16+
vpc: {
17+
vpcId: 'vpc-cp54x9m7',
18+
subnetId: 'subnet-267yufru',
19+
},
20+
};
21+
const client = new Client(credentials, inputs.region);
22+
const outputs = await client.deploy(inputs);
23+
console.log('outputs', JSON.stringify(outputs));
24+
25+
await sleep(1000);
26+
await client.remove(outputs);
27+
}
28+
29+
runTest();
30+
31+
process.on('unhandledRejection', (e) => {
32+
throw e;
33+
});

0 commit comments

Comments
 (0)