MovableInkAWS 1.0.13 → 1.0.18
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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/Gemfile.lock +20 -20
- data/lib/movable_ink/aws.rb +5 -1
- data/lib/movable_ink/aws/ec2.rb +28 -30
- data/lib/movable_ink/version.rb +1 -1
- data/spec/aws_spec.rb +6 -4
- data/spec/ec2_spec.rb +56 -16
- data/spec/ssm_spec.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c67a1debb22324f3f567c390c5a5baf61c714b56567712dd6269dd044b2ed9dd
|
4
|
+
data.tar.gz: 9b02840d52d5ee4a4f99060ec274f9938617247e1df9468efbb352fb2ff2285f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f547de79011e7fc83bb33db7d905da20c55d8a5308ef6e539193bfabacbcf1a5f0cde3a417ec454b6c24f0361ec1bef5b0d05ebbba5730f1cc5427643be28550
|
7
|
+
data.tar.gz: 87ad9c72f123ef2e70d3ff35d89eeef5dac3948144668e88554de402eff5b71e733144d2d7dc9fd51473662a3e36fc479525c1ff01a63ac0d34c1046d1d2d2c7
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
MovableInkAWS (1.0.
|
4
|
+
MovableInkAWS (1.0.18)
|
5
5
|
aws-sdk-athena (~> 1)
|
6
6
|
aws-sdk-autoscaling (~> 1)
|
7
7
|
aws-sdk-cloudwatch (~> 1)
|
@@ -19,48 +19,48 @@ PATH
|
|
19
19
|
GEM
|
20
20
|
remote: https://rubygems.org/
|
21
21
|
specs:
|
22
|
-
aws-eventstream (1.0
|
23
|
-
aws-partitions (1.
|
24
|
-
aws-sdk-athena (1.
|
22
|
+
aws-eventstream (1.1.0)
|
23
|
+
aws-partitions (1.322.0)
|
24
|
+
aws-sdk-athena (1.26.0)
|
25
25
|
aws-sdk-core (~> 3, >= 3.71.0)
|
26
26
|
aws-sigv4 (~> 1.1)
|
27
|
-
aws-sdk-autoscaling (1.
|
27
|
+
aws-sdk-autoscaling (1.37.0)
|
28
28
|
aws-sdk-core (~> 3, >= 3.71.0)
|
29
29
|
aws-sigv4 (~> 1.1)
|
30
|
-
aws-sdk-cloudwatch (1.
|
30
|
+
aws-sdk-cloudwatch (1.38.0)
|
31
31
|
aws-sdk-core (~> 3, >= 3.71.0)
|
32
32
|
aws-sigv4 (~> 1.1)
|
33
|
-
aws-sdk-core (3.
|
34
|
-
aws-eventstream (~> 1
|
33
|
+
aws-sdk-core (3.97.0)
|
34
|
+
aws-eventstream (~> 1, >= 1.0.2)
|
35
35
|
aws-partitions (~> 1, >= 1.239.0)
|
36
36
|
aws-sigv4 (~> 1.1)
|
37
37
|
jmespath (~> 1.0)
|
38
|
-
aws-sdk-ec2 (1.
|
38
|
+
aws-sdk-ec2 (1.164.0)
|
39
39
|
aws-sdk-core (~> 3, >= 3.71.0)
|
40
40
|
aws-sigv4 (~> 1.1)
|
41
|
-
aws-sdk-elasticache (1.
|
41
|
+
aws-sdk-elasticache (1.35.0)
|
42
42
|
aws-sdk-core (~> 3, >= 3.71.0)
|
43
43
|
aws-sigv4 (~> 1.1)
|
44
|
-
aws-sdk-kms (1.
|
44
|
+
aws-sdk-kms (1.32.0)
|
45
45
|
aws-sdk-core (~> 3, >= 3.71.0)
|
46
46
|
aws-sigv4 (~> 1.1)
|
47
|
-
aws-sdk-rds (1.
|
47
|
+
aws-sdk-rds (1.85.0)
|
48
48
|
aws-sdk-core (~> 3, >= 3.71.0)
|
49
49
|
aws-sigv4 (~> 1.1)
|
50
|
-
aws-sdk-route53 (1.
|
50
|
+
aws-sdk-route53 (1.35.0)
|
51
51
|
aws-sdk-core (~> 3, >= 3.71.0)
|
52
52
|
aws-sigv4 (~> 1.1)
|
53
|
-
aws-sdk-s3 (1.
|
54
|
-
aws-sdk-core (~> 3, >= 3.
|
53
|
+
aws-sdk-s3 (1.67.0)
|
54
|
+
aws-sdk-core (~> 3, >= 3.96.1)
|
55
55
|
aws-sdk-kms (~> 1)
|
56
56
|
aws-sigv4 (~> 1.1)
|
57
|
-
aws-sdk-sns (1.
|
57
|
+
aws-sdk-sns (1.24.0)
|
58
58
|
aws-sdk-core (~> 3, >= 3.71.0)
|
59
59
|
aws-sigv4 (~> 1.1)
|
60
|
-
aws-sdk-ssm (1.
|
60
|
+
aws-sdk-ssm (1.79.0)
|
61
61
|
aws-sdk-core (~> 3, >= 3.71.0)
|
62
62
|
aws-sigv4 (~> 1.1)
|
63
|
-
aws-sigv4 (1.1.
|
63
|
+
aws-sigv4 (1.1.4)
|
64
64
|
aws-eventstream (~> 1.0, >= 1.0.2)
|
65
65
|
diff-lcs (1.3)
|
66
66
|
httparty (0.16.3)
|
@@ -69,7 +69,7 @@ GEM
|
|
69
69
|
jmespath (1.4.0)
|
70
70
|
mime-types (3.3.1)
|
71
71
|
mime-types-data (~> 3.2015)
|
72
|
-
mime-types-data (3.
|
72
|
+
mime-types-data (3.2020.0512)
|
73
73
|
multi_xml (0.6.0)
|
74
74
|
rspec (3.9.0)
|
75
75
|
rspec-core (~> 3.9.0)
|
@@ -93,4 +93,4 @@ DEPENDENCIES
|
|
93
93
|
rspec (~> 3.6)
|
94
94
|
|
95
95
|
BUNDLED WITH
|
96
|
-
1.17.
|
96
|
+
1.17.3
|
data/lib/movable_ink/aws.rb
CHANGED
@@ -59,6 +59,7 @@ module MovableInk
|
|
59
59
|
return yield
|
60
60
|
rescue Aws::EC2::Errors::RequestLimitExceeded,
|
61
61
|
Aws::EC2::Errors::ResourceAlreadyAssociated,
|
62
|
+
Aws::EC2::Errors::Unavailable,
|
62
63
|
Aws::SNS::Errors::ThrottledException,
|
63
64
|
Aws::AutoScaling::Errors::ThrottledException,
|
64
65
|
Aws::S3::Errors::SlowDown,
|
@@ -76,12 +77,15 @@ module MovableInk
|
|
76
77
|
notify_and_sleep(sleep_time, $!.class)
|
77
78
|
end
|
78
79
|
rescue Aws::Errors::ServiceError => e
|
79
|
-
message = "#{e.class}: #{e.message}\nFrom
|
80
|
+
message = "#{e.class}: #{e.message}\nFrom #{$0}\n```\n#{e.backtrace.first(3).join("\n").gsub("`","'")}\n```"
|
80
81
|
notify_slack(subject: 'Unhandled AWS API Error', message: message)
|
81
82
|
puts message
|
82
83
|
raise MovableInk::AWS::Errors::ServiceError
|
83
84
|
end
|
84
85
|
end
|
86
|
+
message = "From: #{$0}\n```\n#{Thread.current.backtrace.first(3).join("\n").gsub("`","'")}\n```"
|
87
|
+
notify_slack(subject: "AWS API failed after #{tries} attempts", message: message)
|
88
|
+
puts message
|
85
89
|
raise MovableInk::AWS::Errors::FailedWithBackoff
|
86
90
|
end
|
87
91
|
|
data/lib/movable_ink/aws/ec2.rb
CHANGED
@@ -29,23 +29,12 @@ module MovableInk
|
|
29
29
|
raise MovableInk::AWS::Errors::NoEnvironmentTagError
|
30
30
|
end
|
31
31
|
|
32
|
-
def thopter_filter
|
33
|
-
[{
|
34
|
-
name: 'tag:mi:roles',
|
35
|
-
values: ['*thopter*']
|
36
|
-
},
|
37
|
-
{
|
38
|
-
name: 'tag:mi:env',
|
39
|
-
values: [mi_env]
|
40
|
-
},
|
41
|
-
{
|
42
|
-
name: 'instance-state-name',
|
43
|
-
values: ['running']
|
44
|
-
}]
|
45
|
-
end
|
46
|
-
|
47
32
|
def thopter_instance
|
48
|
-
@thopter_instance ||=
|
33
|
+
@thopter_instance ||= all_instances(region: 'us-east-1').select do |instance|
|
34
|
+
instance.tags.select{ |tag| tag.key == 'mi:roles' }.detect do |tag|
|
35
|
+
tag.value.include?('thopter')
|
36
|
+
end
|
37
|
+
end
|
49
38
|
end
|
50
39
|
|
51
40
|
def all_instances(region: my_region, no_filter: false)
|
@@ -102,18 +91,27 @@ module MovableInk
|
|
102
91
|
@me ||= all_instances.select{|instance| instance.instance_id == instance_id}.first rescue nil
|
103
92
|
end
|
104
93
|
|
105
|
-
def instances(role:, exclude_roles: [], region: my_region, availability_zone: nil, exact_match: false)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
94
|
+
def instances(role:, exclude_roles: [], region: my_region, availability_zone: nil, exact_match: false, use_cache: true)
|
95
|
+
roles = role.split(/\s*,\s*/)
|
96
|
+
if use_cache == false
|
97
|
+
filter = default_filter.push({
|
98
|
+
name: 'tag:mi:roles',
|
99
|
+
values: roles
|
100
|
+
})
|
101
|
+
instances = load_all_instances(my_region, filter: filter)
|
102
|
+
else
|
103
|
+
instances = all_instances(region: region).select { |instance|
|
104
|
+
instance.tags.select{ |tag| tag.key == 'mi:roles' }.detect { |tag|
|
105
|
+
tag_roles = tag.value.split(/\s*,\s*/)
|
106
|
+
if exact_match
|
107
|
+
tag_roles == roles
|
108
|
+
else
|
109
|
+
exclude_roles.push('decommissioned')
|
110
|
+
tag_roles.any? { |tag_role| roles.include?(tag_role) } && !tag_roles.any? { |role| exclude_roles.include?(role) }
|
111
|
+
end
|
112
|
+
}
|
115
113
|
}
|
116
|
-
|
114
|
+
end
|
117
115
|
|
118
116
|
if availability_zone
|
119
117
|
instances.select { |instance|
|
@@ -129,15 +127,15 @@ module MovableInk
|
|
129
127
|
end
|
130
128
|
|
131
129
|
def statsd_host
|
132
|
-
instance_ip_addresses_by_role(role: 'statsd', availability_zone: availability_zone).sample
|
130
|
+
instance_ip_addresses_by_role(role: 'statsd', availability_zone: availability_zone, use_cache: false).sample
|
133
131
|
end
|
134
132
|
|
135
133
|
def private_ip_addresses(instances)
|
136
134
|
instances.map(&:private_ip_address)
|
137
135
|
end
|
138
136
|
|
139
|
-
def instance_ip_addresses_by_role(role:, exclude_roles: [], region: my_region, availability_zone: nil, exact_match: false)
|
140
|
-
private_ip_addresses(instances(role: role, exclude_roles: exclude_roles, region: region, availability_zone: availability_zone, exact_match: exact_match))
|
137
|
+
def instance_ip_addresses_by_role(role:, exclude_roles: [], region: my_region, availability_zone: nil, exact_match: false, use_cache: true)
|
138
|
+
private_ip_addresses(instances(role: role, exclude_roles: exclude_roles, region: region, availability_zone: availability_zone, exact_match: exact_match, use_cache: use_cache))
|
141
139
|
end
|
142
140
|
|
143
141
|
def instance_ip_addresses_by_role_ordered(role:, exclude_roles: [], region: my_region, exact_match: false)
|
data/lib/movable_ink/version.rb
CHANGED
data/spec/aws_spec.rb
CHANGED
@@ -42,9 +42,9 @@ describe MovableInk::AWS do
|
|
42
42
|
ec2 = Aws::EC2::Client.new(stub_responses: true)
|
43
43
|
ec2.stub_responses(:describe_instances, 'RequestLimitExceeded')
|
44
44
|
|
45
|
-
expect(aws).to receive(:notify_slack).exactly(
|
45
|
+
expect(aws).to receive(:notify_slack).exactly(10).times
|
46
46
|
expect(aws).to receive(:sleep).exactly(9).times.and_return(true)
|
47
|
-
expect(STDOUT).to receive(:puts).exactly(
|
47
|
+
expect(STDOUT).to receive(:puts).exactly(10).times
|
48
48
|
|
49
49
|
aws.run_with_backoff { ec2.describe_instances } rescue nil
|
50
50
|
end
|
@@ -64,9 +64,9 @@ describe MovableInk::AWS do
|
|
64
64
|
ec2 = Aws::EC2::Client.new(stub_responses: true)
|
65
65
|
ec2.stub_responses(:describe_instances, 'RequestLimitExceeded')
|
66
66
|
|
67
|
-
expect(aws).to receive(:notify_slack).exactly(
|
67
|
+
expect(aws).to receive(:notify_slack).exactly(2).times
|
68
68
|
expect(aws).to receive(:sleep).exactly(9).times.and_return(true)
|
69
|
-
expect(STDOUT).to receive(:puts).exactly(
|
69
|
+
expect(STDOUT).to receive(:puts).exactly(2).times
|
70
70
|
|
71
71
|
aws.run_with_backoff(quiet: true) { ec2.describe_instances } rescue nil
|
72
72
|
end
|
@@ -77,6 +77,8 @@ describe MovableInk::AWS do
|
|
77
77
|
ec2.stub_responses(:describe_instances, 'RequestLimitExceeded')
|
78
78
|
|
79
79
|
expect(aws).to receive(:notify_and_sleep).exactly(9).times
|
80
|
+
expect(aws).to receive(:notify_slack).exactly(1).times
|
81
|
+
expect(STDOUT).to receive(:puts).exactly(1).times
|
80
82
|
expect{ aws.run_with_backoff { ec2.describe_instances } }.to raise_error(MovableInk::AWS::Errors::FailedWithBackoff)
|
81
83
|
end
|
82
84
|
end
|
data/spec/ec2_spec.rb
CHANGED
@@ -153,18 +153,6 @@ describe MovableInk::AWS::EC2 do
|
|
153
153
|
availability_zone: availability_zone
|
154
154
|
}
|
155
155
|
},
|
156
|
-
{
|
157
|
-
tags: [
|
158
|
-
{
|
159
|
-
key: 'mi:roles',
|
160
|
-
value: 'something_else'
|
161
|
-
}
|
162
|
-
],
|
163
|
-
private_ip_address: '10.0.0.3',
|
164
|
-
placement: {
|
165
|
-
availability_zone: availability_zone
|
166
|
-
}
|
167
|
-
}
|
168
156
|
]])
|
169
157
|
}
|
170
158
|
|
@@ -183,8 +171,8 @@ describe MovableInk::AWS::EC2 do
|
|
183
171
|
context "instances" do
|
184
172
|
let(:my_availability_zone) { 'us-east-1a' }
|
185
173
|
let(:other_availability_zone) { 'us-east-1b' }
|
186
|
-
let(:
|
187
|
-
|
174
|
+
let(:instances) {
|
175
|
+
[
|
188
176
|
{
|
189
177
|
tags: [
|
190
178
|
{
|
@@ -252,12 +240,54 @@ describe MovableInk::AWS::EC2 do
|
|
252
240
|
placement: {
|
253
241
|
availability_zone: other_availability_zone
|
254
242
|
}
|
243
|
+
},
|
244
|
+
{
|
245
|
+
tags: [
|
246
|
+
{
|
247
|
+
key: 'mi:name',
|
248
|
+
value: 'instance5'
|
249
|
+
},
|
250
|
+
{
|
251
|
+
key: 'mi:roles',
|
252
|
+
value: 'app_db'
|
253
|
+
}
|
254
|
+
],
|
255
|
+
instance_id: 'i-321cba',
|
256
|
+
private_ip_address: '10.0.0.5',
|
257
|
+
placement: {
|
258
|
+
availability_zone: other_availability_zone
|
259
|
+
}
|
255
260
|
}
|
256
|
-
]
|
261
|
+
]
|
262
|
+
}
|
263
|
+
let(:single_role_instance_data) { ec2.stub_data(:describe_instances, reservations: [
|
264
|
+
instances: instances.select { |instance|
|
265
|
+
instance[:tags].detect { |tag| tag[:key] == 'mi:roles' && tag[:value] == 'app_db_replica' }
|
266
|
+
}
|
267
|
+
])}
|
268
|
+
let(:multi_role_instance_data) { ec2.stub_data(:describe_instances, reservations: [
|
269
|
+
instances: instances.select { |instance|
|
270
|
+
instance[:tags].detect { |tag|
|
271
|
+
tag[:key] == 'mi:roles' && ['app_db', 'app_db_replica'].any?(tag[:value])
|
272
|
+
}
|
273
|
+
}
|
274
|
+
])}
|
275
|
+
let(:all_roles_instance_data) { ec2.stub_data(:describe_instances, reservations: [ instances: instances ])
|
257
276
|
}
|
258
277
|
|
259
278
|
before(:each) do
|
260
|
-
ec2.stub_responses(:describe_instances,
|
279
|
+
ec2.stub_responses(:describe_instances, -> (context) {
|
280
|
+
if (context.params[:filters].length == 2)
|
281
|
+
all_roles_instance_data
|
282
|
+
else
|
283
|
+
role_filter = context.params[:filters].detect { |filter| filter[:name] == 'tag:mi:roles' }
|
284
|
+
if role_filter[:values].length == 1
|
285
|
+
single_role_instance_data
|
286
|
+
else
|
287
|
+
multi_role_instance_data
|
288
|
+
end
|
289
|
+
end
|
290
|
+
})
|
261
291
|
allow(aws).to receive(:mi_env).and_return('test')
|
262
292
|
allow(aws).to receive(:availability_zone).and_return(my_availability_zone)
|
263
293
|
allow(aws).to receive(:my_region).and_return('us-east-1')
|
@@ -283,6 +313,16 @@ describe MovableInk::AWS::EC2 do
|
|
283
313
|
expect(instances.map{|i| i.tags.first.value }).to eq(['instance4'])
|
284
314
|
end
|
285
315
|
|
316
|
+
it "returns roles with exactly the specified role, letting the API to the filtering" do
|
317
|
+
instances = aws.instances(role: 'app_db_replica', use_cache: false)
|
318
|
+
expect(instances.map{|i| i.tags.first.value }).to eq(['instance4'])
|
319
|
+
end
|
320
|
+
|
321
|
+
it "returns roles with any of the specified roles, letting the API to the filtering" do
|
322
|
+
instances = aws.instances(role: 'app_db,app_db_replica', use_cache: false)
|
323
|
+
expect(instances.map{|i| i.tags.first.value }).to eq(['instance4', 'instance5'])
|
324
|
+
end
|
325
|
+
|
286
326
|
it "excludes requested roles" do
|
287
327
|
instances = aws.instances(role: 'app_db_replica', exclude_roles: ['db'])
|
288
328
|
expect(instances.map{|i| i.tags.first.value }).to eq(['instance1', 'instance4'])
|
data/spec/ssm_spec.rb
CHANGED
@@ -82,6 +82,8 @@ describe MovableInk::AWS::SSM do
|
|
82
82
|
allow(aws).to receive(:ssm_client).and_return(1)
|
83
83
|
allow(aws).to receive(:ssm_client_failover).and_return(2)
|
84
84
|
allow(aws).to receive(:notify_and_sleep).and_return(nil)
|
85
|
+
allow(aws).to receive(:notify_slack).and_return(nil)
|
86
|
+
allow(STDOUT).to receive(:puts).and_return(nil)
|
85
87
|
|
86
88
|
results = []
|
87
89
|
calls = 0
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: MovableInkAWS
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Chesler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-core
|