infopark-aws_utils 0.6.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5e4eda7134849d7d411e0fd9163df8c56ac911c6
4
- data.tar.gz: c512370d7a63a4ba0cf01657efc72dfccf684030
2
+ SHA256:
3
+ metadata.gz: d3e7e356a45fa25bf635a55425020ea0b6a05af17731565e996ac52d444eec87
4
+ data.tar.gz: 138f8b6bf8e7266956756eca4511544d6386eb4e41de0c1887c3fc642910ba88
5
5
  SHA512:
6
- metadata.gz: 75352c70287394b1f55fa1bb54f6c662d6d5bab945630fc6ef44650062d2f6c52952497a4ec4898b83c126c5104f094a83ce2221436983a2abd934802d9dd483
7
- data.tar.gz: 629523227982d924ab0afce3b9495bbcbf5fe3fb95944a7dbe69ab7905649a19f6900ae5af2c4a18b208026d034955d5f1f41db8894fed4b1c6022798ea4ba21
6
+ metadata.gz: e162493fcf4a2de9eb0a68f1cf5781d40a586f6a12e6d49f379002d65dc4009a7aae5b2a5016489b71fe301e24ad587b0343b79e20846adc267f99976e766a5d
7
+ data.tar.gz: 8e74fb1c214710bc22201e59e3da2d71fc8a68dd0a6ed7e8afd8c3e1e0310736ed1a5d736ac622169899445fc3cd4e190294d67da6fa40b0a3023da3258996b8
@@ -1,14 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2
4
- - 2.3
3
+ - 2.4
4
+ - 2.5
5
+ - 2.6
5
6
  script:
6
7
  - bundle exec rspec spec
7
- deploy:
8
- provider: rubygems
9
- api_key:
10
- secure: e4QeU1KKglgUR6y0kWCxGTjjhmC1Txmw4p1PiWt5Sj+dg3eSnr5PO5cCU+YsBo1fVBOhxpcZXwDk0iv8q0s3SqWbask6awXCBh9I7nnstLI5HgoR0ydS6rVsOUX7tWSPHVwHFUBL83iArHkuFRvsCZl2HQr3YecvBAQzXVc7EsPfvu1Rpfjyz3N4wWzpkItge+j5m6uX80dacOpPd9YXOMMd1qMzAB3VbySN8KUXszJL3YgMV/MAaEc4djj+s3GiPCnVjTPVdIb5ZVl0HH+LtkXfgVgxHMyDhwPflBmgg/lnYQG51DcrlHn8mNsJOO0crgqc/B6xqjAalaRLf6iBDqSdx08TulgwQeBlhuq+YWBsV7ZL39NZgZiXLU+NW9ZW9iXy1I7z0PAhHlx1JaCVpNxUlG5fGvPkvOywo368taFJaYvdiTjW+IyaPO5UwcxTlWZlR+vQD/QEc7dsIHXu9/pWxfyycZI/hSnGJwa3lOx+mnU8GZbtufWsIRqnfxM6X0BVWS2BNLlK5drluj+jt0aW8tLSiYRNSY1DuL8U2CM9p3TjeOWvgBPGGzwApBI9/2RRP/E4KtW6ms+YnjT5veXE5rz1z/WmCoyWPdVfchd9J421+QGpq8WNGxnYImug0/mZtkGNkHg0b6nRWuorao/fxWkkDstjK/tk7T0iTug=
11
- gem: cloudscopes
12
- on:
13
- tags: true
14
- repo: infopark/aws_utils
@@ -6,24 +6,29 @@ module Infopark
6
6
  AWS_AMI_OWNER = "137112412989"
7
7
 
8
8
  class << self
9
- def gather_all(client, method, **options)
10
- @gather_cache ||= {}
11
- cache_key = [client, method, options]
12
- return @gather_cache[cache_key] if @gather_cache[cache_key]
9
+ def gather_all(client:, method:, response_key:, **options)
10
+ unless block_given?
11
+ @gather_cache ||= {}
12
+ cache_key = [client, method, options]
13
+ return @gather_cache[cache_key] if @gather_cache[cache_key]
14
+ end
13
15
 
14
16
  result = []
