MovableInkAWS 2.7.5 → 2.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96e412e659e0f48c3a469c1151da0e2e610aaafe2b0817ad22e7dae4eae39765
4
- data.tar.gz: 5ae7c22cfedb9ddbd89c902f9531e01f88293e6843e1d057b9c6ca1f818b49b9
3
+ metadata.gz: f349ad96411750bb34591fdab29321576d2d253571311ac28b17945befe0da25
4
+ data.tar.gz: 1dfddfb2d024bf894a6b769115e57116a711458788da44920f15c1a75a9c0d55
5
5
  SHA512:
6
- metadata.gz: a877074eb719b30bdba76b22176e3cfc7965760a93de3d98cb9197a1e362c190d8a559f7cebdc5ebb0ad46138fdb8992622fd40c753cf593ced446aa5c68ed8f
7
- data.tar.gz: 399aae9bbe6a4f14fa2fae2cb44c9bc2b378b898af8961bf2a8f01f3555f7db613c350cfedced06ffc357e863f7415a8e4a57f95c6eaabd76655ded6e080e2c9
6
+ metadata.gz: 65af34acc71341c2c30f7e05cfc43c8712cc92b659f3505dbf520904524da80ccbd17e0e6e2430ee40fc406d25c200a9f3ca8088733bccbee0692a1cc11b83b5
7
+ data.tar.gz: f4f630f2920477c57af48c5613207e646c0d870029ee72663250fdc95dbe108d652f9786b2af97940c087195c1611aab11f10ccf5a5a158d5d2931cc6219600c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- MovableInkAWS (2.7.5)
4
+ MovableInkAWS (2.8.0)
5
5
  aws-sdk-athena (~> 1)
6
6
  aws-sdk-autoscaling (~> 1)
7
7
  aws-sdk-cloudwatch (~> 1)
@@ -211,12 +211,26 @@ module MovableInk
211
211
  private_ip_addresses(ordered_instances)
212
212
  end
213
213
 
214
- def redis_by_role(role, port)
215
- instance_ip_addresses_by_role(role: role)
216
- .shuffle
217
- .inject([]) { |redii, instance|
218
- redii.push({"host" => instance, "port" => port})
219
- }
214
+ def redis_by_role(role, port, availability_zones = [])
215
+ if availability_zones.class != Array
216
+ raise MovableInk::AWS::Errors::AvailabilityZonesListInvalidError
217
+ end
218
+
219
+ redis_instances = []
220
+
221
+ def redis(host, port)
222
+ {"host" => host, "port" => port}
223
+ end
224
+
225
+ if availability_zones.length > 0
226
+ availability_zones.each do |az|
227
+ redis_instances << instance_ip_addresses_by_role(role: role, availability_zone: az).inject([]) { |redii, instance| redii.push(redis(instance, port)) }
228
+ end
229
+ else
230
+ redis_instances << instance_ip_addresses_by_role(role: role).inject([]) { |redii, instance| redii.push(redis(instance, port)) }
231
+ end
232
+
233
+ redis_instances.flatten.shuffle
220
234
  end
221
235
 
222
236
  def elastic_ips
@@ -8,6 +8,7 @@ module MovableInk
8
8
  class InvalidDiscoveryTypeError < StandardError; end
9
9
  class RoleNameRequiredError < StandardError; end
10
10
  class RoleNameInvalidError < StandardError; end
11
+ class AvailabilityZonesListInvalidError < StandardError; end
11
12
 
12
13
  class ExpectedError
13
14
  def initialize(error_class, message_patterns = [])
@@ -35,11 +35,20 @@ module MovableInk
35
35
  end
36
36
 
37
37
  def list_all_r53_resource_record_sets(hosted_zone_id, client = nil)
38
- run_with_backoff do
39
- route53(client).list_resource_record_sets({
40
- hosted_zone_id: hosted_zone_id
41
- }).flat_map(&:resource_record_sets)
38
+ resp = run_with_backoff { route53(client).list_resource_record_sets({ hosted_zone_id: hosted_zone_id }) }
39
+ rrs = resp.resource_record_sets
40
+
41
+ # https://docs.aws.amazon.com/Route53/latest/APIReference/API_ListResourceRecordSets.html
42
+ while resp.is_truncated
43
+ resp = run_with_backoff { route53(client).list_resource_record_sets({
44
+ hosted_zone_id: hosted_zone_id,
45
+ start_record_name: resp.next_record_name,
46
+ start_record_type: resp.next_record_type,
47
+ start_record_identifier: resp.next_record_identifier
48
+ }) }
49
+ rrs += resp.resource_record_sets
42
50
  end
