MovableInkAWS 2.1.0 → 2.3.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.
- checksums.yaml +4 -4
- data/.github/workflows/test.yaml +39 -0
- data/Gemfile.lock +30 -30
- data/lib/movable_ink/aws.rb +5 -1
- data/lib/movable_ink/aws/ec2.rb +55 -27
- data/lib/movable_ink/aws/errors.rb +1 -1
- data/lib/movable_ink/aws/metadata.rb +29 -33
- data/lib/movable_ink/aws/sns.rb +47 -35
- data/lib/movable_ink/version.rb +1 -1
- data/spec/aws_spec.rb +21 -1
- data/spec/ec2_spec.rb +69 -8
- data/spec/metadata_spec.rb +13 -8
- data/spec/sns_spec.rb +1 -1
- metadata +4 -4
- data/.travis.yml +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46d76e882265a792568c24853fbc6953bcfa54c4677d67b8aaf97d009896cb24
|
4
|
+
data.tar.gz: f02414993d6c9509bd72f5ec246e6bf99fc60c20a036487be9336cb41e780e8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b987bbb77c3fd5d2c1fc23c84c62e3af00df58074dbbdc9db21fd05fc8181c23f10bf096665f197ee98f79deaf4aaaaabc3fea1418ffcb85f0f256145fe13260
|
7
|
+
data.tar.gz: ddc7c1eff50e05f3d1cd83cb65df72f688c6aadbed822dc3a87cd9e2096451ab23f62293092443f9d22f4e76a84eb7073da2ffb41117987341bfb2663915cc25
|
@@ -0,0 +1,39 @@
|
|
1
|
+
name: test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: ['**']
|
6
|
+
tags: ['v*']
|
7
|
+
pull_request:
|
8
|
+
branches: [$default-branch]
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
test:
|
12
|
+
|
13
|
+
runs-on: ubuntu-18.04
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
|
18
|
+
- name: Install ruby
|
19
|
+
uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: 2.6
|
22
|
+
|
23
|
+
- name: Install dependencies
|
24
|
+
run: bundle install --retry=3
|
25
|
+
|
26
|
+
- name: Run tests
|
27
|
+
run: bundle exec rspec spec/
|
28
|
+
|
29
|
+
- name: Publish to RubyGems
|
30
|
+
if: startsWith(github.ref, 'refs/tags/')
|
31
|
+
run: |
|
32
|
+
mkdir -p $HOME/.gem
|
33
|
+
touch $HOME/.gem/credentials
|
34
|
+
chmod 0600 $HOME/.gem/credentials
|
35
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
36
|
+
gem build *.gemspec
|
37
|
+
gem push *.gem
|
38
|
+
env:
|
39
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
MovableInkAWS (2.
|
4
|
+
MovableInkAWS (2.3.0)
|
5
5
|
aws-sdk-athena (~> 1)
|
6
6
|
aws-sdk-autoscaling (~> 1)
|
7
7
|
aws-sdk-cloudwatch (~> 1)
|
@@ -23,51 +23,51 @@ GEM
|
|
23
23
|
specs:
|
24
24
|
addressable (2.7.0)
|
25
25
|
public_suffix (>= 2.0.2, < 5.0)
|
26
|
-
aws-eventstream (1.1.
|
27
|
-
aws-partitions (1.
|
28
|
-
aws-sdk-athena (1.
|
29
|
-
aws-sdk-core (~> 3, >= 3.
|
26
|
+
aws-eventstream (1.1.1)
|
27
|
+
aws-partitions (1.445.0)
|
28
|
+
aws-sdk-athena (1.37.0)
|
29
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
30
30
|
aws-sigv4 (~> 1.1)
|
31
|
-
aws-sdk-autoscaling (1.
|
32
|
-
aws-sdk-core (~> 3, >= 3.
|
31
|
+
aws-sdk-autoscaling (1.60.0)
|
32
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
33
33
|
aws-sigv4 (~> 1.1)
|
34
|
-
aws-sdk-cloudwatch (1.
|
35
|
-
aws-sdk-core (~> 3, >= 3.
|
34
|
+
aws-sdk-cloudwatch (1.51.0)
|
35
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
36
36
|
aws-sigv4 (~> 1.1)
|
37
|
-
aws-sdk-core (3.
|
37
|
+
aws-sdk-core (3.114.0)
|
38
38
|
aws-eventstream (~> 1, >= 1.0.2)
|
39
39
|
aws-partitions (~> 1, >= 1.239.0)
|
40
40
|
aws-sigv4 (~> 1.1)
|
41
41
|
jmespath (~> 1.0)
|
42
|
-
aws-sdk-ec2 (1.
|
43
|
-
aws-sdk-core (~> 3, >= 3.
|
42
|
+
aws-sdk-ec2 (1.234.0)
|
43
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
44
44
|
aws-sigv4 (~> 1.1)
|
45
|
-
aws-sdk-eks (1.
|
46
|
-
aws-sdk-core (~> 3, >= 3.
|
45
|
+
aws-sdk-eks (1.51.0)
|
46
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
47
47
|
aws-sigv4 (~> 1.1)
|
48
|
-
aws-sdk-elasticache (1.
|
49
|
-
aws-sdk-core (~> 3, >= 3.
|
48
|
+
aws-sdk-elasticache (1.55.0)
|
49
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
50
50
|
aws-sigv4 (~> 1.1)
|
51
|
-
aws-sdk-kms (1.
|
52
|
-
aws-sdk-core (~> 3, >= 3.
|
51
|
+
aws-sdk-kms (1.43.0)
|
52
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
53
53
|
aws-sigv4 (~> 1.1)
|
54
|
-
aws-sdk-rds (1.
|
55
|
-
aws-sdk-core (~> 3, >= 3.
|
54
|
+
aws-sdk-rds (1.118.0)
|
55
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
56
56
|
aws-sigv4 (~> 1.1)
|
57
|
-
aws-sdk-route53 (1.
|
58
|
-
aws-sdk-core (~> 3, >= 3.
|
57
|
+
aws-sdk-route53 (1.49.0)
|
58
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
59
59
|
aws-sigv4 (~> 1.1)
|
60
|
-
aws-sdk-s3 (1.
|
61
|
-
aws-sdk-core (~> 3, >= 3.
|
60
|
+
aws-sdk-s3 (1.93.1)
|
61
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
62
62
|
aws-sdk-kms (~> 1)
|
63
63
|
aws-sigv4 (~> 1.1)
|
64
|
-
aws-sdk-sns (1.
|
65
|
-
aws-sdk-core (~> 3, >= 3.
|
64
|
+
aws-sdk-sns (1.39.0)
|
65
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
66
66
|
aws-sigv4 (~> 1.1)
|
67
|
-
aws-sdk-ssm (1.
|
68
|
-
aws-sdk-core (~> 3, >= 3.
|
67
|
+
aws-sdk-ssm (1.108.0)
|
68
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
69
69
|
aws-sigv4 (~> 1.1)
|
70
|
-
aws-sigv4 (1.2.
|
70
|
+
aws-sigv4 (1.2.3)
|
71
71
|
aws-eventstream (~> 1, >= 1.0.2)
|
72
72
|
crack (0.4.3)
|
73
73
|
safe_yaml (~> 1.0.0)
|
@@ -85,7 +85,7 @@ GEM
|
|
85
85
|
jmespath (1.4.0)
|
86
86
|
mime-types (3.3.1)
|
87
87
|
mime-types-data (~> 3.2015)
|
88
|
-
mime-types-data (3.
|
88
|
+
mime-types-data (3.2021.0225)
|
89
89
|
multi_xml (0.6.0)
|
90
90
|
multipart-post (2.1.1)
|
91
91
|
public_suffix (4.0.5)
|
data/lib/movable_ink/aws.rb
CHANGED
@@ -103,7 +103,11 @@ module MovableInk
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def my_region
|
106
|
-
@my_region ||=
|
106
|
+
@my_region ||= if ENV['AWS_REGION'].nil?
|
107
|
+
availability_zone.chop
|
108
|
+
else
|
109
|
+
ENV['AWS_REGION']
|
110
|
+
end
|
107
111
|
end
|
108
112
|
|
109
113
|
def datacenter(region: my_region)
|
data/lib/movable_ink/aws/ec2.rb
CHANGED
@@ -112,10 +112,6 @@ module MovableInk
|
|
112
112
|
raise MovableInk::AWS::Errors::RoleNameRequiredError
|
113
113
|
end
|
114
114
|
|
115
|
-
if role.include?('_')
|
116
|
-
raise MovableInk::AWS::Errors::RoleNameInvalidError
|
117
|
-
end
|
118
|
-
|
119
115
|
consul_service_options = {
|
120
116
|
dc: datacenter(region: region),
|
121
117
|
stale: true,
|
@@ -124,32 +120,64 @@ module MovableInk
|
|
124
120
|
}
|
125
121
|
consul_service_options[:node_meta] = "availability_zone:#{availability_zone}" unless availability_zone.nil?
|
126
122
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
},
|
137
|
-
{
|
138
|
-
key: 'mi:roles',
|
139
|
-
value: endpoint.Node['Meta']['mi_roles']
|
140
|
-
},
|
141
|
-
{
|
142
|
-
key: 'mi:monitoring_roles',
|
143
|
-
value: endpoint.Node['Meta']['mi_monitoring_roles']
|
144
|
-
}
|
145
|
-
],
|
146
|
-
placement: {
|
147
|
-
availability_zone: endpoint.Node['Meta']['availability_zone']
|
148
|
-
}
|
149
|
-
})
|
123
|
+
# We replace underscores with dashes in the role name in order to comply with
|
124
|
+
# consul service naming conventions while still retaining the role name we use
|
125
|
+
# within MI configuration
|
126
|
+
Diplomat::Health.service(role.gsub('_', '-'), consul_service_options).map { |endpoint|
|
127
|
+
if endpoint.Node.dig('Meta', 'external-source') == 'kubernetes'
|
128
|
+
map_k8s_consul_endpoint(endpoint, role)
|
129
|
+
else
|
130
|
+
map_ec2_consul_endpoint(endpoint)
|
131
|
+
end
|
150
132
|
}
|
151
133
|
end
|
152
134
|
|
135
|
+
def map_k8s_consul_endpoint(endpoint, role)
|
136
|
+
OpenStruct.new ({
|
137
|
+
private_ip_address: endpoint.Service.dig('Address'),
|
138
|
+
instance_id: nil,
|
139
|
+
tags: [
|
140
|
+
{
|
141
|
+
key: 'Name',
|
142
|
+
value: endpoint.Service.dig('ID')
|
143
|
+
},
|
144
|
+
{
|
145
|
+
key: 'mi:roles',
|
146
|
+
value: role
|
147
|
+
},
|
148
|
+
{
|
149
|
+
key: 'mi:monitoring_roles',
|
150
|
+
value: role
|
151
|
+
}
|
152
|
+
],
|
153
|
+
placement: { availability_zone: nil }
|
154
|
+
})
|
155
|
+
end
|
156
|
+
|
157
|
+
def map_ec2_consul_endpoint(endpoint)
|
158
|
+
OpenStruct.new ({
|
159
|
+
private_ip_address: endpoint.Node['Address'],
|
160
|
+
instance_id: endpoint.Node['Meta']['instance_id'],
|
161
|
+
tags: [
|
162
|
+
{
|
163
|
+
key: 'Name',
|
164
|
+
value: endpoint.Node['Node']
|
165
|
+
},
|
166
|
+
{
|
167
|
+
key: 'mi:roles',
|
168
|
+
value: endpoint.Node['Meta']['mi_roles']
|
169
|
+
},
|
170
|
+
{
|
171
|
+
key: 'mi:monitoring_roles',
|
172
|
+
value: endpoint.Node['Meta']['mi_monitoring_roles']
|
173
|
+
}
|
174
|
+
],
|
175
|
+
placement: {
|
176
|
+
availability_zone: endpoint.Node['Meta']['availability_zone']
|
177
|
+
}
|
178
|
+
})
|
179
|
+
end
|
180
|
+
|
153
181
|
def instances(role:, exclude_roles: [], region: my_region, availability_zone: nil, exact_match: false, use_cache: true, discovery_type: 'ec2')
|
154
182
|
if discovery_type == 'ec2'
|
155
183
|
instances_with_ec2_discovery(role: role, exclude_roles: exclude_roles, region: region, availability_zone: availability_zone, exact_match: exact_match, use_cache: use_cache)
|
@@ -3,7 +3,7 @@ module MovableInk
|
|
3
3
|
module Errors
|
4
4
|
class ServiceError < StandardError; end
|
5
5
|
class FailedWithBackoff < StandardError; end
|
6
|
-
class
|
6
|
+
class MetadataTimeout < StandardError; end
|
7
7
|
class NoEnvironmentTagError < StandardError; end
|
8
8
|
class InvalidDiscoveryTypeError < StandardError; end
|
9
9
|
class RoleNameRequiredError < StandardError; end
|
@@ -3,59 +3,55 @@ require 'net/http'
|
|
3
3
|
module MovableInk
|
4
4
|
class AWS
|
5
5
|
module Metadata
|
6
|
-
def http
|
7
|
-
@http
|
6
|
+
def http(timeout_seconds: 1)
|
7
|
+
@http = begin
|
8
8
|
http = Net::HTTP.new("169.254.169.254", 80)
|
9
|
-
http.open_timeout =
|
10
|
-
http.read_timeout =
|
9
|
+
http.open_timeout = timeout_seconds
|
10
|
+
http.read_timeout = timeout_seconds
|
11
11
|
http
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
def retrieve_metadata(key)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
def retrieve_metadata(key, tries: 3)
|
16
|
+
tries.times do |num|
|
17
|
+
num += 1
|
18
|
+
request = Net::HTTP::Get.new("/latest/meta-data/#{key}")
|
19
|
+
request['X-aws-ec2-metadata-token'] = imds_token
|
20
|
+
response = http(timeout_seconds: num * 3).request(request)
|
21
|
+
return response.body
|
22
|
+
rescue Net::OpenTimeout, Net::ReadTimeout, Errno::EHOSTDOWN
|
23
|
+
sleep(num * 2)
|
24
|
+
end
|
25
|
+
|
26
|
+
raise MovableInk::AWS::Errors::MetadataTimeout
|
22
27
|
end
|
23
28
|
|
24
29
|
def availability_zone
|
25
|
-
@availability_zone ||=
|
26
|
-
az = retrieve_metadata('placement/availability-zone')
|
27
|
-
raise(MovableInk::AWS::Errors::EC2Required) if az.empty?
|
28
|
-
az
|
29
|
-
end
|
30
|
+
@availability_zone ||= retrieve_metadata('placement/availability-zone')
|
30
31
|
end
|
31
32
|
|
32
33
|
def instance_id
|
33
|
-
@instance_id ||=
|
34
|
-
id = retrieve_metadata('instance-id')
|
35
|
-
raise(MovableInk::AWS::Errors::EC2Required) if id.empty?
|
36
|
-
id
|
37
|
-
end
|
34
|
+
@instance_id ||= retrieve_metadata('instance-id')
|
38
35
|
end
|
39
36
|
|
40
37
|
def private_ipv4
|
41
|
-
@ipv4 ||=
|
42
|
-
ipv4 = retrieve_metadata('local-ipv4')
|
43
|
-
raise(MovableInk::AWS::Errors::EC2Required) if ipv4.empty?
|
44
|
-
ipv4
|
45
|
-
end
|
38
|
+
@ipv4 ||= retrieve_metadata('local-ipv4')
|
46
39
|
end
|
47
40
|
|
48
41
|
private
|
49
42
|
|
50
|
-
def imds_token
|
51
|
-
|
52
|
-
|
43
|
+
def imds_token(tries: 3)
|
44
|
+
tries.times do |num|
|
45
|
+
num += 1
|
46
|
+
request = Net::HTTP::Get.new('/latest/api/token')
|
53
47
|
request['X-aws-ec2-metadata-token-ttl-seconds'] = 120
|
54
|
-
response = http.request(request)
|
55
|
-
response.body
|
56
|
-
rescue
|
57
|
-
|
48
|
+
response = http(timeout_seconds: num * 3).request(request)
|
49
|
+
return response.body
|
50
|
+
rescue Net::OpenTimeout, Net::ReadTimeout, Errno::EHOSTDOWN
|
51
|
+
sleep(num * 2)
|
58
52
|
end
|
53
|
+
|
54
|
+
raise MovableInk::AWS::Errors::MetadataTimeout
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
data/lib/movable_ink/aws/sns.rb
CHANGED
@@ -29,42 +29,27 @@ module MovableInk
|
|
29
29
|
sleep seconds
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
summary = "Unable to drain NSQ for instance #{instance_id} in region #{region}"
|
40
|
-
|
41
|
-
# the PagerDuty integration key is added to the payload in the AWS integration
|
42
|
-
json_message = {
|
43
|
-
pagerduty: {
|
44
|
-
event_action: 'trigger',
|
45
|
-
payload: {
|
46
|
-
source: 'MovableInkAWS',
|
47
|
-
summary: summary,
|
48
|
-
timestamp: Time.now.utc.iso8601,
|
49
|
-
severity: 'error',
|
50
|
-
component: 'nsq',
|
51
|
-
group: 'nsq',
|
52
|
-
custom_details: {
|
53
|
-
InstanceId: instance_id,
|
54
|
-
},
|
55
|
-
},
|
56
|
-
dedup_key: "nsq-not-draining-#{instance_id}",
|
57
|
-
links: [{
|
58
|
-
href: "https://#{region}.console.aws.amazon.com/ec2/v2/home?region=#{region}#Instances:search=#{instance_id};sort=instanceId",
|
59
|
-
text: 'View Instance'
|
60
|
-
}],
|
61
|
-
}
|
62
|
-
}.to_json
|
63
|
-
|
32
|
+
def send_alert(
|
33
|
+
source: instance_id,
|
34
|
+
links: [],
|
35
|
+
custom_details: {},
|
36
|
+
summary:,
|
37
|
+
dedup_key:
|
38
|
+
)
|
64
39
|
run_with_backoff do
|
65
|
-
|
66
|
-
|
67
|
-
|
40
|
+
message_json = pd_message_json({
|
41
|
+
source: source,
|
42
|
+
summary: summary,
|
43
|
+
links: links,
|
44
|
+
custom_details: custom_details,
|
45
|
+
dedup_key: dedup_key,
|
46
|
+
})
|
47
|
+
|
48
|
+
sns.publish({
|
49
|
+
topic_arn: sns_pagerduty_topic_arn,
|
50
|
+
subject: summary,
|
51
|
+
message: message_json
|
52
|
+
})
|
68
53
|
end
|
69
54
|
end
|
70
55
|
|
@@ -78,6 +63,33 @@ module MovableInk
|
|
78
63
|
message: "#{required_info}\n#{message}")
|
79
64
|
end
|
80
65
|
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def pd_message_json(
|
70
|
+
source:,
|
71
|
+
summary:,
|
72
|
+
links:,
|
73
|
+
custom_details:,
|
74
|
+
dedup_key:
|
75
|
+
)
|
76
|
+
{
|
77
|
+
pagerduty: {
|
78
|
+
event_action: 'trigger',
|
79
|
+
payload: {
|
80
|
+
source: source,
|
81
|
+
summary: summary,
|
82
|
+
timestamp: Time.now.utc.iso8601,
|
83
|
+
severity: 'error',
|
84
|
+
component: source,
|
85
|
+
group: source,
|
86
|
+
custom_details: custom_details,
|
87
|
+
},
|
88
|
+
dedup_key: dedup_key,
|
89
|
+
links: links,
|
90
|
+
}
|
91
|
+
}.to_json
|
92
|
+
end
|
81
93
|
end
|
82
94
|
end
|
83
95
|
end
|
data/lib/movable_ink/version.rb
CHANGED
data/spec/aws_spec.rb
CHANGED
@@ -1,17 +1,37 @@
|
|
1
1
|
require_relative '../lib/movable_ink/aws'
|
2
|
+
require 'webmock/rspec'
|
2
3
|
|
3
4
|
describe MovableInk::AWS do
|
4
5
|
context "outside EC2" do
|
6
|
+
before(:each) do
|
7
|
+
allow_any_instance_of(MovableInk::AWS).to receive(:sleep).and_return(true)
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:each) { ENV['AWS_REGION'] = nil }
|
11
|
+
|
5
12
|
it 'doesnt raise an error if instance_id is set' do
|
6
13
|
aws = MovableInk::AWS.new(instance_id: 'i-987654321')
|
7
14
|
expect(aws.instance_id).to eq('i-987654321')
|
8
15
|
end
|
16
|
+
|
17
|
+
it 'doesnt raise if AWS_REGION is set' do
|
18
|
+
ENV['AWS_REGION'] = 'us-east-1'
|
19
|
+
miaws = MovableInk::AWS.new
|
20
|
+
expect(miaws.my_region).to eq('us-east-1')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'raises when AWS_REGION is not set and the metadata service is not available' do
|
24
|
+
miaws = MovableInk::AWS.new
|
25
|
+
# stub an error making a request to the metadata api
|
26
|
+
stub_request(:get, 'http://169.254.169.254/latest/api/token').to_raise(Net::OpenTimeout)
|
27
|
+
expect { miaws.my_region }.to raise_error(MovableInk::AWS::Errors::MetadataTimeout)
|
28
|
+
end
|
9
29
|
end
|
10
30
|
|
11
31
|
context "inside EC2" do
|
12
32
|
it "should find the datacenter by region" do
|
13
33
|
aws = MovableInk::AWS.new
|
14
|
-
expect(aws).to receive(:
|
34
|
+
expect(aws).to receive(:availability_zone).and_return("us-east-1a")
|
15
35
|
expect(aws.datacenter).to eq('iad')
|
16
36
|
end
|
17
37
|
|
data/spec/ec2_spec.rb
CHANGED
@@ -2,12 +2,16 @@ require_relative '../lib/movable_ink/aws'
|
|
2
2
|
require 'webmock/rspec'
|
3
3
|
|
4
4
|
describe MovableInk::AWS::EC2 do
|
5
|
+
before(:each) do
|
6
|
+
allow_any_instance_of(MovableInk::AWS).to receive(:sleep).and_return(true)
|
7
|
+
end
|
8
|
+
|
5
9
|
context "outside EC2" do
|
6
10
|
it "should raise an error if trying to load mi_env outside of EC2" do
|
7
11
|
aws = MovableInk::AWS.new
|
8
|
-
|
9
|
-
|
10
|
-
expect{ aws.mi_env }.to raise_error(MovableInk::AWS::Errors::
|
12
|
+
# stub an error making a request to the metadata api
|
13
|
+
stub_request(:get, 'http://169.254.169.254/latest/api/token').to_raise(Net::OpenTimeout)
|
14
|
+
expect{ aws.mi_env }.to raise_error(MovableInk::AWS::Errors::MetadataTimeout)
|
11
15
|
end
|
12
16
|
|
13
17
|
it "should use the provided environment" do
|
@@ -17,12 +21,16 @@ describe MovableInk::AWS::EC2 do
|
|
17
21
|
|
18
22
|
it "should not find a 'me'" do
|
19
23
|
aws = MovableInk::AWS.new
|
24
|
+
# stub an error making a request to the metadata api
|
25
|
+
stub_request(:get, 'http://169.254.169.254/latest/api/token').to_raise(Net::OpenTimeout)
|
20
26
|
expect(aws.me).to eq(nil)
|
21
27
|
end
|
22
28
|
end
|
23
29
|
|
24
30
|
context "inside EC2" do
|
25
|
-
WebMock.allow_net_connect!
|
31
|
+
before(:each) { WebMock.allow_net_connect! }
|
32
|
+
after(:each) { WebMock.disable_net_connect! }
|
33
|
+
|
26
34
|
let(:aws) { MovableInk::AWS.new }
|
27
35
|
let(:ec2) { Aws::EC2::Client.new(stub_responses: true) }
|
28
36
|
let(:tag_data) { ec2.stub_data(:describe_tags, tags: [
|
@@ -386,6 +394,36 @@ describe MovableInk::AWS::EC2 do
|
|
386
394
|
}]
|
387
395
|
}
|
388
396
|
|
397
|
+
let(:consul_kubernetes_service_instances) do
|
398
|
+
[
|
399
|
+
{
|
400
|
+
"Node": {
|
401
|
+
"ID": "",
|
402
|
+
"Node": "k8s-sync",
|
403
|
+
"Address": "127.0.0.1",
|
404
|
+
"Datacenter": "my_datacenter",
|
405
|
+
"TaggedAddresses": nil,
|
406
|
+
"Meta": {
|
407
|
+
"external-source": "kubernetes",
|
408
|
+
"CreateIndex": 987654321,
|
409
|
+
"ModifyIndex": 123456789,
|
410
|
+
}
|
411
|
+
},
|
412
|
+
"Service": {
|
413
|
+
"ID": "pod-name-ac8f920827af",
|
414
|
+
"Service": "kubernetes-service-name",
|
415
|
+
"Tags": ["k8s"],
|
416
|
+
"Address": "10.0.0.1",
|
417
|
+
"Port": 8080,
|
418
|
+
"Meta": {
|
419
|
+
"external-source": "kubernetes",
|
420
|
+
"external-k8s-ns": "default",
|
421
|
+
}
|
422
|
+
}
|
423
|
+
}
|
424
|
+
]
|
425
|
+
end
|
426
|
+
|
389
427
|
before(:each) do
|
390
428
|
allow(aws).to receive(:mi_env).and_return('test')
|
391
429
|
allow(aws).to receive(:availability_zone).and_return(my_availability_zone)
|
@@ -397,10 +435,6 @@ describe MovableInk::AWS::EC2 do
|
|
397
435
|
expect{ aws.instances(role: nil, discovery_type: 'consul') }.to raise_error(MovableInk::AWS::Errors::RoleNameRequiredError)
|
398
436
|
end
|
399
437
|
|
400
|
-
it "returns an error if an invalid role is passed" do
|
401
|
-
expect{ aws.instances(role: 'asset_proxy', discovery_type: 'consul') }.to raise_error(MovableInk::AWS::Errors::RoleNameInvalidError)
|
402
|
-
end
|
403
|
-
|
404
438
|
it "returns all instances matching a consul service" do
|
405
439
|
miaws = double(MovableInk::AWS)
|
406
440
|
allow(miaws).to receive(:my_region).and_return('us-east-1')
|
@@ -449,6 +483,33 @@ describe MovableInk::AWS::EC2 do
|
|
449
483
|
ojos_instances = aws.instances(role: 'ojos', availability_zone: other_availability_zone, discovery_type: 'consul')
|
450
484
|
expect(ojos_instances.map{|i| i.tags.first[:value]}).to eq(['ojos_instance2', 'ojos_instance3'])
|
451
485
|
end
|
486
|
+
|
487
|
+
it "returns backends that are synced from consul-k8s" do
|
488
|
+
miaws = double(MovableInk::AWS)
|
489
|
+
allow(miaws).to receive(:my_region).and_return('us-east-1')
|
490
|
+
|
491
|
+
json = JSON.generate(consul_kubernetes_service_instances)
|
492
|
+
stub_request(:get, "https://localhost:8501/v1/health/service/kubernetes-service-name?cached&dc=#{my_datacenter}&passing&stale")
|
493
|
+
.with({
|
494
|
+
headers: {
|
495
|
+
'Accept'=>'*/*',
|
496
|
+
'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
|
497
|
+
'User-Agent'=>'Faraday v1.0.1'
|
498
|
+
}
|
499
|
+
})
|
500
|
+
.to_return(status: 200, body: json, headers: {})
|
501
|
+
|
502
|
+
resp_instances = aws.instances(role: 'kubernetes-service-name', discovery_type: 'consul')
|
503
|
+
backend = resp_instances.first
|
504
|
+
name_tag = backend.tags.find {|t| t[:key] == 'Name' }
|
505
|
+
roles_tag = backend.tags.find {|t| t[:key] == 'mi:roles' }
|
506
|
+
|
507
|
+
expect(name_tag[:value]).to eq('pod-name-ac8f920827af')
|
508
|
+
expect(roles_tag[:value]).to eq('kubernetes-service-name')
|
509
|
+
expect(backend.instance_id).to eq(nil)
|
510
|
+
expect(backend.private_ip_address).to eq('10.0.0.1')
|
511
|
+
expect(backend.private_ip_address).to eq('10.0.0.1')
|
512
|
+
end
|
452
513
|
end
|
453
514
|
|
454
515
|
context "ordered roles" do
|
data/spec/metadata_spec.rb
CHANGED
@@ -1,20 +1,25 @@
|
|
1
1
|
require_relative '../lib/movable_ink/aws'
|
2
|
+
require 'webmock/rspec'
|
2
3
|
|
3
4
|
describe MovableInk::AWS::Metadata do
|
5
|
+
before(:each) do
|
6
|
+
allow_any_instance_of(MovableInk::AWS).to receive(:sleep).and_return(true)
|
7
|
+
end
|
8
|
+
|
4
9
|
context 'outside ec2' do
|
5
|
-
it 'should raise an error if
|
10
|
+
it 'should raise an error if the metadata service times out' do
|
6
11
|
aws = MovableInk::AWS.new
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
expect{ aws.
|
11
|
-
expect{ aws.availability_zone }.to raise_error(MovableInk::AWS::Errors::EC2Required)
|
12
|
+
# stub an error making a request to the metadata api
|
13
|
+
stub_request(:get, 'http://169.254.169.254/latest/api/token').to_raise(Net::OpenTimeout)
|
14
|
+
expect{ aws.instance_id }.to raise_error(MovableInk::AWS::Errors::MetadataTimeout)
|
15
|
+
expect{ aws.availability_zone }.to raise_error(MovableInk::AWS::Errors::MetadataTimeout)
|
12
16
|
end
|
13
17
|
|
14
18
|
it 'should raise an error if trying to load private_ipv4 outside of EC2' do
|
15
19
|
aws = MovableInk::AWS.new
|
16
|
-
|
17
|
-
|
20
|
+
# stub an error making a request to the metadata api
|
21
|
+
stub_request(:get, 'http://169.254.169.254/latest/api/token').to_raise(Net::OpenTimeout)
|
22
|
+
expect{ aws.private_ipv4 }.to raise_error(MovableInk::AWS::Errors::MetadataTimeout)
|
18
23
|
end
|
19
24
|
end
|
20
25
|
|
data/spec/sns_spec.rb
CHANGED
@@ -47,7 +47,7 @@ describe MovableInk::AWS::SNS do
|
|
47
47
|
allow(aws).to receive(:sns).and_return(sns)
|
48
48
|
allow(aws).to receive(:private_ipv4).and_return('10.0.0.1')
|
49
49
|
|
50
|
-
expect(aws.
|
50
|
+
expect(aws.send_alert(summary: 'Something bad happened', dedup_key: 'i-987654321').message_id).to eq('messageId')
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should truncate subjects longer than 100 characters" do
|
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: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Chesler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-core
|
@@ -227,7 +227,7 @@ extensions: []
|
|
227
227
|
extra_rdoc_files: []
|
228
228
|
files:
|
229
229
|
- ".github/workflows/pr-lint.yaml"
|
230
|
-
- ".
|
230
|
+
- ".github/workflows/test.yaml"
|
231
231
|
- Gemfile
|
232
232
|
- Gemfile.lock
|
233
233
|
- MovableInkAWS.gemspec
|
@@ -276,7 +276,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
276
|
- !ruby/object:Gem::Version
|
277
277
|
version: '0'
|
278
278
|
requirements: []
|
279
|
-
rubygems_version: 3.0.
|
279
|
+
rubygems_version: 3.0.3.1
|
280
280
|
signing_key:
|
281
281
|
specification_version: 4
|
282
282
|
summary: AWS Utility methods for MovableInk
|
data/.travis.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
rvm:
|
4
|
-
- 2.6
|
5
|
-
|
6
|
-
bundler_args: "--retry=3"
|
7
|
-
|
8
|
-
script:
|
9
|
-
- rspec spec/
|
10
|
-
|
11
|
-
deploy:
|
12
|
-
provider: rubygems
|
13
|
-
api_key:
|
14
|
-
secure: NAHVFo9MwOnAYhq1NzZz22/2p34Iw/L71ZNt2WHSbWuMVnA/xyvVu7Ja/S25aQmaV/btNkxTYtbJbf83QZTO9/IwkashWFcWJtLiptZkBRdpkiunMPWX9Gw3Ap5fODUIPxLFyLYWd53huNBJppBCVQTUPwkLEcWJcQZP4MU7dkhW5QKdQgmyNTlMy8epxyMqCQe7V0n98LCwreUsHxHMToe6/V0FemysjYjpnyNvcFpGFa9kf28VQw8ZpDR0iobw9hg6qs61Xj69Y3ns9fWI3sdnk8VjY29M+V415/ksyn7kzCjYiQsGGCFerzjMffIt/4PXqX81GRvcymxmpXWwtikJYP95kiHYbLGFUNS5GJngbyVgO5+amjx7vSZfaBGSXcUCSkxLV1Ki4QfMYnA4ihogwTdQhIALSEV9GzOfFt147lUok2LgZDzNfn9nCPL+qKMBNaBRe7/YoWGuvLQG/smYjunPYhis0ynAQ1Sytc7lgtbdEtLFzfET87ITVS4Y2F9TQ+z1fxROAn/YwMmdSPyiaXVLEOIUc/gx0BjJneTl43M4l6ZId8Q6maJTNG2Fd0yK0hwLJcsN/257HbnPEiTTgkXBcg58E6/ABfZqwDnJrP3sQPem85M4BxLJIPUvfBkYzyeAEV+ALYDJx+KLaqYCCgavF9M+41VbkkNZyKU=
|
15
|
-
gem: MovableInkAWS
|
16
|
-
on:
|
17
|
-
tags: true
|
18
|
-
repo: movableink/awslib
|