kitchen-ec2 1.4.0 → 2.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
2
  SHA1:
3
- metadata.gz: '0629654ede02f6b7f39315c2434f07bc9325f622'
4
- data.tar.gz: aa125bda4edbab056fbaf0c37ba63ee9e7fec696
3
+ metadata.gz: d121c852a28622ac97b1d1ecd53d8925b8d69807
4
+ data.tar.gz: e3099c025db1fefaadc834cc3d0af54b18a1da7a
5
5
  SHA512:
6
- metadata.gz: b3fd4e4b7152d22b5c3952e8c60a718feddad53f9c69be85bbcac95803dfe1437f3cc9501e250a7d90cd8b011eccb168496e42b1339424d1a98629f637338bd2
7
- data.tar.gz: 7d96f594e0600b78209d5d89c86d1ddb5ca54afc86e53f9f04c4acfd275a0cd9fdf45da80cd36069d78e326eab4746abcb31b3e25458014a81c814408f44679a
6
+ metadata.gz: 0a761d862424e0fa29e2d5f1304ef5a65d66f6da5e5a38fa6ac437cfff0bd1619bcb8ece93066fd8c16036c62875028f9bdbd8b2572f6f825bde7d9c410aea59
7
+ data.tar.gz: 3716edf1589f8952d7aa7460f5e1056d0e5c78c1a0dfb6096ae1db5bf527ec31c33c0e3aada585164c0c07b6e9400c26c347b9c894604fad3b2a74226397799c
data/.gitignore CHANGED
File without changes
data/.rspec CHANGED
File without changes
data/.travis.yml CHANGED
File without changes
data/.yardopts CHANGED
File without changes
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## [v2.0.0](https://github.com/test-kitchen/kitchen-ec2/tree/v2.0.0) (2017-12-08)
4
+ [Full Changelog](https://github.com/test-kitchen/kitchen-ec2/compare/v1.4.0...v2.0.0)
5
+
6
+ **Improvements**
7
+
8
+ - Clean up original Authentication; Rely on SDK for Chain. [\#353](https://github.com/test-kitchen/kitchen-ec2/pull/320) ([rhyas](https://github.com/rhyas))
9
+ - Use quadratic backoff when encountering RequestLimit errors [\#320](https://github.com/test-kitchen/kitchen-ec2/pull/320) ([kamaradclimber](https://github.com/kamaradclimber))
10
+
3
11
  ## [v1.4.0](https://github.com/test-kitchen/kitchen-ec2/tree/v1.4.0) (2017-11-29)
4
12
  [Full Changelog](https://github.com/test-kitchen/kitchen-ec2/compare/v1.3.2...v1.4.0)
5
13
 
data/Gemfile CHANGED
File without changes
data/LICENSE CHANGED
File without changes
data/README.md CHANGED
@@ -149,35 +149,18 @@ follow the other `image_search` rules for preference.
149
149
 
150
150
  ### AWS Authentication
151
151
 
152
- In order to connect to AWS, you must specify the AWS access key id and secret key
153
- for your account. There are 3 ways you do this, and we will try them in the
154
- following order:
155
-
156
- 1. You can specify the access key and access secret (and optionally the session
157
- token) through config. See the `aws_access_key_id` and `aws_secret_access_key`
158
- config sections below to see how to specify these in your .kitchen.yml or
159
- through environment variables. If you would like to specify your session token
160
- use the environment variable `AWS_SESSION_TOKEN`.
161
- 2. The shared credentials ini file at `~/.aws/credentials`. This is the file
162
- populated by `aws configure` command line and used by AWS tools in general, so if
163
- you are set up for any other AWS tools, you probably already have this. You can
164
- specify multiple profiles in this file and select one with the `AWS_PROFILE`
165
- environment variable or the `shared_credentials_profile` driver config. Read
166
- [this][credentials_docs] for more information.
167
- 3. From an instance profile when running on EC2. This accesses the local
168
- metadata service to discover the local instance's IAM instance profile.
169
-
170
- This precedence order is taken from http://docs.aws.amazon.com/sdkforruby/api/index.html#Configuration
171
-
172
- The first method attempted that works will be used. IE, if you want to auth
173
- using the instance profile, you must not set any of the access key configs
174
- or environment variables, and you must not specify a `~/.aws/credentials`
175
- file.
152
+ In order to connect to AWS, you must specify AWS credentials. We rely on the SDK
153
+ to find credentials in the standard way, documented here:
154
+ https://github.com/aws/aws-sdk-ruby/#configuration
155
+
156
+ The SDK Chain will search environment variables, then config files, then IAM role
157
+ data from the instance profile, in that order. In the case config files being
158
+ present, the 'default' profile will be used unless `shared_credentials_profile`
159
+ is defined to point to another profile.
176
160
 
177
161
  Because the Test Kitchen test should be checked into source control and ran
178
162
  through CI we no longer recommend storing the AWS credentials in the
179
- `.kitchen.yml` file. Instead, specify them as environment variables or in the
180
- `~/.aws/credentials` file.
163
+ `.kitchen.yml` file.
181
164
 
182
165
  ### Instance Login Configuration
183
166
 
data/Rakefile CHANGED
File without changes
data/kitchen-ec2.gemspec CHANGED
File without changes
@@ -34,7 +34,7 @@ module Kitchen
34
34
 
35
35
  def initialize( # rubocop:disable Metrics/ParameterLists
36
36
  region,
37
- profile_name = nil,
37
+ profile_name = "default",
38
38
  access_key_id = nil,
39
39
  secret_access_key = nil,
40
40
  session_token = nil,
@@ -42,63 +42,17 @@ module Kitchen
42
42
  retry_limit = nil,
43
43
  ssl_verify_peer = true
44
44
  )
45
- creds = self.class.get_credentials(
46
- profile_name, access_key_id, secret_access_key, session_token, region
47
- )
48
45
  ::Aws.config.update(
49
46
  :region => region,
50
- :credentials => creds,
47
+ :profile => profile_name,
51
48
  :http_proxy => http_proxy,
52
49
  :ssl_verify_peer => ssl_verify_peer
53
50
  )
54
51
  ::Aws.config.update(:retry_limit => retry_limit) unless retry_limit.nil?
55
52
  end
56
53
 
57
- # Try and get the credentials from an ordered list of locations
58
- # http://docs.aws.amazon.com/sdkforruby/api/index.html#Configuration
59
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
60
- # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
61
- def self.get_credentials(profile_name, access_key_id, secret_access_key, session_token,
62
- region, options = {})
63
- source_creds =
64
- if access_key_id && secret_access_key
65
- ::Aws::Credentials.new(access_key_id, secret_access_key, session_token)
66
- elsif ENV["AWS_ACCESS_KEY_ID"] && ENV["AWS_SECRET_ACCESS_KEY"]
67
- ::Aws::Credentials.new(
68
- ENV["AWS_ACCESS_KEY_ID"],
69
- ENV["AWS_SECRET_ACCESS_KEY"],
70
- ENV["AWS_SESSION_TOKEN"]
71
- )
72
- elsif profile_name
73
- ::Aws::SharedCredentials.new(:profile_name => profile_name)
74
- elsif default_shared_credentials?
75
- ::Aws::SharedCredentials.new
76
- else
77
- ::Aws::InstanceProfileCredentials.new(:retries => 1)
78
- end
79
-
80
- if options[:assume_role_arn] && options[:assume_role_session_name]
81
- sts = ::Aws::STS::Client.new(:credentials => source_creds, :region => region)
82
-
83
- assume_role_options = (options[:assume_role_options] || {}).merge(
84
- :client => sts,
85
- :role_arn => options[:assume_role_arn],
86
- :role_session_name => options[:assume_role_session_name]
87
- )
88
-
89
- ::Aws::AssumeRoleCredentials.new(assume_role_options)
90
- else
91
- source_creds
92
- end
93
- end
94
54
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
95
55
 
96
- def self.default_shared_credentials?
97
- ::Aws::SharedCredentials.new.loadable?
98
- rescue ::Aws::Errors::NoSuchProfileError
99
- false
100
- end
101
-
102
56
  def create_instance(options)
103
57
  resource.create_instances(options)[0]
104
58
  end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -462,12 +462,14 @@ module Kitchen
462
462
  info "Waited #{c}/#{t}s for instance <#{state[:server_id]}> #{status_msg}."
463
463
  end
464
464
  begin
465
- server.wait_until(
466
- :max_attempts => config[:retryable_tries],
467
- :delay => config[:retryable_sleep],
468
- :before_attempt => wait_log,
469
- &block
470
- )
465
+ with_request_limit_backoff(state) do
466
+ server.wait_until(
467
+ :max_attempts => config[:retryable_tries],
468
+ :delay => config[:retryable_sleep],
469
+ :before_attempt => wait_log,
470
+ &block
471
+ )
472
+ end
471
473
  rescue ::Aws::Waiters::Errors::WaiterFailed
472
474
  error("Ran out of time waiting for the server with id [#{state[:server_id]}]" \
473
475
  " #{status_msg}, attempting to destroy it")
@@ -485,12 +487,28 @@ module Kitchen
485
487
  # Password data is blank until password is available
486
488
  !enc.nil? && !enc.empty?
487
489
  end
488
- pass = server.decrypt_windows_password(File.expand_path(instance.transport[:ssh_key]))
490
+ pass = with_request_limit_backoff(state) do
491
+ server.decrypt_windows_password(File.expand_path(instance.transport[:ssh_key]))
492
+ end
489
493
  state[:password] = pass
490
494
  info("Retrieved Windows password for instance <#{state[:server_id]}>.")
491
495
  end
492
496
  # rubocop:enable Lint/UnusedBlockArgument
493
497
 
498
+ def with_request_limit_backoff(state)
499
+ retries = 0
500
+ begin
501
+ yield
502
+ rescue ::Aws::EC2::Errors::RequestLimitExceeded, ::Aws::Waiters::Errors::UnexpectedError => e
503
+ raise unless retries < 5 && e.message.include?("Request limit exceeded")
504
+ retries += 1
505
+ info("Request limit exceeded for instance <#{state[:server_id]}>." \
506
+ " Trying again in #{retries**2} seconds.")
507
+ sleep(retries**2)
508
+ retry
509
+ end
510
+ end
511
+
494
512
  #
495
513
  # Ordered mapping from config name to Fog name. Ordered by preference
496
514
  # when looking up hostname.
@@ -21,6 +21,6 @@ module Kitchen
21
21
  module Driver
22
22
 
23
23
  # Version string for EC2 Test Kitchen driver
24
- EC2_VERSION = "1.4.0"
24
+ EC2_VERSION = "2.0.0"
25
25
  end
26
26
  end
@@ -20,135 +20,6 @@ require "kitchen/driver/aws/client"
20
20
  require "climate_control"
21
21
 
22
22
  describe Kitchen::Driver::Aws::Client do
23
- describe "::get_credentials" do
24
- # nothing else is set, so we default to this
25
- it "loads IAM credentials last" do
26
- iam = instance_double(Aws::InstanceProfileCredentials)
27
-
28
- allow(Kitchen::Driver::Aws::Client).to receive(:default_shared_credentials?).and_return(false)
29
- allow(Aws::InstanceProfileCredentials).to receive(:new).and_return(iam)
30
-
31
- env_creds(nil, nil) do
32
- expect(Kitchen::Driver::Aws::Client.get_credentials(nil, nil, nil, nil, nil)).to eq(iam)
33
- end
34
- end
35
-
36
- it "loads the default shared creds profile second to last" do
37
- shared = instance_double(Aws::SharedCredentials)
38
-
39
- allow(Kitchen::Driver::Aws::Client).to receive(:default_shared_credentials?).and_return(true)
40
- allow(Aws::SharedCredentials).to \
41
- receive(:new).and_return(shared)
42
-
43
- env_creds(nil, nil) do
44
- expect(Kitchen::Driver::Aws::Client.get_credentials(nil, nil, nil, nil, nil)).to \
45
- eq(shared)
46
- end
47
- end
48
-
49
- it "loads a custom shared credentials profile third to last" do
50
- shared = instance_double(Aws::SharedCredentials)
51
-
52
- allow(Aws::SharedCredentials).to \
53
- receive(:new).with(:profile_name => "profile").and_return(shared)
54
-
55
- env_creds(nil, nil) do
56
- expect(Kitchen::Driver::Aws::Client.get_credentials("profile", nil, nil, nil, nil)).to \
57
- eq(shared)
58
- end
59
- end
60
-
61
- it "loads credentials from the environment third to last" do
62
- env_creds("key_id", "secret") do
63
- expect(Kitchen::Driver::Aws::Client.get_credentials(nil, nil, nil, nil, nil)).to \
64
- be_a(Aws::Credentials).and have_attributes(
65
- :access_key_id => "key_id",
66
- :secret_access_key => "secret"
67
- )
68
- end
69
- end
70
-
71
- it "loads provided credentials first" do
72
- expect(Kitchen::Driver::Aws::Client.get_credentials(
73
- "profile",
74
- "key3",
75
- "value3",
76
- nil,
77
- "us-west-1"
78
- )).to \
79
- be_a(Aws::Credentials).and have_attributes(
80
- :access_key_id => "key3",
81
- :secret_access_key => "value3",
82
- :session_token => nil
83
- )
84
- end
85
-
86
- it "uses a session token if provided" do
87
- expect(Kitchen::Driver::Aws::Client.get_credentials(
88
- "profile",
89
- "key3",
90
- "value3",
91
- "t",
92
- "us-west-1"
93
- )).to \
94
- be_a(Aws::Credentials).and have_attributes(
95
- :access_key_id => "key3",
96
- :secret_access_key => "value3",
97
- :session_token => "t"
98
- )
99
- end
100
- end
101
-
102
- describe "::get_credentials + STS AssumeRole" do
103
- let(:shared) { instance_double(Aws::SharedCredentials) }
104
- let(:iam) { instance_double(Aws::InstanceProfileCredentials) }
105
- let(:assume_role) { instance_double(Aws::AssumeRoleCredentials) }
106
- let(:sts_client) { instance_double(Aws::STS::Client) }
107
-
108
- before do
109
- expect(Aws::AssumeRoleCredentials).to \
110
- receive(:new).with(
111
- :client => sts_client,
112
- :role_arn => "role_arn",
113
- :role_session_name => "role_session_name"
114
- ).and_return(assume_role)
115
- end
116
-
117
- # nothing else is set, so we default to this
118
- it "loads an Instance Profile last" do
119
- allow(Kitchen::Driver::Aws::Client).to receive(:default_shared_credentials?).and_return(false)
120
-
121
- expect(Aws::InstanceProfileCredentials).to \
122
- receive(:new).and_return(iam)
123
- expect(Aws::STS::Client).to \
124
- receive(:new).with(:credentials => iam, :region => "us-west-1").and_return(sts_client)
125
-
126
- expect(Kitchen::Driver::Aws::Client.get_credentials(
127
- nil,
128
- nil,
129
- nil,
130
- nil,
131
- "us-west-1",
132
- :assume_role_arn => "role_arn", :assume_role_session_name => "role_session_name"
133
- )).to eq(assume_role)
134
- end
135
-
136
- it "loads shared credentials second to last" do
137
- expect(::Aws::SharedCredentials).to \
138
- receive(:new).with(:profile_name => "profile").and_return(shared)
139
- expect(Aws::STS::Client).to \
140
- receive(:new).with(:credentials => shared, :region => "us-west-1").and_return(sts_client)
141
-
142
- expect(Kitchen::Driver::Aws::Client.get_credentials(
143
- "profile",
144
- nil,
145
- nil,
146
- nil,
147
- "us-west-1",
148
- :assume_role_arn => "role_arn", :assume_role_session_name => "role_session_name"
149
- )).to eq(assume_role)
150
- end
151
- end
152
23
 
153
24
  let(:client) { Kitchen::Driver::Aws::Client.new("us-west-1") }
154
25
 
@@ -167,7 +38,7 @@ describe Kitchen::Driver::Aws::Client do
167
38
  let(:client) do
168
39
  Kitchen::Driver::Aws::Client.new(
169
40
  "us-west-1",
170
- "profile_name",
41
+ "test-profile",
171
42
  "access_key_id",
172
43
  "secret_access_key",
173
44
  "session_token",
@@ -176,12 +47,10 @@ describe Kitchen::Driver::Aws::Client do
176
47
  false
177
48
  )
178
49
  end
179
- let(:creds) { double("creds") }
180
50
  it "Sets the AWS config" do
181
- expect(Kitchen::Driver::Aws::Client).to receive(:get_credentials).and_return(creds)
182
51
  client
183
52
  expect(Aws.config[:region]).to eq("us-west-1")
184
- expect(Aws.config[:credentials]).to eq(creds)
53
+ expect(Aws.config[:profile]).to eq("test-profile")
185
54
  expect(Aws.config[:http_proxy]).to eq("http_proxy")
186
55
  expect(Aws.config[:retry_limit]).to eq(999)
187
56
  expect(Aws.config[:ssl_verify_peer]).to eq(false)
@@ -196,13 +65,4 @@ describe Kitchen::Driver::Aws::Client do
196
65
  it "returns a resource" do
197
66
  expect(client.resource).to be_a(Aws::EC2::Resource)
198
67
  end
199
-
200
- def env_creds(key_id, secret, &block)
201
- ClimateControl.modify(
202
- "AWS_ACCESS_KEY_ID" => key_id,
203
- "AWS_SECRET_ACCESS_KEY" => secret
204
- ) do
205
- yield
206
- end
207
- end
208
68
  end
File without changes
File without changes
File without changes
data/spec/spec_helper.rb CHANGED
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-ec2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fletcher Nichol
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-30 00:00:00.000000000 Z
11
+ date: 2017-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-kitchen