serverless-vpc-discovery 5.0.2 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mocharc.json +5 -0
- package/README.md +3 -2
- package/dist/src/aws/ec2-wrapper.js +76 -92
- package/dist/src/common/lambda-function.js +70 -87
- package/dist/src/globals.js +9 -15
- package/dist/src/index.js +68 -84
- package/dist/src/utils.js +17 -31
- package/dist/src/validation.js +1 -2
- package/package.json +32 -36
- package/tsconfig.json +1 -1
- package/.eslintrc.json +0 -41
package/.mocharc.json
ADDED
package/README.md
CHANGED
|
@@ -183,10 +183,11 @@ All tests should pass.
|
|
|
183
183
|
To run integration tests, set an environment variable TEST\_VPC\_NAME to the VPC you will be testing for. Then,
|
|
184
184
|
|
|
185
185
|
```
|
|
186
|
+
export SERVERLESS_LICENSE_KEY=<license_key>
|
|
186
187
|
export AWS_PROFILE=your_profile
|
|
187
188
|
export TEST_VPC_NAME=vpc_name
|
|
188
|
-
npm run build
|
|
189
|
-
npm run integration-test
|
|
189
|
+
npx npm run build
|
|
190
|
+
npx npm run integration-test
|
|
190
191
|
```
|
|
191
192
|
|
|
192
193
|
If there is an error build and install the node\_module inside the serverless-vpc-discovery folder:
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -17,6 +8,7 @@ const utils_1 = require("../utils");
|
|
|
17
8
|
const client_ec2_1 = require("@aws-sdk/client-ec2");
|
|
18
9
|
const globals_1 = __importDefault(require("../globals"));
|
|
19
10
|
class EC2Wrapper {
|
|
11
|
+
ec2;
|
|
20
12
|
constructor(credentials) {
|
|
21
13
|
this.ec2 = new client_ec2_1.EC2Client({
|
|
22
14
|
credentials,
|
|
@@ -28,29 +20,25 @@ class EC2Wrapper {
|
|
|
28
20
|
* Returns the promise that contains the vpc list
|
|
29
21
|
* @returns {Promise.<Vpc[]>}
|
|
30
22
|
*/
|
|
31
|
-
getVpcs() {
|
|
32
|
-
return
|
|
33
|
-
return yield (0, utils_1.getAWSPagedResults)(this.ec2, "Vpcs", "NextToken", "NextToken", new client_ec2_1.DescribeVpcsCommand({}));
|
|
34
|
-
});
|
|
23
|
+
async getVpcs() {
|
|
24
|
+
return await (0, utils_1.getAWSPagedResults)(this.ec2, "Vpcs", "NextToken", "NextToken", new client_ec2_1.DescribeVpcsCommand({}));
|
|
35
25
|
}
|
|
36
26
|
/**
|
|
37
27
|
* Returns the promise that contains the vpc-id
|
|
38
28
|
* @param {string} vpcName
|
|
39
29
|
* @returns {Promise.<string>}
|
|
40
30
|
*/
|
|
41
|
-
getVpcId(vpcName) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return vpcItems[0].VpcId;
|
|
53
|
-
});
|
|
31
|
+
async getVpcId(vpcName) {
|
|
32
|
+
const vpcItems = await (0, utils_1.getAWSPagedResults)(this.ec2, "Vpcs", "NextToken", "NextToken", new client_ec2_1.DescribeVpcsCommand({
|
|
33
|
+
Filters: [{
|
|
34
|
+
Name: "tag:Name",
|
|
35
|
+
Values: [vpcName]
|
|
36
|
+
}]
|
|
37
|
+
}));
|
|
38
|
+
if (vpcItems.length === 0) {
|
|
39
|
+
throw new Error(`VPC with tag key 'Name' and tag value '${vpcName}' does not exist.`);
|
|
40
|
+
}
|
|
41
|
+
return vpcItems[0].VpcId;
|
|
54
42
|
}
|
|
55
43
|
/**
|
|
56
44
|
* Returns the promise that contains the subnet IDs
|
|
@@ -60,30 +48,28 @@ class EC2Wrapper {
|
|
|
60
48
|
* @param {string[]} tagValues
|
|
61
49
|
* @returns {Promise.<string[]>}
|
|
62
50
|
*/
|
|
63
|
-
getSubnetIds(vpcId, tagKey, tagValues) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return (0, utils_1.wildcardMatches)(tagValue, (0, utils_1.getValueFromTags)(subnet.Tags, tagKey));
|
|
78
|
-
});
|
|
79
|
-
return subnetsByName.length === 0;
|
|
51
|
+
async getSubnetIds(vpcId, tagKey, tagValues) {
|
|
52
|
+
const subnets = await (0, utils_1.getAWSPagedResults)(this.ec2, "Subnets", "NextToken", "NextToken", new client_ec2_1.DescribeSubnetsCommand({
|
|
53
|
+
Filters: [{
|
|
54
|
+
Name: "vpc-id",
|
|
55
|
+
Values: [vpcId]
|
|
56
|
+
}, {
|
|
57
|
+
Name: `tag:${tagKey}`,
|
|
58
|
+
Values: tagValues
|
|
59
|
+
}]
|
|
60
|
+
}));
|
|
61
|
+
const missingSubnetValues = tagValues.filter((tagValue) => {
|
|
62
|
+
// collect subnets by name
|
|
63
|
+
const subnetsByName = subnets.filter((subnet) => {
|
|
64
|
+
return (0, utils_1.wildcardMatches)(tagValue, (0, utils_1.getValueFromTags)(subnet.Tags, tagKey));
|
|
80
65
|
});
|
|
81
|
-
|
|
82
|
-
throw new Error(`Subnets with vpc id '${vpcId}', tag key '${tagKey}' and tag values '${missingSubnetValues}' do not exist. ` +
|
|
83
|
-
"Please check the `tagKey` and `tagValues` are correct or remove it.");
|
|
84
|
-
}
|
|
85
|
-
return subnets.map((subnet) => subnet.SubnetId);
|
|
66
|
+
return subnetsByName.length === 0;
|
|
86
67
|
});
|
|
68
|
+
if (!subnets.length || missingSubnetValues.length) {
|
|
69
|
+
throw new Error(`Subnets with vpc id '${vpcId}', tag key '${tagKey}' and tag values '${missingSubnetValues}' do not exist. ` +
|
|
70
|
+
"Please check the `tagKey` and `tagValues` are correct or remove it.");
|
|
71
|
+
}
|
|
72
|
+
return subnets.map((subnet) => subnet.SubnetId);
|
|
87
73
|
}
|
|
88
74
|
/**
|
|
89
75
|
* Returns the promise that contains the security group IDs
|
|
@@ -93,54 +79,52 @@ class EC2Wrapper {
|
|
|
93
79
|
* @param {string[]} tagValues
|
|
94
80
|
* @returns {Promise.<string[]>}
|
|
95
81
|
*/
|
|
96
|
-
getSecurityGroupIds(vpcId, names, tagKey, tagValues) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return (0, utils_1.wildcardMatches)(groupName, securityGroup.GroupName);
|
|
119
|
-
});
|
|
120
|
-
return securityGroupsByName.length === 0;
|
|
82
|
+
async getSecurityGroupIds(vpcId, names, tagKey, tagValues) {
|
|
83
|
+
// init filter by vpc id
|
|
84
|
+
const input = { Filters: [{ Name: "vpc-id", Values: [vpcId] }] };
|
|
85
|
+
// update filters with names if specified
|
|
86
|
+
if (names) {
|
|
87
|
+
input.Filters.push({ Name: "group-name", Values: names });
|
|
88
|
+
}
|
|
89
|
+
// update filters with tag and values if specified
|
|
90
|
+
if (tagKey && tagValues) {
|
|
91
|
+
input.Filters.push({ Name: `tag:${tagKey}`, Values: tagValues });
|
|
92
|
+
}
|
|
93
|
+
const securityGroups = await (0, utils_1.getAWSPagedResults)(this.ec2, "SecurityGroups", "NextToken", "NextToken", new client_ec2_1.DescribeSecurityGroupsCommand(input));
|
|
94
|
+
if (securityGroups.length === 0) {
|
|
95
|
+
const namesErrorText = names ? `, names '${names}'` : "";
|
|
96
|
+
const tagErrorText = tagKey && tagValues ? `, tag key '${tagKey}' and tag values '${tagValues}'` : "";
|
|
97
|
+
throw new Error(`Security groups with vpc id '${vpcId}'${namesErrorText}${tagErrorText} do not exist`);
|
|
98
|
+
}
|
|
99
|
+
if (names) {
|
|
100
|
+
const missingGroupsNames = names.filter((groupName) => {
|
|
101
|
+
// collect security groups by name
|
|
102
|
+
const securityGroupsByName = securityGroups.filter((securityGroup) => {
|
|
103
|
+
return (0, utils_1.wildcardMatches)(groupName, securityGroup.GroupName);
|
|
121
104
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
105
|
+
return securityGroupsByName.length === 0;
|
|
106
|
+
});
|
|
107
|
+
if (missingGroupsNames.length) {
|
|
108
|
+
throw new Error(`Security groups do not exist for the names: ${missingGroupsNames}. ` +
|
|
109
|
+
"Please check the 'names' are correct or remove it.");
|
|
126
110
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return groupsByName.length === 0;
|
|
111
|
+
}
|
|
112
|
+
if (tagKey && tagValues) {
|
|
113
|
+
tagValues = tagValues || [];
|
|
114
|
+
const missingGroupsTagNames = tagValues.filter((tagValue) => {
|
|
115
|
+
// collect subnets by name
|
|
116
|
+
const groupsByName = securityGroups.filter((securityGroup) => {
|
|
117
|
+
const groupTagValue = (0, utils_1.getValueFromTags)(securityGroup.Tags, tagKey);
|
|
118
|
+
return groupTagValue === tagValue;
|
|
136
119
|
});
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
120
|
+
return groupsByName.length === 0;
|
|
121
|
+
});
|
|
122
|
+
if (missingGroupsTagNames.length) {
|
|
123
|
+
throw new Error(`Security groups do not exist for the tag '${tagKey}' and tag values: '${missingGroupsTagNames}'. ` +
|
|
124
|
+
"Please check the 'tagKey' and 'tagValues' are correct or remove it.");
|
|
141
125
|
}
|
|
142
|
-
|
|
143
|
-
|
|
126
|
+
}
|
|
127
|
+
return securityGroups.map((group) => group.GroupId);
|
|
144
128
|
}
|
|
145
129
|
}
|
|
146
130
|
exports.EC2Wrapper = EC2Wrapper;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -19,10 +10,12 @@ const validation_1 = require("../validation");
|
|
|
19
10
|
const logging_1 = __importDefault(require("../logging"));
|
|
20
11
|
const ts_md5_1 = require("ts-md5");
|
|
21
12
|
class LambdaFunction {
|
|
13
|
+
ec2Wrapper;
|
|
14
|
+
basicVPCDiscovery;
|
|
15
|
+
vpcIdsCache = {};
|
|
16
|
+
subnetsIdsCache = {};
|
|
17
|
+
SGIdsCache = {};
|
|
22
18
|
constructor(credentials, basicVPCDiscovery) {
|
|
23
|
-
this.vpcIdsCache = {};
|
|
24
|
-
this.subnetsIdsCache = {};
|
|
25
|
-
this.SGIdsCache = {};
|
|
26
19
|
this.ec2Wrapper = new ec2_wrapper_1.EC2Wrapper(credentials);
|
|
27
20
|
this.basicVPCDiscovery = basicVPCDiscovery;
|
|
28
21
|
}
|
|
@@ -30,105 +23,95 @@ class LambdaFunction {
|
|
|
30
23
|
* Validate and return VPC config for the given function
|
|
31
24
|
* @returns {Promise<VPC>}
|
|
32
25
|
*/
|
|
33
|
-
getFuncVPC(funcName, funcVPCDiscovery) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if ((0, utils_1.isObjectEmpty)(vpcDiscovery)) {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
// validate func vpcDiscovery config
|
|
47
|
-
try {
|
|
48
|
-
(0, validation_1.validateVPCDiscoveryConfig)(vpcDiscovery);
|
|
49
|
-
}
|
|
50
|
-
catch (e) {
|
|
51
|
-
throw new Error(`Function '${funcName}' is not configured correctly: ${e} VPC not configured. ` +
|
|
52
|
-
"Please see the README for the proper setup.");
|
|
53
|
-
}
|
|
54
|
-
try {
|
|
55
|
-
logging_1.default.logInfo(`Getting VPC config for the function: '${funcName}'\n`);
|
|
56
|
-
return yield this.getVpcConfig(vpcDiscovery);
|
|
57
|
-
}
|
|
58
|
-
catch (e) {
|
|
59
|
-
logging_1.default.logError(`Function '${funcName}' VPC not configured based on the error: ${e}`);
|
|
60
|
-
}
|
|
26
|
+
async getFuncVPC(funcName, funcVPCDiscovery) {
|
|
27
|
+
if (typeof funcVPCDiscovery === "boolean" && !funcVPCDiscovery) {
|
|
28
|
+
// skip vpc setup for `vpcDiscovery=false` option
|
|
29
|
+
logging_1.default.logInfo(`Skipping VPC config for the function '${funcName}'`);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
// inherit the `custom.vpcDiscovery`
|
|
33
|
+
const vpcDiscovery = Object.assign({}, this.basicVPCDiscovery, funcVPCDiscovery);
|
|
34
|
+
// return null in case vpcDiscovery not setup
|
|
35
|
+
if ((0, utils_1.isObjectEmpty)(vpcDiscovery)) {
|
|
61
36
|
return null;
|
|
62
|
-
}
|
|
37
|
+
}
|
|
38
|
+
// validate func vpcDiscovery config
|
|
39
|
+
try {
|
|
40
|
+
(0, validation_1.validateVPCDiscoveryConfig)(vpcDiscovery);
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
throw new Error(`Function '${funcName}' is not configured correctly: ${e} VPC not configured. ` +
|
|
44
|
+
"Please see the README for the proper setup.");
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
logging_1.default.logInfo(`Getting VPC config for the function: '${funcName}'\n`);
|
|
48
|
+
return await this.getVpcConfig(vpcDiscovery);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
logging_1.default.logError(`Function '${funcName}' VPC not configured based on the error: ${e}`);
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
63
54
|
}
|
|
64
55
|
/**
|
|
65
56
|
* Gets the desired vpc with the designated subnets and security groups
|
|
66
57
|
* that were set in serverless config file
|
|
67
58
|
* @returns {Promise<object>}
|
|
68
59
|
*/
|
|
69
|
-
getVpcConfig(vpcDiscovery) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
vpc.subnetIds = vpc.subnetIds.concat(subnetIds);
|
|
79
|
-
}
|
|
80
|
-
// remove duplicate elements from the array
|
|
81
|
-
vpc.subnetIds = [...new Set(vpc.subnetIds)];
|
|
60
|
+
async getVpcConfig(vpcDiscovery) {
|
|
61
|
+
const vpc = {};
|
|
62
|
+
const vpcId = await this.getVPCId(vpcDiscovery.vpcName);
|
|
63
|
+
logging_1.default.logInfo(`Found VPC with id '${vpcId}'`);
|
|
64
|
+
if (vpcDiscovery.subnets) {
|
|
65
|
+
vpc.subnetIds = [];
|
|
66
|
+
for (const subnet of vpcDiscovery.subnets) {
|
|
67
|
+
const subnetIds = await this.getVPCSubnets(vpcId, subnet.tagKey, subnet.tagValues);
|
|
68
|
+
vpc.subnetIds = vpc.subnetIds.concat(subnetIds);
|
|
82
69
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
vpc.securityGroupIds =
|
|
70
|
+
// remove duplicate elements from the array
|
|
71
|
+
vpc.subnetIds = [...new Set(vpc.subnetIds)];
|
|
72
|
+
}
|
|
73
|
+
if (vpcDiscovery.securityGroups) {
|
|
74
|
+
vpc.securityGroupIds = [];
|
|
75
|
+
for (const group of vpcDiscovery.securityGroups) {
|
|
76
|
+
const groupIds = await this.getVPCSecurityGroups(vpcId, group.names, group.tagKey, group.tagValues);
|
|
77
|
+
vpc.securityGroupIds = vpc.securityGroupIds.concat(groupIds);
|
|
91
78
|
}
|
|
92
|
-
|
|
93
|
-
|
|
79
|
+
// remove duplicate elements from the array
|
|
80
|
+
vpc.securityGroupIds = [...new Set(vpc.securityGroupIds)];
|
|
81
|
+
}
|
|
82
|
+
return vpc;
|
|
94
83
|
}
|
|
95
84
|
/**
|
|
96
85
|
* Get the VPC id from cache or read from AWS
|
|
97
86
|
* @returns {Promise<object>}
|
|
98
87
|
*/
|
|
99
|
-
getVPCId(vpcName) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return this.vpcIdsCache[vpcName];
|
|
105
|
-
});
|
|
88
|
+
async getVPCId(vpcName) {
|
|
89
|
+
if (this.vpcIdsCache[vpcName] === undefined) {
|
|
90
|
+
this.vpcIdsCache[vpcName] = await this.ec2Wrapper.getVpcId(vpcName);
|
|
91
|
+
}
|
|
92
|
+
return this.vpcIdsCache[vpcName];
|
|
106
93
|
}
|
|
107
94
|
/**
|
|
108
95
|
* Get the subnet ids from cache or read from AWS
|
|
109
96
|
* @returns {Promise<object>}
|
|
110
97
|
*/
|
|
111
|
-
getVPCSubnets(vpcId, tagKey, tagValues) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return this.subnetsIdsCache[hash];
|
|
118
|
-
});
|
|
98
|
+
async getVPCSubnets(vpcId, tagKey, tagValues) {
|
|
99
|
+
const hash = ts_md5_1.Md5.hashStr(vpcId + tagKey + tagValues.join());
|
|
100
|
+
if (!this.subnetsIdsCache[hash]) {
|
|
101
|
+
this.subnetsIdsCache[hash] = await this.ec2Wrapper.getSubnetIds(vpcId, tagKey, tagValues);
|
|
102
|
+
}
|
|
103
|
+
return this.subnetsIdsCache[hash];
|
|
119
104
|
}
|
|
120
105
|
/**
|
|
121
106
|
* Get the security group ids from cache or read from AWS
|
|
122
107
|
* @returns {Promise<object>}
|
|
123
108
|
*/
|
|
124
|
-
getVPCSecurityGroups(vpcId, names, tagKey, tagValues) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return this.SGIdsCache[hash];
|
|
131
|
-
});
|
|
109
|
+
async getVPCSecurityGroups(vpcId, names, tagKey, tagValues) {
|
|
110
|
+
const hash = ts_md5_1.Md5.hashStr(vpcId + (names || []).join() + tagKey + (tagValues || []).join());
|
|
111
|
+
if (!this.SGIdsCache[hash]) {
|
|
112
|
+
this.SGIdsCache[hash] = await this.ec2Wrapper.getSecurityGroupIds(vpcId, names, tagKey, tagValues);
|
|
113
|
+
}
|
|
114
|
+
return this.SGIdsCache[hash];
|
|
132
115
|
}
|
|
133
116
|
}
|
|
134
117
|
exports.LambdaFunction = LambdaFunction;
|
package/dist/src/globals.js
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
const util_retry_1 = require("@smithy/util-retry");
|
|
13
4
|
const credential_providers_1 = require("@aws-sdk/credential-providers");
|
|
14
5
|
class Globals {
|
|
6
|
+
static pluginName = "Serverless VPC Discovery";
|
|
7
|
+
static serverless;
|
|
8
|
+
static options;
|
|
9
|
+
static v3Utils;
|
|
10
|
+
static currentRegion;
|
|
11
|
+
static credentials;
|
|
12
|
+
static defaultRegion = "us-east-1";
|
|
15
13
|
static getRegion() {
|
|
16
14
|
const slsRegion = Globals.options.region || Globals.serverless.service.provider.region;
|
|
17
15
|
return slsRegion || Globals.currentRegion || Globals.defaultRegion;
|
|
18
16
|
}
|
|
19
|
-
static getProfileCreds(profile) {
|
|
20
|
-
return
|
|
21
|
-
return yield (0, credential_providers_1.fromIni)({ profile })();
|
|
22
|
-
});
|
|
17
|
+
static async getProfileCreds(profile) {
|
|
18
|
+
return await (0, credential_providers_1.fromIni)({ profile })();
|
|
23
19
|
}
|
|
24
20
|
static getRetryStrategy(attempts = 3, delay = 3000, backoff = 500) {
|
|
25
21
|
return new util_retry_1.ConfiguredRetryStrategy(attempts, // max attempts.
|
|
@@ -29,6 +25,4 @@ class Globals {
|
|
|
29
25
|
);
|
|
30
26
|
}
|
|
31
27
|
}
|
|
32
|
-
Globals.pluginName = "Serverless VPC Discovery";
|
|
33
|
-
Globals.defaultRegion = "us-east-1";
|
|
34
28
|
exports.default = Globals;
|
package/dist/src/index.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -19,11 +10,14 @@ const logging_1 = __importDefault(require("./logging"));
|
|
|
19
10
|
const node_config_provider_1 = require("@smithy/node-config-provider");
|
|
20
11
|
const config_resolver_1 = require("@smithy/config-resolver");
|
|
21
12
|
class VPCPlugin {
|
|
13
|
+
serverless;
|
|
14
|
+
hooks;
|
|
15
|
+
lambdaFunction;
|
|
22
16
|
constructor(serverless, options, v3Utils) {
|
|
23
17
|
this.serverless = serverless;
|
|
24
18
|
globals_1.default.serverless = serverless;
|
|
25
19
|
globals_1.default.options = options;
|
|
26
|
-
if (v3Utils
|
|
20
|
+
if (v3Utils?.log) {
|
|
27
21
|
globals_1.default.v3Utils = v3Utils;
|
|
28
22
|
}
|
|
29
23
|
/* hooks are the actual code that will run when called */
|
|
@@ -37,12 +31,10 @@ class VPCPlugin {
|
|
|
37
31
|
* Wrapper for lifecycle function, initializes variables and checks if enabled.
|
|
38
32
|
* @param lifecycleFunc lifecycle function that actually does desired action
|
|
39
33
|
*/
|
|
40
|
-
hookWrapper(lifecycleFunc) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return yield lifecycleFunc.call(this);
|
|
45
|
-
});
|
|
34
|
+
async hookWrapper(lifecycleFunc) {
|
|
35
|
+
this.validateCustomVPCDiscoveryConfig();
|
|
36
|
+
await this.initResources();
|
|
37
|
+
return await lifecycleFunc.call(this);
|
|
46
38
|
}
|
|
47
39
|
/**
|
|
48
40
|
* Validate if the plugin config exists
|
|
@@ -86,89 +78,81 @@ class VPCPlugin {
|
|
|
86
78
|
/**
|
|
87
79
|
* Setup AWS resources
|
|
88
80
|
*/
|
|
89
|
-
initResources() {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
this.lambdaFunction = new lambda_function_1.LambdaFunction(globals_1.default.credentials, baseVPCDiscovery);
|
|
105
|
-
}
|
|
81
|
+
async initResources() {
|
|
82
|
+
// setup AWS resources
|
|
83
|
+
await this.initSLSCredentials();
|
|
84
|
+
await this.initAWSRegion();
|
|
85
|
+
const baseVPCDiscovery = this.serverless.service.custom ? this.serverless.service.custom.vpcDiscovery : null;
|
|
86
|
+
this.lambdaFunction = new lambda_function_1.LambdaFunction(globals_1.default.credentials, baseVPCDiscovery);
|
|
87
|
+
// start of the legacy AWS SDK V2 creds support
|
|
88
|
+
// TODO: remove it in case serverless will add V3 support
|
|
89
|
+
try {
|
|
90
|
+
await this.lambdaFunction.ec2Wrapper.getVpcs();
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (error.message.includes("Could not load credentials from any providers")) {
|
|
94
|
+
globals_1.default.credentials = this.serverless.providers.aws.getCredentials();
|
|
95
|
+
this.lambdaFunction = new lambda_function_1.LambdaFunction(globals_1.default.credentials, baseVPCDiscovery);
|
|
106
96
|
}
|
|
107
|
-
}
|
|
97
|
+
}
|
|
108
98
|
}
|
|
109
99
|
/**
|
|
110
100
|
* Init AWS credentials based on sls `provider.profile`
|
|
111
101
|
*/
|
|
112
|
-
initSLSCredentials() {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
globals_1.default.credentials = slsProfile ? yield globals_1.default.getProfileCreds(slsProfile) : null;
|
|
116
|
-
});
|
|
102
|
+
async initSLSCredentials() {
|
|
103
|
+
const slsProfile = globals_1.default.options["aws-profile"] || globals_1.default.serverless.service.provider.profile;
|
|
104
|
+
globals_1.default.credentials = slsProfile ? await globals_1.default.getProfileCreds(slsProfile) : null;
|
|
117
105
|
}
|
|
118
106
|
/**
|
|
119
107
|
* Init AWS current region based on Node options
|
|
120
108
|
*/
|
|
121
|
-
initAWSRegion() {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
});
|
|
109
|
+
async initAWSRegion() {
|
|
110
|
+
try {
|
|
111
|
+
globals_1.default.currentRegion = await (0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_REGION_CONFIG_OPTIONS, config_resolver_1.NODE_REGION_CONFIG_FILE_OPTIONS)();
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
logging_1.default.logInfo("Node region was not found.");
|
|
115
|
+
}
|
|
130
116
|
}
|
|
131
117
|
/**
|
|
132
118
|
* Updates functions vpc config
|
|
133
119
|
* @returns {Promise<object>}
|
|
134
120
|
*/
|
|
135
|
-
updateFunctionsVpcConfig() {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
// init vpc empty config in case not exists
|
|
150
|
-
func.vpc = func.vpc || {};
|
|
151
|
-
// log warning in case vpc.subnetIds and vpcDiscovery.subnetNames are specified.
|
|
152
|
-
if (func.vpc.subnetIds && func.vpcDiscovery && func.vpcDiscovery.subnets) {
|
|
153
|
-
logging_1.default.logWarning(`vpc.subnetIds' are specified for the function '${funcName}' ` +
|
|
154
|
-
"and overrides 'vpcDiscovery.subnets' discovery config.");
|
|
155
|
-
}
|
|
156
|
-
// log warning in case vpc.securityGroupIds and vpcDiscovery.securityGroupNames are specified.
|
|
157
|
-
if (func.vpc.securityGroupIds && func.vpcDiscovery && func.vpcDiscovery.securityGroups) {
|
|
158
|
-
logging_1.default.logWarning(`vpc.securityGroupIds' are specified for the function '${funcName}' ` +
|
|
159
|
-
"and overrides 'vpcDiscovery.securityGroups' discovery config.");
|
|
160
|
-
}
|
|
161
|
-
// set vpc.subnetIds if it does not exists
|
|
162
|
-
if (!func.vpc.subnetIds && funcVPC.subnetIds) {
|
|
163
|
-
func.vpc.subnetIds = funcVPC.subnetIds;
|
|
164
|
-
}
|
|
165
|
-
// set vpc.securityGroupIds if it does not exists
|
|
166
|
-
if (!func.vpc.securityGroupIds && funcVPC.securityGroupIds) {
|
|
167
|
-
func.vpc.securityGroupIds = funcVPC.securityGroupIds;
|
|
168
|
-
}
|
|
121
|
+
async updateFunctionsVpcConfig() {
|
|
122
|
+
logging_1.default.logInfo("Updating VPC config...");
|
|
123
|
+
const service = this.serverless.service;
|
|
124
|
+
const functions = service.functions || {};
|
|
125
|
+
// Sets the serverless's vpc config
|
|
126
|
+
// loop through the functions and update VPC config
|
|
127
|
+
for (const funcName of Object.keys(functions)) {
|
|
128
|
+
const func = service.functions[funcName];
|
|
129
|
+
this.updateVPCDiscoveryConfigCompatibility(func.vpcDiscovery);
|
|
130
|
+
const funcVPC = await this.lambdaFunction.getFuncVPC(funcName, func.vpcDiscovery);
|
|
131
|
+
if (!funcVPC) {
|
|
132
|
+
continue;
|
|
169
133
|
}
|
|
170
|
-
|
|
171
|
-
|
|
134
|
+
// init vpc empty config in case not exists
|
|
135
|
+
func.vpc = func.vpc || {};
|
|
136
|
+
// log warning in case vpc.subnetIds and vpcDiscovery.subnetNames are specified.
|
|
137
|
+
if (func.vpc.subnetIds && func.vpcDiscovery && func.vpcDiscovery.subnets) {
|
|
138
|
+
logging_1.default.logWarning(`vpc.subnetIds' are specified for the function '${funcName}' ` +
|
|
139
|
+
"and overrides 'vpcDiscovery.subnets' discovery config.");
|
|
140
|
+
}
|
|
141
|
+
// log warning in case vpc.securityGroupIds and vpcDiscovery.securityGroupNames are specified.
|
|
142
|
+
if (func.vpc.securityGroupIds && func.vpcDiscovery && func.vpcDiscovery.securityGroups) {
|
|
143
|
+
logging_1.default.logWarning(`vpc.securityGroupIds' are specified for the function '${funcName}' ` +
|
|
144
|
+
"and overrides 'vpcDiscovery.securityGroups' discovery config.");
|
|
145
|
+
}
|
|
146
|
+
// set vpc.subnetIds if it does not exists
|
|
147
|
+
if (!func.vpc.subnetIds && funcVPC.subnetIds) {
|
|
148
|
+
func.vpc.subnetIds = funcVPC.subnetIds;
|
|
149
|
+
}
|
|
150
|
+
// set vpc.securityGroupIds if it does not exists
|
|
151
|
+
if (!func.vpc.securityGroupIds && funcVPC.securityGroupIds) {
|
|
152
|
+
func.vpc.securityGroupIds = funcVPC.securityGroupIds;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return service.functions;
|
|
172
156
|
}
|
|
173
157
|
}
|
|
174
158
|
module.exports = VPCPlugin;
|
package/dist/src/utils.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
3
|
+
exports.sleep = sleep;
|
|
4
|
+
exports.getAWSPagedResults = getAWSPagedResults;
|
|
5
|
+
exports.isObjectEmpty = isObjectEmpty;
|
|
6
|
+
exports.wildcardMatches = wildcardMatches;
|
|
7
|
+
exports.getValueFromTags = getValueFromTags;
|
|
13
8
|
/**
|
|
14
9
|
* Iterate through the pages of a AWS SDK response and collect them into a single array
|
|
15
10
|
*
|
|
@@ -19,35 +14,28 @@ exports.getValueFromTags = exports.wildcardMatches = exports.isObjectEmpty = exp
|
|
|
19
14
|
* @param nextRequestTokenKey - The response key name that has the next paging token value
|
|
20
15
|
* @param params - Parameters to send in the request
|
|
21
16
|
*/
|
|
22
|
-
function getAWSPagedResults(client, resultsKey, nextTokenKey, nextRequestTokenKey, params) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return results;
|
|
33
|
-
});
|
|
17
|
+
async function getAWSPagedResults(client, resultsKey, nextTokenKey, nextRequestTokenKey, params) {
|
|
18
|
+
let results = [];
|
|
19
|
+
let response = await client.send(params);
|
|
20
|
+
results = results.concat(response[resultsKey] || results);
|
|
21
|
+
while (nextRequestTokenKey in response && response[nextRequestTokenKey]) {
|
|
22
|
+
params.input[nextTokenKey] = response[nextRequestTokenKey];
|
|
23
|
+
response = await client.send(params);
|
|
24
|
+
results = results.concat(response[resultsKey]);
|
|
25
|
+
}
|
|
26
|
+
return results;
|
|
34
27
|
}
|
|
35
|
-
exports.getAWSPagedResults = getAWSPagedResults;
|
|
36
28
|
/**
|
|
37
29
|
* Stops event thread execution for given number of seconds.
|
|
38
30
|
* @param seconds
|
|
39
31
|
* @returns {Promise<void>} Resolves after given number of seconds.
|
|
40
32
|
*/
|
|
41
|
-
function sleep(seconds) {
|
|
42
|
-
return
|
|
43
|
-
return new Promise((resolve) => setTimeout(resolve, 1000 * seconds));
|
|
44
|
-
});
|
|
33
|
+
async function sleep(seconds) {
|
|
34
|
+
return new Promise((resolve) => setTimeout(resolve, 1000 * seconds));
|
|
45
35
|
}
|
|
46
|
-
exports.sleep = sleep;
|
|
47
36
|
function isObjectEmpty(value) {
|
|
48
37
|
return Object.keys(value).length === 0;
|
|
49
38
|
}
|
|
50
|
-
exports.isObjectEmpty = isObjectEmpty;
|
|
51
39
|
function replaceAll(input, search, replace) {
|
|
52
40
|
return input.split(search).join(replace);
|
|
53
41
|
}
|
|
@@ -57,7 +45,6 @@ function wildcardMatches(inputArn, actualArn) {
|
|
|
57
45
|
const inputArnRegex = new RegExp(`^${inputArnRegexStr}$`);
|
|
58
46
|
return inputArnRegex.test(actualArn);
|
|
59
47
|
}
|
|
60
|
-
exports.wildcardMatches = wildcardMatches;
|
|
61
48
|
function getValueFromTags(tags, tagKey) {
|
|
62
49
|
const tagItem = tags.find((tag) => tag.Key === tagKey);
|
|
63
50
|
if (tagItem) {
|
|
@@ -65,4 +52,3 @@ function getValueFromTags(tags, tagKey) {
|
|
|
65
52
|
}
|
|
66
53
|
return null;
|
|
67
54
|
}
|
|
68
|
-
exports.getValueFromTags = getValueFromTags;
|
package/dist/src/validation.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateVPCDiscoveryConfig =
|
|
3
|
+
exports.validateVPCDiscoveryConfig = validateVPCDiscoveryConfig;
|
|
4
4
|
/**
|
|
5
5
|
* Validate vpc discovery subnets config
|
|
6
6
|
* @param subnets - the `SubnetItem` options
|
|
@@ -61,4 +61,3 @@ function validateVPCDiscoveryConfig(vpcDiscovery) {
|
|
|
61
61
|
validateVPCSecurityGroups(vpcDiscovery.securityGroups);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
exports.validateVPCDiscoveryConfig = validateVPCDiscoveryConfig;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "serverless-vpc-discovery",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"engines": {
|
|
5
|
-
"node": ">=
|
|
5
|
+
"node": ">=18"
|
|
6
6
|
},
|
|
7
7
|
"description": "Serverless Plugin to modify VPC values",
|
|
8
8
|
"author": "Amplify Education Inc",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"main": "dist/src/index.js",
|
|
31
31
|
"bin": {},
|
|
32
32
|
"scripts": {
|
|
33
|
-
"test": "
|
|
34
|
-
"integration-test": "
|
|
35
|
-
"lint": "eslint src
|
|
33
|
+
"test": "c8 mocha -r tsx test/unit-tests/index.test.ts",
|
|
34
|
+
"integration-test": "mocha -r tsx test/integration-tests/*.test.ts",
|
|
35
|
+
"lint": "eslint src",
|
|
36
36
|
"lint:fix": "npm run lint -- --fix",
|
|
37
37
|
"build": "tsc --project .",
|
|
38
38
|
"prepare": "npm run build"
|
|
@@ -43,45 +43,41 @@
|
|
|
43
43
|
"*.json",
|
|
44
44
|
"dist/**/*.js"
|
|
45
45
|
],
|
|
46
|
-
"nyc": {
|
|
47
|
-
"extension": [
|
|
48
|
-
".ts"
|
|
49
|
-
]
|
|
50
|
-
},
|
|
51
46
|
"devDependencies": {
|
|
52
|
-
"@aws-sdk/client-lambda": "
|
|
47
|
+
"@aws-sdk/client-lambda": "~3.967.0",
|
|
48
|
+
"@types/chai": "^5.0.1",
|
|
49
|
+
"@types/chai-spies": "^1.0.6",
|
|
53
50
|
"@types/js-yaml": "^4.0.9",
|
|
54
|
-
"@types/mocha": "^10.0.
|
|
55
|
-
"@types/node": "^
|
|
56
|
-
"@types/randomstring": "^1.
|
|
51
|
+
"@types/mocha": "^10.0.10",
|
|
52
|
+
"@types/node": "^18.0.0",
|
|
53
|
+
"@types/randomstring": "^1.3.0",
|
|
57
54
|
"@types/shelljs": "^0.8.15",
|
|
58
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"chai": "^4.3.10",
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
56
|
+
"aws-sdk-client-mock": "^4.1.0",
|
|
57
|
+
"chai": "^6.2.2",
|
|
62
58
|
"chai-spies": "^1.1.0",
|
|
63
|
-
"eslint": "^
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"eslint-plugin-promise": "^5.2.0",
|
|
68
|
-
"js-yaml": "^4.1.0",
|
|
69
|
-
"mocha": "^10.2.0",
|
|
59
|
+
"eslint": "^9.0.0",
|
|
60
|
+
"neostandard": "^0.12.0",
|
|
61
|
+
"js-yaml": "^4.1.1",
|
|
62
|
+
"mocha": "^11.0.0",
|
|
70
63
|
"mocha-param": "^2.0.1",
|
|
71
|
-
"
|
|
72
|
-
"randomstring": "^1.3.
|
|
73
|
-
"serverless": "^
|
|
64
|
+
"c8": "^10.0.0",
|
|
65
|
+
"randomstring": "^1.3.1",
|
|
66
|
+
"serverless": "^4.32.0",
|
|
74
67
|
"shelljs": "^0.8.5",
|
|
75
|
-
"
|
|
76
|
-
"typescript": "5.
|
|
68
|
+
"tsx": "^4.21.0",
|
|
69
|
+
"typescript": "^5.9.3"
|
|
77
70
|
},
|
|
78
71
|
"dependencies": {
|
|
79
|
-
"@aws-sdk/client-ec2": "
|
|
80
|
-
"@aws-sdk/credential-providers": "
|
|
81
|
-
"@smithy/config-resolver": "
|
|
82
|
-
"@smithy/node-config-provider": "
|
|
83
|
-
"@smithy/smithy-client": "
|
|
84
|
-
"@smithy/util-retry": "
|
|
72
|
+
"@aws-sdk/client-ec2": "~3.967.0",
|
|
73
|
+
"@aws-sdk/credential-providers": "~3.967.0",
|
|
74
|
+
"@smithy/config-resolver": "~4.4.5",
|
|
75
|
+
"@smithy/node-config-provider": "~4.3.7",
|
|
76
|
+
"@smithy/smithy-client": "~4.10.4",
|
|
77
|
+
"@smithy/util-retry": "~4.2.7",
|
|
85
78
|
"ts-md5": "^1.3.1"
|
|
79
|
+
},
|
|
80
|
+
"overrides": {
|
|
81
|
+
"fast-xml-parser": "^5.3.6"
|
|
86
82
|
}
|
|
87
83
|
}
|
package/tsconfig.json
CHANGED
package/.eslintrc.json
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"browser": true,
|
|
4
|
-
"es2021": true,
|
|
5
|
-
"commonjs": true,
|
|
6
|
-
"node": true,
|
|
7
|
-
"mocha": true
|
|
8
|
-
},
|
|
9
|
-
"extends": [
|
|
10
|
-
"standard",
|
|
11
|
-
"eslint:recommended",
|
|
12
|
-
"plugin:@typescript-eslint/eslint-recommended"
|
|
13
|
-
],
|
|
14
|
-
"parser": "@typescript-eslint/parser",
|
|
15
|
-
"parserOptions": {
|
|
16
|
-
"ecmaVersion": 2020,
|
|
17
|
-
"sourceType": "module"
|
|
18
|
-
},
|
|
19
|
-
"plugins": [
|
|
20
|
-
"@typescript-eslint"
|
|
21
|
-
],
|
|
22
|
-
"rules": {
|
|
23
|
-
"quotes": [
|
|
24
|
-
"error",
|
|
25
|
-
"double"
|
|
26
|
-
],
|
|
27
|
-
"semi": [
|
|
28
|
-
"error",
|
|
29
|
-
"always"
|
|
30
|
-
],
|
|
31
|
-
"arrow-parens": [
|
|
32
|
-
"error",
|
|
33
|
-
"always"
|
|
34
|
-
],
|
|
35
|
-
"complexity": [
|
|
36
|
-
"error",
|
|
37
|
-
15
|
|
38
|
-
],
|
|
39
|
-
"guard-for-in": "error"
|
|
40
|
-
}
|
|
41
|
-
}
|