15
17
  loop do
16
- response = client.send(method, **options)
17
- key = (response.members - [:next_token, :failures]).first
18
+ response = retry_on_throttle { client.send(method, **options) }
18
19
  if response.members.include?(:failures) && !response.failures.empty?
19
20
  raise "Failed gathering all #{method}: #{response.failures}"
20
21
  end
21
- result += response[key]
22
+ if block_given?
23
+ response[response_key].each {|entity| retry_on_throttle { yield entity } }
24
+ else
25
+ result += response[response_key]
26
+ end
22
27
  unless options[:next_token] = response.members.include?(:next_token) && response.next_token
23
28
  break
24
29
  end
25
30
  end
26
- @gather_cache[cache_key] = result
31
+ @gather_cache[cache_key] = result unless block_given?
27
32
  end
28
33
 
29
34
  def wait_for(progress, client, waiter, delay: 2, max_attempts: 60, **waiter_params)
@@ -46,6 +51,18 @@ module Infopark
46
51
  end
47
52
  )
48
53
  end
54
+
55
+ private
56
+
57
+ def retry_on_throttle
58
+ yield
59
+ rescue => e
60
+ if e.class.name =~ /Throttl/
61
+ sleep 0.1
62
+ retry
63
+ end
64
+ raise
65
+ end
49
66
  end
50
67
 
51
68
  DEV_ACCOUNT_ID = ENV['INFOPARK_AWS_DEV_ACCOUNT_ID'] || self.local_config['dev_account_id']
@@ -26,8 +26,22 @@ class Env
26
26
 
27
27
  def initialize(profile_name = nil)
28
28
  @credentials = Aws::SharedCredentials.new(profile_name: profile_name)
29
+ if @credentials.credentials.nil?
30
+ raise "No credentials for AWS profile “#{profile_name}” found."\
31
+ " Please provide them via ~/.aws/credentials."
32
+ end
33
+
34
+ region = Aws.shared_config.region(profile: profile_name)
35
+ if region.nil?
36
+ raise "No region for AWS profile “#{profile_name}” found."\
37
+ " Please provide them via ~/.aws/config."
38
+ end
39
+
29
40
  @clients = Hash.new do |clients, mod|
30
- clients[mod] = mod.const_get(:Client).new(credentials: @credentials, region: 'eu-west-1')
41
+ clients[mod] = mod.const_get(:Client).new(
42
+ credentials: @credentials,
43
+ region: region,
44
+ )
31
45
  end
32
46
  end
33
47
 
@@ -96,31 +110,45 @@ class Env
96
110
  else
97
111
  raise "invalid root_device_type: #{root_device_type}"
98
112
  end
99
- available_images = AwsUtils.gather_all(ec2, :describe_images,
100
- owners: [AWS_AMI_OWNER],
101
- filters: [
102
- {name: "root-device-type", values: root_device_filter_value},
103
- {name: "ena-support", values: ["true"]},
104
- {name: "image-type", values: ["machine"]},
105
- {name: "virtualization-type", values: ["hvm"]},
106
- ])
107
- .reject {|image| image.name.include?(".rc-") }
108
- .reject {|image| image.name.include?("-minimal-") }
109
- .reject {|image| image.name.include?("-test") }
110
- .reject {|image| image.name.include?("amzn-ami-vpc-nat-") }
111
- (reject_image_name_patterns || []) do |pattern|
113
+ available_images = AwsUtils.gather_all(
114
+ client: ec2,
115
+ method: :describe_images,
116
+ response_key: :image_details,
117
+ owners: [AWS_AMI_OWNER],
118
+ filters: [
119
+ {name: "root-device-type", values: root_device_filter_value},
120
+ {name: "ena-support", values: ["true"]},
121
+ {name: "image-type", values: ["machine"]},
122
+ {name: "virtualization-type", values: ["hvm"]},
123
+ ],
124
+ )
125
+ .reject {|image| image.name.include?(".rc-") }
126
+ .reject {|image| image.name.include?("-minimal-") }
127
+ .reject {|image| image.name.include?("-test") }
128
+ .reject {|image| image.name.include?("amzn-ami-vpc-nat-") }
129
+ (reject_image_name_patterns || []).each do |pattern|
112
130
  available_images.reject! {|image| image.name =~ pattern }
