cloudformation-ruby-dsl 1.2.3 → 1.2.4
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/README.md +1 -0
- data/Rakefile +8 -0
- data/bin/cfntemplate-to-ruby +2 -0
- data/cloudformation-ruby-dsl.gemspec +3 -0
- data/docs/Contributing.md +3 -2
- data/examples/cloudformation-ruby-script.rb +20 -0
- data/examples/simple_template.rb +9 -0
- data/lib/cloudformation-ruby-dsl/cfntemplate.rb +28 -16
- data/lib/cloudformation-ruby-dsl/dsl.rb +93 -11
- data/lib/cloudformation-ruby-dsl/version.rb +1 -1
- data/spec/spec_helper.rb +161 -0
- data/spec/validation_spec.rb +26 -0
- metadata +36 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b96d9566c8f7eb64af7c88c4d809d6c6b6cd79ac
|
4
|
+
data.tar.gz: d43e2ce163a5047f8aeecd15cf936bdf422bfff8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 457204dfb740fbccc51371e4017006bab15e9b03e3ced9bace517850f0494008dc653171b60626c02addc13fe191c25c5601cd466a469c16d0381c4ae12a67e6
|
7
|
+
data.tar.gz: 12a0a10691d43c267fb2172a9a0ba7b703f4f16ecebd95f856a1028ac4b5924def354dae0f10d1ea60d6e27371a33e31b035fd99244b37142ea294b978439c53
|
data/README.md
CHANGED
data/Rakefile
CHANGED
data/bin/cfntemplate-to-ruby
CHANGED
@@ -113,6 +113,8 @@ def pprint_cfn_template(tpl)
|
|
113
113
|
puts
|
114
114
|
tpl.each do |section, v|
|
115
115
|
case section
|
116
|
+
when 'Metadata'
|
117
|
+
v.each { |name, options| pprint_cfn_section 'metadata', name, options }
|
116
118
|
when 'Parameters'
|
117
119
|
v.each { |name, options| pprint_cfn_section 'parameter', name, options }
|
118
120
|
when 'Mappings'
|
data/docs/Contributing.md
CHANGED
@@ -8,7 +8,8 @@ To get started:
|
|
8
8
|
|
9
9
|
- fork this project on github
|
10
10
|
- create a new branch named after the change you want to make; i.e., `git checkout -b mynewfeature`
|
11
|
-
- make your changes and commit them
|
11
|
+
- make your changes (including tests) and commit them
|
12
|
+
- run the tests to make sure you haven't broken anything: ```rspec```
|
12
13
|
- send a pull request to this project from your fork/branch
|
13
14
|
|
14
15
|
Once you've sent your pull request, one of the project collaborators will review it and provide feedback. Please accept this commentary as constructive! It is intended as such.
|
@@ -18,4 +19,4 @@ Once you've sent your pull request, one of the project collaborators will review
|
|
18
19
|
We're opinionated about git. Don't be surprised if we ask you to update your pull request to meet the following standards.
|
19
20
|
|
20
21
|
- rebase+squash your branch into a single commit. For clean git history, we'd prefer we merged in just 1 commit that contains the entire set of changes.
|
21
|
-
- don't write commit messages longer than 50 characters. See [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) for some examples of how to achieve this, and why.
|
22
|
+
- don't write commit messages longer than 50 characters. See [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) for some examples of how to achieve this, and why.
|
@@ -23,6 +23,26 @@ require 'cloudformation-ruby-dsl/table'
|
|
23
23
|
|
24
24
|
template do
|
25
25
|
|
26
|
+
# Metadata may be embedded into the stack, as per http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html
|
27
|
+
# The below definition produces CloudFormation interface metadata.
|
28
|
+
metadata 'AWS::CloudFormation::Interface', {
|
29
|
+
:ParameterGroups => [
|
30
|
+
{
|
31
|
+
:Label => { :default => 'Instance options' },
|
32
|
+
:Parameters => [ 'InstanceType', 'ImageId', 'KeyPairName' ]
|
33
|
+
},
|
34
|
+
{
|
35
|
+
:Label => { :default => 'Other options' },
|
36
|
+
:Parameters => [ 'Label', 'EmailAddress' ]
|
37
|
+
}
|
38
|
+
],
|
39
|
+
:ParameterLabels => {
|
40
|
+
:EmailAddress => {
|
41
|
+
:default => "We value your privacy!"
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
26
46
|
parameter 'Label',
|
27
47
|
:Description => 'The label to apply to the servers.',
|
28
48
|
:Type => 'String',
|
@@ -37,7 +37,7 @@ class AwsCfn
|
|
37
37
|
def initialize(args)
|
38
38
|
Aws.config[:region] = args[:region] if args.key?(:region)
|
39
39
|
# Profile definition was replaced with environment variables
|
40
|
-
if args.key?(:aws_profile)
|
40
|
+
if args.key?(:aws_profile) && !(args[:aws_profile].nil? || args[:aws_profile].empty?)
|
41
41
|
ENV['AWS_PROFILE'] = args[:aws_profile]
|
42
42
|
ENV['AWS_ACCESS_KEY'] = nil
|
43
43
|
ENV['AWS_ACCESS_KEY_ID'] = nil
|
@@ -78,26 +78,32 @@ end
|
|
78
78
|
|
79
79
|
# Parse command-line arguments and return the parameters and region
|
80
80
|
def parse_args
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
81
|
+
args = {
|
82
|
+
:stack_name => nil,
|
83
|
+
:parameters => {},
|
84
|
+
:interactive => false,
|
85
|
+
:region => default_region,
|
86
|
+
:profile => nil,
|
87
|
+
:nopretty => false,
|
88
|
+
}
|
86
89
|
ARGV.slice_before(/^--/).each do |name, value|
|
87
90
|
case name
|
88
91
|
when '--stack-name'
|
89
|
-
stack_name = value
|
92
|
+
args[:stack_name] = value
|
90
93
|
when '--parameters'
|
91
|
-
parameters = Hash[value.split(/;/).map { |pair| pair.split(/=/, 2) }] #/# fix for syntax highlighting
|
94
|
+
args[:parameters] = Hash[value.split(/;/).map { |pair| pair.split(/=/, 2) }] #/# fix for syntax highlighting
|
95
|
+
when '--interactive'
|
96
|
+
args[:interactive] = true
|
92
97
|
when '--region'
|
93
|
-
region = value
|
98
|
+
args[:region] = value
|
94
99
|
when '--profile'
|
95
|
-
profile = value
|
100
|
+
args[:profile] = value
|
96
101
|
when '--nopretty'
|
97
|
-
nopretty = true
|
102
|
+
args[:nopretty] = true
|
98
103
|
end
|
99
104
|
end
|
100
|
-
|
105
|
+
|
106
|
+
args
|
101
107
|
end
|
102
108
|
|
103
109
|
def validate_action(action)
|
@@ -294,13 +300,16 @@ def cfn(template)
|
|
294
300
|
template_body: template_string,
|
295
301
|
parameters: template.parameters.map { |k,v| {parameter_key: k, parameter_value: v}}.to_a,
|
296
302
|
tags: cfn_tags.map { |k,v| {"key" => k.to_s, "value" => v} }.to_a,
|
297
|
-
capabilities: ["
|
303
|
+
capabilities: ["CAPABILITY_NAMED_IAM"],
|
298
304
|
}
|
299
305
|
|
300
306
|
# fill in options from the command line
|
301
307
|
extra_options = parse_arg_array_as_hash(options)
|
302
308
|
create_stack_opts = extra_options.merge(create_stack_opts)
|
303
309
|
|
310
|
+
# remove custom options
|
311
|
+
create_stack_opts.delete(:interactive)
|
312
|
+
|
304
313
|
# create stack
|
305
314
|
create_result = cfn_client.create_stack(create_stack_opts)
|
306
315
|
if create_result.successful?
|
@@ -486,13 +495,16 @@ def cfn(template)
|
|
486
495
|
template_body: template_string,
|
487
496
|
parameters: template.parameters.map { |k,v| {parameter_key: k, parameter_value: v}}.to_a,
|
488
497
|
tags: cfn_tags.map { |k,v| {"key" => k.to_s, "value" => v.to_s} }.to_a,
|
489
|
-
capabilities: ["
|
498
|
+
capabilities: ["CAPABILITY_NAMED_IAM"],
|
490
499
|
}
|
491
500
|
|
492
501
|
# fill in options from the command line
|
493
502
|
extra_options = parse_arg_array_as_hash(options)
|
494
503
|
update_stack_opts = extra_options.merge(update_stack_opts)
|
495
504
|
|
505
|
+
# remove custom options
|
506
|
+
update_stack_opts.delete(:interactive)
|
507
|
+
|
496
508
|
# update the stack
|
497
509
|
update_result = cfn_client.update_stack(update_stack_opts)
|
498
510
|
if update_result.successful?
|
@@ -567,6 +579,6 @@ end
|
|
567
579
|
|
568
580
|
# Main entry point
|
569
581
|
def template(&block)
|
570
|
-
|
571
|
-
raw_template(
|
582
|
+
options = parse_args
|
583
|
+
raw_template(options, &block)
|
572
584
|
end
|
@@ -44,8 +44,8 @@ end
|
|
44
44
|
############################# CloudFormation DSL
|
45
45
|
|
46
46
|
# Main entry point
|
47
|
-
def raw_template(
|
48
|
-
TemplateDSL.new(
|
47
|
+
def raw_template(options, &block)
|
48
|
+
TemplateDSL.new(options, &block)
|
49
49
|
end
|
50
50
|
|
51
51
|
def default_region
|
@@ -54,14 +54,20 @@ end
|
|
54
54
|
|
55
55
|
# Core interpreter for the DSL
|
56
56
|
class TemplateDSL < JsonObjectDSL
|
57
|
-
attr_reader :parameters,
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
attr_reader :parameters,
|
58
|
+
:parameter_cli,
|
59
|
+
:aws_region,
|
60
|
+
:nopretty,
|
61
|
+
:stack_name,
|
62
|
+
:aws_profile
|
63
|
+
|
64
|
+
def initialize(options)
|
65
|
+
@parameters = options[:parameters]
|
66
|
+
@interactive = options[:interactive]
|
67
|
+
@stack_name = options[:stack_name]
|
68
|
+
@aws_region = options[:region]
|
69
|
+
@aws_profile = options[:profile]
|
70
|
+
@nopretty = options[:nopretty]
|
65
71
|
super()
|
66
72
|
end
|
67
73
|
|
@@ -71,7 +77,12 @@ class TemplateDSL < JsonObjectDSL
|
|
71
77
|
|
72
78
|
def parameter(name, options)
|
73
79
|
default(:Parameters, {})[name] = options
|
74
|
-
|
80
|
+
|
81
|
+
if @interactive
|
82
|
+
@parameters[name] ||= _get_parameter_from_cli(name, options)
|
83
|
+
else
|
84
|
+
@parameters[name] ||= options[:Default]
|
85
|
+
end
|
75
86
|
end
|
76
87
|
|
77
88
|
# Find parameters where the specified attribute is true then remove the attribute from the cfn template.
|
@@ -144,6 +155,8 @@ class TemplateDSL < JsonObjectDSL
|
|
144
155
|
end
|
145
156
|
end
|
146
157
|
|
158
|
+
def metadata(name, options) default(:Metadata, {})[name] = options end
|
159
|
+
|
147
160
|
def condition(name, options) default(:Conditions, {})[name] = options end
|
148
161
|
|
149
162
|
def resource(name, options) default(:Resources, {})[name] = options end
|
@@ -160,6 +173,73 @@ class TemplateDSL < JsonObjectDSL
|
|
160
173
|
{ :'Fn::FindInMap' => [ map, key, name ] }
|
161
174
|
end
|
162
175
|
end
|
176
|
+
|
177
|
+
private
|
178
|
+
def _get_parameter_from_cli(name, options)
|
179
|
+
# basic request
|
180
|
+
param_request = "Parameter '#{name}' (#{options[:Type]})"
|
181
|
+
|
182
|
+
# add description to request
|
183
|
+
if options.has_key?(:Description)
|
184
|
+
param_request += "\nDescription: #{options[:Description]}"
|
185
|
+
end
|
186
|
+
|
187
|
+
# add validation to the request
|
188
|
+
|
189
|
+
# allowed pattern
|
190
|
+
if options.has_key?(:AllowedPattern)
|
191
|
+
param_request += "\nAllowed Pattern: /#{options[:AllowedPattern]}/"
|
192
|
+
end
|
193
|
+
|
194
|
+
# allowed values
|
195
|
+
if options.has_key?(:AllowedValues)
|
196
|
+
param_request += "\nAllowed Values: #{options[:AllowedValues].join(', ')}"
|
197
|
+
end
|
198
|
+
|
199
|
+
# min/max length
|
200
|
+
if options.has_key?(:MinLength) or options.has_key?(:MaxLength)
|
201
|
+
min_length = "-infinity"
|
202
|
+
max_length = "+infinity"
|
203
|
+
if options.has_key?(:MinLength)
|
204
|
+
min_length = options[:MinLength]
|
205
|
+
end
|
206
|
+
if options.has_key?(:MaxLength)
|
207
|
+
max_length = options[:MaxLength]
|
208
|
+
end
|
209
|
+
param_request += "\nValid Length: #{min_length} < string < #{max_length}"
|
210
|
+
end
|
211
|
+
|
212
|
+
# min/max value
|
213
|
+
if options.has_key?(:MinValue) or options.has_key?(:MaxValue)
|
214
|
+
min_value = "-infinity"
|
215
|
+
max_value = "+infinity"
|
216
|
+
if options.has_key?(:MinValue)
|
217
|
+
min_value = options[:MinValue]
|
218
|
+
end
|
219
|
+
if options.has_key?(:MaxValue)
|
220
|
+
max_value = options[:MaxValue]
|
221
|
+
end
|
222
|
+
param_request += "\nValid Number: #{min_value} < number < #{max_value}"
|
223
|
+
end
|
224
|
+
|
225
|
+
# add default to request
|
226
|
+
if options.has_key?(:Default) and !options[:Default].nil?
|
227
|
+
param_request += "\nLeave value empty for default: #{options[:Default]}"
|
228
|
+
end
|
229
|
+
|
230
|
+
param_request += "\nValue: "
|
231
|
+
|
232
|
+
# request the param
|
233
|
+
$stdout.puts "===================="
|
234
|
+
$stdout.print param_request
|
235
|
+
input = $stdin.gets.chomp
|
236
|
+
|
237
|
+
if input.nil? or input.empty?
|
238
|
+
options[:Default]
|
239
|
+
else
|
240
|
+
input
|
241
|
+
end
|
242
|
+
end
|
163
243
|
end
|
164
244
|
|
165
245
|
def base64(value) { :'Fn::Base64' => value } end
|
@@ -170,6 +250,8 @@ def get_att(resource, attribute) { :'Fn::GetAtt' => [ resource, attribute ] } en
|
|
170
250
|
|
171
251
|
def get_azs(region = '') { :'Fn::GetAZs' => region } end
|
172
252
|
|
253
|
+
def import_value(value) { :'Fn::ImportValue' => value } end
|
254
|
+
|
173
255
|
def join(delim, *list)
|
174
256
|
case list.length
|
175
257
|
when 0 then ''
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'json'
|
3
|
+
require 'open3'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Error encapsulating information about a failed command
|
7
|
+
class CommandError < StandardError
|
8
|
+
attr_reader :command, :status, :stderr
|
9
|
+
|
10
|
+
def initialize(command, status, stderr)
|
11
|
+
@command = command
|
12
|
+
@status = status
|
13
|
+
@stderr = stderr
|
14
|
+
super "FAILURE (#{status}) #{stderr}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Helpers for dealing with pathing from specs
|
20
|
+
module PathHelpers
|
21
|
+
##
|
22
|
+
# Returns an absolute path for the specified path that
|
23
|
+
# is relative to the project root irregardless of where
|
24
|
+
# rspec/ruby is invoked
|
25
|
+
def from_project_root(relative_path)
|
26
|
+
source_dir = File.expand_path(File.dirname(__FILE__))
|
27
|
+
File.join(source_dir, "..", relative_path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Mixin containing helper methods for working with
|
33
|
+
# commands executed in a subshell
|
34
|
+
module CommandHelpers
|
35
|
+
include PathHelpers
|
36
|
+
|
37
|
+
##
|
38
|
+
# Logs the command that failed and raises an exception
|
39
|
+
# inlcuding status and stderr
|
40
|
+
def cmd_failed(command, status, stderr)
|
41
|
+
STDERR.puts("FAILURE executing #{command}")
|
42
|
+
raise CommandError.new(command, status, stderr)
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# execute a command within a specified directory and
|
47
|
+
# return results or yield them to a block if one is
|
48
|
+
# given to this method. Results are an array of
|
49
|
+
# strings:
|
50
|
+
#
|
51
|
+
# [stdout, token1, token2, ..., tokenN]
|
52
|
+
#
|
53
|
+
# where stdout is the captured standard output and
|
54
|
+
# the tokens are the words extracted from the output.
|
55
|
+
#
|
56
|
+
# If the command has a non-zero exit status, an
|
57
|
+
# exception is raised including the exit code
|
58
|
+
# and stderr.
|
59
|
+
#
|
60
|
+
# example call:
|
61
|
+
# exec_cmd("ls", :within => "/")
|
62
|
+
def exec_cmd(cmd, opts={:within => "."})
|
63
|
+
exec_dir = from_project_root(opts[:within])
|
64
|
+
Dir.chdir(exec_dir) do
|
65
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
66
|
+
results = stdout.split(" ").unshift(stdout)
|
67
|
+
|
68
|
+
cmd_failed(cmd, status, stderr) if status != 0
|
69
|
+
if (block_given?)
|
70
|
+
yield results
|
71
|
+
else
|
72
|
+
results
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Mixin with helper methods for dealing with JSON generated
|
80
|
+
# from cloudformation-ruby-dsl
|
81
|
+
module JsonHelpers
|
82
|
+
##
|
83
|
+
# Parse the json string, making sure to write all of it to
|
84
|
+
# STDERR if parsing fails to make it easier to troubleshoot
|
85
|
+
# failures in generated json.
|
86
|
+
def jsparse(json_string)
|
87
|
+
begin
|
88
|
+
JSON.parse(json_string)
|
89
|
+
rescue StandardError => e
|
90
|
+
STDERR.puts "Error parsing JSON:"
|
91
|
+
STDERR.puts json_string
|
92
|
+
raise e
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Mixin with helper methods for dealing with files generated
|
99
|
+
# from a test/spec
|
100
|
+
module FileHelpers
|
101
|
+
include PathHelpers
|
102
|
+
|
103
|
+
##
|
104
|
+
# Delete a file from the spec/tmp directory
|
105
|
+
def delete_test_file(filename)
|
106
|
+
abs_path = File.join(from_project_root("spec/tmp"), filename)
|
107
|
+
FileUtils.rm(abs_path)
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# Write a file to the spec/tmp directory
|
112
|
+
def write_test_file(filename, contents)
|
113
|
+
dest_dir = from_project_root("spec/tmp")
|
114
|
+
dest_file = File.join(dest_dir, filename)
|
115
|
+
|
116
|
+
FileUtils.mkdir_p(dest_dir)
|
117
|
+
File.open(dest_file, "w") { |f| f.write(contents) }
|
118
|
+
dest_file
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Mixin to assist in using aws cli for validating results of
|
124
|
+
# cloudformation-ruby-dsl
|
125
|
+
module AwsHelpers
|
126
|
+
include CommandHelpers
|
127
|
+
|
128
|
+
##
|
129
|
+
# Validate a cloudformation template within the spec/tmp directory
|
130
|
+
# using aws cli
|
131
|
+
def validate_cfn_template(template_name)
|
132
|
+
template_path = File.join(from_project_root("spec/tmp"), template_name)
|
133
|
+
command = validation_command(template_path)
|
134
|
+
exec_cmd(command) do |output|
|
135
|
+
begin
|
136
|
+
JSON.parse(output.first)
|
137
|
+
rescue JSON::ParserError
|
138
|
+
STDERR.puts "ERROR parsing output of: #{command}"
|
139
|
+
raise
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def profile
|
145
|
+
ENV["AWS_PROFILE"] || "default"
|
146
|
+
end
|
147
|
+
|
148
|
+
def region
|
149
|
+
ENV["AWS_REGION"] || "us-east-1"
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
def validation_command(template_path)
|
155
|
+
return <<-EOF
|
156
|
+
aws cloudformation validate-template --template-body file://#{template_path} \
|
157
|
+
--region #{region} \
|
158
|
+
--profile #{profile}
|
159
|
+
EOF
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.shared_examples "template acceptance validations" do
|
4
|
+
include CommandHelpers
|
5
|
+
include JsonHelpers
|
6
|
+
include FileHelpers
|
7
|
+
include AwsHelpers
|
8
|
+
|
9
|
+
it "should create a valid JSON template from the example ruby template" do
|
10
|
+
delete_test_file(json_template)
|
11
|
+
json = exec_cmd("./#{ruby_template} expand", :within => "examples").first
|
12
|
+
write_test_file(json_template, json)
|
13
|
+
validate_cfn_template(json_template)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "cloudformation-ruby-dsl" do
|
18
|
+
context "simplest template" do
|
19
|
+
let(:ruby_template) { "simple_template.rb" }
|
20
|
+
let(:json_template) { "simple_template.json" }
|
21
|
+
|
22
|
+
include_examples "template acceptance validations"
|
23
|
+
end
|
24
|
+
|
25
|
+
# TODO validate examples/cloudformation-ruby-script.rb
|
26
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudformation-ruby-dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shawn Smith
|
@@ -15,7 +15,7 @@ authors:
|
|
15
15
|
autorequire:
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
|
-
date: 2016-
|
18
|
+
date: 2016-10-12 00:00:00.000000000 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: detabulator
|
@@ -115,6 +115,34 @@ dependencies:
|
|
115
115
|
- - '>='
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
|
+
- !ruby/object:Gem::Dependency
|
119
|
+
name: rspec
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
type: :development
|
126
|
+
prerelease: false
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
- !ruby/object:Gem::Dependency
|
133
|
+
name: pry
|
134
|
+
requirement: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
type: :development
|
140
|
+
prerelease: false
|
141
|
+
version_requirements: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
118
146
|
description: Ruby DSL library that provides a wrapper around the CloudFormation.
|
119
147
|
email:
|
120
148
|
- Shawn.Smith@bazaarvoice.com
|
@@ -150,6 +178,7 @@ files:
|
|
150
178
|
- examples/maps/more_maps/map3.json
|
151
179
|
- examples/maps/table.txt
|
152
180
|
- examples/maps/vpc.txt
|
181
|
+
- examples/simple_template.rb
|
153
182
|
- examples/userdata.sh
|
154
183
|
- initial_contributions.md
|
155
184
|
- lib/cloudformation-ruby-dsl.rb
|
@@ -158,6 +187,8 @@ files:
|
|
158
187
|
- lib/cloudformation-ruby-dsl/spotprice.rb
|
159
188
|
- lib/cloudformation-ruby-dsl/table.rb
|
160
189
|
- lib/cloudformation-ruby-dsl/version.rb
|
190
|
+
- spec/spec_helper.rb
|
191
|
+
- spec/validation_spec.rb
|
161
192
|
homepage: http://github.com/bazaarvoice/cloudformation-ruby-dsl
|
162
193
|
licenses: []
|
163
194
|
metadata: {}
|
@@ -183,4 +214,6 @@ signing_key:
|
|
183
214
|
specification_version: 4
|
184
215
|
summary: Ruby DSL library that provides a wrapper around the CloudFormation. Written
|
185
216
|
by [Bazaarvoice](http://www.bazaarvoice.com).
|
186
|
-
test_files:
|
217
|
+
test_files:
|
218
|
+
- spec/spec_helper.rb
|
219
|
+
- spec/validation_spec.rb
|