kitchen-ec2 1.4.0 → 2.0.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 +4 -4
- data/.gitignore +0 -0
- data/.rspec +0 -0
- data/.travis.yml +0 -0
- data/.yardopts +0 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +0 -0
- data/LICENSE +0 -0
- data/README.md +9 -26
- data/Rakefile +0 -0
- data/kitchen-ec2.gemspec +0 -0
- data/lib/kitchen/driver/aws/client.rb +2 -48
- data/lib/kitchen/driver/aws/instance_generator.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/amazon.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/centos.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/debian.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/fedora.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/freebsd.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/rhel.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/ubuntu.rb +0 -0
- data/lib/kitchen/driver/aws/standard_platform/windows.rb +0 -0
- data/lib/kitchen/driver/ec2.rb +25 -7
- data/lib/kitchen/driver/ec2_version.rb +1 -1
- data/spec/kitchen/driver/ec2/client_spec.rb +2 -142
- data/spec/kitchen/driver/ec2/image_selection_spec.rb +0 -0
- data/spec/kitchen/driver/ec2/instance_generator_spec.rb +0 -0
- data/spec/kitchen/driver/ec2_spec.rb +0 -0
- data/spec/spec_helper.rb +0 -0
- 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: d121c852a28622ac97b1d1ecd53d8925b8d69807
|
|
4
|
+
data.tar.gz: e3099c025db1fefaadc834cc3d0af54b18a1da7a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a761d862424e0fa29e2d5f1304ef5a65d66f6da5e5a38fa6ac437cfff0bd1619bcb8ece93066fd8c16036c62875028f9bdbd8b2572f6f825bde7d9c410aea59
|
|
7
|
+
data.tar.gz: 3716edf1589f8952d7aa7460f5e1056d0e5c78c1a0dfb6096ae1db5bf527ec31c33c0e3aada585164c0c07b6e9400c26c347b9c894604fad3b2a74226397799c
|
data/.gitignore
CHANGED
|
File without changes
|
data/.rspec
CHANGED
|
File without changes
|
data/.travis.yml
CHANGED
|
File without changes
|
data/.yardopts
CHANGED
|
File without changes
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## [v2.0.0](https://github.com/test-kitchen/kitchen-ec2/tree/v2.0.0) (2017-12-08)
|
|
4
|
+
[Full Changelog](https://github.com/test-kitchen/kitchen-ec2/compare/v1.4.0...v2.0.0)
|
|
5
|
+
|
|
6
|
+
**Improvements**
|
|
7
|
+
|
|
8
|
+
- Clean up original Authentication; Rely on SDK for Chain. [\#353](https://github.com/test-kitchen/kitchen-ec2/pull/320) ([rhyas](https://github.com/rhyas))
|
|
9
|
+
- Use quadratic backoff when encountering RequestLimit errors [\#320](https://github.com/test-kitchen/kitchen-ec2/pull/320) ([kamaradclimber](https://github.com/kamaradclimber))
|
|
10
|
+
|
|
3
11
|
## [v1.4.0](https://github.com/test-kitchen/kitchen-ec2/tree/v1.4.0) (2017-11-29)
|
|
4
12
|
[Full Changelog](https://github.com/test-kitchen/kitchen-ec2/compare/v1.3.2...v1.4.0)
|
|
5
13
|
|
data/Gemfile
CHANGED
|
File without changes
|
data/LICENSE
CHANGED
|
File without changes
|
data/README.md
CHANGED
|
@@ -149,35 +149,18 @@ follow the other `image_search` rules for preference.
|
|
|
149
149
|
|
|
150
150
|
### AWS Authentication
|
|
151
151
|
|
|
152
|
-
In order to connect to AWS, you must specify
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
use the environment variable `AWS_SESSION_TOKEN`.
|
|
161
|
-
2. The shared credentials ini file at `~/.aws/credentials`. This is the file
|
|
162
|
-
populated by `aws configure` command line and used by AWS tools in general, so if
|
|
163
|
-
you are set up for any other AWS tools, you probably already have this. You can
|
|
164
|
-
specify multiple profiles in this file and select one with the `AWS_PROFILE`
|
|
165
|
-
environment variable or the `shared_credentials_profile` driver config. Read
|
|
166
|
-
[this][credentials_docs] for more information.
|
|
167
|
-
3. From an instance profile when running on EC2. This accesses the local
|
|
168
|
-
metadata service to discover the local instance's IAM instance profile.
|
|
169
|
-
|
|
170
|
-
This precedence order is taken from http://docs.aws.amazon.com/sdkforruby/api/index.html#Configuration
|
|
171
|
-
|
|
172
|
-
The first method attempted that works will be used. IE, if you want to auth
|
|
173
|
-
using the instance profile, you must not set any of the access key configs
|
|
174
|
-
or environment variables, and you must not specify a `~/.aws/credentials`
|
|
175
|
-
file.
|
|
152
|
+
In order to connect to AWS, you must specify AWS credentials. We rely on the SDK
|
|
153
|
+
to find credentials in the standard way, documented here:
|
|
154
|
+
https://github.com/aws/aws-sdk-ruby/#configuration
|
|
155
|
+
|
|
156
|
+
The SDK Chain will search environment variables, then config files, then IAM role
|
|
157
|
+
data from the instance profile, in that order. In the case config files being
|
|
158
|
+
present, the 'default' profile will be used unless `shared_credentials_profile`
|
|
159
|
+
is defined to point to another profile.
|
|
176
160
|
|
|
177
161
|
Because the Test Kitchen test should be checked into source control and ran
|
|
178
162
|
through CI we no longer recommend storing the AWS credentials in the
|
|
179
|
-
`.kitchen.yml` file.
|
|
180
|
-
`~/.aws/credentials` file.
|
|
163
|
+
`.kitchen.yml` file.
|
|
181
164
|
|
|
182
165
|
### Instance Login Configuration
|
|
183
166
|
|
data/Rakefile
CHANGED
|
File without changes
|
data/kitchen-ec2.gemspec
CHANGED
|
File without changes
|
|
@@ -34,7 +34,7 @@ module Kitchen
|
|
|
34
34
|
|
|
35
35
|
def initialize( # rubocop:disable Metrics/ParameterLists
|
|
36
36
|
region,
|
|
37
|
-
profile_name =
|
|
37
|
+
profile_name = "default",
|
|
38
38
|
access_key_id = nil,
|
|
39
39
|
secret_access_key = nil,
|
|
40
40
|
session_token = nil,
|
|
@@ -42,63 +42,17 @@ module Kitchen
|
|
|
42
42
|
retry_limit = nil,
|
|
43
43
|
ssl_verify_peer = true
|
|
44
44
|
)
|
|
45
|
-
creds = self.class.get_credentials(
|
|
46
|
-
profile_name, access_key_id, secret_access_key, session_token, region
|
|
47
|
-
)
|
|
48
45
|
::Aws.config.update(
|
|
49
46
|
:region => region,
|
|
50
|
-
:
|
|
47
|
+
:profile => profile_name,
|
|
51
48
|
:http_proxy => http_proxy,
|
|
52
49
|
:ssl_verify_peer => ssl_verify_peer
|
|
53
50
|
)
|
|
54
51
|
::Aws.config.update(:retry_limit => retry_limit) unless retry_limit.nil?
|
|
55
52
|
end
|
|
56
53
|
|
|
57
|
-
# Try and get the credentials from an ordered list of locations
|
|
58
|
-
# http://docs.aws.amazon.com/sdkforruby/api/index.html#Configuration
|
|
59
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
60
|
-
# rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
|
|
61
|
-
def self.get_credentials(profile_name, access_key_id, secret_access_key, session_token,
|
|
62
|
-
region, options = {})
|
|
63
|
-
source_creds =
|
|
64
|
-
if access_key_id && secret_access_key
|
|
65
|
-
::Aws::Credentials.new(access_key_id, secret_access_key, session_token)
|
|
66
|
-
elsif ENV["AWS_ACCESS_KEY_ID"] && ENV["AWS_SECRET_ACCESS_KEY"]
|
|
67
|
-
::Aws::Credentials.new(
|
|
68
|
-
ENV["AWS_ACCESS_KEY_ID"],
|
|
69
|
-
ENV["AWS_SECRET_ACCESS_KEY"],
|
|
70
|
-
ENV["AWS_SESSION_TOKEN"]
|
|
71
|
-
)
|
|
72
|
-
elsif profile_name
|
|
73
|
-
::Aws::SharedCredentials.new(:profile_name => profile_name)
|
|
74
|
-
elsif default_shared_credentials?
|
|
75
|
-
::Aws::SharedCredentials.new
|
|
76
|
-
else
|
|
77
|
-
::Aws::InstanceProfileCredentials.new(:retries => 1)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
if options[:assume_role_arn] && options[:assume_role_session_name]
|
|
81
|
-
sts = ::Aws::STS::Client.new(:credentials => source_creds, :region => region)
|
|
82
|
-
|
|
83
|
-
assume_role_options = (options[:assume_role_options] || {}).merge(
|
|
84
|
-
:client => sts,
|
|
85
|
-
:role_arn => options[:assume_role_arn],
|
|
86
|
-
:role_session_name => options[:assume_role_session_name]
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
::Aws::AssumeRoleCredentials.new(assume_role_options)
|
|
90
|
-
else
|
|
91
|
-
source_creds
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
54
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
95
55
|
|
|
96
|
-
def self.default_shared_credentials?
|
|
97
|
-
::Aws::SharedCredentials.new.loadable?
|
|
98
|
-
rescue ::Aws::Errors::NoSuchProfileError
|
|
99
|
-
false
|
|
100
|
-
end
|
|
101
|
-
|
|
102
56
|
def create_instance(options)
|
|
103
57
|
resource.create_instances(options)[0]
|
|
104
58
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/kitchen/driver/ec2.rb
CHANGED
|
@@ -462,12 +462,14 @@ module Kitchen
|
|
|
462
462
|
info "Waited #{c}/#{t}s for instance <#{state[:server_id]}> #{status_msg}."
|
|
463
463
|
end
|
|
464
464
|
begin
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
465
|
+
with_request_limit_backoff(state) do
|
|
466
|
+
server.wait_until(
|
|
467
|
+
:max_attempts => config[:retryable_tries],
|
|
468
|
+
:delay => config[:retryable_sleep],
|
|
469
|
+
:before_attempt => wait_log,
|
|
470
|
+
&block
|
|
471
|
+
)
|
|
472
|
+
end
|
|
471
473
|
rescue ::Aws::Waiters::Errors::WaiterFailed
|
|
472
474
|
error("Ran out of time waiting for the server with id [#{state[:server_id]}]" \
|
|
473
475
|
" #{status_msg}, attempting to destroy it")
|
|
@@ -485,12 +487,28 @@ module Kitchen
|
|
|
485
487
|
# Password data is blank until password is available
|
|
486
488
|
!enc.nil? && !enc.empty?
|
|
487
489
|
end
|
|
488
|
-
pass =
|
|
490
|
+
pass = with_request_limit_backoff(state) do
|
|
491
|
+
server.decrypt_windows_password(File.expand_path(instance.transport[:ssh_key]))
|
|
492
|
+
end
|
|
489
493
|
state[:password] = pass
|
|
490
494
|
info("Retrieved Windows password for instance <#{state[:server_id]}>.")
|
|
491
495
|
end
|
|
492
496
|
# rubocop:enable Lint/UnusedBlockArgument
|
|
493
497
|
|
|
498
|
+
def with_request_limit_backoff(state)
|
|
499
|
+
retries = 0
|
|
500
|
+
begin
|
|
501
|
+
yield
|
|
502
|
+
rescue ::Aws::EC2::Errors::RequestLimitExceeded, ::Aws::Waiters::Errors::UnexpectedError => e
|
|
503
|
+
raise unless retries < 5 && e.message.include?("Request limit exceeded")
|
|
504
|
+
retries += 1
|
|
505
|
+
info("Request limit exceeded for instance <#{state[:server_id]}>." \
|
|
506
|
+
" Trying again in #{retries**2} seconds.")
|
|
507
|
+
sleep(retries**2)
|
|
508
|
+
retry
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
|
|
494
512
|
#
|
|
495
513
|
# Ordered mapping from config name to Fog name. Ordered by preference
|
|
496
514
|
# when looking up hostname.
|
|
@@ -20,135 +20,6 @@ require "kitchen/driver/aws/client"
|
|
|
20
20
|
require "climate_control"
|
|
21
21
|
|
|
22
22
|
describe Kitchen::Driver::Aws::Client do
|
|
23
|
-
describe "::get_credentials" do
|
|
24
|
-
# nothing else is set, so we default to this
|
|
25
|
-
it "loads IAM credentials last" do
|
|
26
|
-
iam = instance_double(Aws::InstanceProfileCredentials)
|
|
27
|
-
|
|
28
|
-
allow(Kitchen::Driver::Aws::Client).to receive(:default_shared_credentials?).and_return(false)
|
|
29
|
-
allow(Aws::InstanceProfileCredentials).to receive(:new).and_return(iam)
|
|
30
|
-
|
|
31
|
-
env_creds(nil, nil) do
|
|
32
|
-
expect(Kitchen::Driver::Aws::Client.get_credentials(nil, nil, nil, nil, nil)).to eq(iam)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "loads the default shared creds profile second to last" do
|
|
37
|
-
shared = instance_double(Aws::SharedCredentials)
|
|
38
|
-
|
|
39
|
-
allow(Kitchen::Driver::Aws::Client).to receive(:default_shared_credentials?).and_return(true)
|
|
40
|
-
allow(Aws::SharedCredentials).to \
|
|
41
|
-
receive(:new).and_return(shared)
|
|
42
|
-
|
|
43
|
-
env_creds(nil, nil) do
|
|
44
|
-
expect(Kitchen::Driver::Aws::Client.get_credentials(nil, nil, nil, nil, nil)).to \
|
|
45
|
-
eq(shared)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it "loads a custom shared credentials profile third to last" do
|
|
50
|
-
shared = instance_double(Aws::SharedCredentials)
|
|
51
|
-
|
|
52
|
-
allow(Aws::SharedCredentials).to \
|
|
53
|
-
receive(:new).with(:profile_name => "profile").and_return(shared)
|
|
54
|
-
|
|
55
|
-
env_creds(nil, nil) do
|
|
56
|
-
expect(Kitchen::Driver::Aws::Client.get_credentials("profile", nil, nil, nil, nil)).to \
|
|
57
|
-
eq(shared)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "loads credentials from the environment third to last" do
|
|
62
|
-
env_creds("key_id", "secret") do
|
|
63
|
-
expect(Kitchen::Driver::Aws::Client.get_credentials(nil, nil, nil, nil, nil)).to \
|
|
64
|
-
be_a(Aws::Credentials).and have_attributes(
|
|
65
|
-
:access_key_id => "key_id",
|
|
66
|
-
:secret_access_key => "secret"
|
|
67
|
-
)
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
it "loads provided credentials first" do
|
|
72
|
-
expect(Kitchen::Driver::Aws::Client.get_credentials(
|
|
73
|
-
"profile",
|
|
74
|
-
"key3",
|
|
75
|
-
"value3",
|
|
76
|
-
nil,
|
|
77
|
-
"us-west-1"
|
|
78
|
-
)).to \
|
|
79
|
-
be_a(Aws::Credentials).and have_attributes(
|
|
80
|
-
:access_key_id => "key3",
|
|
81
|
-
:secret_access_key => "value3",
|
|
82
|
-
:session_token => nil
|
|
83
|
-
)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
it "uses a session token if provided" do
|
|
87
|
-
expect(Kitchen::Driver::Aws::Client.get_credentials(
|
|
88
|
-
"profile",
|
|
89
|
-
"key3",
|
|
90
|
-
"value3",
|
|
91
|
-
"t",
|
|
92
|
-
"us-west-1"
|
|
93
|
-
)).to \
|
|
94
|
-
be_a(Aws::Credentials).and have_attributes(
|
|
95
|
-
:access_key_id => "key3",
|
|
96
|
-
:secret_access_key => "value3",
|
|
97
|
-
:session_token => "t"
|
|
98
|
-
)
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
describe "::get_credentials + STS AssumeRole" do
|
|
103
|
-
let(:shared) { instance_double(Aws::SharedCredentials) }
|
|
104
|
-
let(:iam) { instance_double(Aws::InstanceProfileCredentials) }
|
|
105
|
-
let(:assume_role) { instance_double(Aws::AssumeRoleCredentials) }
|
|
106
|
-
let(:sts_client) { instance_double(Aws::STS::Client) }
|
|
107
|
-
|
|
108
|
-
before do
|
|
109
|
-
expect(Aws::AssumeRoleCredentials).to \
|
|
110
|
-
receive(:new).with(
|
|
111
|
-
:client => sts_client,
|
|
112
|
-
:role_arn => "role_arn",
|
|
113
|
-
:role_session_name => "role_session_name"
|
|
114
|
-
).and_return(assume_role)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# nothing else is set, so we default to this
|
|
118
|
-
it "loads an Instance Profile last" do
|
|
119
|
-
allow(Kitchen::Driver::Aws::Client).to receive(:default_shared_credentials?).and_return(false)
|
|
120
|
-
|
|
121
|
-
expect(Aws::InstanceProfileCredentials).to \
|
|
122
|
-
receive(:new).and_return(iam)
|
|
123
|
-
expect(Aws::STS::Client).to \
|
|
124
|
-
receive(:new).with(:credentials => iam, :region => "us-west-1").and_return(sts_client)
|
|
125
|
-
|
|
126
|
-
expect(Kitchen::Driver::Aws::Client.get_credentials(
|
|
127
|
-
nil,
|
|
128
|
-
nil,
|
|
129
|
-
nil,
|
|
130
|
-
nil,
|
|
131
|
-
"us-west-1",
|
|
132
|
-
:assume_role_arn => "role_arn", :assume_role_session_name => "role_session_name"
|
|
133
|
-
)).to eq(assume_role)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
it "loads shared credentials second to last" do
|
|
137
|
-
expect(::Aws::SharedCredentials).to \
|
|
138
|
-
receive(:new).with(:profile_name => "profile").and_return(shared)
|
|
139
|
-
expect(Aws::STS::Client).to \
|
|
140
|
-
receive(:new).with(:credentials => shared, :region => "us-west-1").and_return(sts_client)
|
|
141
|
-
|
|
142
|
-
expect(Kitchen::Driver::Aws::Client.get_credentials(
|
|
143
|
-
"profile",
|
|
144
|
-
nil,
|
|
145
|
-
nil,
|
|
146
|
-
nil,
|
|
147
|
-
"us-west-1",
|
|
148
|
-
:assume_role_arn => "role_arn", :assume_role_session_name => "role_session_name"
|
|
149
|
-
)).to eq(assume_role)
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
23
|
|
|
153
24
|
let(:client) { Kitchen::Driver::Aws::Client.new("us-west-1") }
|
|
154
25
|
|
|
@@ -167,7 +38,7 @@ describe Kitchen::Driver::Aws::Client do
|
|
|
167
38
|
let(:client) do
|
|
168
39
|
Kitchen::Driver::Aws::Client.new(
|
|
169
40
|
"us-west-1",
|
|
170
|
-
"
|
|
41
|
+
"test-profile",
|
|
171
42
|
"access_key_id",
|
|
172
43
|
"secret_access_key",
|
|
173
44
|
"session_token",
|
|
@@ -176,12 +47,10 @@ describe Kitchen::Driver::Aws::Client do
|
|
|
176
47
|
false
|
|
177
48
|
)
|
|
178
49
|
end
|
|
179
|
-
let(:creds) { double("creds") }
|
|
180
50
|
it "Sets the AWS config" do
|
|
181
|
-
expect(Kitchen::Driver::Aws::Client).to receive(:get_credentials).and_return(creds)
|
|
182
51
|
client
|
|
183
52
|
expect(Aws.config[:region]).to eq("us-west-1")
|
|
184
|
-
expect(Aws.config[:
|
|
53
|
+
expect(Aws.config[:profile]).to eq("test-profile")
|
|
185
54
|
expect(Aws.config[:http_proxy]).to eq("http_proxy")
|
|
186
55
|
expect(Aws.config[:retry_limit]).to eq(999)
|
|
187
56
|
expect(Aws.config[:ssl_verify_peer]).to eq(false)
|
|
@@ -196,13 +65,4 @@ describe Kitchen::Driver::Aws::Client do
|
|
|
196
65
|
it "returns a resource" do
|
|
197
66
|
expect(client.resource).to be_a(Aws::EC2::Resource)
|
|
198
67
|
end
|
|
199
|
-
|
|
200
|
-
def env_creds(key_id, secret, &block)
|
|
201
|
-
ClimateControl.modify(
|
|
202
|
-
"AWS_ACCESS_KEY_ID" => key_id,
|
|
203
|
-
"AWS_SECRET_ACCESS_KEY" => secret
|
|
204
|
-
) do
|
|
205
|
-
yield
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
68
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/spec/spec_helper.rb
CHANGED
|
File without changes
|
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: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Fletcher Nichol
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-12-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: test-kitchen
|