kitchen-ec2 0.9.0 → 0.9.1
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 +4 -4
- data/.rubocop.yml +6 -0
- data/CHANGELOG.md +17 -1
- data/lib/kitchen/driver/aws/instance_generator.rb +8 -3
- data/lib/kitchen/driver/ec2.rb +21 -12
- data/lib/kitchen/driver/ec2_version.rb +1 -1
- data/spec/kitchen/driver/ec2/instance_generator_spec.rb +49 -5
- data/spec/kitchen/driver/ec2_spec.rb +81 -1
- 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: 63b191e76f8a9ca14b90f8fbccbdfd1ce3f331b6
|
|
4
|
+
data.tar.gz: 852a2dc5b108ecb0cef3f27c65162e9716e938c3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1e9ac692d5b4d8f9b60633f5eb890bc70efb773fe4980e2478e6743b8dfbba2b7ac713f428f0bc5875da292ea8f6efc62dd4108fce061621d212d12b41be7971
|
|
7
|
+
data.tar.gz: 827a0183547e2c3f24202711edf9a14b4f17663e677a13915230896076cb08b1cc065107c1ee42dbe3bf395b6715aaa9cab6928bdd245ac3201db19cac4c10eb
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 0.9.1 / 2015-05-21
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* Pull Request [#124][]: AWS SDK V2 returns `instance.public_dns_name` as empty string instead of nil, and we were only checking for nil. Caused timeouts trying to connect. ([@tyler-ball][])
|
|
6
|
+
* Fixed regression: Adding back `interface` config value that I accidently removed, code is now in line with README.
|
|
7
|
+
* Pull Request [#125][]: When specifying `associate_public_ip` we must send the subnet (if provided) in the `network_interfaces` section of the payload instead of the main section. ([@tyler-ball][])
|
|
8
|
+
* Fixed regression: Accidently renamed config `associate_public_ip` to `associate_public_ip_address`, reverting.
|
|
9
|
+
* Fixed regression: Accidently renamed config `iam_profile_name` to `iam_instance_profile`, reverting.
|
|
10
|
+
|
|
11
|
+
### New Features
|
|
12
|
+
|
|
13
|
+
### Improvements
|
|
14
|
+
|
|
1
15
|
## 0.9.0 / 2015-05-18
|
|
2
16
|
|
|
3
17
|
### Bug Fixes
|
|
@@ -110,6 +124,8 @@
|
|
|
110
124
|
[#107]: https://github.com/test-kitchen/kitchen-ec2/issues/107
|
|
111
125
|
[#110]: https://github.com/test-kitchen/kitchen-ec2/issues/110
|
|
112
126
|
[#112]: https://github.com/test-kitchen/kitchen-ec2/issues/112
|
|
127
|
+
[#124]: https://github.com/test-kitchen/kitchen-ec2/issues/124
|
|
128
|
+
[#125]: https://github.com/test-kitchen/kitchen-ec2/issues/125
|
|
113
129
|
[@Atalanta]: https://github.com/Atalanta
|
|
114
130
|
[@Igorshp]: https://github.com/Igorshp
|
|
115
131
|
[@JamesAwesome]: https://github.com/JamesAwesome
|
|
@@ -136,4 +152,4 @@
|
|
|
136
152
|
[@someara]: https://github.com/someara
|
|
137
153
|
[@spheromak]: https://github.com/spheromak
|
|
138
154
|
[@tiwilliam]: https://github.com/tiwilliam
|
|
139
|
-
[@tyler-ball]: https://github.com/tyler-ball
|
|
155
|
+
[@tyler-ball]: https://github.com/tyler-ball
|
|
@@ -55,15 +55,20 @@ module Kitchen
|
|
|
55
55
|
i[:block_device_mappings] = block_device_mappings unless block_device_mappings.empty?
|
|
56
56
|
i[:security_group_ids] = config[:security_group_ids] if config[:security_group_ids]
|
|
57
57
|
i[:user_data] = prepared_user_data if prepared_user_data
|
|
58
|
-
if config[:
|
|
58
|
+
if config[:iam_profile_name]
|
|
59
59
|
i[:iam_instance_profile] = { :name => config[:iam_profile_name] }
|
|
60
60
|
end
|
|
61
|
-
if !config.fetch(:
|
|
61
|
+
if !config.fetch(:associate_public_ip, nil).nil?
|
|
62
62
|
i[:network_interfaces] =
|
|
63
63
|
[{
|
|
64
64
|
:device_index => 0,
|
|
65
|
-
:associate_public_ip_address => config[:
|
|
65
|
+
:associate_public_ip_address => config[:associate_public_ip]
|
|
66
66
|
}]
|
|
67
|
+
# If specifying `:network_interfaces` in the request, you must specify the
|
|
68
|
+
# subnet_id in the network_interfaces block and not at the top level
|
|
69
|
+
if config[:subnet_id]
|
|
70
|
+
i[:network_interfaces][0][:subnet_id] = i.delete(:subnet_id)
|
|
71
|
+
end
|
|
67
72
|
end
|
|
68
73
|
i
|
|
69
74
|
end
|
data/lib/kitchen/driver/ec2.rb
CHANGED
|
@@ -20,9 +20,10 @@ require "benchmark"
|
|
|
20
20
|
require "json"
|
|
21
21
|
require "aws"
|
|
22
22
|
require "kitchen"
|
|
23
|
-
|
|
23
|
+
require_relative "ec2_version"
|
|
24
24
|
require_relative "aws/client"
|
|
25
25
|
require_relative "aws/instance_generator"
|
|
26
|
+
require "aws-sdk-core/waiters/errors"
|
|
26
27
|
|
|
27
28
|
module Kitchen
|
|
28
29
|
|
|
@@ -60,6 +61,7 @@ module Kitchen
|
|
|
60
61
|
end
|
|
61
62
|
default_config :username, nil
|
|
62
63
|
default_config :associate_public_ip, nil
|
|
64
|
+
default_config :interface, nil
|
|
63
65
|
|
|
64
66
|
required_config :aws_ssh_key_id
|
|
65
67
|
required_config :image_id
|
|
@@ -194,14 +196,21 @@ module Kitchen
|
|
|
194
196
|
t = config[:retryable_tries] * config[:retryable_sleep]
|
|
195
197
|
info "Waited #{c}/#{t}s for instance <#{state[:server_id]}> to become ready."
|
|
196
198
|
end
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
199
|
+
begin
|
|
200
|
+
server = server.wait_until(
|
|
201
|
+
:max_attempts => config[:retryable_tries],
|
|
202
|
+
:delay => config[:retryable_sleep],
|
|
203
|
+
:before_attempt => wait_log
|
|
204
|
+
) do |s|
|
|
205
|
+
hostname = hostname(s, config[:interface])
|
|
206
|
+
# Euca instances often report ready before they have an IP
|
|
207
|
+
s.exists? && s.state.name == "running" && !hostname.nil? && hostname != "0.0.0.0"
|
|
208
|
+
end
|
|
209
|
+
rescue ::Aws::Waiters::Errors::WaiterFailed
|
|
210
|
+
error("Ran out of time waiting for the server with id [#{state[:server_id]}]" \
|
|
211
|
+
" to become ready, attempting to destroy it")
|
|
212
|
+
destroy(state)
|
|
213
|
+
raise
|
|
205
214
|
end
|
|
206
215
|
|
|
207
216
|
info("EC2 instance <#{state[:server_id]}> ready.")
|
|
@@ -217,7 +226,7 @@ module Kitchen
|
|
|
217
226
|
server = ec2.get_instance(state[:server_id])
|
|
218
227
|
unless server.nil?
|
|
219
228
|
instance.transport.connection(state).close
|
|
220
|
-
server.terminate
|
|
229
|
+
server.terminate
|
|
221
230
|
end
|
|
222
231
|
if state[:spot_request_id]
|
|
223
232
|
debug("Deleting spot request <#{state[:server_id]}>")
|
|
@@ -235,8 +244,6 @@ module Kitchen
|
|
|
235
244
|
region && region[instance.platform.name]
|
|
236
245
|
end
|
|
237
246
|
|
|
238
|
-
private
|
|
239
|
-
|
|
240
247
|
def ec2
|
|
241
248
|
@ec2 ||= Aws::Client.new(
|
|
242
249
|
config[:region],
|
|
@@ -354,6 +361,8 @@ module Kitchen
|
|
|
354
361
|
potential_hostname = nil
|
|
355
362
|
INTERFACE_TYPES.values.each do |type|
|
|
356
363
|
potential_hostname ||= server.send(type)
|
|
364
|
+
# AWS returns an empty string if the dns name isn't populated yet
|
|
365
|
+
potential_hostname = nil if potential_hostname == ""
|
|
357
366
|
end
|
|
358
367
|
potential_hostname
|
|
359
368
|
end
|
|
@@ -244,6 +244,47 @@ describe Kitchen::Driver::Aws::InstanceGenerator do
|
|
|
244
244
|
end
|
|
245
245
|
end
|
|
246
246
|
|
|
247
|
+
context "when subnet_id is provided" do
|
|
248
|
+
let(:config) do
|
|
249
|
+
{
|
|
250
|
+
:subnet_id => "s-456"
|
|
251
|
+
}
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it "adds a network_interfaces block" do
|
|
255
|
+
expect(generator.ec2_instance_data).to eq(
|
|
256
|
+
:placement => { :availability_zone => nil },
|
|
257
|
+
:instance_type => nil,
|
|
258
|
+
:ebs_optimized => nil,
|
|
259
|
+
:image_id => nil,
|
|
260
|
+
:key_name => nil,
|
|
261
|
+
:subnet_id => "s-456",
|
|
262
|
+
:private_ip_address => nil
|
|
263
|
+
)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
context "when associate_public_ip is provided" do
|
|
268
|
+
let(:config) do
|
|
269
|
+
{
|
|
270
|
+
:associate_public_ip => true
|
|
271
|
+
}
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it "adds a network_interfaces block" do
|
|
275
|
+
expect(generator.ec2_instance_data).to eq(
|
|
276
|
+
:placement => { :availability_zone => nil },
|
|
277
|
+
:instance_type => nil,
|
|
278
|
+
:ebs_optimized => nil,
|
|
279
|
+
:image_id => nil,
|
|
280
|
+
:key_name => nil,
|
|
281
|
+
:subnet_id => nil,
|
|
282
|
+
:private_ip_address => nil,
|
|
283
|
+
:network_interfaces => [{ :device_index => 0, :associate_public_ip_address => true }]
|
|
284
|
+
)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
247
288
|
context "when provided the maximum config" do
|
|
248
289
|
let(:config) do
|
|
249
290
|
{
|
|
@@ -266,8 +307,8 @@ describe Kitchen::Driver::Aws::InstanceGenerator do
|
|
|
266
307
|
],
|
|
267
308
|
:security_group_ids => ["sg-789"],
|
|
268
309
|
:user_data => "foo",
|
|
269
|
-
:
|
|
270
|
-
:
|
|
310
|
+
:iam_profile_name => "iam-123",
|
|
311
|
+
:associate_public_ip => true
|
|
271
312
|
}
|
|
272
313
|
end
|
|
273
314
|
|
|
@@ -278,7 +319,6 @@ describe Kitchen::Driver::Aws::InstanceGenerator do
|
|
|
278
319
|
:ebs_optimized => true,
|
|
279
320
|
:image_id => "ami-123",
|
|
280
321
|
:key_name => "key",
|
|
281
|
-
:subnet_id => "s-456",
|
|
282
322
|
:private_ip_address => "0.0.0.0",
|
|
283
323
|
:block_device_mappings => [
|
|
284
324
|
{
|
|
@@ -292,8 +332,12 @@ describe Kitchen::Driver::Aws::InstanceGenerator do
|
|
|
292
332
|
:virtual_name => "test"
|
|
293
333
|
}
|
|
294
334
|
],
|
|
295
|
-
:iam_instance_profile => { :name =>
|
|
296
|
-
:network_interfaces => [{
|
|
335
|
+
:iam_instance_profile => { :name => "iam-123" },
|
|
336
|
+
:network_interfaces => [{
|
|
337
|
+
:device_index => 0,
|
|
338
|
+
:associate_public_ip_address => true,
|
|
339
|
+
:subnet_id => "s-456"
|
|
340
|
+
}],
|
|
297
341
|
:security_group_ids => ["sg-789"],
|
|
298
342
|
:user_data => "foo"
|
|
299
343
|
)
|
|
@@ -71,7 +71,7 @@ describe Kitchen::Driver::Ec2 do
|
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
describe "finalize_config!" do
|
|
74
|
+
describe "#finalize_config!" do
|
|
75
75
|
it "defaults the availability zone if not provided" do
|
|
76
76
|
expect(config[:availability_zone]).to eq(nil)
|
|
77
77
|
driver.finalize_config!(instance)
|
|
@@ -79,4 +79,84 @@ describe Kitchen::Driver::Ec2 do
|
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
81
|
|
|
82
|
+
describe "#hostname" do
|
|
83
|
+
let(:public_dns_name) { nil }
|
|
84
|
+
let(:public_ip_address) { nil }
|
|
85
|
+
let(:private_ip_address) { nil }
|
|
86
|
+
let(:server) {
|
|
87
|
+
double("server",
|
|
88
|
+
:public_dns_name => public_dns_name,
|
|
89
|
+
:public_ip_address => public_ip_address,
|
|
90
|
+
:private_ip_address => private_ip_address
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
it "returns nil if all sources are nil" do
|
|
95
|
+
expect(driver.hostname(server)).to eq(nil)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "raises an error if provided an unknown interface" do
|
|
99
|
+
expect { driver.hostname(server, "foobar") }.to raise_error(Kitchen::UserError)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
shared_examples "an interface type provided" do
|
|
103
|
+
it "returns public_dns_name when requested" do
|
|
104
|
+
expect(driver.hostname(server, "dns")).to eq(public_dns_name)
|
|
105
|
+
end
|
|
106
|
+
it "returns public_ip_address when requested" do
|
|
107
|
+
expect(driver.hostname(server, "public")).to eq(public_ip_address)
|
|
108
|
+
end
|
|
109
|
+
it "returns private_ip_address when requested" do
|
|
110
|
+
expect(driver.hostname(server, "private")).to eq(private_ip_address)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
context "private_ip_address is populated" do
|
|
115
|
+
let(:private_ip_address) { "10.0.0.1" }
|
|
116
|
+
|
|
117
|
+
it "returns the private_ip_address" do
|
|
118
|
+
expect(driver.hostname(server)).to eq(private_ip_address)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
include_examples "an interface type provided"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context "public_ip_address is populated" do
|
|
125
|
+
let(:private_ip_address) { "10.0.0.1" }
|
|
126
|
+
let(:public_ip_address) { "127.0.0.1" }
|
|
127
|
+
|
|
128
|
+
it "returns the public_ip_address" do
|
|
129
|
+
expect(driver.hostname(server)).to eq(public_ip_address)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
include_examples "an interface type provided"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context "public_dns_name is populated" do
|
|
136
|
+
let(:private_ip_address) { "10.0.0.1" }
|
|
137
|
+
let(:public_ip_address) { "127.0.0.1" }
|
|
138
|
+
let(:public_dns_name) { "public_dns_name" }
|
|
139
|
+
|
|
140
|
+
it "returns the public_dns_name" do
|
|
141
|
+
expect(driver.hostname(server)).to eq(public_dns_name)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
include_examples "an interface type provided"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
context "public_dns_name returns as empty string" do
|
|
148
|
+
let(:public_dns_name) { "" }
|
|
149
|
+
it "returns nil" do
|
|
150
|
+
expect(driver.hostname(server)).to eq(nil)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context "and private_ip_address is populated" do
|
|
154
|
+
let(:private_ip_address) { "10.0.0.1" }
|
|
155
|
+
it "returns the private_ip_address" do
|
|
156
|
+
expect(driver.hostname(server)).to eq(private_ip_address)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
82
162
|
end
|
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: 0.9.
|
|
4
|
+
version: 0.9.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Fletcher Nichol
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-05-
|
|
11
|
+
date: 2015-05-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: test-kitchen
|