kitchen-cloudformation 0.0.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 +7 -0
- data/CHANGELOG.md +3 -0
- data/LICENSE +12 -0
- data/README.md +146 -0
- data/ca-bundle.crt +3721 -0
- data/kitchen-cloudformation.gemspec +26 -0
- data/lib/kitchen/driver/aws/cf_client.rb +108 -0
- data/lib/kitchen/driver/aws/stack_generator.rb +60 -0
- data/lib/kitchen/driver/cloud_formation.rb +185 -0
- data/lib/kitchen/driver/cloudformation_version.rb +22 -0
- metadata +123 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "kitchen/driver/cloudformation_version.rb"
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "kitchen-cloudformation"
|
8
|
+
gem.version = Kitchen::Driver::CLOUDFORMATION_VERSION
|
9
|
+
gem.license = "Apache 2.0"
|
10
|
+
gem.authors = ["Neill Turner"]
|
11
|
+
gem.email = ["neillwturner@gmail.com"]
|
12
|
+
gem.description = "A Test Kitchen Driver for Amazon AWS CloudFormation"
|
13
|
+
gem.summary = gem.description
|
14
|
+
gem.homepage = "https://github.com/neillturner/kitchen-cloudformation"
|
15
|
+
candidates = Dir.glob('{lib}/**/*') + ['README.md', 'CHANGELOG.md', 'LICENSE' , 'ca-bundle.crt', 'kitchen-cloudformation.gemspec']
|
16
|
+
gem.files = candidates.sort
|
17
|
+
gem.executables = []
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "test-kitchen", "~> 1.4"
|
21
|
+
gem.add_dependency "excon"
|
22
|
+
gem.add_dependency "multi_json"
|
23
|
+
gem.add_dependency "aws-sdk-v1", "~> 1.59.0"
|
24
|
+
gem.add_dependency "aws-sdk", "~> 2"
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require "aws-sdk"
|
17
|
+
require "aws-sdk-core/credentials"
|
18
|
+
require "aws-sdk-core/shared_credentials"
|
19
|
+
require "aws-sdk-core/instance_profile_credentials"
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
|
23
|
+
module Driver
|
24
|
+
|
25
|
+
class Aws
|
26
|
+
|
27
|
+
# A class for creating and managing the Cloud Formation client connection
|
28
|
+
#
|
29
|
+
class CfClient
|
30
|
+
|
31
|
+
def initialize(
|
32
|
+
region,
|
33
|
+
profile_name = nil,
|
34
|
+
ssl_cert_file = nil,
|
35
|
+
access_key_id = nil,
|
36
|
+
secret_access_key = nil,
|
37
|
+
session_token = nil
|
38
|
+
)
|
39
|
+
creds = self.class.get_credentials(
|
40
|
+
profile_name, access_key_id, secret_access_key, session_token
|
41
|
+
)
|
42
|
+
|
43
|
+
::AWS.config(
|
44
|
+
:region => region,
|
45
|
+
:credentials => creds,
|
46
|
+
:ssl_ca_bundle => ssl_cert_file
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Try and get the credentials from an ordered list of locations
|
51
|
+
# http://docs.aws.amazon.com/sdkforruby/api/index.html#Configuration
|
52
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
53
|
+
def self.get_credentials(profile_name, access_key_id, secret_access_key, session_token)
|
54
|
+
shared_creds = ::Aws::SharedCredentials.new(:profile_name => profile_name)
|
55
|
+
if access_key_id && secret_access_key
|
56
|
+
::Aws::Credentials.new(access_key_id, secret_access_key, session_token)
|
57
|
+
# TODO: these are deprecated, remove them in the next major version
|
58
|
+
elsif ENV["AWS_ACCESS_KEY"] && ENV["AWS_SECRET_KEY"]
|
59
|
+
::Aws::Credentials.new(
|
60
|
+
ENV["AWS_ACCESS_KEY"],
|
61
|
+
ENV["AWS_SECRET_KEY"],
|
62
|
+
ENV["AWS_TOKEN"]
|
63
|
+
)
|
64
|
+
elsif ENV["AWS_ACCESS_KEY_ID"] && ENV["AWS_SECRET_ACCESS_KEY"]
|
65
|
+
::Aws::Credentials.new(
|
66
|
+
ENV["AWS_ACCESS_KEY_ID"],
|
67
|
+
ENV["AWS_SECRET_ACCESS_KEY"],
|
68
|
+
ENV["AWS_SESSION_TOKEN"]
|
69
|
+
)
|
70
|
+
elsif shared_creds.loadable?
|
71
|
+
shared_creds
|
72
|
+
else
|
73
|
+
::Aws::InstanceProfileCredentials.new(:retries => 1)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_stack(options)
|
78
|
+
resource.create_stack(options)
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_stack(stack_name)
|
82
|
+
resource.stack(stack_name)
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_stack_events(stack_name)
|
86
|
+
client.describe_stack_events({:stack_name => stack_name})
|
87
|
+
end
|
88
|
+
|
89
|
+
def delete_stack(stack_name)
|
90
|
+
s = resource.stack(stack_name)
|
91
|
+
s.delete
|
92
|
+
end
|
93
|
+
|
94
|
+
def client
|
95
|
+
@client ||= ::Aws::CloudFormation::Client.new
|
96
|
+
end
|
97
|
+
|
98
|
+
def resource
|
99
|
+
@resource ||= ::Aws::CloudFormation::Resource.new
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require "kitchen/logging"
|
17
|
+
|
18
|
+
module Kitchen
|
19
|
+
|
20
|
+
module Driver
|
21
|
+
|
22
|
+
class Aws
|
23
|
+
|
24
|
+
# A class for encapsulating the stack payload logic
|
25
|
+
#
|
26
|
+
class StackGenerator
|
27
|
+
|
28
|
+
include Logging
|
29
|
+
|
30
|
+
attr_reader :config, :cf
|
31
|
+
|
32
|
+
def initialize(config, cf)
|
33
|
+
@config = config
|
34
|
+
@cf = cf
|
35
|
+
end
|
36
|
+
|
37
|
+
# Transform the provided config into the hash to send to AWS. Some fields
|
38
|
+
# can be passed in null, others need to be ommitted if they are null
|
39
|
+
def cf_stack_data # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
40
|
+
s ={:stack_name => config[:stack_name]}
|
41
|
+
s[:template_url] = config[:template_url] if config[:template_file]
|
42
|
+
if config[:template_file]
|
43
|
+
s[:template_body] = File.open(config[:template_file], 'rb') { |file| file.read }
|
44
|
+
end
|
45
|
+
s[:timeout_in_minutes] = config[:timeout_in_minutes] if config[:timeout_in_minutes] != nil and config[:timeout_in_minutes]>0
|
46
|
+
s[:disable_rollback] = config[:disable_rollback] if config[:disable_rollback] != nil and config[:disable_rollback] == true or config[:disable_rollback] == false
|
47
|
+
s[:parameters] = []
|
48
|
+
config[:parameters].each do |k,v|
|
49
|
+
s[:parameters].push({:parameter_key => k.to_s, :parameter_value => v.to_s})
|
50
|
+
end
|
51
|
+
s
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require "benchmark"
|
16
|
+
require "json"
|
17
|
+
require "aws"
|
18
|
+
require "kitchen"
|
19
|
+
require_relative "cloudformation_version"
|
20
|
+
require_relative "aws/cf_client"
|
21
|
+
require_relative "aws/stack_generator"
|
22
|
+
#require "aws-sdk-core/waiters/errors"
|
23
|
+
|
24
|
+
module Kitchen
|
25
|
+
|
26
|
+
module Driver
|
27
|
+
|
28
|
+
# Amazon CloudFormation driver for Test Kitchen.
|
29
|
+
#
|
30
|
+
class CloudFormation < Kitchen::Driver::Base # rubocop:disable Metrics/ClassLength
|
31
|
+
|
32
|
+
kitchen_driver_api_version 2
|
33
|
+
|
34
|
+
plugin_version Kitchen::Driver::CLOUDFORMATION_VERSION
|
35
|
+
|
36
|
+
default_config :region, ENV["AWS_REGION"] || "us-east-1"
|
37
|
+
default_config :shared_credentials_profile, nil
|
38
|
+
default_config :aws_access_key_id, nil
|
39
|
+
default_config :aws_secret_access_key, nil
|
40
|
+
default_config :aws_session_token, nil
|
41
|
+
default_config :ssl_cert_file, ENV["SSL_CERT_FILE"]
|
42
|
+
default_config :stack_name, nil
|
43
|
+
default_config :template_file, nil
|
44
|
+
default_config :parameters, {}
|
45
|
+
default_config :disable_rollback, false
|
46
|
+
default_config :timeout_in_minutes, 0
|
47
|
+
default_config :parameters, {}
|
48
|
+
|
49
|
+
default_config :ssh_key, nil
|
50
|
+
default_config :username, 'root'
|
51
|
+
default_config :hostname, nil
|
52
|
+
#default_config :interface, nil
|
53
|
+
|
54
|
+
required_config :ssh_key
|
55
|
+
required_config :stack_name
|
56
|
+
|
57
|
+
def create(state) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
58
|
+
copy_deprecated_configs(state)
|
59
|
+
return if state[:stack_name]
|
60
|
+
|
61
|
+
info(Kitchen::Util.outdent!(<<-END))
|
62
|
+
Creating CloudFormation Stack <#{config[:stack_name]}>...
|
63
|
+
If you are not using an account that qualifies under the AWS
|
64
|
+
free-tier, you may be charged to run these suites. The charge
|
65
|
+
should be minimal, but neither Test Kitchen nor its maintainers
|
66
|
+
are responsible for your incurred costs.
|
67
|
+
END
|
68
|
+
begin
|
69
|
+
stack = create_stack
|
70
|
+
rescue Exception => e
|
71
|
+
error("CloudFormation #{e.message}.")
|
72
|
+
return
|
73
|
+
end
|
74
|
+
state[:stack_name] = stack.stack_name
|
75
|
+
state[:hostname] = config[:hostname]
|
76
|
+
info("Stack <#{state[:stack_name]}> requested.")
|
77
|
+
#tag_stack(stack)
|
78
|
+
|
79
|
+
s = cf.get_stack(state[:stack_name])
|
80
|
+
while s.stack_status == 'CREATE_IN_PROGRESS'
|
81
|
+
debug_stack_events(state[:stack_name])
|
82
|
+
info("CloudFormation waiting for stack <#{state[:stack_name]}> to be created.....")
|
83
|
+
sleep(30)
|
84
|
+
s = cf.get_stack(state[:stack_name])
|
85
|
+
end
|
86
|
+
if s.stack_status == 'CREATE_COMPLETE'
|
87
|
+
display_stack_events(state[:stack_name])
|
88
|
+
info("CloudFormation stack <#{state[:stack_name]}> created.")
|
89
|
+
else
|
90
|
+
display_stack_events(state[:stack_name])
|
91
|
+
error("CloudFormation stack <#{stack.stack_name}> failed to create....attempting to delete")
|
92
|
+
destroy(state)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def destroy(state)
|
97
|
+
stack = cf.get_stack(state[:stack_name])
|
98
|
+
if stack.nil?
|
99
|
+
state.delete(:stack_name)
|
100
|
+
else
|
101
|
+
cf.delete_stack(state[:stack_name])
|
102
|
+
begin
|
103
|
+
stack = cf.get_stack(state[:stack_name])
|
104
|
+
while stack.stack_status == 'DELETE_IN_PROGRESS'
|
105
|
+
debug_stack_events(state[:stack_name])
|
106
|
+
info("CloudFormation waiting for stack <#{state[:stack_name]}> to be deleted.....")
|
107
|
+
sleep(30)
|
108
|
+
stack = cf.get_stack(state[:stack_name])
|
109
|
+
end
|
110
|
+
rescue Exception => e
|
111
|
+
info("CloudFormation stack <#{state[:stack_name]}> deleted.")
|
112
|
+
state.delete(:stack_name)
|
113
|
+
return
|
114
|
+
end
|
115
|
+
display_stack_events(state[:stack_name])
|
116
|
+
error("CloudFormation stack <#{stack.stack_name}> failed to deleted.")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def cf
|
121
|
+
@cf ||= Aws::CfClient.new(
|
122
|
+
config[:region],
|
123
|
+
config[:shared_credentials_profile],
|
124
|
+
config[:ssl_cert_file],
|
125
|
+
config[:aws_access_key_id],
|
126
|
+
config[:aws_secret_access_key],
|
127
|
+
config[:aws_session_token]
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
131
|
+
def stack_generator
|
132
|
+
@stack_generator ||= Aws::StackGenerator.new(config, cf)
|
133
|
+
end
|
134
|
+
|
135
|
+
# This copies transport config from the current config object into the
|
136
|
+
# state. This relies on logic in the transport that merges the transport
|
137
|
+
# config with the current state object, so its a bad coupling. But we
|
138
|
+
# can get rid of this when we get rid of these deprecated configs!
|
139
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
140
|
+
def copy_deprecated_configs(state)
|
141
|
+
if config[:ssh_timeout]
|
142
|
+
state[:connection_timeout] = config[:ssh_timeout]
|
143
|
+
end
|
144
|
+
if config[:ssh_retries]
|
145
|
+
state[:connection_retries] = config[:ssh_retries]
|
146
|
+
end
|
147
|
+
if config[:username]
|
148
|
+
state[:username] = config[:username]
|
149
|
+
#elsif instance.transport[:username] == instance.transport.class.defaults[:username]
|
150
|
+
# # If the transport has the default username, copy it from amis.json
|
151
|
+
# # This duplicated old behavior but I hate amis.json
|
152
|
+
# ami_username = amis["usernames"][instance.platform.name]
|
153
|
+
# state[:username] = ami_username if ami_username
|
154
|
+
end
|
155
|
+
if config[:ssh_key]
|
156
|
+
state[:ssh_key] = config[:ssh_key]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
160
|
+
|
161
|
+
# Fog AWS helper for creating the stack
|
162
|
+
def create_stack
|
163
|
+
stack_data = stack_generator.cf_stack_data
|
164
|
+
info("Creating CloudFormation Stack #{stack_data[:stack_name]}")
|
165
|
+
cf.create_stack(stack_data)
|
166
|
+
end
|
167
|
+
|
168
|
+
def debug_stack_events(stack_name)
|
169
|
+
return unless logger.debug?
|
170
|
+
response = cf.get_stack_events(stack_name)
|
171
|
+
response[:stack_events].each do |r|
|
172
|
+
debug("#{r[:timestamp]} #{r[:resource_type]} #{r[:logical_resource_id]} #{r[:resource_status]} #{r[:resource_status_reason]}")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def display_stack_events(stack_name)
|
177
|
+
response = cf.get_stack_events(stack_name)
|
178
|
+
response[:stack_events].each do |r|
|
179
|
+
info("#{r[:timestamp]} #{r[:resource_type]} #{r[:logical_resource_id]} #{r[:resource_status]} #{r[:resource_status_reason]}")
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Kitchen
|
16
|
+
|
17
|
+
module Driver
|
18
|
+
|
19
|
+
# Version string for CloudFormation Test Kitchen driver
|
20
|
+
CLOUDFORMATION_VERSION = "0.0.1"
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kitchen-cloudformation
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Neill Turner
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: test-kitchen
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: excon
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: multi_json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: aws-sdk-v1
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.59.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.59.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: aws-sdk
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2'
|
83
|
+
description: A Test Kitchen Driver for Amazon AWS CloudFormation
|
84
|
+
email:
|
85
|
+
- neillwturner@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- CHANGELOG.md
|
91
|
+
- LICENSE
|
92
|
+
- README.md
|
93
|
+
- ca-bundle.crt
|
94
|
+
- kitchen-cloudformation.gemspec
|
95
|
+
- lib/kitchen/driver/aws/cf_client.rb
|
96
|
+
- lib/kitchen/driver/aws/stack_generator.rb
|
97
|
+
- lib/kitchen/driver/cloud_formation.rb
|
98
|
+
- lib/kitchen/driver/cloudformation_version.rb
|
99
|
+
homepage: https://github.com/neillturner/kitchen-cloudformation
|
100
|
+
licenses:
|
101
|
+
- Apache 2.0
|
102
|
+
metadata: {}
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubyforge_project:
|
119
|
+
rubygems_version: 2.2.3
|
120
|
+
signing_key:
|
121
|
+
specification_version: 4
|
122
|
+
summary: A Test Kitchen Driver for Amazon AWS CloudFormation
|
123
|
+
test_files: []
|