51
+ rrs
43
52
  end
44
53
 
45
54
  def list_health_checks(client = nil)
@@ -62,6 +71,18 @@ module MovableInk
62
71
  get_health_check_tags(health_check.id, client).detect { |tag| tag.key == key && tag.value.include?(value) }
63
72
  end
64
73
  end
74
+
75
+ def list_hosted_zones(client: nil)
76
+ resp = run_with_backoff { route53(client).list_hosted_zones() }
77
+ zones = resp.hosted_zones
78
+
79
+ # https://docs.aws.amazon.com/Route53/latest/APIReference/API_ListHostedZones.html
80
+ while resp.is_truncated
81
+ resp = run_with_backoff { route53(client).list_hosted_zones({marker: resp.next_marker}) }
82
+ zones += resp.hosted_zones
83
+ end
84
+ zones
85
+ end
65
86
  end
66
87
  end
67
88
  end
@@ -1,5 +1,5 @@
1
1
  module MovableInk
2
2
  class AWS
3
- VERSION = '2.7.5'
3
+ VERSION = '2.8.0'
4
4
  end
5
5
  end
data/spec/ec2_spec.rb CHANGED
@@ -589,6 +589,34 @@ describe MovableInk::AWS::EC2 do
589
589
  }
590
590
  ]])
591
591
  }
592
+ let(:redis_data_cross_azs) { ec2.stub_data(:describe_instances, reservations: [
593
+ instances: [
594
+ {
595
+ tags: [
596
+ {
597
+ key: 'mi:roles',
598
+ value: 'visitor_redis'
599
+ }
600
+ ],
601
+ private_ip_address: '10.0.0.1',
602
+ placement: {
603
+ availability_zone: availability_zone
604
+ }
605
+ },
606
+ {
607
+ tags: [
608
+ {
609
+ key: 'mi:roles',
610
+ value: 'visitor_redis'
611
+ }
612
+ ],
613
+ private_ip_address: '10.0.0.2',
614
+ placement: {
615
+ availability_zone: 'us-east-1z'
616
+ }
617
+ }
618
+ ]])
619
+ }
592
620
  let(:redii) { [{"host" => '10.0.0.1', "port" => 6379},{"host" => '10.0.0.2', "port" => 6379}] }
593
621
 
594
622
  it "should return redis IPs and ports" do
@@ -600,6 +628,20 @@ describe MovableInk::AWS::EC2 do
600
628
 
601
629
  expect(aws.redis_by_role('visitor_redis', port)).to match_array(redii)
602
630
  end
631
+
632
+ it "should return redis IPs and ports only from specified AZs" do
633
+ ec2.stub_responses(:describe_instances, redis_data_cross_azs)
634
+ allow(aws).to receive(:mi_env).and_return('test')
635
+ allow(aws).to receive(:availability_zone).and_return(availability_zone)
636
+ allow(aws).to receive(:my_region).and_return('us-east-1')
637
+ allow(aws).to receive(:ec2).and_return(ec2)
638
+
639
+ expect(aws.redis_by_role('visitor_redis', port, ['us-east-1z'])).to match_array([{"host" => '10.0.0.2', "port" => 6379}])
640
+ end
641
+
642
+ it "should throw exception if specified AZs list isnt array" do
643
+ expect { aws.redis_by_role('visitor_redis', port, 'us-east-1z') }.to raise_error(MovableInk::AWS::Errors::AvailabilityZonesListInvalidError)
644
+ end
603
645
  end
604
646
 
605
647
  context "elastic IPs" do
data/spec/route53_spec.rb CHANGED
@@ -3,9 +3,60 @@ require_relative '../lib/movable_ink/aws'
3
3
  describe MovableInk::AWS::Route53 do
4
4
  let(:aws) { MovableInk::AWS.new }
5
5
 
