kitchen-ec2 3.2.0 → 3.7.0

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
  SHA256:
3
- metadata.gz: 828a479cf1ebe8de5423fad1926bc74f1cb66ddc1a1b4f853977424e65dd4709
4
- data.tar.gz: 67851982c4d376be9ca701040e38d8e7b5cb308a7cf52cd0056da8f898558dcd
3
+ metadata.gz: 0d6429e51c08d43c0e1084b9acc55b76feacae05bbe42b7cf3a1e35e0de70f87
4
+ data.tar.gz: 9f2a0adbe2866ad6a267ab8adc14d24a890b22b71b0abe272808a2a52def3933
5
5
  SHA512:
6
- metadata.gz: 1165fa8225401552970c19983091d8cb38f234a08f9f84a68ebb45cdf05b5670271e92b780b9e8fa0fdecc1c18083e3702f3ddace3561a76628226d09f67ce26
7
- data.tar.gz: abe70ab29dacefda005ec11ffa0710841532e7f8407c203daf6bd782acb1c1da59d95c1c188bfca81cc20bd010d2ce7df5c6e78371eff0960f46dcbf3c885245
6
+ metadata.gz: aa308480b37d109ec173851aefe0098523d2a59c06481e88004bf76ccb8d87dfbd865300d2383157af13b38af47588ec2d1adf0541734f7279669a8dbcb0b673
7
+ data.tar.gz: 48f6f1a3dc22caf5d04079ef1579c19850e7e72558708e633537adb752969c3aac1b79702804864fac3fad9140e8d9053347c3ecde47e578e0545366d0b0b619
@@ -49,14 +49,24 @@ module Kitchen
49
49
  ::Aws.config.update(retry_limit: retry_limit) unless retry_limit.nil?
50
50
  end
51
51
 
52
+ # create a new AWS EC2 instance
53
+ # @param options [Hash] has of instance options
54
+ # @see https://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Resource.html#create_instances-instance_method
55
+ # @return [Aws::EC2::Instance]
52
56
  def create_instance(options)
53
57
  resource.create_instances(options).first
54
58
  end
55
59
 
60
+ # get an instance object given an id
61
+ # @param id [String] aws instance id
62
+ # @return [Aws::EC2::Instance]
56
63
  def get_instance(id)
57
64
  resource.instance(id)
58
65
  end
59
66
 
67
+ # get an instance object given a spot request ID
68
+ # @param request_id [String] aws spot instance id
69
+ # @return [Aws::EC2::Instance]
60
70
  def get_instance_from_spot_request(request_id)
61
71
  resource.instances(
62
72
  filters: [{
@@ -39,29 +39,34 @@ module Kitchen
39
39
  @logger = logger
40
40
  end
41
41
 
42
- # Transform the provided config into the hash to send to AWS. Some fields
42
+ # Transform the provided kitchen config into the hash we'll use to create the aws instance
43
43
  # can be passed in null, others need to be ommitted if they are null
44
+ # Some fields can be passed in null, others need to be ommitted if they are null
45
+ # @return [Hash]
44
46
  def ec2_instance_data # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
45
47
  # Support for looking up security group id and subnet id using tags.
46
-
48
+ vpc_id = nil
49
+ client = ::Aws::EC2::Client.new(region: config[:region])
47
50
  if config[:subnet_id].nil? && config[:subnet_filter]
48
- config[:subnet_id] = ::Aws::EC2::Client
49
- .new(region: config[:region]).describe_subnets(
50
- filters: [
51
- {
52
- name: "tag:#{config[:subnet_filter][:tag]}",
53
- values: [config[:subnet_filter][:value]],
54
- },
55
- ]
56
- )[0][0].subnet_id
57
-
58
- if config[:subnet_id].nil?
59
- raise "The subnet tagged '#{config[:subnet_filter][:tag]}\
60
- #{config[:subnet_filter][:value]}' does not exist!"
61
- end
51
+ subnets = client.describe_subnets(
52
+ filters: [
53
+ {
54
+ name: "tag:#{config[:subnet_filter][:tag]}",
55
+ values: [config[:subnet_filter][:value]],
56
+ },
57
+ ]
58
+ ).subnets
59
+ raise "The subnet tagged '#{config[:subnet_filter][:tag]}:#{config[:subnet_filter][:value]}' does not exist!" unless subnets.any?
60
+
61
+ # => Select the least-populated subnet if we have multiple matches
62
+ subnet = subnets.sort_by { |s| s[:available_ip_address_count] }.last
63
+ vpc_id = subnet.vpc_id
64
+ config[:subnet_id] = subnet.subnet_id
62
65
  end
63
66
 
64
67
  if config[:security_group_ids].nil? && config[:security_group_filter]
68
+ # => Grab the VPC in the case a Subnet ID rather than Filter was set
69
+ vpc_id ||= client.describe_subnets(subnet_ids: [config[:subnet_id]]).subnets[0].vpc_id
65
70
  security_groups = []
66
71
  filters = [config[:security_group_filter]].flatten
67
72
  filters.each do |sg_filter|
@@ -72,6 +77,10 @@ module Kitchen
72
77
  name: "group-name",
73
78
  values: [sg_filter[:name]],
74
79
  },
80
+ {
81
+ name: "vpc-id",
82
+ values: [vpc_id],
83
+ },
75
84
  ]
76
85
  end
77
86
 
@@ -81,13 +90,17 @@ module Kitchen
81
90
  name: "tag:#{sg_filter[:tag]}",
82
91
  values: [sg_filter[:value]],
83
92
  },