113
131
  end
114
132
  available_images.sort_by(&:creation_date).last
115
133
  end
116
134
 
117
135
  def find_image_by_id(id)
118
- AwsUtils.gather_all(ec2, :describe_images, image_ids: [id]).first
136
+ AwsUtils.gather_all(
137
+ client: ec2,
138
+ method: :describe_images,
139
+ response_key: :image_details,
140
+ image_ids: [id],
141
+ ).first
119
142
  end
120
143
 
121
144
  def find_image_by_name(name)
122
- AwsUtils.gather_all(ec2, :describe_images, owners: [DEV_ACCOUNT_ID],
123
- filters: [{name: "name", values: [name]}]).first
145
+ AwsUtils.gather_all(
146
+ client: ec2,
147
+ method: :describe_images,
148
+ response_key: :image_details,
149
+ owners: [DEV_ACCOUNT_ID],
150
+ filters: [{name: "name", values: [name]}],
151
+ ).first
124
152
  end
125
153
 
126
154
  private
@@ -1,5 +1,5 @@
1
1
  module Infopark
2
2
  module AwsUtils
3
- VERSION = "0.6.0"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -1,7 +1,7 @@
1
1
  RSpec.describe Infopark::AwsUtils::Env do
2
2
  let(:account_id) { nil }
3
3
  let(:sts) do
4
- Aws::STS::Client.new.tap do |client|
4
+ Aws::STS::Client.new(region: "eu-west-1").tap do |client|
5
5
  allow(client).to receive(:get_caller_identity)
6
6
  .and_return(double(:caller_identity, account: account_id))
7
7
  end
@@ -18,8 +18,16 @@ RSpec.describe Infopark::AwsUtils::Env do
18
18
  subject { Infopark::AwsUtils::Env.profile(requested_profile) }
19
19
 
20
20
  before do
21
- allow(Aws::SharedCredentials).to receive(:new).with(profile_name: requested_profile).
22
- and_return(instance_double(Aws::SharedCredentials, profile_name: requested_profile))
21
+ allow(Aws::SharedCredentials).to receive(:new).with(profile_name: requested_profile)
22
+ .and_return(
23
+ instance_double(
24
+ Aws::SharedCredentials,
25
+ profile_name: requested_profile,
26
+ credentials: instance_double(Aws::Credentials),
27
+ ),
28
+ )
29
+ allow(Aws.shared_config).to receive(:region).with(profile: requested_profile)
30
+ .and_return("eu-west-1")
23
31
  end
24
32
 
25
33
  it { is_expected.to be_a(Infopark::AwsUtils::Env) }
@@ -42,14 +50,55 @@ RSpec.describe Infopark::AwsUtils::Env do
42
50
  end
43
51
  end
44
52
 
53
+ context "when requested profile has no credentials configured" do
54
+ before do
55
+ allow(Aws::SharedCredentials).to receive(:new).with(profile_name: requested_profile)
56
+ .and_return(
57
+ instance_double(
58
+ Aws::SharedCredentials,
59
+ profile_name: requested_profile,
60
+ credentials: nil,
61
+ ),
62
+ )
63
+ end
64
+
65
+ it "raises an error, asking for the credentials to be configured" do
66
+ expect {
67
+ subject
68
+ }.to raise_error("No credentials for AWS profile “#{requested_profile}” found."\
69
+ " Please provide them via ~/.aws/credentials.")
70
+ end
71
+ end
72
+
73
+ context "when requested profile has no region configured" do
74
+ before do
75
+ allow(Aws.shared_config).to receive(:region).with(profile: requested_profile)
76
+ .and_return(nil)
77
+ end
78
+
79
+ it "raises an error, asking for the region to be configured" do
80
+ expect {
81
+ subject
82
+ }.to raise_error("No region for AWS profile “#{requested_profile}” found."\
83
+ " Please provide them via ~/.aws/config.")
84
+ end
85
+ end
86
+
45
87
  context "when environment variable is set" do
46
88
  let(:value) { "#{requested_profile}_by_env" }