6
+ context 'hosted zones' do
7
+ let(:route53) { Aws::Route53::Client.new(stub_responses: true) }
8
+
9
+ it "should list all hosted zones" do
10
+ zones_data = route53.stub_data(:list_hosted_zones, is_truncated: false, hosted_zones: [{
11
+ id: '123456789X',
12
+ name: 'domain.tld'
13
+ }])
14
+ route53.stub_responses(:list_hosted_zones, zones_data)
15
+ allow(aws).to receive(:route53).and_return(route53)
16
+
17
+ expect(aws.list_hosted_zones.count).to eq(1)
18
+ expect(aws.list_hosted_zones.first.id).to eq('123456789X')
19
+ expect(aws.list_hosted_zones.first.name).to eq('domain.tld')
20
+ end
21
+
22
+ it "should list all hosted zones w/ pagination" do
23
+ zones_response_1 = {
24
+ is_truncated: true,
25
+ next_marker: 'this is fake marker',
26
+ marker: 'this is fake marker',
27
+ max_items: 1,
28
+ hosted_zones: [{
29
+ id: '123456789X',
30
+ name: 'domain.tld',
31
+ caller_reference: '123'
32
+ }]}
33
+
34
+ zones_response_2 = {
35
+ is_truncated: false,
36
+ next_marker: nil,
37
+ marker: 'this is fake marker',
38
+ max_items: 1,
39
+ hosted_zones: [{
40
+ id: 'X123456789',
41
+ name: 'tld.domain',
42
+ caller_reference: '321'
43
+ }]}
44
+
45
+ route53.stub_responses(:list_hosted_zones, [ zones_response_1, zones_response_2 ])
46
+ allow(aws).to receive(:route53).and_return(route53)
47
+
48
+ zones = aws.list_hosted_zones
49
+ expect(zones.count).to eq(2)
50
+ expect(zones.first.id).to eq('123456789X')
51
+ expect(zones.first.name).to eq('domain.tld')
52
+ expect(zones[1].id).to eq('X123456789')
53
+ expect(zones[1].name).to eq('tld.domain')
54
+ end
55
+ end
56
+
6
57
  context "resource record sets" do
7
58
  let(:route53) { Aws::Route53::Client.new(stub_responses: true) }
8
- let(:rrset_data) { route53.stub_data(:list_resource_record_sets, resource_record_sets: [
59
+ let(:rrset_data) { route53.stub_data(:list_resource_record_sets, is_truncated: false, resource_record_sets: [
9
60
  {
10
61
  name: 'host1.domain.tld.',
11
62
  set_identifier: '10_0_0_1',
@@ -34,6 +85,42 @@ describe MovableInk::AWS::Route53 do
34
85
  expect(aws.resource_record_sets('Z123')[2].name).to eq('host2-other.domain.tld.')
35
86
  end
36
87
 
88
+ it "should retrieve all rrsets for zone w/ pagination" do
89
+
90
+ rrs_response_1 = {
91
+ is_truncated: true,
92
+ max_items: 1,
93
+ next_record_name: 'record2.domain.',
94
+ next_record_type: 'A',
95
+ next_record_identifier: nil,
96
+ resource_record_sets: [{
97
+ name: 'record1.domain.',
98
+ type: 'A',
99
+ set_identifier: nil
100
+ }]}
101
+
102
+ rrs_response_2 = {
103
+ is_truncated: false,
104
+ max_items: 1,
105
+ next_record_name: nil,
106
+ next_record_type: nil,
107
+ next_record_identifier: nil,
108
+ resource_record_sets: [{
109
+ name: 'record2.domain.',
110
+ type: 'A',
111
+ set_identifier: nil
112
+ }]}
113
+
114
+ rrset_data = [rrs_response_1, rrs_response_2]
115
+ route53.stub_responses(:list_resource_record_sets, rrset_data)
116
+ allow(aws).to receive(:route53).and_return(route53)
117
+
118
+ rrs = aws.resource_record_sets('Z123')
119
+ expect(rrs.count).to eq(2)
120
+ expect(rrs[0].name).to eq('record1.domain.')
121
+ expect(rrs[1].name).to eq('record2.domain.')
122
+ end
123
+
37
124
  it "returns all sets with an identifier" do
38
125
  route53.stub_responses(:list_resource_record_sets, rrset_data)
39
126
  allow(aws).to receive(:route53).and_return(route53)
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.7.5
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - MI SRE
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-22 00:00:00.000000000 Z
11
+ date: 2022-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-core