93
+ {
94
+ name: "vpc-id",
95
+ values: [vpc_id],
96
+ },
84
97
  ]
85
98
  end
86
99
 
87
- security_group = ::Aws::EC2::Client.new(region: config[:region]).describe_security_groups(r)[0][0]
100
+ security_group = client.describe_security_groups(r).security_groups
88
101
 
89
- if security_group
90
- security_groups.push(security_group.group_id)
102
+ if security_group.any?
103
+ security_group.each { |sg| security_groups.push(sg.group_id) }
91
104
  else
92
105
  raise "A Security Group matching the following filter could not be found:\n#{sg_filter}"
93
106
  end
@@ -102,8 +115,22 @@ module Kitchen
102
115
  key_name: config[:aws_ssh_key_id],
103
116
  subnet_id: config[:subnet_id],
104
117
  private_ip_address: config[:private_ip_address],
118
+ min_count: 1,
119
+ max_count: 1,
105
120
  }
106
121
 
122
+ if config[:tags] && !config[:tags].empty?
123
+ tags = config[:tags].map do |k, v|
124
+ # we convert the value to a string because
125
+ # nils should be passed as an empty String
126
+ # and Integers need to be represented as Strings
127
+ { key: k, value: v.to_s }
128
+ end
129
+ instance_tag_spec = { resource_type: "instance", tags: tags }
130
+ volume_tag_spec = { resource_type: "volume", tags: tags }
131
+ i[:tag_specifications] = [instance_tag_spec, volume_tag_spec]
132
+ end
133
+
107
134
  availability_zone = config[:availability_zone]
108
135
  if availability_zone
109
136
  if availability_zone =~ /^[a-z]$/i
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "kitchen/driver/aws/standard_platform"
16
+ require_relative "../standard_platform"
17
17
 
18
18
  module Kitchen
19
19
  module Driver
@@ -23,6 +23,8 @@ module Kitchen
23
23
  class Amazon < StandardPlatform
24
24
  StandardPlatform.platforms["amazon"] = self
25
25
 
26
+ # default username for this platform's ami
27
+ # @return [String]
26
28
  def username
27
29
  "ec2-user"
28
30
  end
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "kitchen/driver/aws/standard_platform"
16
+ require_relative "../standard_platform"
17
17
 
18
18
  module Kitchen
19
19
  module Driver
@@ -23,6 +23,8 @@ module Kitchen
23
23
  class Amazon2 < StandardPlatform
24
24
  StandardPlatform.platforms["amazon2"] = self
25
25
 
26
+ # default username for this platform's ami
27
+ # @return [String]
26
28
  def username
27
29
  "ec2-user"
28
30
  end
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "kitchen/driver/aws/standard_platform"
16
+ require_relative "../standard_platform"
17
17
 
