kitchen-ec2 2.5.0 → 3.0.0.preview
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kitchen/driver/aws/client.rb +9 -9
- data/lib/kitchen/driver/aws/instance_generator.rb +25 -25
- data/lib/kitchen/driver/aws/standard_platform.rb +3 -3
- data/lib/kitchen/driver/aws/standard_platform/centos.rb +3 -3
- data/lib/kitchen/driver/aws/standard_platform/windows.rb +3 -3
- data/lib/kitchen/driver/ec2.rb +25 -29
- data/lib/kitchen/driver/ec2_version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2778637095bcb2e87ba702a0c04c496debc70e9b0eb781e6581e079667875edd
|
4
|
+
data.tar.gz: 3215d5359bd928d6446bdce249e34940e1f3b1a86dfeadf06f8bf36c5b21a4de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 308bf0b88efe068274892048e443f5704c646080eaed86c0ae0ad1d75c511e87226f027b4fce86f4b7193459e3baafb26ccc9c884b5ec3961c55d0a1f3b7cf3c
|
7
|
+
data.tar.gz: b2e1c18a028972c97ca062eafe64c57b0f9334d07bb0f098d4c250117e4ea2a8b492ee18fdc5b4b23b64c8803015b85b9b7ba27e2cd13d4ae9cf93375611911f
|
@@ -17,7 +17,7 @@
|
|
17
17
|
# See the License for the specific language governing permissions and
|
18
18
|
# limitations under the License.
|
19
19
|
|
20
|
-
require "aws-sdk"
|
20
|
+
require "aws-sdk-ec2"
|
21
21
|
require "aws-sdk-core/credentials"
|
22
22
|
require "aws-sdk-core/shared_credentials"
|
23
23
|
require "aws-sdk-core/instance_profile_credentials"
|
@@ -41,12 +41,12 @@ module Kitchen
|
|
41
41
|
ssl_verify_peer = true
|
42
42
|
)
|
43
43
|
::Aws.config.update(
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
44
|
+
region: region,
|
45
|
+
profile: profile_name,
|
46
|
+
http_proxy: http_proxy,
|
47
|
+
ssl_verify_peer: ssl_verify_peer
|
48
48
|
)
|
49
|
-
::Aws.config.update(:
|
49
|
+
::Aws.config.update(retry_limit: retry_limit) unless retry_limit.nil?
|
50
50
|
end
|
51
51
|
|
52
52
|
def create_instance(options)
|
@@ -59,9 +59,9 @@ module Kitchen
|
|
59
59
|
|
60
60
|
def get_instance_from_spot_request(request_id)
|
61
61
|
resource.instances(
|
62
|
-
:
|
63
|
-
:
|
64
|
-
:
|
62
|
+
filters: [{
|
63
|
+
name: "spot-instance-request-id",
|
64
|
+
values: [request_id],
|
65
65
|
}]
|
66
66
|
).to_a[0]
|
67
67
|
end
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# limitations under the License.
|
19
19
|
|
20
20
|
require "base64"
|
21
|
-
require "aws-sdk"
|
21
|
+
require "aws-sdk-ec2"
|
22
22
|
|
23
23
|
module Kitchen
|
24
24
|
|
@@ -45,12 +45,12 @@ module Kitchen
|
|
45
45
|
# Support for looking up security group id and subnet id using tags.
|
46
46
|
|
47
47
|
if config[:subnet_id].nil? && config[:subnet_filter]
|
48
|
-
config[:subnet_id] = ::Aws::EC2::Client
|
49
|
-
new(:
|
50
|
-
:
|
48
|
+
config[:subnet_id] = ::Aws::EC2::Client
|
49
|
+
.new(region: config[:region]).describe_subnets(
|
50
|
+
filters: [
|
51
51
|
{
|
52
|
-
:
|
53
|
-
:
|
52
|
+
name: "tag:#{config[:subnet_filter][:tag]}",
|
53
|
+
values: [config[:subnet_filter][:value]],
|
54
54
|
},
|
55
55
|
]
|
56
56
|
)[0][0].subnet_id
|
@@ -62,12 +62,12 @@ module Kitchen
|
|
62
62
|
end
|
63
63
|
|
64
64
|
if config[:security_group_ids].nil? && config[:security_group_filter]
|
65
|
-
security_group = ::Aws::EC2::Client
|
66
|
-
new(:
|
67
|
-
:
|
65
|
+
security_group = ::Aws::EC2::Client
|
66
|
+
.new(region: config[:region]).describe_security_groups(
|
67
|
+
filters: [
|
68
68
|
{
|
69
|
-
:
|
70
|
-
:
|
69
|
+
name: "tag:#{config[:security_group_filter][:tag]}",
|
70
|
+
values: [config[:security_group_filter][:value]],
|
71
71
|
},
|
72
72
|
]
|
73
73
|
)[0][0]
|
@@ -81,12 +81,12 @@ module Kitchen
|
|
81
81
|
end
|
82
82
|
|
83
83
|
i = {
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
87
|
-
:
|
88
|
-
:
|
89
|
-
:
|
84
|
+
instance_type: config[:instance_type],
|
85
|
+
ebs_optimized: config[:ebs_optimized],
|
86
|
+
image_id: config[:image_id],
|
87
|
+
key_name: config[:aws_ssh_key_id],
|
88
|
+
subnet_id: config[:subnet_id],
|
89
|
+
private_ip_address: config[:private_ip_address],
|
90
90
|
}
|
91
91
|
|
92
92
|
availability_zone = config[:availability_zone]
|
@@ -94,14 +94,14 @@ module Kitchen
|
|
94
94
|
if availability_zone =~ /^[a-z]$/i
|
95
95
|
availability_zone = "#{config[:region]}#{availability_zone}"
|
96
96
|
end
|
97
|
-
i[:placement] = { :
|
97
|
+
i[:placement] = { availability_zone: availability_zone.downcase }
|
98
98
|
end
|
99
99
|
tenancy = config[:tenancy]
|
100
100
|
if tenancy
|
101
101
|
if i.key?(:placement)
|
102
102
|
i[:placement][:tenancy] = tenancy
|
103
103
|
else
|
104
|
-
i[:placement] = { :
|
104
|
+
i[:placement] = { tenancy: tenancy }
|
105
105
|
end
|
106
106
|
end
|
107
107
|
unless config[:block_device_mappings].nil? || config[:block_device_mappings].empty?
|
@@ -110,14 +110,14 @@ module Kitchen
|
|
110
110
|
i[:security_group_ids] = Array(config[:security_group_ids]) if config[:security_group_ids]
|
111
111
|
i[:user_data] = prepared_user_data if prepared_user_data
|
112
112
|
if config[:iam_profile_name]
|
113
|
-
i[:iam_instance_profile] = { :
|
113
|
+
i[:iam_instance_profile] = { name: config[:iam_profile_name] }
|
114
114
|
end
|
115
115
|
if !config.fetch(:associate_public_ip, nil).nil?
|
116
116
|
i[:network_interfaces] =
|
117
117
|
[{
|
118
|
-
:
|
119
|
-
:
|
120
|
-
:
|
118
|
+
device_index: 0,
|
119
|
+
associate_public_ip_address: config[:associate_public_ip],
|
120
|
+
delete_on_termination: true,
|
121
121
|
}]
|
122
122
|
# If specifying `:network_interfaces` in the request, you must specify
|
123
123
|
# network specific configs in the network_interfaces block and not at
|
@@ -137,14 +137,14 @@ module Kitchen
|
|
137
137
|
if availability_zone =~ /^[a-z]$/i
|
138
138
|
availability_zone = "#{config[:region]}#{availability_zone}"
|
139
139
|
end
|
140
|
-
i[:placement] = { :
|
140
|
+
i[:placement] = { availability_zone: availability_zone.downcase }
|
141
141
|
end
|
142
142
|
tenancy = config[:tenancy]
|
143
143
|
if tenancy
|
144
144
|
if i.key?(:placement)
|
145
145
|
i[:placement][:tenancy] = tenancy
|
146
146
|
else
|
147
|
-
i[:placement] = { :
|
147
|
+
i[:placement] = { tenancy: tenancy }
|
148
148
|
end
|
149
149
|
end
|
150
150
|
unless config[:instance_initiated_shutdown_behavior].nil? ||
|
@@ -88,7 +88,7 @@ module Kitchen
|
|
88
88
|
#
|
89
89
|
# The list of supported architectures
|
90
90
|
#
|
91
|
-
SUPPORTED_ARCHITECTURES = %w{x86_64 i386 arm64}
|
91
|
+
SUPPORTED_ARCHITECTURES = %w{x86_64 i386 arm64}.freeze
|
92
92
|
|
93
93
|
#
|
94
94
|
# Find the best matching image for the given image search.
|
@@ -98,11 +98,11 @@ module Kitchen
|
|
98
98
|
driver.debug("Searching for images matching #{image_search} ...")
|
99
99
|
# Convert to ec2 search format (pairs of name+values)
|
100
100
|
filters = image_search.map do |key, value|
|
101
|
-
{ :
|
101
|
+
{ name: key.to_s, values: Array(value).map(&:to_s) }
|
102
102
|
end
|
103
103
|
|
104
104
|
# We prefer most recent first
|
105
|
-
images = driver.ec2.resource.images(:
|
105
|
+
images = driver.ec2.resource.images(filters: filters)
|
106
106
|
images = sort_images(images)
|
107
107
|
show_returned_images(images)
|
108
108
|
|
@@ -43,9 +43,9 @@ module Kitchen
|
|
43
43
|
# 7.1 -> [ img1, img2, img3 ]
|
44
44
|
# 6 -> [ img4, img5 ]
|
45
45
|
# ...
|
46
|
-
images.group_by { |image| self.class.from_image(driver, image).version }
|
47
|
-
sort_by { |k, _v| (k && k.include?(".") ? k.to_f : "#{k}.999".to_f) }
|
48
|
-
reverse.flat_map { |_k, v| v }
|
46
|
+
images.group_by { |image| self.class.from_image(driver, image).version }
|
47
|
+
.sort_by { |k, _v| (k && k.include?(".") ? k.to_f : "#{k}.999".to_f) }
|
48
|
+
.reverse.flat_map { |_k, v| v }
|
49
49
|
end
|
50
50
|
|
51
51
|
def self.from_image(driver, image)
|
@@ -60,9 +60,9 @@ module Kitchen
|
|
60
60
|
# 2008r2rtm -> [ img1, img2, img3 ]
|
61
61
|
# 2012r2sp1 -> [ img4, img5 ]
|
62
62
|
# ...
|
63
|
-
images.group_by { |image| self.class.from_image(driver, image).windows_version_parts }
|
64
|
-
sort_by { |version, _platform_images| version }
|
65
|
-
reverse.flat_map { |_version, platform_images| platform_images }
|
63
|
+
images.group_by { |image| self.class.from_image(driver, image).windows_version_parts }
|
64
|
+
.sort_by { |version, _platform_images| version }
|
65
|
+
.reverse.flat_map { |_version, platform_images| platform_images }
|
66
66
|
end
|
67
67
|
|
68
68
|
def self.from_image(driver, image)
|
data/lib/kitchen/driver/ec2.rb
CHANGED
@@ -33,14 +33,13 @@ require_relative "aws/standard_platform/fedora"
|
|
33
33
|
require_relative "aws/standard_platform/freebsd"
|
34
34
|
require_relative "aws/standard_platform/ubuntu"
|
35
35
|
require_relative "aws/standard_platform/windows"
|
36
|
+
require "aws-sdk-ec2"
|
36
37
|
require "aws-sdk-core/waiters/errors"
|
37
38
|
require "retryable"
|
38
39
|
require "time"
|
39
40
|
require "etc"
|
40
41
|
require "socket"
|
41
42
|
|
42
|
-
Aws.eager_autoload!
|
43
|
-
|
44
43
|
module Kitchen
|
45
44
|
|
46
45
|
module Driver
|
@@ -55,7 +54,7 @@ module Kitchen
|
|
55
54
|
plugin_version Kitchen::Driver::EC2_VERSION
|
56
55
|
|
57
56
|
default_config :region, ENV["AWS_REGION"] || "us-east-1"
|
58
|
-
default_config :shared_credentials_profile,
|
57
|
+
default_config :shared_credentials_profile, ENV["AWS_PROFILE"]
|
59
58
|
default_config :availability_zone, nil
|
60
59
|
default_config :instance_type do |driver|
|
61
60
|
driver.default_instance_type
|
@@ -96,9 +95,6 @@ module Kitchen
|
|
96
95
|
|
97
96
|
def initialize(*args, &block)
|
98
97
|
super
|
99
|
-
# AWS Ruby SDK loading isn't thread safe, so as soon as we know we're
|
100
|
-
# going to use EC2, autoload it. Seems to have been fixed in Ruby 2.3+
|
101
|
-
::Aws.eager_autoload! unless RUBY_VERSION.to_f >= 2.3
|
102
98
|
end
|
103
99
|
|
104
100
|
def self.validation_warn(driver, old_key, new_key)
|
@@ -252,15 +248,15 @@ module Kitchen
|
|
252
248
|
# Tagging an instance is possible before volumes are attached. Tagging the volumes after
|
253
249
|
# instance creation is consistent.
|
254
250
|
Retryable.retryable(
|
255
|
-
:
|
256
|
-
:
|
257
|
-
:
|
251
|
+
tries: 10,
|
252
|
+
sleep: lambda { |n| [2**n, 30].min },
|
253
|
+
on: ::Aws::EC2::Errors::InvalidInstanceIDNotFound
|
258
254
|
) do |r, _|
|
259
255
|
info("Attempting to tag the instance, #{r} retries")
|
260
256
|
tag_server(server)
|
261
257
|
|
262
258
|
# Get information about the AMI (image) used to create the image.
|
263
|
-
image_data = ec2.client.describe_images({ :
|
259
|
+
image_data = ec2.client.describe_images({ image_ids: [server.image_id] })[0][0]
|
264
260
|
|
265
261
|
state[:server_id] = server.id
|
266
262
|
info("EC2 instance <#{state[:server_id]}> created.")
|
@@ -303,7 +299,7 @@ module Kitchen
|
|
303
299
|
if state[:spot_request_id]
|
304
300
|
debug("Deleting spot request <#{state[:server_id]}>")
|
305
301
|
ec2.client.cancel_spot_instance_requests(
|
306
|
-
:
|
302
|
+
spot_instance_request_ids: [state[:spot_request_id]]
|
307
303
|
)
|
308
304
|
state.delete(:spot_request_id)
|
309
305
|
end
|
@@ -433,7 +429,7 @@ module Kitchen
|
|
433
429
|
state[:spot_request_id] = spot_request_id
|
434
430
|
ec2.client.wait_until(
|
435
431
|
:spot_instance_request_fulfilled,
|
436
|
-
:
|
432
|
+
spot_instance_request_ids: [spot_request_id]
|
437
433
|
) do |w|
|
438
434
|
w.max_attempts = config[:retryable_tries]
|
439
435
|
w.delay = config[:retryable_sleep]
|
@@ -449,9 +445,9 @@ module Kitchen
|
|
449
445
|
def create_spot_request
|
450
446
|
request_duration = config[:retryable_tries] * config[:retryable_sleep]
|
451
447
|
request_data = {
|
452
|
-
:
|
453
|
-
:
|
454
|
-
:
|
448
|
+
spot_price: config[:spot_price].to_s,
|
449
|
+
launch_specification: instance_generator.ec2_instance_data,
|
450
|
+
valid_until: Time.now + request_duration,
|
455
451
|
}
|
456
452
|
if config[:block_duration_minutes]
|
457
453
|
request_data[:block_duration_minutes] = config[:block_duration_minutes]
|
@@ -467,19 +463,19 @@ module Kitchen
|
|
467
463
|
# we convert the value to a string because
|
468
464
|
# nils should be passed as an empty String
|
469
465
|
# and Integers need to be represented as Strings
|
470
|
-
{ :
|
466
|
+
{ key: k, value: v.to_s }
|
471
467
|
end
|
472
|
-
server.create_tags(:
|
468
|
+
server.create_tags(tags: tags)
|
473
469
|
end
|
474
470
|
end
|
475
471
|
|
476
472
|
def tag_volumes(server)
|
477
473
|
if config[:tags] && !config[:tags].empty?
|
478
474
|
tags = config[:tags].map do |k, v|
|
479
|
-
{ :
|
475
|
+
{ key: k, value: v.to_s }
|
480
476
|
end
|
481
477
|
server.volumes.each do |volume|
|
482
|
-
volume.create_tags(:
|
478
|
+
volume.create_tags(tags: tags)
|
483
479
|
end
|
484
480
|
end
|
485
481
|
end
|
@@ -493,8 +489,8 @@ module Kitchen
|
|
493
489
|
described_volume_count = 0
|
494
490
|
ready_volume_count = 0
|
495
491
|
if aws_instance.exists?
|
496
|
-
described_volume_count = ec2.client.describe_volumes(:
|
497
|
-
{ :
|
492
|
+
described_volume_count = ec2.client.describe_volumes(filters: [
|
493
|
+
{ name: "attachment.instance-id", values: ["#{state[:server_id]}"] }]
|
498
494
|
).volumes.length
|
499
495
|
aws_instance.volumes.each { ready_volume_count += 1 }
|
500
496
|
end
|
@@ -542,9 +538,9 @@ module Kitchen
|
|
542
538
|
begin
|
543
539
|
with_request_limit_backoff(state) do
|
544
540
|
server.wait_until(
|
545
|
-
:
|
546
|
-
:
|
547
|
-
:
|
541
|
+
max_attempts: config[:retryable_tries],
|
542
|
+
delay: config[:retryable_sleep],
|
543
|
+
before_attempt: wait_log,
|
548
544
|
&block
|
549
545
|
)
|
550
546
|
end
|
@@ -559,7 +555,7 @@ module Kitchen
|
|
559
555
|
def fetch_windows_admin_password(server, state)
|
560
556
|
wait_with_destroy(server, state, "to fetch windows admin password") do |aws_instance|
|
561
557
|
enc = server.client.get_password_data(
|
562
|
-
:
|
558
|
+
instance_id: state[:server_id]
|
563
559
|
).password_data
|
564
560
|
# Password data is blank until password is available
|
565
561
|
!enc.nil? && !enc.empty?
|
@@ -595,7 +591,7 @@ module Kitchen
|
|
595
591
|
"public" => "public_ip_address",
|
596
592
|
"private" => "private_ip_address",
|
597
593
|
"private_dns" => "private_dns_name",
|
598
|
-
}
|
594
|
+
}.freeze
|
599
595
|
|
600
596
|
#
|
601
597
|
# Lookup hostname of provided server. If interface_type is provided use
|
@@ -668,7 +664,7 @@ module Kitchen
|
|
668
664
|
#Firewall Config
|
669
665
|
& netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" profile=public protocol=tcp localport=5985 remoteip=localsubnet new remoteip=any >> $logfile
|
670
666
|
Set-ItemProperty -Name LocalAccountTokenFilterPolicy -Path HKLM:\\software\\Microsoft\\Windows\\CurrentVersion\\Policies\\system -Value 1
|
671
|
-
|
667
|
+
EOH
|
672
668
|
|
673
669
|
# Preparing custom static admin user if we defined something other than Administrator
|
674
670
|
custom_admin_script = ""
|
@@ -712,8 +708,8 @@ module Kitchen
|
|
712
708
|
end
|
713
709
|
|
714
710
|
def image_info(image)
|
715
|
-
root_device = image.block_device_mappings
|
716
|
-
find { |b| b.device_name == image.root_device_name }
|
711
|
+
root_device = image.block_device_mappings
|
712
|
+
.find { |b| b.device_name == image.root_device_name }
|
717
713
|
volume_type = " #{root_device.ebs.volume_type}" if root_device && root_device.ebs
|
718
714
|
|
719
715
|
" Architecture: #{image.architecture}," \
|
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: 3.0.0.preview
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fletcher Nichol
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-kitchen
|
@@ -59,19 +59,19 @@ dependencies:
|
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
|
-
name: aws-sdk
|
62
|
+
name: aws-sdk-ec2
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
67
|
+
version: '1.0'
|
68
68
|
type: :runtime
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
74
|
+
version: '1.0'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: retryable
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -218,12 +218,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
218
218
|
requirements:
|
219
219
|
- - ">="
|
220
220
|
- !ruby/object:Gem::Version
|
221
|
-
version: 2.
|
221
|
+
version: '2.3'
|
222
222
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
223
|
requirements:
|
224
|
-
- - "
|
224
|
+
- - ">"
|
225
225
|
- !ruby/object:Gem::Version
|
226
|
-
version:
|
226
|
+
version: 1.3.1
|
227
227
|
requirements: []
|
228
228
|
rubygems_version: 3.0.3
|
229
229
|
signing_key:
|