presidium 0.15.36 → 0.16.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/AutoScaling.js +117 -0
- package/AutoScaling.test.js +57 -0
- package/EC2.js +181 -0
- package/EC2.test.js +48 -0
- package/internal/AWSAutoScalingDescribeAutoScalingGroupsFilters.js +46 -0
- package/internal/AWSEC2DescribeInstancesFilters.js +151 -0
- package/internal/AutoScalingListGroupsDescribeFilterOptions.ss +7 -0
- package/internal/EC2ListInstancesDescribeFilterOptions.ss +91 -0
- package/internal/filterExists.js +7 -0
- package/internal/filterExistsAndNotEmpty.js +12 -0
- package/internal/objectFilterKeys.js +21 -0
- package/internal/toArray.js +13 -0
- package/package.json +2 -2
package/AutoScaling.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
const rubico = require('rubico')
|
|
2
|
+
const AWSAutoscaling = require('aws-sdk/clients/autoscaling')
|
|
3
|
+
const AWSAutoScalingDescribeAutoScalingGroupsFilters =
|
|
4
|
+
require('./internal/AWSAutoScalingDescribeAutoScalingGroupsFilters')
|
|
5
|
+
const filterExistsAndNotEmpty = require('./internal/filterExistsAndNotEmpty')
|
|
6
|
+
const filterExists = require('./internal/filterExists')
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
pipe, tap,
|
|
10
|
+
switchCase, tryCatch,
|
|
11
|
+
fork, assign, get, set, pick, omit,
|
|
12
|
+
map, filter, reduce, transform, flatMap,
|
|
13
|
+
and, or, not, any, all,
|
|
14
|
+
eq, gt, lt, gte, lte,
|
|
15
|
+
thunkify, always,
|
|
16
|
+
curry, __,
|
|
17
|
+
} = rubico
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @name AutoScaling
|
|
21
|
+
*
|
|
22
|
+
* @synopsis
|
|
23
|
+
* ```coffeescript [specscript]
|
|
24
|
+
* new AutoScaling(options {
|
|
25
|
+
* ...({
|
|
26
|
+
* accessKeyId: string,
|
|
27
|
+
* secretAccessKey: string,
|
|
28
|
+
* region: string,
|
|
29
|
+
* })|({
|
|
30
|
+
* endpoint: string,
|
|
31
|
+
* region: string,
|
|
32
|
+
* })
|
|
33
|
+
* }) -> AutoScaling object
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
const AutoScaling = function (options) {
|
|
37
|
+
this.awsAutoScaling = new AWSAutoscaling({
|
|
38
|
+
apiVersion: '2011-01-01',
|
|
39
|
+
...pick([
|
|
40
|
+
'accessKeyId',
|
|
41
|
+
'secretAccessKey',
|
|
42
|
+
'region',
|
|
43
|
+
'endpoint',
|
|
44
|
+
])(options),
|
|
45
|
+
})
|
|
46
|
+
return this
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @name AutoScaling.prototype.listAutoScalingGroups
|
|
51
|
+
*
|
|
52
|
+
* @synopsis
|
|
53
|
+
* ```coffeescript [specscript]
|
|
54
|
+
* import AutoScalingListGroupsDescribeFilterOptions
|
|
55
|
+
* from './internal/AutoScalingListGroupsDescribeFilterOptions.ss'
|
|
56
|
+
*
|
|
57
|
+
* new AutoScaling(...).listAutoScalingGroups(options? {
|
|
58
|
+
* ...AutoScalingListGroupsDescribeFilterOptions.map(value => value|Array<value>),
|
|
59
|
+
* limit?: 5-100, // default 100
|
|
60
|
+
* nextToken?: string, // last result's NextToken
|
|
61
|
+
* }) -> Promise<{
|
|
62
|
+
* AutoScalingGroups: Array<{
|
|
63
|
+
* AutoScalingGroupName: string, // 'presidium-test'
|
|
64
|
+
* AutoScalingGroupARN: string, // 'arn:aws:autoscaling:us-west-1:095798571722:autoScalingGroup:934690c8-d95d-46be-ac49-54950de41ef5:autoScalingGroupName/presidium-test'
|
|
65
|
+
* LaunchTemplate: Object,
|
|
66
|
+
* MinSize: number, // 1
|
|
67
|
+
* MaxSize: number, // 1
|
|
68
|
+
* DesiredCapacity: number, // 1
|
|
69
|
+
* DefaultCooldown: number, // 300
|
|
70
|
+
* AvailabilityZones: Array,
|
|
71
|
+
* LoadBalancerNames: Array,
|
|
72
|
+
* TargetGroupARNs: Array,
|
|
73
|
+
* HealthCheckType: string, // 'EC2'
|
|
74
|
+
* HealthCheckGracePeriod: number, // 300
|
|
75
|
+
* Instances: Array,
|
|
76
|
+
* CreatedTime: Date, // 2022-04-28T20:26:13.289Z
|
|
77
|
+
* SuspendedProcesses: Array,
|
|
78
|
+
* VPCZoneIdentifier: string, // 'subnet-916bb8f7,subnet-677c933d'
|
|
79
|
+
* EnabledMetrics: Array,
|
|
80
|
+
* Tags: Array,
|
|
81
|
+
* TerminationPolicies: Array,
|
|
82
|
+
* NewInstancesProtectedFromScaleIn: boolean,
|
|
83
|
+
* ServiceLinkedRoleARN: string, // 'arn:aws:iam::095798571722:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling'
|
|
84
|
+
* }>,
|
|
85
|
+
* NextToken: string|null,
|
|
86
|
+
* }>
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
AutoScaling.prototype.listAutoScalingGroups = function (options = {}) {
|
|
90
|
+
return this.awsAutoScaling.describeAutoScalingGroups(filterExistsAndNotEmpty({
|
|
91
|
+
Filters: AWSAutoScalingDescribeAutoScalingGroupsFilters(options),
|
|
92
|
+
MaxRecords: options.limit ?? 100,
|
|
93
|
+
NextToken: options.nextToken,
|
|
94
|
+
})).promise()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @name AutoScaling.prototype.setDesiredCapacity
|
|
99
|
+
*
|
|
100
|
+
* @synopsis
|
|
101
|
+
* ```coffeescript [specscript]
|
|
102
|
+
* new AutoScaling(...).setDesiredCapacity(options {
|
|
103
|
+
* autoScalingGroupName: string,
|
|
104
|
+
* desiredCapacity: number,
|
|
105
|
+
* honorCooldown?: boolean, // whether Amazon EC2 Auto Scaling waits for the cooldown period to complete before initializing a scaling activity to set your Auto Scaling group to its new capacity, default false
|
|
106
|
+
* }) -> Promise<{}>
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
AutoScaling.prototype.setDesiredCapacity = function (options) {
|
|
110
|
+
return this.awsAutoScaling.setDesiredCapacity(filterExists({
|
|
111
|
+
AutoScalingGroupName: options.autoScalingGroupName,
|
|
112
|
+
DesiredCapacity: options.desiredCapacity,
|
|
113
|
+
HonorCooldown: options.honorCooldown,
|
|
114
|
+
})).promise()
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = AutoScaling
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const Test = require('thunk-test')
|
|
2
|
+
const assert = require('assert')
|
|
3
|
+
const AwsCredentials = require('./internal/AwsCredentials')
|
|
4
|
+
const AutoScaling = require('./AutoScaling')
|
|
5
|
+
|
|
6
|
+
const test = new Test('AutoScaling', async function () {
|
|
7
|
+
const awsCreds = await AwsCredentials('default').catch(error => {
|
|
8
|
+
if (error.code == 'ENOENT') {
|
|
9
|
+
const accessKeyId = process.env.AWS_ACCESS_KEY_ID
|
|
10
|
+
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY
|
|
11
|
+
if (accessKeyId == null || secretAccessKey == null) {
|
|
12
|
+
throw new Error('No AWS credential file or environment variables')
|
|
13
|
+
}
|
|
14
|
+
return { accessKeyId, secretAccessKey }
|
|
15
|
+
}
|
|
16
|
+
throw error
|
|
17
|
+
})
|
|
18
|
+
awsCreds.region = 'us-west-1'
|
|
19
|
+
|
|
20
|
+
const autoScaling = new AutoScaling({
|
|
21
|
+
...awsCreds,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// there is one auto scaling group named presidium-test with one ec2 instance in this region
|
|
25
|
+
|
|
26
|
+
{ // listInstances all instances
|
|
27
|
+
const response = await autoScaling.listAutoScalingGroups()
|
|
28
|
+
assert(
|
|
29
|
+
response.AutoScalingGroups.map(group => group.AutoScalingGroupName).includes('presidium-test'),
|
|
30
|
+
'There is no presidium-test autoscaling group, check the aws account'
|
|
31
|
+
)
|
|
32
|
+
assert.equal(response.NextToken, null)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
{ // listAutoScalingGroups with tag
|
|
36
|
+
const response = await autoScaling.listAutoScalingGroups({
|
|
37
|
+
'tag:Env': 'test',
|
|
38
|
+
})
|
|
39
|
+
assert(
|
|
40
|
+
response.AutoScalingGroups.map(group => group.AutoScalingGroupName).includes('presidium-test'),
|
|
41
|
+
'There is no presidium-test autoscaling group, check the aws account'
|
|
42
|
+
)
|
|
43
|
+
assert.equal(response.NextToken, null)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// setDesiredCapacity (errors if not auto scaling group not found)
|
|
47
|
+
await autoScaling.setDesiredCapacity({
|
|
48
|
+
autoScalingGroupName: 'presidium-test',
|
|
49
|
+
desiredCapacity: 1,
|
|
50
|
+
})
|
|
51
|
+
}).case()
|
|
52
|
+
|
|
53
|
+
if (process.argv[1] == __filename) {
|
|
54
|
+
test()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = test
|
package/EC2.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
const rubico = require('rubico')
|
|
2
|
+
const AWSEC2 = require('aws-sdk/clients/ec2')
|
|
3
|
+
const AWSEC2DescribeInstancesFilters = require('./internal/AWSEC2DescribeInstancesFilters.js')
|
|
4
|
+
const filterExistsAndNotEmpty = require('./internal/filterExistsAndNotEmpty')
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
pipe, tap,
|
|
8
|
+
switchCase, tryCatch,
|
|
9
|
+
fork, assign, get, set, pick, omit,
|
|
10
|
+
map, filter, reduce, transform, flatMap,
|
|
11
|
+
and, or, not, any, all,
|
|
12
|
+
eq, gt, lt, gte, lte,
|
|
13
|
+
thunkify, always,
|
|
14
|
+
curry, __,
|
|
15
|
+
} = rubico
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @name EC2
|
|
19
|
+
*
|
|
20
|
+
* @synopsis
|
|
21
|
+
* ```coffeescript [specscript]
|
|
22
|
+
* new EC2(options {
|
|
23
|
+
* ...({
|
|
24
|
+
* accessKeyId: string,
|
|
25
|
+
* secretAccessKey: string,
|
|
26
|
+
* region: string,
|
|
27
|
+
* })|({
|
|
28
|
+
* endpoint: string,
|
|
29
|
+
* region: string,
|
|
30
|
+
* })
|
|
31
|
+
* }) -> EC2
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @description
|
|
35
|
+
* https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/EC2.html
|
|
36
|
+
*/
|
|
37
|
+
const EC2 = function (options) {
|
|
38
|
+
this.awsEc2 = new AWSEC2({
|
|
39
|
+
apiVersion: '2016-11-15',
|
|
40
|
+
...pick([
|
|
41
|
+
'accessKeyId',
|
|
42
|
+
'secretAccessKey',
|
|
43
|
+
'region',
|
|
44
|
+
'endpoint',
|
|
45
|
+
])(options),
|
|
46
|
+
})
|
|
47
|
+
return this
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @name EC2.prototype.listInstances
|
|
52
|
+
*
|
|
53
|
+
* @synopsis
|
|
54
|
+
* ```coffeescript [specscript]
|
|
55
|
+
* import EC2ListInstancesDescribeFilterOptions from './internal/EC2ListInstancesDescribeFilterOptions.ss'
|
|
56
|
+
*
|
|
57
|
+
* new EC2(...).listInstances(options? {
|
|
58
|
+
* ...EC2ListInstancesDescribeFilterOptions.map(value => value|Array<value>),
|
|
59
|
+
* limit?: 5-1000, // default 1000
|
|
60
|
+
* nextToken?: string, // last result's NextToken
|
|
61
|
+
* }) -> Promise<{
|
|
62
|
+
* Instances: Array<{
|
|
63
|
+
* InstanceId: string,
|
|
64
|
+
* AmiLaunchIndex: number, // 0
|
|
65
|
+
* ImageId: string, // 'ami-09625adacc474a7b4'
|
|
66
|
+
* InstanceId: 'i-04a9d2103428c73c0'
|
|
67
|
+
* InstanceType: string, // 't2.micro'
|
|
68
|
+
* KeyName: string, // 'solumlibs-test'
|
|
69
|
+
* LaunchTime: Date, // 2022-04-28T17:08:41.000Z
|
|
70
|
+
* Monitoring: {
|
|
71
|
+
* State: string, // 'disabled'
|
|
72
|
+
* },
|
|
73
|
+
* Placement: {
|
|
74
|
+
* AvailabilityZone: string, // 'us-west-1a'
|
|
75
|
+
* GroupName: string, // ''
|
|
76
|
+
* Tenancy: string, // 'default'
|
|
77
|
+
* },
|
|
78
|
+
* PrivateDnsName: string, // 'ip-172-31-31-44.us-west-1.compute.internal'
|
|
79
|
+
* PrivateIpAddress: string, // '172.31.31.44'
|
|
80
|
+
* ProductCodes: Array<string>,
|
|
81
|
+
* PublicDnsName: string, // 'ec2-3-101-88-163.us-west-1.compute.amazonaws.com'
|
|
82
|
+
* PublicIpAddress: string, // '3.101.88.163'
|
|
83
|
+
* State: {
|
|
84
|
+
* Code: number, // 16
|
|
85
|
+
* Name: string, // 'running'
|
|
86
|
+
* },
|
|
87
|
+
* StateTransitionReason: string,
|
|
88
|
+
* SubnetId: string, // 'subnet-916bb8f7'
|
|
89
|
+
* VpcId: string, // 'vpc-9c42a2fa'
|
|
90
|
+
* Architecture: string, // 'x86_64'
|
|
91
|
+
* BlockDeviceMappings: Array<Object>,
|
|
92
|
+
* ClientToken: string,
|
|
93
|
+
* EbsOptimized: boolean,
|
|
94
|
+
* EnaSupport: boolean,
|
|
95
|
+
* Hypervisor: string, // 'xen'
|
|
96
|
+
* ElasticGpuAssociations: Array,
|
|
97
|
+
* ElasticInferenceAcceleratorAssociations: Array,
|
|
98
|
+
* NetworkInterfaces: Array<Object>,
|
|
99
|
+
* RootDeviceName: string, // '/dev/xvda'
|
|
100
|
+
* RootDeviceType: string, // 'ebs'
|
|
101
|
+
* SecurityGroups: Array<Object>,
|
|
102
|
+
* SourceDestCheck: boolean,
|
|
103
|
+
* Tags: Array<Object>,
|
|
104
|
+
* VirtualizationType: string, // 'hvm'
|
|
105
|
+
* CpuOptions: {
|
|
106
|
+
* CoreCount: number, // 1
|
|
107
|
+
* ThreadsPerCore: number, // 1
|
|
108
|
+
* },
|
|
109
|
+
* CapacityReservationSpecification: {
|
|
110
|
+
* CapacityReservationPreference: string, // 'open'
|
|
111
|
+
* },
|
|
112
|
+
* HibernationOptions: {
|
|
113
|
+
* Configured: boolean, // false
|
|
114
|
+
* },
|
|
115
|
+
* Licenses: [],
|
|
116
|
+
* MetadataOptions: {
|
|
117
|
+
* State: string, // 'applied'
|
|
118
|
+
* HttpTokens: string, // 'optional'
|
|
119
|
+
* HttpPutResponseHopLimit: number, // 1
|
|
120
|
+
* HttpEndpoint: string, // 'enabled'
|
|
121
|
+
* },
|
|
122
|
+
* EnclaveOptions: {
|
|
123
|
+
* Enabled: boolean, // false
|
|
124
|
+
* },
|
|
125
|
+
* AvailabilityZone: string, // 'us-west-1a'
|
|
126
|
+
* Events: Array,
|
|
127
|
+
* InstanceState: {
|
|
128
|
+
* Code: number, // 16
|
|
129
|
+
* Name: string, // 'running'
|
|
130
|
+
* },
|
|
131
|
+
* InstanceStatus: {
|
|
132
|
+
* Details: Array,
|
|
133
|
+
* Status: string, // 'ok'
|
|
134
|
+
* },
|
|
135
|
+
* SystemStatus: {
|
|
136
|
+
* Details: Array,
|
|
137
|
+
* Status: string, // 'ok'
|
|
138
|
+
* }
|
|
139
|
+
* }>,
|
|
140
|
+
* NextToken: string|null,
|
|
141
|
+
* }>
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
EC2.prototype.listInstances = async function (options = {}) {
|
|
146
|
+
const {
|
|
147
|
+
Reservations: reservations,
|
|
148
|
+
NextToken: nextToken,
|
|
149
|
+
} = await this.awsEc2.describeInstances(filterExistsAndNotEmpty({
|
|
150
|
+
Filters: AWSEC2DescribeInstancesFilters(options),
|
|
151
|
+
MaxResults: options.limit ?? 1000,
|
|
152
|
+
NextToken: options.nextToken,
|
|
153
|
+
})).promise()
|
|
154
|
+
|
|
155
|
+
const instances = reservations.flatMap(get('Instances'))
|
|
156
|
+
const instanceIds = instances.map(get('InstanceId'))
|
|
157
|
+
|
|
158
|
+
const instanceIdStatusMap = new Map()
|
|
159
|
+
let instanceIndex = 0
|
|
160
|
+
while (instanceIndex < instanceIds.length) {
|
|
161
|
+
const { InstanceStatuses: instanceStatuses } =
|
|
162
|
+
await this.awsEc2.describeInstanceStatus({
|
|
163
|
+
InstanceIds: instanceIds.slice(instanceIndex, (instanceIndex += 100)),
|
|
164
|
+
}).promise()
|
|
165
|
+
for (const instanceStatus of instanceStatuses) {
|
|
166
|
+
instanceIdStatusMap.set(instanceStatus.InstanceId, instanceStatus)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const instancesWithStatusFields = instances.map(instance => ({
|
|
171
|
+
...instance,
|
|
172
|
+
...instanceIdStatusMap.get(instance.InstanceId),
|
|
173
|
+
}))
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
Instances: instancesWithStatusFields,
|
|
177
|
+
NextToken: nextToken,
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
module.exports = EC2
|
package/EC2.test.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const Test = require('thunk-test')
|
|
2
|
+
const assert = require('assert')
|
|
3
|
+
const AwsCredentials = require('./internal/AwsCredentials')
|
|
4
|
+
const EC2 = require('./EC2')
|
|
5
|
+
|
|
6
|
+
const test = new Test('EC2', async function () {
|
|
7
|
+
const awsCreds = await AwsCredentials('default').catch(error => {
|
|
8
|
+
if (error.code == 'ENOENT') {
|
|
9
|
+
const accessKeyId = process.env.AWS_ACCESS_KEY_ID
|
|
10
|
+
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY
|
|
11
|
+
if (accessKeyId == null || secretAccessKey == null) {
|
|
12
|
+
throw new Error('No AWS credential file or environment variables')
|
|
13
|
+
}
|
|
14
|
+
return { accessKeyId, secretAccessKey }
|
|
15
|
+
}
|
|
16
|
+
throw error
|
|
17
|
+
})
|
|
18
|
+
awsCreds.region = 'us-west-1'
|
|
19
|
+
|
|
20
|
+
const ec2 = new EC2({
|
|
21
|
+
...awsCreds,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// there is one test instance in this region
|
|
25
|
+
|
|
26
|
+
{ // listInstances all instances
|
|
27
|
+
const response = await ec2.listInstances()
|
|
28
|
+
assert(
|
|
29
|
+
response.Instances.filter(instance => instance.State.Name == 'running').length == 1,
|
|
30
|
+
'There is not a running instance, check the aws account'
|
|
31
|
+
)
|
|
32
|
+
assert.equal(response.NextToken, null)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
{ // listInstances with tag
|
|
36
|
+
const response = await ec2.listInstances({
|
|
37
|
+
'tag:Env': 'test',
|
|
38
|
+
})
|
|
39
|
+
assert.equal(response.Instances.length, 1)
|
|
40
|
+
assert.equal(response.NextToken, null)
|
|
41
|
+
}
|
|
42
|
+
}).case()
|
|
43
|
+
|
|
44
|
+
if (process.argv[1] == __filename) {
|
|
45
|
+
test()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = test
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const rubico = require('rubico')
|
|
2
|
+
const filterExists = require('./filterExists')
|
|
3
|
+
const objectFilterKeys = require('./objectFilterKeys')
|
|
4
|
+
const toArray = require('./toArray')
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
pipe, tap,
|
|
8
|
+
switchCase, tryCatch,
|
|
9
|
+
fork, assign, get, set, pick, omit,
|
|
10
|
+
map, filter, reduce, transform, flatMap,
|
|
11
|
+
and, or, not, any, all,
|
|
12
|
+
eq, gt, lt, gte, lte,
|
|
13
|
+
thunkify, always,
|
|
14
|
+
curry, __,
|
|
15
|
+
} = rubico
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @name AWSAutoScalingDescribeAutoScalingGroupsFilters
|
|
19
|
+
*
|
|
20
|
+
* @synopsis
|
|
21
|
+
* ```coffeescript [specscript]
|
|
22
|
+
* import AutoScalingListGroupsDescribeFilterOptions
|
|
23
|
+
* from './AutoScalingListGroupsDescribeFilterOptions.ss'
|
|
24
|
+
*
|
|
25
|
+
* AWSAutoScalingDescribeAutoScalingGroupsFilters(
|
|
26
|
+
* options AutoScalingListGroupsDescribeFilterOptions
|
|
27
|
+
* ) -> awsAutoScalingDescribeAutoScalingGroupsFilters Array<{ Name: string, Values: Array }>
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
const AWSAutoScalingDescribeAutoScalingGroupsFilters = pipe([
|
|
31
|
+
options => ({
|
|
32
|
+
'tag-key': options.tagKey,
|
|
33
|
+
'tag-value': options.tagValue,
|
|
34
|
+
...objectFilterKeys(options, key => key.startsWith('tag:')),
|
|
35
|
+
}),
|
|
36
|
+
filterExists,
|
|
37
|
+
options => {
|
|
38
|
+
const filters = []
|
|
39
|
+
for (const name in options) {
|
|
40
|
+
filters.push({ Name: name, Values: toArray(options[name]) })
|
|
41
|
+
}
|
|
42
|
+
return filters
|
|
43
|
+
},
|
|
44
|
+
])
|
|
45
|
+
|
|
46
|
+
module.exports = AWSAutoScalingDescribeAutoScalingGroupsFilters
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
const rubico = require('rubico')
|
|
2
|
+
const filterExists = require('./filterExists')
|
|
3
|
+
const objectFilterKeys = require('./objectFilterKeys')
|
|
4
|
+
const toArray = require('./toArray')
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
pipe, tap,
|
|
8
|
+
switchCase, tryCatch,
|
|
9
|
+
fork, assign, get, set, pick, omit,
|
|
10
|
+
map, filter, reduce, transform, flatMap,
|
|
11
|
+
and, or, not, any, all,
|
|
12
|
+
eq, gt, lt, gte, lte,
|
|
13
|
+
thunkify, always,
|
|
14
|
+
curry, __,
|
|
15
|
+
} = rubico
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @name AWSEC2DescribeInstancesFilters
|
|
19
|
+
*
|
|
20
|
+
* @synopsis
|
|
21
|
+
* ```coffeescript [specscript]
|
|
22
|
+
* import EC2ListInstancesDescribeFilterOptions from './EC2ListInstancesDescribeFilterOptions.ss'
|
|
23
|
+
*
|
|
24
|
+
* AWSEC2DescribeInstancesFilters(
|
|
25
|
+
* options EC2ListInstancesDescribeFilterOptions.map(value => value|Array<value>)
|
|
26
|
+
* ) -> awsEC2DescribeInstancesFilters Array<{ Name: string, Values: Array }>
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
const AWSEC2DescribeInstancesFilters = pipe([
|
|
30
|
+
options => ({
|
|
31
|
+
'affinity': options.affinity,
|
|
32
|
+
'architecture': options.architecture,
|
|
33
|
+
'availability-zone': options.availabilityZone,
|
|
34
|
+
'block-device-mapping.attach-time': options.blockDeviceMappingAttachTime,
|
|
35
|
+
'block-device-mapping.delete-on-termination':
|
|
36
|
+
options.blockDeviceMappingDeleteOnTermination,
|
|
37
|
+
'block-device-mapping.device-name': options.blockDeviceMappingDeviceName,
|
|
38
|
+
'block-device-mapping.status': options.blockDeviceMappingStatus,
|
|
39
|
+
'block-device-mapping.volume-id': options.blockDeviceMappingVolumeId,
|
|
40
|
+
'capacity-reservation-id': options.capacityReservationId,
|
|
41
|
+
'client-token': options.clientToken,
|
|
42
|
+
'dns-name': options.dnsName,
|
|
43
|
+
'hibernation-options.configured': options.hibernationOptionsConfigured,
|
|
44
|
+
'host-id': options.hostId,
|
|
45
|
+
'hypervisor': options.hypervisor,
|
|
46
|
+
'iam-instance-profile.arn': options.iamInstanceProfileArn,
|
|
47
|
+
'image-id': options.imageId,
|
|
48
|
+
'instance-id': options.instanceId,
|
|
49
|
+
'instance-lifecycle': options.instanceLifecycle,
|
|
50
|
+
'instance-state-code': options.instanceStateCode,
|
|
51
|
+
'instance-state-name': options.instanceStateName,
|
|
52
|
+
'instance-type': options.instanceType,
|
|
53
|
+
'instance.group-id': options.instanceGroupId,
|
|
54
|
+
'instance.group-name': options.instanceGroupName,
|
|
55
|
+
'ip-address': options.ipAddress,
|
|
56
|
+
'kernel-id': options.kernelId,
|
|
57
|
+
'key-name': options.keyName,
|
|
58
|
+
'launch-index': options.launchIndex,
|
|
59
|
+
'launch-time': options.launchTime,
|
|
60
|
+
'metadata-options.http-tokens': options.metadataOptionsHttpTokens,
|
|
61
|
+
'metadata-options.http-put-response-hop-limit':
|
|
62
|
+
options.metadataOptionsHttpPutResponseHopLimit,
|
|
63
|
+
'metadata-options.http-endpoint': options.metadataOptionsHttpEndpoint,
|
|
64
|
+
'monitoring-state': options.monitoringState,
|
|
65
|
+
'network-interface.addresses.private-ip-address':
|
|
66
|
+
options.networkInterfaceAddressesPrivateIpAddress,
|
|
67
|
+
'network-interface.addresses.primary':
|
|
68
|
+
options.networkInterfaceAddressesPrimary,
|
|
69
|
+
'network-interface.addresses.association.public-ip':
|
|
70
|
+
options.networkInterfaceAddressesAssociationPublicIp,
|
|
71
|
+
'network-interface.addresses.association.ip-owner-id':
|
|
72
|
+
options.networkInterfaceAddressesAssociationIpOwnerId,
|
|
73
|
+
'network-interface.association.public-ip':
|
|
74
|
+
options.networkInterfaceAssociationPublicIp,
|
|
75
|
+
'network-interface.association.ip-owner-id':
|
|
76
|
+
options.networkInterfaceAssociationIpOwnerId,
|
|
77
|
+
'network-interface.association.allocation-id':
|
|
78
|
+
options.networkInterfaceAssociationAllocationId,
|
|
79
|
+
'network-interface.association.association-id':
|
|
80
|
+
options.networkInterfaceAssociationId,
|
|
81
|
+
'network-interface.attachment.attachment-id':
|
|
82
|
+
options.networkInterfaceAttachmentId,
|
|
83
|
+
'network-interface.attachment.instance-id':
|
|
84
|
+
options.networkInterfaceAttachmentInstanceId,
|
|
85
|
+
'network-interface.attachment.instance-owner-id':
|
|
86
|
+
options.networkInterfaceAttachmentInstanceOwnerId,
|
|
87
|
+
'network-interface.attachment.device-index':
|
|
88
|
+
options.networkInterfaceAttachmentDeviceIndex,
|
|
89
|
+
'network-interface.attachment.status':
|
|
90
|
+
options.networkInterfaceAttachmentStatus,
|
|
91
|
+
'network-interface.attachment.attach-time':
|
|
92
|
+
options.networkInterfaceAttachTime,
|
|
93
|
+
'network-interface.attachment.delete-on-termination':
|
|
94
|
+
options.networkInterfaceAttachmentDeleteOnTermination,
|
|
95
|
+
'network-interface.availability-zone':
|
|
96
|
+
options.networkInterfaceAvailabilityZone,
|
|
97
|
+
'network-interface.description': options.networkInterfaceDescription,
|
|
98
|
+
'network-interface.group-id': options.networkInterfaceGroupId,
|
|
99
|
+
'network-interface.group-name': options.networkInterfaceGroupName,
|
|
100
|
+
'network-interface.ipv6-addresses.ipv6-address':
|
|
101
|
+
options.networkInterfaceIpv6Address,
|
|
102
|
+
'network-interface.mac-address': options.networkInterfaceMacAddress,
|
|
103
|
+
'network-interface.network-interface-id': options.networkInterfaceId,
|
|
104
|
+
'network-interface.owner-id': options.networkInterfaceOwnerId,
|
|
105
|
+
'network-interface.private-dns-name':
|
|
106
|
+
options.networkInterfacePrivateDnsName,
|
|
107
|
+
'network-interface.requester-id': options.networkInterfaceRequesterId,
|
|
108
|
+
'network-interface.requester-managed':
|
|
109
|
+
options.networkInterfaceRequesterManaged,
|
|
110
|
+
'network-interface.status': options.networkInterfaceStatus,
|
|
111
|
+
'network-interface.source-dest-check':
|
|
112
|
+
options.networkInterfaceSourceDestCheck,
|
|
113
|
+
'network-interface.subnet-id': options.networkInterfaceSubnetId,
|
|
114
|
+
'network-interface.vpc-id': options.networkInterfaceVpcId,
|
|
115
|
+
'outpost-arn': options.outpostArn,
|
|
116
|
+
'owner-id': options.ownerId,
|
|
117
|
+
'placement-group-name': options.placementGroupName,
|
|
118
|
+
'placement-partition-number': options.placementPartitionNumber,
|
|
119
|
+
'platform': options.platform,
|
|
120
|
+
'private-dns-name': options.privateDnsName,
|
|
121
|
+
'private-ip-address': options.privateIpAddress,
|
|
122
|
+
'product-code': options.productCode,
|
|
123
|
+
'product-code.type': options.productCodeType,
|
|
124
|
+
'ramdisk-id': options.ramdiskId,
|
|
125
|
+
'reason': options.reason,
|
|
126
|
+
'requester-id': options.requesterId,
|
|
127
|
+
'reservation-id': options.reservationId,
|
|
128
|
+
'root-device-name': options.rootDeviceName,
|
|
129
|
+
'root-device-type': options.rootDeviceType,
|
|
130
|
+
'source-dest-check': options.sourceDestCheck,
|
|
131
|
+
'spot-instance-request-id': options.spotInstanceRequestId,
|
|
132
|
+
'state-reason-code': options.stateReasonCode,
|
|
133
|
+
'state-reason-message': options.stateReasonMessage,
|
|
134
|
+
'subnet-id': options.subnetId,
|
|
135
|
+
'tag-key': options.tagKey,
|
|
136
|
+
'tenancy': options.tenancy,
|
|
137
|
+
'virtualization-type': options.virtualizationType,
|
|
138
|
+
'vpc-id': options.vpcId,
|
|
139
|
+
...objectFilterKeys(options, key => key.startsWith('tag:')),
|
|
140
|
+
}),
|
|
141
|
+
filterExists,
|
|
142
|
+
options => {
|
|
143
|
+
const filters = []
|
|
144
|
+
for (const name in options) {
|
|
145
|
+
filters.push({ Name: name, Values: toArray(options[name]) })
|
|
146
|
+
}
|
|
147
|
+
return filters
|
|
148
|
+
},
|
|
149
|
+
])
|
|
150
|
+
|
|
151
|
+
module.exports = AWSEC2DescribeInstancesFilters
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
AutoScalingListGroupsDescribeFilterOptions {
|
|
2
|
+
tagKey?: string, // filter by tag keys
|
|
3
|
+
tagValue?: string, // filter tag values
|
|
4
|
+
`tag:${key string}`?: string, // filter by the specified tag key/value pairs
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export default AutoScalingListGroupsDescribeFilterOptions
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
EC2FindInstancesDescribeFilterOptions {
|
|
2
|
+
affinity?: 'default'|'host',
|
|
3
|
+
architecture?: 'i386'|'x86_64'|'arm64',
|
|
4
|
+
availabilityZone?: string,
|
|
5
|
+
blockDeviceMappingAttachTime?: string, // e.g. '2010-09-15T17:15:20.000Z'
|
|
6
|
+
blockDeviceMappingDeleteOnTermination?: boolean, // whether EBS volume is deleted on instance termination
|
|
7
|
+
blockDeviceMappingDeviceName?: string, // device name specified in the block mapping e.g. /dev/sdh or xvdh
|
|
8
|
+
blockDeviceMappingStatus?: 'attaching'|'attached'|'detaching'|'detached',
|
|
9
|
+
blockDeviceMappingVolumeId?: string, // volume ID of the EBS volume
|
|
10
|
+
capacityReservationId?: string, // ID of the Capacity Reservation into which the instance was launched
|
|
11
|
+
clientToken?: string, // idempotency token you provided when you launched the instance
|
|
12
|
+
dnsName?: string, // public DNS name of the instance
|
|
13
|
+
hibernationOptionsConfigured?: boolean, // whether instance is enabled for hibernation
|
|
14
|
+
hostId?: string, // ID of the dedicated host on which the instance is running
|
|
15
|
+
hypervisor?: 'ovm'|'xen', // 'xen' is used for both Xen and Nitro hypervisors
|
|
16
|
+
iamInstanceProfileArn?: string, // ARN of the instance profile associated with the instance
|
|
17
|
+
imageId?: string, // ID of the image used to launch the instance
|
|
18
|
+
instanceId?: string, // ID of the instance
|
|
19
|
+
instanceLifecycle?: 'spot'|'scheduled', // whether this is a Spot or Scheduled instance
|
|
20
|
+
instanceStateCode?: 0|16|32|48|64|80, // state of the instance as a 16 bit unsigned int: 0 - pending; 16 - running; 32 - shutting-down; 48 - terminated; 64 - stopping; 80 - stopped
|
|
21
|
+
instanceStateName?: 'pending'|'running'|'shutting-down'|'terminated'|'stopping'|'stopped', // state of the instance
|
|
22
|
+
instanceType?: string, // type of the instance, e.g. 't2.micro'
|
|
23
|
+
instanceGroupId?: string, // ID of the security group for the instance
|
|
24
|
+
instanceGroupName?: string, // name of the security group for the instance
|
|
25
|
+
ipAddress?: string, // public IPv4 address of the instance
|
|
26
|
+
kernelId?: string, // kernel ID
|
|
27
|
+
keyName?: string, // name of the key pair used when the instance was launched
|
|
28
|
+
launchIndex?: number, // when launching multiple instances, index for the instance in the launch group e.g. 0, 1, 2
|
|
29
|
+
launchTime?: string, // time when the instance was launched in ISO 8601 format in UTC (YYYY-MM-DDThh:mm:ss.sssZ). Wildcard `*` (2021-09-29T*) matches an entire day
|
|
30
|
+
metadataOptionsHttpTokens?: 'optional'|'required', // metadata request authorization state
|
|
31
|
+
metadataOptionsHttpPutResponseHopLimit?: 1-64, // http metadata request put response hop limit
|
|
32
|
+
metadataOptionsHttpEndpoint?: 'enabled'|'disabled', // enable or disable metadata access on http endpoint
|
|
33
|
+
monitoringState?: 'enabled'|'disabled', // whether detailed monitoring is enabled
|
|
34
|
+
networkInterfaceAddressesPrivateIpAddress?: string, // private IPv4 address associated with the network interface
|
|
35
|
+
networkInterfaceAddressesPrimary?: boolean, // whether the IPv4 address of the network interface is the primary private IPv4 address
|
|
36
|
+
networkInterfaceAddressesAssociationPublicIp?: string, // ID of the association of an IPv4 Elastic IP Address with a network interface
|
|
37
|
+
networkInterfaceAddressesAssociationIpOwnerId?: string, // owner ID of the private IPv4 address associated with the network interface
|
|
38
|
+
networkInterfaceAssociationPublicIp?: string, // address of the Elastic IPv4 address bound to the network interface
|
|
39
|
+
networkInterfaceAssociationIpOwnerId?: string, // ownern of the Elastic IPv4 address associated with the network interface
|
|
40
|
+
networkInterfaceAssociationAllocationId?: string, // allocation ID returned when you allocated the IPv4 Elastic IP Address for your network interface
|
|
41
|
+
networkInterfaceAssociationId?: string, // association ID returned when the network interface was associated with an IPv4 address
|
|
42
|
+
networkInterfaceAttachmentId?: string, // ID of the interface attachment
|
|
43
|
+
networkInterfaceAttachmentInstanceId?: string, // ID of the instance to which the network interface is attached
|
|
44
|
+
networkInterfaceAttachmentInstanceOwnerId?: string, // owner ID of the instance to which the network interface is attached
|
|
45
|
+
networkInterfaceAttachmentDeviceIndex?: number, // device index to which the network interface is attached
|
|
46
|
+
networkInterfaceAttachmentStatus?: 'attaching'|'attached'|'detaching'|'detached',
|
|
47
|
+
networkInterfaceAttachTime?: string, // ISO 8601 string for time when network interface was attached to an instance
|
|
48
|
+
networkInterfaceAttachmentDeleteOnTermination?: boolean, // whether the attachment is deleted when an instance is terminated
|
|
49
|
+
networkInterfaceAvailabilityZone?: string, // Availability Zone of the network interface
|
|
50
|
+
networkInterfaceDescription?: string, // description of the network interface
|
|
51
|
+
networkInterfaceGroupId?: string, // ID of a security group associated with the network interface
|
|
52
|
+
networkInterfaceGroupName?: string, // name of a security group associated with the network interface
|
|
53
|
+
networkInterfaceIpv6Address?: string, // IPv6 address associated with the network interface
|
|
54
|
+
networkInterfaceMacAddress?: string, // MAC address of the network interface
|
|
55
|
+
networkInterfaceId?: string, // ID of the network interface
|
|
56
|
+
networkInterfaceOwnerId?: string, // ID of the owner of the network interface
|
|
57
|
+
networkInterfacePrivateDnsName?: string, // private DNS name of the network interface
|
|
58
|
+
networkInterfaceRequesterId?: string, // requester ID of the network interface
|
|
59
|
+
networkInterfaceRequesterManaged?: boolean, // whether the network interface is being managed by AWS
|
|
60
|
+
networkInterfaceStatus?: 'available'|'in-use',
|
|
61
|
+
networkInterfaceSourceDestCheck?: boolean, // whether network interface performs source/destination checking, must be false for the network interface to perform network address translation (NAT) in your VPC
|
|
62
|
+
networkInterfaceSubnetId?: string, // ID of the subnet for the network interface
|
|
63
|
+
networkInterfaceVpcId?: string, // ID of the vpc for the network interface
|
|
64
|
+
outpostArn?: string, // ARN of the Outpost
|
|
65
|
+
ownerId?: string, // the AWS account ID of the instance's owner
|
|
66
|
+
placementGroupName?: string, // name of the placement group for the instance
|
|
67
|
+
placementPartitionNumber?: number, // partition in which the instance is located
|
|
68
|
+
platform?: 'Windows', // platform, only valid value is 'Windows'
|
|
69
|
+
privateDnsName?: string, // private IPv4 DNS name of the instance
|
|
70
|
+
privateIpAddress?: string, // private IPv4 address of the instance
|
|
71
|
+
productCode?: string, // product code associated with the AMI used to launch the instance
|
|
72
|
+
productCodeType?: 'devpay'|'marketplace', // type of the product code
|
|
73
|
+
ramdiskId?: string, // RAM disk ID
|
|
74
|
+
reason?: string, // reason for the current state of the instance, e.g. 'User Initiated [date]' when you stop or terminate an instance
|
|
75
|
+
requesterId?: string, // ID of the entity that launched the instance on your behalf, e.g. 'Amazon Web Services Management Console' or 'Auto Scaling'
|
|
76
|
+
reservationId?: string, // ID of the instance's reservation. A reservation ID has 1:1 relationship with an instance launch request. An instance launch request can have multiple instances
|
|
77
|
+
rootDeviceName?: string, // device name of the root device volume e.g. '/dev/sda1'
|
|
78
|
+
rootDeviceType?: 'ebs'|'instance-store', // type of the root device volume
|
|
79
|
+
sourceDestCheck?: boolean, // whether instance performs source/destination checking. Must be false for instance to perform network address translation (NAT) in your VPC
|
|
80
|
+
spotInstanceRequestId?: string, // ID of the spot instance reequest
|
|
81
|
+
stateReasonCode?: string, // reason code for the state change
|
|
82
|
+
stateReasonMessage?: string, // message the describes the state change
|
|
83
|
+
subnetId?: string, // ID of the subnet for the instance
|
|
84
|
+
`tag:${key string}`?: string, // key/value combination of a tag assigned to the resource. For example, to find all resources that have a tag with key `Owner` and value `TeamA`, specify `tag:Owner` with value `TeamA`
|
|
85
|
+
tagKey?: string, // key of a tag assigned to the resource. Use to find all resources with a specific tag, regardless of the value
|
|
86
|
+
tenancy?: 'dedicated'|'default'|'host', // tenancy of the instance
|
|
87
|
+
virtualizationType?: 'paravirtual'|'hvm', // virtualization type of the instance
|
|
88
|
+
vpcId?: string, // ID of the VPC that the instance is running in
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export default EC2FindInstancesDescribeFilterOptions
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const filter = require('rubico/filter')
|
|
2
|
+
const and = require('rubico/and')
|
|
3
|
+
const not = require('rubico/not')
|
|
4
|
+
const isEmpty = require('rubico/x/isEmpty')
|
|
5
|
+
|
|
6
|
+
const exists = value => value != null
|
|
7
|
+
|
|
8
|
+
const notEmpty = not(isEmpty)
|
|
9
|
+
|
|
10
|
+
const filterExistsAndNotEmpty = filter(and([exists, notEmpty]))
|
|
11
|
+
|
|
12
|
+
module.exports = filterExistsAndNotEmpty
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name objectFilterKeys
|
|
3
|
+
*
|
|
4
|
+
* @synopsis
|
|
5
|
+
* ```coffeescript [specscript]
|
|
6
|
+
* objectFilterKeys(object Object, predicate function) -> filteredObject Object
|
|
7
|
+
* ```
|
|
8
|
+
*
|
|
9
|
+
* @TODO handle async
|
|
10
|
+
*/
|
|
11
|
+
const objectFilterKeys = function (object, predicate) {
|
|
12
|
+
const result = {}
|
|
13
|
+
for (const key in object) {
|
|
14
|
+
if (predicate(key)) {
|
|
15
|
+
result[key] = object[key]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = objectFilterKeys
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const isArray = require('./isArray')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @name toArray
|
|
5
|
+
*
|
|
6
|
+
* @synopsis
|
|
7
|
+
* ```coffeescript [specscript]
|
|
8
|
+
* toArray(value Array|any) -> originalValueOrArrayOfJustValue Array
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
const toArray = value => isArray(value) ? value : [value]
|
|
12
|
+
|
|
13
|
+
module.exports = toArray
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "presidium",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "A library for creating web services",
|
|
5
5
|
"author": "Richard Tong",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@elastic/elasticsearch": "^7.10.0",
|
|
33
|
-
"aws-sdk": "^2.
|
|
33
|
+
"aws-sdk": "^2.1123.0",
|
|
34
34
|
"ioredis": "^4.19.0",
|
|
35
35
|
"mongodb": "^3.6.3",
|
|
36
36
|
"node-fetch": "^2.6.1",
|