47
89
 
48
90
  before do
49
91
  allow(ENV).to receive(:[]).and_call_original
50
92
  allow(ENV).to receive(:[]).with(env_var).and_return(value)
51
- allow(Aws::SharedCredentials).to receive(:new).with(profile_name: value).
52
- and_return(instance_double(Aws::SharedCredentials, profile_name: value))
93
+ allow(Aws::SharedCredentials).to receive(:new).with(profile_name: value).and_return(
94
+ instance_double(
95
+ Aws::SharedCredentials,
96
+ profile_name: value,
97
+ credentials: instance_double(Aws::Credentials),
98
+ ),
99
+ )
100
+ allow(Aws.shared_config).to receive(:region).with(profile: value)
101
+ .and_return("eu-west-1")
53
102
  end
54
103
 
55
104
  it "uses credentials for this profile" do
@@ -73,6 +122,17 @@ RSpec.describe Infopark::AwsUtils::Env do
73
122
  end
74
123
 
75
124
  describe "#account_type" do
125
+ before do
126
+ allow(Aws::SharedCredentials).to receive(:new).and_return(
127
+ instance_double(
128
+ Aws::SharedCredentials,
129
+ profile_name: "foo",
130
+ credentials: instance_double(Aws::Credentials),
131
+ ),
132
+ )
133
+ allow(Aws.shared_config).to receive(:region).and_return("eu-west-1")
134
+ end
135
+
76
136
  subject(:account_type) { env.account_type }
77
137
 
78
138
  context "for profile in development account" do
@@ -99,6 +159,17 @@ RSpec.describe Infopark::AwsUtils::Env do
99
159
  end
100
160
 
101
161
  describe "#dev_account?" do
162
+ before do
163
+ allow(Aws::SharedCredentials).to receive(:new).and_return(
164
+ instance_double(
165
+ Aws::SharedCredentials,
166
+ profile_name: "foo",
167
+ credentials: instance_double(Aws::Credentials),
168
+ ),
169
+ )
170
+ allow(Aws.shared_config).to receive(:region).and_return("eu-west-1")
171
+ end
172
+
102
173
  subject { env.dev_account? }
103
174
 
104
175
  context "for development account" do
@@ -121,6 +192,17 @@ RSpec.describe Infopark::AwsUtils::Env do
121
192
  end
122
193
 
123
194
  describe "#prod_account?" do
195
+ before do
196
+ allow(Aws::SharedCredentials).to receive(:new).and_return(
197
+ instance_double(
198
+ Aws::SharedCredentials,
199
+ profile_name: "foo",
200
+ credentials: instance_double(Aws::Credentials),
201
+ ),
202
+ )
203
+ allow(Aws.shared_config).to receive(:region).and_return("eu-west-1")
204
+ end
205
+
124
206
  subject { env.prod_account? }
125
207
 
126
208
  context "for development account" do
@@ -154,6 +236,17 @@ RSpec.describe Infopark::AwsUtils::Env do
154
236
  [:sts, Aws::STS],
155
237
  ].each do |_client, _mod|
156
238
  describe "##{_client}" do
239
+ before do
240
+ allow(Aws::SharedCredentials).to receive(:new).and_return(
241
+ instance_double(
242
+ Aws::SharedCredentials,
243
+ profile_name: "foo",
244
+ credentials: instance_double(Aws::Credentials),
245
+ ),
246
+ )
247
+ allow(Aws.shared_config).to receive(:region).and_return("eu-west-1")
248
+ end
249
+
157
250
  subject(:client) { env.send(_client) }
158
251
 
159
252
  it { is_expected.to be_a(_mod.const_get("Client")) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: infopark-aws_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tilo Prütz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-11 00:00:00.000000000 Z
11
+ date: 2020-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-applicationautoscaling
@@ -200,8 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
200
  - !ruby/object:Gem::Version
201
201
  version: '0'
202
202
  requirements: []
203
- rubyforge_project:
204
- rubygems_version: 2.6.13
203
+ rubygems_version: 3.0.3
205
204
  signing_key:
206
205
  specification_version: 4
207
206
  summary: A utility lib to ease the use of the AWS SDK