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 +4 -4
- data/.gitignore +0 -0
- data/.rspec +0 -0
- data/.travis.yml +0 -0
- data/.yardopts +0 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +0 -0
- data/LICENSE +0 -0
- data/README.md +9 -26
- data/Rakefile +0 -0
- data/kitchen-ec2.gemspec +0 -0
- data/lib/kitchen/driver/aws/client.rb +2 -48
- data/lib/kitchen/driver/aws/instance_generator.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/amazon.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/centos.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/debian.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/fedora.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/freebsd.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/rhel.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/ubuntu.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/windows.rb +0 -0
- data/lib/kitchen/driver/ec2.rb +25 -7
- data/lib/kitchen/driver/ec2_version.rb +1 -1
- data/spec/kitchen/driver/ec2/client_spec.rb +2 -142
- data/spec/kitchen/driver/ec2/image_selection_spec.rb +0 -0
- data/spec/kitchen/driver/ec2/instance_generator_spec.rb +0 -0
- data/spec/kitchen/driver/ec2_spec.rb +0 -0
- data/spec/spec_helper.rb +0 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d121c852a28622ac97b1d1ecd53d8925b8d69807
|
4
|
+
data.tar.gz: e3099c025db1fefaadc834cc3d0af54b18a1da7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
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.
|
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 =
|
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
|
-
:
|
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
|
data/lib/kitchen/driver/ec2.rb
CHANGED
@@ -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
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
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 =
|
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.
|
@@ -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
|
-
"
|
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[:
|
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:
|
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
|
+
date: 2017-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-kitchen
|