Skip to content

Commit 9018887

Browse files
committed
Adding changelog and cleaning up tests for #107
1 parent ac3d1c4 commit 9018887

File tree

3 files changed

+115
-117
lines changed

3 files changed

+115
-117
lines changed

CHANGELOG.md

+33-17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## Unreleased
2+
3+
### Bug Fixes
4+
5+
### New Features
6+
7+
* Pull Request [#68][], [#104][], [#107][]: If provisioning from an EC2 host and credentials are not set use the local nodes's credentials. If access key & secret are set, do not use local session token - leave it unset. ([@JamesAwesome][], [@Igorshp][], [@daanemanz][])
8+
9+
### Improvements
10+
111
## 0.8.0 / 2014-02-11
212

313
### Bug fixes
@@ -61,27 +71,33 @@
6171
* Remove default_config :port in favor of SSHBase default (also 22). ([@fnichol][])
6272

6373
<!--- The following link definition list is generated by PimpMyChangelog --->
64-
[#2]: https://github.com/opscode/kitchen-ec2/issues/2
65-
[#5]: https://github.com/opscode/kitchen-ec2/issues/5
66-
[#7]: https://github.com/opscode/kitchen-ec2/issues/7
67-
[#8]: https://github.com/opscode/kitchen-ec2/issues/8
68-
[#9]: https://github.com/opscode/kitchen-ec2/issues/9
69-
[#13]: https://github.com/opscode/kitchen-ec2/issues/13
70-
[#14]: https://github.com/opscode/kitchen-ec2/issues/14
71-
[#15]: https://github.com/opscode/kitchen-ec2/issues/15
72-
[#20]: https://github.com/opscode/kitchen-ec2/issues/20
73-
[#21]: https://github.com/opscode/kitchen-ec2/issues/21
74-
[#22]: https://github.com/opscode/kitchen-ec2/issues/22
75-
[#23]: https://github.com/opscode/kitchen-ec2/issues/23
76-
[#27]: https://github.com/opscode/kitchen-ec2/issues/27
77-
[#28]: https://github.com/opscode/kitchen-ec2/issues/28
78-
[#29]: https://github.com/opscode/kitchen-ec2/issues/29
79-
[#31]: https://github.com/opscode/kitchen-ec2/issues/31
80-
[#34]: https://github.com/opscode/kitchen-ec2/issues/34
74+
[#2]: https://github.com/test-kitchen/kitchen-ec2/issues/2
75+
[#5]: https://github.com/test-kitchen/kitchen-ec2/issues/5
76+
[#7]: https://github.com/test-kitchen/kitchen-ec2/issues/7
77+
[#8]: https://github.com/test-kitchen/kitchen-ec2/issues/8
78+
[#9]: https://github.com/test-kitchen/kitchen-ec2/issues/9
79+
[#13]: https://github.com/test-kitchen/kitchen-ec2/issues/13
80+
[#14]: https://github.com/test-kitchen/kitchen-ec2/issues/14
81+
[#15]: https://github.com/test-kitchen/kitchen-ec2/issues/15
82+
[#20]: https://github.com/test-kitchen/kitchen-ec2/issues/20
83+
[#21]: https://github.com/test-kitchen/kitchen-ec2/issues/21
84+
[#22]: https://github.com/test-kitchen/kitchen-ec2/issues/22
85+
[#23]: https://github.com/test-kitchen/kitchen-ec2/issues/23
86+
[#27]: https://github.com/test-kitchen/kitchen-ec2/issues/27
87+
[#28]: https://github.com/test-kitchen/kitchen-ec2/issues/28
88+
[#29]: https://github.com/test-kitchen/kitchen-ec2/issues/29
89+
[#31]: https://github.com/test-kitchen/kitchen-ec2/issues/31
90+
[#34]: https://github.com/test-kitchen/kitchen-ec2/issues/34
91+
[#68]: https://github.com/test-kitchen/kitchen-ec2/issues/68
92+
[#104]: https://github.com/test-kitchen/kitchen-ec2/issues/104
93+
[#107]: https://github.com/test-kitchen/kitchen-ec2/issues/107
8194
[@Atalanta]: https://github.com/Atalanta
95+
[@Igorshp]: https://github.com/Igorshp
96+
[@JamesAwesome]: https://github.com/JamesAwesome
8297
[@arangamani]: https://github.com/arangamani
8398
[@bozinsky]: https://github.com/bozinsky
8499
[@coderanger]: https://github.com/coderanger
100+
[@daanemanz]: https://github.com/daanemanz
85101
[@dissonanz]: https://github.com/dissonanz
86102
[@dysinger]: https://github.com/dysinger
87103
[@eherot]: https://github.com/eherot

lib/kitchen/driver/ec2.rb

+14-9
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ class Ec2 < Kitchen::Driver::SSHBase
100100
end
101101

102102
# First we check the existence of the metadata host. Only fetch_credentials
103-
# if we can find the host. Ping logic taken from
104-
# http://stackoverflow.com/questions/7519159/ruby-ping-pingecho-missing
103+
# if we can find the host.
105104
def iam_creds
106105
require 'net/http'
107106
require 'timeout'
@@ -110,7 +109,7 @@ def iam_creds
110109
Net::HTTP.get(URI.parse('http://169.254.169.254'))
111110
end
112111
fetch_credentials(use_iam_profile: true)
113-
rescue Errno::EHOSTUNREACH, Timeout::Error, NoMethodError, ::StandardError => e
112+
rescue Errno::EHOSTUNREACH, Errno::EHOSTDOWN, Timeout::Error, NoMethodError, ::StandardError => e
114113
debug("fetch_credentials failed with exception #{e.message}:#{e.backtrace.join("\n")}")
115114
{}
116115
end
@@ -176,14 +175,20 @@ def default_public_ip_association
176175
!!config[:subnet_id]
177176
end
178177

178+
# If running on an EC2 node there are 3 possible scenarios:
179+
# 1) The user has supplied the session token as an environment variable
180+
# 2) The user has manually set access key/secret - don't use the session token from
181+
# the metadata service, only auth with key/secret supplied
182+
# 3) The user has not set the access key/secret - because we default these values
183+
# we cannot tell if these have not been set. So we do our best guess by checking
184+
# if the current value is the same as what is returned from the metadata service.
185+
# If they are the same we assume no user values have been set and we use the
186+
# metadata service values.
179187
def default_aws_session_token
180188
env = ENV['AWS_SESSION_TOKEN'] || ENV['AWS_TOKEN']
181-
if config[:aws_secret_access_key] == iam_creds[:aws_secret_access_key] \
182-
&& config[:aws_access_key_id] == iam_creds[:aws_access_key_id]
183-
env || iam_creds[:aws_session_token]
184-
else
185-
env
186-
end
189+
env ||= iam_creds[:aws_session_token] if config[:aws_secret_access_key] == iam_creds[:aws_secret_access_key] &&
190+
config[:aws_access_key_id] == iam_creds[:aws_access_key_id]
191+
env
187192
end
188193

189194
private

spec/create_spec.rb

+68-91
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,51 @@
33

44
describe Kitchen::Driver::Ec2 do
55

6-
let(:config) do
7-
{
8-
aws_ssh_key_id: 'larry',
9-
aws_access_key_id: 'secret',
10-
aws_secret_access_key: 'moarsecret',
11-
user_data: nil
12-
}
13-
end
6+
let(:config) do
7+
{
8+
aws_ssh_key_id: 'larry',
9+
aws_access_key_id: 'secret',
10+
aws_secret_access_key: 'moarsecret',
11+
user_data: nil
12+
}
13+
end
1414

15-
let(:state) do
16-
{}
17-
end
15+
let(:state) do
16+
{}
17+
end
1818

19-
let(:server) do
20-
double(
21-
:id => "123",
22-
:wait_for => nil,
23-
:dns_name => "server.example.com",
24-
:private_ip_address => '172.13.16.11',
25-
:public_ip_address => '213.225.123.134'
26-
)
27-
end
19+
let(:server) do
20+
double(
21+
:id => "123",
22+
:wait_for => nil,
23+
:dns_name => "server.example.com",
24+
:private_ip_address => '172.13.16.11',
25+
:public_ip_address => '213.225.123.134'
26+
)
27+
end
2828

29-
let(:instance) do
30-
Kitchen::Instance.new(
31-
:platform => double(:name => "centos-6.4"),
32-
:suite => double(:name => "default"),
33-
:driver => driver,
34-
:provisioner => Kitchen::Provisioner::Dummy.new({}),
35-
:busser => double("busser"),
36-
:state_file => double("state_file")
37-
)
38-
end
29+
let(:instance) do
30+
Kitchen::Instance.new(
31+
:platform => double(:name => "centos-6.4"),
32+
:suite => double(:name => "default"),
33+
:driver => driver,
34+
:provisioner => Kitchen::Provisioner::Dummy.new({}),
35+
:busser => double("busser"),
36+
:state_file => double("state_file")
37+
)
38+
end
3939

40-
let(:driver) do
41-
Kitchen::Driver::Ec2.new(config)
42-
end
40+
let(:driver) do
41+
Kitchen::Driver::Ec2.new(config)
42+
end
4343

44-
let(:iam_creds) do
45-
{
46-
aws_access_key_id: 'iam_creds_access_key',
47-
aws_secret_access_key: 'iam_creds_secret_access_key',
48-
aws_session_token: 'iam_creds_session_token'
49-
}
50-
end
44+
let(:iam_creds) do
45+
{
46+
aws_access_key_id: 'iam_creds_access_key',
47+
aws_secret_access_key: 'iam_creds_secret_access_key',
48+
aws_session_token: 'iam_creds_session_token'
49+
}
50+
end
5151

5252
context 'Interface is set in config' do
5353
before do
@@ -160,46 +160,45 @@
160160
end
161161

162162
context 'but they should not be used' do
163-
context 'because :aws_access_key_id is set but not via #iam_creds' do
163+
shared_examples ':aws_session_token not set' do
164+
it 'does not set :aws_session_token via #iam_creds' do
165+
expect(driver[:aws_session_token]).to_not eq(iam_creds[:aws_session_token])
166+
end
167+
end
168+
context 'because :aws_access_key_id is set from config' do
164169
let(:aws_access_key_id) { 'secret' }
165170
before do
166171
config[:aws_access_key_id] = aws_access_key_id
167172
end
168173

169174
it 'does not override :aws_access_key_id' do
170-
expect(driver.send(:config)[:aws_access_key_id]).to eq(aws_access_key_id)
175+
expect(driver[:aws_access_key_id]).to eq(aws_access_key_id)
171176
end
172177

173-
it 'does not set :aws_session_token via #iam_creds' do
174-
expect(driver.send(:config)[:aws_session_token])
175-
.to_not eq(iam_creds[:aws_session_token])
176-
end
178+
include_examples ':aws_session_token not set'
177179
end
178180

179-
context 'because :aws_secret_access_key is set but not via #iam_creds' do
181+
context 'because :aws_secret_access_key is set from config' do
180182
let(:aws_secret_access_key) { 'moarsecret' }
181183

182184
before do
183185
config[:aws_secret_access_key] = aws_secret_access_key
184186
end
185187

186188
it 'does not override :aws_secret_access_key' do
187-
expect(driver.send(:config)[:aws_secret_access_key]).to eq(aws_secret_access_key)
189+
expect(driver[:aws_secret_access_key]).to eq(aws_secret_access_key)
188190
end
189191

190-
it 'does not set :aws_session_token via #iam_creds' do
191-
expect(driver.send(:config)[:aws_session_token])
192-
.to_not eq(iam_creds[:aws_session_token])
193-
end
192+
include_examples ':aws_session_token not set'
194193
end
195194

196-
context 'because :aws_session_token is set but not via #iam_creds' do
195+
context 'because :aws_session_token is set from config' do
197196
let(:aws_session_token) { 'adifferentsessiontoken' }
198197
before do
199198
config[:aws_session_token] = aws_session_token
200199
end
201200
it 'does not override :aws_session_token' do
202-
expect(driver.send(:config)[:aws_session_token]).to eq('adifferentsessiontoken')
201+
expect(driver[:aws_session_token]).to eq('adifferentsessiontoken')
203202
end
204203
end
205204
end
@@ -213,15 +212,15 @@
213212
end
214213

215214
it 'uses :aws_access_key_id from iam_creds' do
216-
expect(driver.send(:config)[:aws_access_key_id]).to eq(iam_creds[:aws_access_key_id])
215+
expect(driver[:aws_access_key_id]).to eq(iam_creds[:aws_access_key_id])
217216
end
218217

219218
it 'uses :aws_secret_key_id from iam_creds' do
220-
expect(driver.send(:config)[:aws_secret_key_id]).to eq(iam_creds[:aws_secret_key_id])
219+
expect(driver[:aws_secret_key_id]).to eq(iam_creds[:aws_secret_key_id])
221220
end
222221

223222
it 'uses :aws_session_token from iam_creds' do
224-
expect(driver.send(:config)[:aws_session_token]).to eq(iam_creds[:aws_session_token])
223+
expect(driver[:aws_session_token]).to eq(iam_creds[:aws_session_token])
225224
end
226225
end
227226
end
@@ -239,44 +238,22 @@
239238
end
240239
end
241240

242-
context 'when #fetch_credentials fails with NoMethodError' do
243-
it 'returns an empty hash' do
244-
allow(driver).to receive(:fetch_credentials).and_raise(NoMethodError)
245-
expect { driver.fetch_credentials }.to raise_error(NoMethodError)
246-
expect(driver.iam_creds).to eq({})
247-
end
248-
end
249-
250-
context 'when #fetch_credentials fails with ::StandardError' do
251-
it 'returns an empty hash' do
252-
allow(driver).to receive(:fetch_credentials).and_raise(::StandardError)
253-
expect { driver.fetch_credentials }.to raise_error(::StandardError)
254-
expect(driver.iam_creds).to eq({})
255-
end
256-
end
257-
258-
context 'when #fetch_credentials fails with Errno::EHOSTUNREACH' do
259-
it 'returns an empty hash' do
260-
allow(driver).to receive(:fetch_credentials).and_raise(Errno::EHOSTUNREACH)
261-
expect { driver.fetch_credentials }.to raise_error(Errno::EHOSTUNREACH)
262-
expect(driver.iam_creds).to eq({})
263-
end
264-
end
265-
266-
context 'when #fetch_credentials fails with Timeout::Error' do
267-
it 'returns an empty hash' do
268-
allow(driver).to receive(:fetch_credentials).and_raise(Timeout::Error)
269-
expect { driver.fetch_credentials }.to raise_error(Timeout::Error)
270-
expect(driver.iam_creds).to eq({})
241+
errors = [NoMethodError, StandardError, Errno::EHOSTUNREACH, Errno::EHOSTDOWN]
242+
errors.each do |e|
243+
context "when #fetch_credentials fails with #{e}" do
244+
it 'returns an empty hash' do
245+
expect(driver).to receive(:fetch_credentials).and_raise(e)
246+
expect(driver.iam_creds).to eq({})
247+
end
271248
end
272249
end
273250
end
274251

275-
context 'when a metadata service is not available' do
276-
it 'will not call #fetch_credentials' do
277-
allow(Net::HTTP).to receive(:get)
278-
.with(URI.parse('http://169.254.169.254')).and_return(false)
279-
expect(driver).to_not receive(:fetch_credentials)
252+
context 'when Net::HTTP#get fails with Timeout::Error' do
253+
it 'returns an empty hash' do
254+
expect(Net::HTTP).to receive(:get)
255+
.with(URI.parse('http://169.254.169.254')).and_raise(Timeout::Error)
256+
expect(driver.iam_creds).to eq({})
280257
end
281258
end
282259
end

0 commit comments

Comments
 (0)