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 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,7 @@
1
+ const filter = require('rubico/filter')
2
+
3
+ const exists = value => value != null
4
+
5
+ const filterExists = filter(exists)
6
+
7
+ module.exports = filterExists
@@ -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.15.36",
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.787.0",
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",