18
18
  module Kitchen
19
19
  module Driver
@@ -23,6 +23,8 @@ module Kitchen
23
23
  class Centos < StandardPlatform
24
24
  StandardPlatform.platforms["centos"] = self
25
25
 
26
+ # default username for this platform's ami
27
+ # @return [String]
26
28
  def username
27
29
  # Centos 6.x images use root as the username (but the "centos 6"
28
30
  # updateable image uses "centos")
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "kitchen/driver/aws/standard_platform"
16
+ require_relative "../standard_platform"
17
17
 
18
18
  module Kitchen
19
19
  module Driver
@@ -26,14 +26,17 @@ module Kitchen
26
26
  # 10/11 are listed last since we default to the first item in the hash
27
27
  # and 10/11 are not released yet. When they're released move them up
28
28
  DEBIAN_CODENAMES = {
29
+ 10 => "buster",
29
30
  9 => "stretch",
30
31
  8 => "jessie",
31
32
  7 => "wheezy",
32
33
  6 => "squeeze",
33
34
  11 => "bullseye",
34
- 10 => "buster",
35
+ 12 => "bookworm",
35
36
  }.freeze
36
37
 
38
+ # default username for this platform's ami
39
+ # @return [String]
37
40
  def username
38
41
  "admin"
39
42
  end
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "kitchen/driver/aws/standard_platform"
16
+ require_relative "../standard_platform"
17
17
 
18
18
  module Kitchen
19
19
  module Driver
@@ -23,6 +23,8 @@ module Kitchen
23
23
  class Fedora < StandardPlatform
24
24
  StandardPlatform.platforms["fedora"] = self
25
25
 
26
+ # default username for this platform's ami
27
+ # @return [String]
26
28
  def username
27
29
  "fedora"
28
30
  end
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "kitchen/driver/aws/standard_platform"
16
+ require_relative "../standard_platform"
17
17
 
18
18
  module Kitchen
19
19
  module Driver
@@ -23,6 +23,8 @@ module Kitchen
23
23
  class Freebsd < StandardPlatform
24
24
  StandardPlatform.platforms["freebsd"] = self
25
25
 
26
+ # default username for this platform's ami
27
+ # @return [String]
26
28
  def username
27
29
  "ec2-user"
28
30
  end
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "kitchen/driver/aws/standard_platform"
16
+ require_relative "../standard_platform"
17
17
 
18
18
  module Kitchen
19
19
  module Driver
@@ -29,6 +29,8 @@ module Kitchen
29
29
  super(driver, "rhel", version, architecture)
30
30
  end
31
31
 
32
+ # default username for this platform's ami
33
+ # @return [String]
32
34
  def username
33
35
  (version && version.to_f < 6.4) ? "root" : "ec2-user"
34
36
  end
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "kitchen/driver/aws/standard_platform"
16
+ require_relative "../standard_platform"
17
17
 
18
18
  module Kitchen
19
19
  module Driver
@@ -23,6 +23,8 @@ module Kitchen
23
23
  class Ubuntu < StandardPlatform
24
24
  StandardPlatform.platforms["ubuntu"] = self
25
25
 
26
+ # default username for this platform's ami
27
+ # @return [String]
26
28
  def username
27
29
  "ubuntu"
28
30
  end
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "kitchen/driver/aws/standard_platform"
16
+ require_relative "../standard_platform"
17
17
 
18
18
  module Kitchen
19
19
  module Driver
@@ -23,6 +23,8 @@ module Kitchen
23
23
  class Windows < StandardPlatform
24
24
  StandardPlatform.platforms["windows"] = self
25
25
 
26
+ # default username for this platform's ami
27
+ # @return [String]
26
28
  def username
27
29
  "administrator"
28
30
  end
@@ -227,7 +227,7 @@ module Kitchen
227
227
 
228
228
  if config[:spot_price]
229
229
  # Spot instance when a price is set
230
- server = with_request_limit_backoff(state) { submit_spots(state) }
230
+ server = with_request_limit_backoff(state) { submit_spots }
231
231
  else
232
232
  # On-demand instance
233
233
  server = with_request_limit_backoff(state) { submit_server }
