MovableInkAWS 2.1.1 → 2.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 294373b3abbbae4f5a9c8f941f08789d2b354bb131589333e5de8f383f1074c9
4
- data.tar.gz: 6db4060c7af410a792116a58f3879e55b41dfff181144f709a8d07e4aa2155ba
3
+ metadata.gz: 24c0d6fea8ea161fb987f26f1574ce3ee48a1c37cbe7f78cc09d8bef82242729
4
+ data.tar.gz: 59f455acf804ee9591647a4ccda51066161424ed8992492038721ece13bd58b6
5
5
  SHA512:
6
- metadata.gz: 432218aca5f383aa189ccd023661a51afebc05e3300ebbc36149751aa155a679162b477436436f7fe8c0be47ad2a8f2c60c8b4ac5a127336b84c14dfafd84a21
7
- data.tar.gz: 7484927a2b2ea53f24a5768d5349646f913d14dcb2ca621426bf6816d89a87ef1db89ee4b8e05a40cff4ffc90b14e3da5278338d6fbe5937e972773165f61026
6
+ metadata.gz: c6144b91d11de9221998cc636469411dcaa40fed4b5a8cbbd2638549d7b34a1c35578faaeee87474f586695c32f80c2be29447fc8cb7d45c8092ab2e9ae0ddda
7
+ data.tar.gz: 5bb11e9cd6d9ef69bbebdfd41d57c9e6cbb54b80cebbaa974595ee77c536db586b17f7e343bcc46d6e9380d1410e91a4a15a3ea899bc69c5998f6537d431c0bc
@@ -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.1.1)
4
+ MovableInkAWS (2.3.1)
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.0)
27
- aws-partitions (1.416.0)
28
- aws-sdk-athena (1.33.0)
29
- aws-sdk-core (~> 3, >= 3.109.0)
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.53.0)
32
- aws-sdk-core (~> 3, >= 3.109.0)
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.47.0)
35
- aws-sdk-core (~> 3, >= 3.109.0)
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.111.0)
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.220.0)
43
- aws-sdk-core (~> 3, >= 3.109.0)
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.0)
46
- aws-sdk-core (~> 3, >= 3.109.0)
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.50.0)
49
- aws-sdk-core (~> 3, >= 3.109.0)
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.41.0)
52
- aws-sdk-core (~> 3, >= 3.109.0)
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.110.0)
55
- aws-sdk-core (~> 3, >= 3.109.0)
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.45.0)
58
- aws-sdk-core (~> 3, >= 3.109.0)
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.87.0)
61
- aws-sdk-core (~> 3, >= 3.109.0)
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.36.0)
65
- aws-sdk-core (~> 3, >= 3.109.0)
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.102.0)
68
- aws-sdk-core (~> 3, >= 3.109.0)
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.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.2020.1104)
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)
@@ -103,7 +103,11 @@ module MovableInk
103
103
  end
104
104
 
105
105
  def my_region
106
- @my_region ||= availability_zone.chop
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)
@@ -112,11 +112,6 @@ module MovableInk
112
112
  raise MovableInk::AWS::Errors::RoleNameRequiredError
113
113
  end
114
114
 
115
- # We replace underscores with dashes in the role name in order to comply with
116
- # consul service naming conventions while still retaining the role name we use
117
- # within MI configuration
118
- role.gsub!('_', '-')
119
-
120
115
  consul_service_options = {
121
116
  dc: datacenter(region: region),
122
117
  stale: true,
@@ -125,32 +120,64 @@ module MovableInk
125
120
  }
126
121
  consul_service_options[:node_meta] = "availability_zone:#{availability_zone}" unless availability_zone.nil?
127
122
 
128
- Diplomat::Health.service(role, consul_service_options).map { |endpoint|
129
- OpenStruct.new (
130
- {
131
- private_ip_address: endpoint.Node['Address'],
132
- instance_id: endpoint.Node['Meta']['instance_id'],
133
- tags: [
134
- {
135
- key: 'Name',
136
- value: endpoint.Node['Node']
137
- },
138
- {
139
- key: 'mi:roles',
140
- value: endpoint.Node['Meta']['mi_roles']
141
- },
142
- {
143
- key: 'mi:monitoring_roles',
144
- value: endpoint.Node['Meta']['mi_monitoring_roles']
145
- }
146
- ],
147
- placement: {
148
- availability_zone: endpoint.Node['Meta']['availability_zone']
149
- }
150
- })
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
151
132
  }
