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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b12924746e2f87674fd4988de55bce1d30507be4
4
- data.tar.gz: 7fbbd13c4e9810f0aad3d15bff357291cd808695
3
+ metadata.gz: 63b191e76f8a9ca14b90f8fbccbdfd1ce3f331b6
4
+ data.tar.gz: 852a2dc5b108ecb0cef3f27c65162e9716e938c3
5
5
  SHA512:
6
- metadata.gz: 67561dd868c1a2e8664f99791b62c237b9dc698ed17d587c0f10ce83ad61713a166742d7b50679d93423acf23f5fbecd55e20eaf8d68f3519106af1ecc5d21b7
7
- data.tar.gz: db02d3bd6413b7a35e6a843ebced5eba8e54c939462966aee92b87881907e81ad314c4df6839633b912c3b33ad60777fa6cc9ce44864a729b27aec749eb37745
6
+ metadata.gz: 1e9ac692d5b4d8f9b60633f5eb890bc70efb773fe4980e2478e6743b8dfbba2b7ac713f428f0bc5875da292ea8f6efc62dd4108fce061621d212d12b41be7971
7
+ data.tar.gz: 827a0183547e2c3f24202711edf9a14b4f17663e677a13915230896076cb08b1cc065107c1ee42dbe3bf395b6715aaa9cab6928bdd245ac3201db19cac4c10eb
data/.rubocop.yml CHANGED
@@ -7,3 +7,9 @@ Style/Next:
7
7
 
8
8
  Style/DoubleNegation:
9
9
  Enabled: false
10
+
11
+ Metrics/CyclomaticComplexity:
12
+ Max: 30
13
+
14
+ Metrics/PerceivedComplexity:
15
+ Max: 30
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[:iam_instance_profile]
58
+ if config[:iam_profile_name]
59
59
  i[:iam_instance_profile] = { :name => config[:iam_profile_name] }
60
60
  end
61
- if !config.fetch(:associate_public_ip_address, nil).nil?
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[:associate_public_ip_address]
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
@@ -20,9 +20,10 @@ require "benchmark"
20
20
  require "json"
21
21
  require "aws"
22
22
  require "kitchen"
23
- require "kitchen/driver/ec2_version"
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
- server = server.wait_until(
198
- :max_attempts => config[:retryable_tries],
199
- :delay => config[:retryable_sleep],
200
- :before_attempt => wait_log
201
- ) do |s|
202
- hostname = hostname(s)
203
- # Euca instances often report ready before they have an IP
204
- s.state.name == "running" && !hostname.nil? && hostname != "0.0.0.0"
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 unless server.nil?
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
@@ -21,6 +21,6 @@ module Kitchen
21
21
  module Driver
22
22
 
23
23
  # Version string for EC2 Test Kitchen driver
24
- EC2_VERSION = "0.9.0"
24
+ EC2_VERSION = "0.9.1"
25
25
  end
26
26
  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
- :iam_instance_profile => "iam-123",
270
- :associate_public_ip_address => true
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 => nil },
296
- :network_interfaces => [{ :device_index => 0, :associate_public_ip_address => true }],
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.0
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-19 00:00:00.000000000 Z
11
+ date: 2015-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-kitchen