@@ -238,32 +238,16 @@ module Kitchen
238
238
  server.wait_until_exists(before_attempt: logging_proc)
239
239
  end
240
240
 
241
+ state[:server_id] = server.id
242
+ info("EC2 instance <#{state[:server_id]}> created.")
243
+
241
244
  # See https://github.com/aws/aws-sdk-ruby/issues/859
242
- # Tagging can fail with a NotFound error even though we waited until the server exists
243
- # Waiting can also fail, so we have to also retry on that. If it means we re-tag the
244
- # instance, so be it.
245
- # Tagging an instance is possible before volumes are attached. Tagging the volumes after
246
- # instance creation is consistent.
245
+ # Waiting can fail, so we have to retry on that.
247
246
  Retryable.retryable(
248
247
  tries: 10,
249
248
  sleep: lambda { |n| [2**n, 30].min },
250
249
  on: ::Aws::EC2::Errors::InvalidInstanceIDNotFound
251
250
  ) do |r, _|
252
- info("Attempting to tag the instance, #{r} retries")
253
- tag_server(server)
254
-
255
- # Get information about the AMI (image) used to create the image.
256
- image_data = ec2.client.describe_images({ image_ids: [server.image_id] })[0][0]
257
-
258
- state[:server_id] = server.id
259
- info("EC2 instance <#{state[:server_id]}> created.")
260
-
261
- # instance-store backed images do not have attached volumes, so only
262
- # wait for the volumes to be ready if the instance EBS-backed.
263
- if image_data.root_device_type == "ebs"
264
- wait_until_volumes_ready(server, state)
265
- tag_volumes(server)
266
- end
267
251
  wait_until_ready(server, state)
268
252
  end
269
253
 
@@ -277,7 +261,7 @@ module Kitchen
277
261
 
278
262
  info("EC2 instance <#{state[:server_id]}> ready (hostname: #{state[:hostname]}).")
279
263
  instance.transport.connection(state).wait_until_ready
280
- create_ec2_json(state) if instance.provisioner.name =~ /chef/
264
+ create_ec2_json(state) if instance.provisioner.name =~ /chef/i
281
265
  debug("ec2:create '#{state[:hostname]}'")
282
266
  rescue Exception
283
267
  # Clean up any auto-created security groups or keys on the way out.
@@ -291,14 +275,11 @@ module Kitchen
291
275
  server = ec2.get_instance(state[:server_id])
292
276
  unless server.nil?
293
277
  instance.transport.connection(state).close
294
- server.terminate
295
- end
296
- if state[:spot_request_id]
297
- debug("Deleting spot request <#{state[:server_id]}>")
298
- ec2.client.cancel_spot_instance_requests(
299
- spot_instance_request_ids: [state[:spot_request_id]]
300
- )
301
- state.delete(:spot_request_id)
278
+ begin
279
+ server.terminate
280
+ rescue ::Aws::EC2::Errors::InvalidInstanceIDNotFound => e
281
+ warn("Received #{e}, instance was probably already destroyed. Ignoring")
282
+ end
302
283
  end
303
284
  # If we are going to clean up an automatic security group, we need
304
285
  # to wait for the instance to shut down. This slightly breaks the
@@ -405,15 +386,14 @@ module Kitchen
405
386
  @instance_generator = Aws::InstanceGenerator.new(config, ec2, instance.logger)
406
387
  end
407
388
 
408
- # Fog AWS helper for creating the instance
389
+ # AWS helper for creating the instance
409
390
  def submit_server
410
391
  instance_data = instance_generator.ec2_instance_data
411
392
  debug("Creating EC2 instance in region #{config[:region]} with properties:")
412
393
  instance_data.each do |key, value|
413
394
  debug("- #{key} = #{value.inspect}")
414
395
  end
415
- instance_data[:min_count] = 1
416
- instance_data[:max_count] = 1
396
+
417
397
  ec2.create_instance(instance_data)
418
398
  end
419
399
 
@@ -441,7 +421,7 @@ module Kitchen
441
421
  configs
442
422
  end
443
423
 
444
- def submit_spots(state)
424
+ def submit_spots
445
425
  configs = [config]