152
133
  end
153
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
+
154
181
  def instances(role:, exclude_roles: [], region: my_region, availability_zone: nil, exact_match: false, use_cache: true, discovery_type: 'ec2')
155
182
  if discovery_type == 'ec2'
156
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 EC2Required < StandardError; end
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 ||= begin
6
+ def http(timeout_seconds: 1)
7
+ @http = begin
8
8
  http = Net::HTTP.new("169.254.169.254", 80)
9
- http.open_timeout = 1
10
- http.read_timeout = 1
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
- request = Net::HTTP::Get.new("/latest/meta-data/#{key}")
17
- request['X-aws-ec2-metadata-token'] = imds_token
18
- response = http.request(request)
19
- response.body
20
- rescue
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 ||= begin
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 ||= begin
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 ||= begin
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
- begin
43
+ def imds_token(tries: 3)
44
+ tries.times do |num|
45
+ num += 1
52
46
  request = Net::HTTP::Put.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
- nil
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
@@ -29,42 +29,27 @@ module MovableInk
29
29
  sleep seconds
30
30
  end
31
31
 
32
- def notify_nsq_can_not_be_drained
33
- notify_slack(subject: 'NSQ not drained',
34
- message: "Unable to drain NSQ for instance <https://#{my_region}.console.aws.amazon.com/ec2/v2/home?region=#{my_region}#Instances:search=#{instance_id};sort=instanceId|#{instance_id}>")
35
- notify_pagerduty(region: my_region, instance_id: instance_id)
36
- end
37
-
38
- def notify_pagerduty(region:, instance_id:)
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
- sns.publish(topic_arn: sns_pagerduty_topic_arn,
66
- subject: "Unable to drain NSQ",
67
- message: json_message)
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
@@ -1,5 +1,5 @@
1
1
  module MovableInk
2
2
  class AWS
3
- VERSION = '2.1.1'
3
+ VERSION = '2.3.1'
4
4
  end
5
5
  end
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(:put, '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(:retrieve_metadata).with('placement/availability-zone').and_return("us-east-1a")
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
- allow(aws).to receive(:retrieve_metadata).with('instance-id').and_return("")
9
- allow(aws).to receive(:retrieve_metadata).with('placement/availability-zone').and_return("")
10
- expect{ aws.mi_env }.to raise_error(MovableInk::AWS::Errors::EC2Required)
12
+ # stub an error making a request to the metadata api
13
+ stub_request(:put, '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(:put, '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)
@@ -445,6 +483,33 @@ describe MovableInk::AWS::EC2 do
445
483
  ojos_instances = aws.instances(role: 'ojos', availability_zone: other_availability_zone, discovery_type: 'consul')
446
484
  expect(ojos_instances.map{|i| i.tags.first[:value]}).to eq(['ojos_instance2', 'ojos_instance3'])
447
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
448
513
  end
449
514
 
450
515
  context "ordered roles" do
@@ -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 EC2 is required' do
10
+ it 'should raise an error if the metadata service times out' do
6
11
  aws = MovableInk::AWS.new
7
- allow(aws).to receive(:retrieve_metadata).with('instance-id').and_return("")
8
- allow(aws).to receive(:retrieve_metadata).with('placement/availability-zone').and_return("")
9
-
10
- expect{ aws.instance_id }.to raise_error(MovableInk::AWS::Errors::EC2Required)
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(:put, '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
- allow(aws).to receive(:retrieve_metadata).with('local-ipv4').and_return('')
17
- expect{ aws.private_ipv4 }.to raise_error(MovableInk::AWS::Errors::EC2Required)
20
+ # stub an error making a request to the metadata api
21
+ stub_request(:put, '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.notify_pagerduty(region: 'us-east-1', instance_id: 'i-987654321').message_id).to eq('messageId')
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.1.1
4
+ version: 2.3.1
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-02-01 00:00:00.000000000 Z
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
- - ".travis.yml"
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.8
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