MovableInkAWS 1.0.12 → 1.0.17
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 +27 -28
- data/lib/movable_ink/version.rb +1 -1
- data/spec/aws_spec.rb +6 -4
- data/spec/ec2_spec.rb +69 -4
- 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: 4563a27230a7711f44768ef561751a2366e03195de236dfb18a29bbff559c78b
|
4
|
+
data.tar.gz: b42568ac0c14f98d09420d4c2819b58eb047be5c31ca9a2e576c61685f69445b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9d9d52abbe8c75ce57a6cbd4165ea5188341106c4cf79cdc49fb96b9eda8db2b1e2216b948c750867c6333a9d29c682ef12084fd75186619b29d435606a99b7
|
7
|
+
data.tar.gz: c956e15226b703d33fdf7d74b367dac8259106cea459f5ca00ddfbe7fd05b17ccca18bdee22bde39c697370c7fb33ddd1ddf6210141efeea329f35b23f0a95c8
|
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.17)
|
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
@@ -14,7 +14,8 @@ module MovableInk
|
|
14
14
|
|
15
15
|
def mi_env
|
16
16
|
@mi_env ||= if File.exist?(mi_env_cache_file_path)
|
17
|
-
File.read(mi_env_cache_file_path)
|
17
|
+
value = File.read(mi_env_cache_file_path)
|
18
|
+
value.empty? ? load_mi_env : value
|
18
19
|
else
|
19
20
|
load_mi_env
|
20
21
|
end
|
@@ -28,23 +29,12 @@ module MovableInk
|
|
28
29
|
raise MovableInk::AWS::Errors::NoEnvironmentTagError
|
29
30
|
end
|
30
31
|
|
31
|
-
def thopter_filter
|
32
|
-
[{
|
33
|
-
name: 'tag:mi:roles',
|
34
|
-
values: ['*thopter*']
|
35
|
-
},
|
36
|
-
{
|
37
|
-
name: 'tag:mi:env',
|
38
|
-
values: [mi_env]
|
39
|
-
},
|
40
|
-
{
|
41
|
-
name: 'instance-state-name',
|
42
|
-
values: ['running']
|
43
|
-
}]
|
44
|
-
end
|
45
|
-
|
46
32
|
def thopter_instance
|
47
|
-
@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
|
48
38
|
end
|
49
39
|
|
50
40
|
def all_instances(region: my_region, no_filter: false)
|
@@ -101,18 +91,27 @@ module MovableInk
|
|
101
91
|
@me ||= all_instances.select{|instance| instance.instance_id == instance_id}.first rescue nil
|
102
92
|
end
|
103
93
|
|
104
|
-
def instances(role:, exclude_roles: [], region: my_region, availability_zone: nil, exact_match: false)
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
+
}
|
114
113
|
}
|
115
|
-
|
114
|
+
end
|
116
115
|
|
117
116
|
if availability_zone
|
118
117
|
instances.select { |instance|
|
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
@@ -45,6 +45,19 @@ describe MovableInk::AWS::EC2 do
|
|
45
45
|
expect(aws.mi_env).to eq('staging')
|
46
46
|
end
|
47
47
|
|
48
|
+
it 'will read tag data if the cache file is empty' do
|
49
|
+
ec2.stub_responses(:describe_tags, tag_data)
|
50
|
+
allow(aws).to receive(:my_region).and_return('us-east-1')
|
51
|
+
allow(aws).to receive(:instance_id).and_return('i-12345')
|
52
|
+
allow(aws).to receive(:ec2).and_return(ec2)
|
53
|
+
|
54
|
+
f = Tempfile.new('cache')
|
55
|
+
f.write('')
|
56
|
+
f.close
|
57
|
+
allow(aws).to receive(:mi_env_cache_file_path).and_return(f.path)
|
58
|
+
expect(aws.mi_env).to eq('test')
|
59
|
+
end
|
60
|
+
|
48
61
|
it "should find the environment from the current instance's tags" do
|
49
62
|
ec2.stub_responses(:describe_tags, tag_data)
|
50
63
|
allow(aws).to receive(:my_region).and_return('us-east-1')
|
@@ -170,8 +183,8 @@ describe MovableInk::AWS::EC2 do
|
|
170
183
|
context "instances" do
|
171
184
|
let(:my_availability_zone) { 'us-east-1a' }
|
172
185
|
let(:other_availability_zone) { 'us-east-1b' }
|
173
|
-
let(:
|
174
|
-
|
186
|
+
let(:instances) {
|
187
|
+
[
|
175
188
|
{
|
176
189
|
tags: [
|
177
190
|
{
|
@@ -239,12 +252,54 @@ describe MovableInk::AWS::EC2 do
|
|
239
252
|
placement: {
|
240
253
|
availability_zone: other_availability_zone
|
241
254
|
}
|
255
|
+
},
|
256
|
+
{
|
257
|
+
tags: [
|
258
|
+
{
|
259
|
+
key: 'mi:name',
|
260
|
+
value: 'instance5'
|
261
|
+
},
|
262
|
+
{
|
263
|
+
key: 'mi:roles',
|
264
|
+
value: 'app_db'
|
265
|
+
}
|
266
|
+
],
|
267
|
+
instance_id: 'i-321cba',
|
268
|
+
private_ip_address: '10.0.0.5',
|
269
|
+
placement: {
|
270
|
+
availability_zone: other_availability_zone
|
271
|
+
}
|
242
272
|
}
|
243
|
-
]
|
273
|
+
]
|
274
|
+
}
|
275
|
+
let(:single_role_instance_data) { ec2.stub_data(:describe_instances, reservations: [
|
276
|
+
instances: instances.select { |instance|
|
277
|
+
instance[:tags].detect { |tag| tag[:key] == 'mi:roles' && tag[:value] == 'app_db_replica' }
|
278
|
+
}
|
279
|
+
])}
|
280
|
+
let(:multi_role_instance_data) { ec2.stub_data(:describe_instances, reservations: [
|
281
|
+
instances: instances.select { |instance|
|
282
|
+
instance[:tags].detect { |tag|
|
283
|
+
tag[:key] == 'mi:roles' && ['app_db', 'app_db_replica'].any?(tag[:value])
|
284
|
+
}
|
285
|
+
}
|
286
|
+
])}
|
287
|
+
let(:all_roles_instance_data) { ec2.stub_data(:describe_instances, reservations: [ instances: instances ])
|
244
288
|
}
|
245
289
|
|
246
290
|
before(:each) do
|
247
|
-
ec2.stub_responses(:describe_instances,
|
291
|
+
ec2.stub_responses(:describe_instances, -> (context) {
|
292
|
+
if (context.params[:filters].length == 2)
|
293
|
+
all_roles_instance_data
|
294
|
+
else
|
295
|
+
role_filter = context.params[:filters].detect { |filter| filter[:name] == 'tag:mi:roles' }
|
296
|
+
if role_filter[:values].length == 1
|
297
|
+
single_role_instance_data
|
298
|
+
else
|
299
|
+
multi_role_instance_data
|
300
|
+
end
|
301
|
+
end
|
302
|
+
})
|
248
303
|
allow(aws).to receive(:mi_env).and_return('test')
|
249
304
|
allow(aws).to receive(:availability_zone).and_return(my_availability_zone)
|
250
305
|
allow(aws).to receive(:my_region).and_return('us-east-1')
|
@@ -270,6 +325,16 @@ describe MovableInk::AWS::EC2 do
|
|
270
325
|
expect(instances.map{|i| i.tags.first.value }).to eq(['instance4'])
|
271
326
|
end
|
272
327
|
|
328
|
+
it "returns roles with exactly the specified role, letting the API to the filtering" do
|
329
|
+
instances = aws.instances(role: 'app_db_replica', use_cache: false)
|
330
|
+
expect(instances.map{|i| i.tags.first.value }).to eq(['instance4'])
|
331
|
+
end
|
332
|
+
|
333
|
+
it "returns roles with any of the specified roles, letting the API to the filtering" do
|
334
|
+
instances = aws.instances(role: 'app_db,app_db_replica', use_cache: false)
|
335
|
+
expect(instances.map{|i| i.tags.first.value }).to eq(['instance4', 'instance5'])
|
336
|
+
end
|
337
|
+
|
273
338
|
it "excludes requested roles" do
|
274
339
|
instances = aws.instances(role: 'app_db_replica', exclude_roles: ['db'])
|
275
340
|
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.17
|
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-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-core
|