446
426
  expanded = []
447
427
  keys = %i{instance_type subnet_id}
@@ -454,40 +434,22 @@ module Kitchen
454
434
  expanded = []
455
435
  end
456
436
 
437
+ errs = []
457
438
  configs.each do |conf|
458
439
  begin
459
440
  @config = conf
460
- return submit_spot(state)
461
- rescue
441
+ return submit_spot
442
+ rescue => e
443
+ errs.append(e)
462
444
  end
463
445
  end
464
-
465
- raise "Could not create a spot"
446
+ raise ["Could not create a spot instance:", errs].flatten.join("\n")
466
447
  end
467
448
 
468
- def submit_spot(state)
449
+ def submit_spot
469
450
  debug("Creating EC2 Spot Instance..")
451
+ instance_data = instance_generator.ec2_instance_data
470
452
 
471
- spot_request_id = create_spot_request
472
- # deleting the instance cancels the request, but deleting the request
473
- # does not affect the instance
474
- state[:spot_request_id] = spot_request_id
475
- ec2.client.wait_until(
476
- :spot_instance_request_fulfilled,
477
- spot_instance_request_ids: [spot_request_id]
478
- ) do |w|
479
- w.max_attempts = config[:spot_wait] / config[:retryable_sleep]
480
- w.delay = config[:retryable_sleep]
481
- w.before_attempt do |attempts|
482
- c = attempts * config[:retryable_sleep]
483
- t = config[:spot_wait]
484
- info "Waited #{c}/#{t}s for spot request <#{spot_request_id}> to become fulfilled."
485
- end
486
- end
487
- ec2.get_instance_from_spot_request(spot_request_id)
488
- end
489
-
490
- def create_spot_request
491
453
  request_duration = config[:spot_wait]
492
454
  config_spot_price = config[:spot_price].to_s
493
455
  if %w{ondemand on-demand}.include?(config_spot_price)
@@ -495,56 +457,36 @@ module Kitchen
495
457
  else
496
458
  spot_price = config_spot_price
497
459
  end
498
- request_data = {
499
- spot_price: spot_price,
500
- launch_specification: instance_generator.ec2_instance_data,
460
+ spot_options = {
461
+ spot_instance_type: "persistent", # Cannot use one-time with valid_until
501
462
  valid_until: Time.now + request_duration,
463
+ instance_interruption_behavior: "stop",
502
464
  }
503
465
  if config[:block_duration_minutes]
504
- request_data[:block_duration_minutes] = config[:block_duration_minutes]
466
+ spot_options[:block_duration_minutes] = config[:block_duration_minutes]
505
467
  end
506
-
507
- response = ec2.client.request_spot_instances(request_data)
508
- response[:spot_instance_requests][0][:spot_instance_request_id]
509
- end
510
-
511
- def tag_server(server)
512
- if config[:tags] && !config[:tags].empty?
513
- tags = config[:tags].map do |k, v|
514
- # we convert the value to a string because
515
- # nils should be passed as an empty String
516
- # and Integers need to be represented as Strings
517
- { key: k.to_s, value: v.to_s }
518
- end
519
- server.create_tags(tags: tags)
468
+ unless spot_price == "" # i.e. on-demand
469
+ spot_options[:max_price] = spot_price
520
470
  end
521
- end
522
471
 
523
- def tag_volumes(server)
524
- if config[:tags] && !config[:tags].empty?
525
- tags = config[:tags].map do |k, v|
526
- { key: k.to_s, value: v.to_s }
527
- end
528
- server.volumes.each do |volume|
529
- volume.create_tags(tags: tags)
530
- end
531
- end
532
- end
472
+ instance_data[:instance_market_options] = {
473
+ market_type: "spot",
474
+ spot_options: spot_options,
475
+ }
533
476
 
534
- # Compares the requested volume count vs what has actually been set to be
535
- # attached to the instance. The information requested through
536
- # ec2.client.described_volumes is updated before the instance volume
537
- # information.
538
- def wait_until_volumes_ready(server, state)
539
- wait_with_destroy(server, state, "volumes to be ready") do |aws_instance|
540
- described_volume_count = 0
541
- ready_volume_count = 0
542
- if aws_instance.exists?
543
- described_volume_count = ec2.client.describe_volumes(filters: [
544
- { name: "attachment.instance-id", values: ["#{state[:server_id]}"] }]).volumes.length
545
- aws_instance.volumes.each { ready_volume_count += 1 }
546
- end
547
- (described_volume_count > 0) && (described_volume_count == ready_volume_count)
477
+ # The preferred way to create a spot instance is via request_spot_instances()
478
+ # However, it does not allow for tagging to occur at creation time.
479
+ # create_instances() allows creation of tagged spot instances, but does
480
+ # not retry if the price could not be satisfied immediately.
481
+ Retryable.retryable(
482
+ tries: config[:spot_wait] / config[:retryable_sleep],
483
+ sleep: lambda { |_n| config[:retryable_sleep] },
484
+ on: ::Aws::EC2::Errors::SpotMaxPriceTooLow
485
+ ) do |retries|
486
+ c = retries * config[:retryable_sleep]
487
+ t = config[:spot_wait]
488
+ info "Waited #{c}/#{t}s for spot request to become fulfilled."
489
+ ec2.create_instance(instance_data)
548
490
  end
549
491
  end
550
492
 
@@ -788,6 +730,7 @@ module Kitchen
788
730
  elsif config[:subnet_filter]
789
731
  subnets = ec2.client.describe_subnets(filters: [{ name: "tag:#{config[:subnet_filter][:tag]}", values: [config[:subnet_filter][:value]] }]).subnets
790
732
  raise "Subnets with tag '#{config[:subnet_filter][:tag]}=#{config[:subnet_filter][:value]}' not found during security group creation" if subnets.empty?
733
+
791
734
  subnets.first.vpc_id
792
735
  else
793
736
  # Try to check for a default VPC.
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
4
  #
5
- # Copyright:: 2016-2018, Chef Software, Inc.
5
+ # Copyright:: Chef Software, Inc.
6
6
  # Copyright:: 2012-2018, Fletcher Nichol
7
7
  #
8
8
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,6 +22,6 @@ module Kitchen
22
22
  module Driver
23
23
 
24
24
  # Version string for EC2 Test Kitchen driver
25
- EC2_VERSION = "3.2.0".freeze
25
+ EC2_VERSION = "3.7.0".freeze
26
26
  end
27
27
  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: 3.2.0
4
+ version: 3.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fletcher Nichol
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-17 00:00:00.000000000 Z
11
+ date: 2020-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-kitchen
@@ -168,14 +168,14 @@ dependencies:
168
168
  requirements:
169
169
  - - '='
170
170
  - !ruby/object:Gem::Version
171
- version: 0.13.3
171
+ version: 1.1.2
172
172
  type: :development
173
173
  prerelease: false
174
174
  version_requirements: !ruby/object:Gem::Requirement
175
175
  requirements:
176
176
  - - '='
177
177
  - !ruby/object:Gem::Version
178
- version: 0.13.3
178
+ version: 1.1.2
179
179
  - !ruby/object:Gem::Dependency
180
180
  name: climate_control
181
181
  requirement: !ruby/object:Gem::Requirement
@@ -216,7 +216,7 @@ homepage: https://github.com/test-kitchen/kitchen-ec2
216
216
  licenses:
217
217
  - Apache-2.0
218
218
  metadata: {}
219
- post_install_message:
219
+ post_install_message:
220
220
  rdoc_options: []
221
221
  require_paths:
222
222
  - lib
@@ -224,15 +224,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
224
224
  requirements:
225
225
  - - ">="
226
226
  - !ruby/object:Gem::Version
227
- version: '2.3'
227
+ version: '2.4'
228
228
  required_rubygems_version: !ruby/object:Gem::Requirement
229
229
  requirements:
230
230
  - - ">="
231
231
  - !ruby/object:Gem::Version
232
232
  version: '0'
233
233
  requirements: []
234
- rubygems_version: 3.0.3
235
- signing_key:
234
+ rubygems_version: 3.1.2
235
+ signing_key:
236
236
  specification_version: 4
237
237
  summary: A Test Kitchen Driver for Amazon EC2
238
238
  test_files: []