cfn2dsl 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 586d1c3a0f6716123303a6cfe7f7af3a7c85b13c
4
+ data.tar.gz: f4d6d21a4e9b79073f0ddbf0b7f9562bc33b4174
5
+ SHA512:
6
+ metadata.gz: 65bd8bf97a568b05a128cec15804d6f218c8ca39943ce791ce7d6c68a1b132e2f664d9d7b5c9dae151d5e1512554b1b1b3ee4d2638a681382c27349f9d82bcb1
7
+ data.tar.gz: 057ba371b67b737e833ce29a2266e6c35ad64b652fd200946b59be27d16437639a3d194b07afaf9460185cbdd5166e2552b59bdddacde6276cd107ee0d215508
data/bin/cfn2dsl ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/cfn2dsl'
3
+
4
+ USAGE = "Usage: #{File.basename(__FILE__)} -t|--template file [-o|--output file]"
5
+ options = {}
6
+ OptionParser.new do |opts|
7
+ opts.banner = USAGE
8
+ opts.on('-t', '--template file', 'Template file path') do |v|
9
+ options[:template] = v
10
+ end
11
+
12
+ opts.on('-o', '--output [file]', 'Output file path') do |v|
13
+ options[:output] = v
14
+ end
15
+
16
+ opts.on_tail('-h', '--help', 'show this message') do |_v|
17
+ puts opts
18
+ exit
19
+ end
20
+
21
+ opts.on_tail('-v', '--version', 'show the version') do |_v|
22
+ puts VERSION
23
+ exit
24
+ end
25
+ end.parse!
26
+
27
+ unless options[:template]
28
+ puts USAGE
29
+ exit 1
30
+ else
31
+ template = JSON.load(File.new(options[:template]))
32
+ cfndsl = CloudFormation.new(template)
33
+ end
34
+
35
+ if options[:output]
36
+ File.open(options[:output], 'w') do |file|
37
+ file.write(Render.new(cfndsl).cfn_to_cfndsl)
38
+ end
39
+ else
40
+ puts Render.new(cfndsl).cfn_to_cfndsl
41
+ end
42
+
data/lib/cfn2dsl.rb ADDED
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require 'json'
4
+ require 'optparse'
5
+ require 'ap'
6
+
7
+ require 'cfn_parser'
8
+ require 'cloudformation'
9
+ require 'condition'
10
+ require 'intrinsic_function'
11
+ require 'mapping'
12
+ require 'output'
13
+ require 'parameter'
14
+ require 'resource'
15
+ require 'render'
16
+
17
+ AwesomePrint.defaults = {
18
+ :indent => -2,
19
+ :index => false,
20
+ :sort_keys => true,
21
+ :plain => true
22
+ }
23
+
24
+ VERSION="0.1.4"
data/lib/cfn_parser.rb ADDED
@@ -0,0 +1,40 @@
1
+ module CfnParser
2
+
3
+ def parse_cfn_json(json)
4
+ send(element_type(json).to_s.snake_case, json)
5
+ end
6
+
7
+ def intrinsic_function?(obj)
8
+ obj.instance_of?(Hash) &&
9
+ obj.keys.size == 1 &&
10
+ (obj.keys.first =~ /^Fn::/ or obj.keys.first == "Ref")
11
+ end
12
+
13
+ def array(json)
14
+ return json.map { |a| parse_cfn_json(a) }
15
+ end
16
+
17
+ def intrinsic_function(json)
18
+ fn_name = json.keys.first
19
+ values = json[fn_name]
20
+ parameters = parse_cfn_json(values)
21
+ return IntrinsicFunction.new(fn_name, parameters)
22
+ end
23
+
24
+ def hash(json)
25
+ return json.merge(json) { |k, v| parse_cfn_json(v) }
26
+ end
27
+
28
+ def primitive(json)
29
+ json
30
+ end
31
+
32
+ private
33
+ def element_type(json)
34
+ return :Array if json.instance_of?(Array)
35
+ return :IntrinsicFunction if intrinsic_function?(json)
36
+ return :Hash if json.instance_of?(Hash)
37
+ return :Primitive
38
+ end
39
+ end
40
+
data/lib/cfndsl.erb ADDED
@@ -0,0 +1,204 @@
1
+ CloudFormation do
2
+ <% if @cfn.description %>
3
+ Description(<%= @cfn.description.dump %>)
4
+ <% end %>
5
+ <% if @cfn.aws_template_format_version %>
6
+ AWSTemplateFormatVersion(<%= @cfn.aws_template_format_version.dump %>)
7
+ <% end %>
8
+ <% # Parameters %>
9
+ <%
10
+ if @cfn.parameters
11
+ @cfn.parameters.each do |param|
12
+ %>
13
+
14
+ Parameter(<%= param.name.dump %>) do
15
+ <% if param.description %>
16
+ Description(<%= param.description.dump %>)
17
+ <% end %>
18
+ <% if param.type %>
19
+ Type(<%= param.type.dump %>)
20
+ <% end %>
21
+ <% if param.default
22
+ default_value = param.default
23
+ if param.default.respond_to? :dump
24
+ default_value = param.default.dump
25
+ end
26
+ %>
27
+ Default(<%= default_value %>)
28
+ <% end %>
29
+ <% if param.allowed_values %>
30
+ AllowedValues(<%= param.allowed_values.ai %>)
31
+ <% end %>
32
+ <% if param.allowed_pattern %>
33
+ AllowedPattern(<%= param.allowed_pattern.dump %>)
34
+ <% end %>
35
+ <% if param.no_echo %>
36
+ NoEcho(<%= param.no_echo %>)
37
+ <% end %>
38
+ <% if param.max_length %>
39
+ MaxLength(<%= param.max_length.to_i %>)
40
+ <% end %>
41
+ <% if param.min_length %>
42
+ MinLength(<%= param.min_length.to_i %>)
43
+ <% end %>
44
+ <% if param.max_value %>
45
+ MaxValue(<%= param.max_value %>)
46
+ <% end %>
47
+ <% if param.min_value %>
48
+ MinValue(<%= param.min_value %>)
49
+ <% end %>
50
+ <% if param.constraint_description %>
51
+ ConstraintDescription(<%= param.constraint_description.dump %>)
52
+ <% end %>
53
+ end
54
+ <%
55
+ end
56
+ end
57
+ %>
58
+ <% # Mappings %>
59
+ <%
60
+ if @cfn.mappings
61
+ @cfn.mappings.each do |map|
62
+ %>
63
+
64
+ Mapping(<%= map.name.dump %>, <%= map.values.ai %>)
65
+ <%
66
+ end
67
+ end
68
+ %>
69
+ <% # Conditions %>
70
+ <%
71
+ if @cfn.conditions
72
+ @cfn.conditions.each do |cond|
73
+ %>
74
+
75
+ Condition(<%= cond.name.dump %>, <%= cond.evaluations.ai %>)
76
+ <%
77
+ end
78
+ end
79
+ %>
80
+ <% # Resources %>
81
+ <%
82
+ @cfn.resources.each do |res|
83
+ %>
84
+
85
+ Resource(<%= res.name.dump %>) do
86
+ Type("<%= res.type %>")
87
+ <%
88
+ if res.creation_policy
89
+ %>
90
+ CreationPolicy(<%= res.creation_policy.dump %>)
91
+ <%
92
+ end
93
+ %>
94
+ <%
95
+ if res.deletion_policy
96
+ %>
97
+ DeletionPolicy(<%= res.deletion_policy.dump %>)
98
+ <%
99
+ end
100
+ %>
101
+ <%
102
+ if res.condition
103
+ %>
104
+ Condition(<%= res.condition.dump %>)
105
+ <%
106
+ end
107
+ %>
108
+ <%
109
+ if res.update_policy
110
+ res.update_policy.each_pair do |name, value|
111
+ if value.instance_of? String
112
+ value = value.dump
113
+ else
114
+ value = value.ai
115
+ end
116
+ %>
117
+ UpdatePolicy(<%= name.dump %>,<%= value %>)
118
+ <%
119
+ end
120
+ end
121
+ %>
122
+ <%
123
+ if res.metadata
124
+ res.metadata.each_pair do |name, value|
125
+ if value.instance_of? String
126
+ value = value.dump
127
+ else
128
+ value = value.ai
129
+ end
130
+ %>
131
+ Metadata(<%= name.dump %>, <%= value %>)
132
+ <%
133
+ end
134
+ end
135
+ %>
136
+ <%
137
+ if res.depends_on
138
+ if res.depends_on.instance_of? String
139
+ value = res.depends_on.dump
140
+ else
141
+ value = res.depends_on.ai
142
+ end
143
+ %>
144
+ DependsOn(<%= value %>)
145
+ <%
146
+ end
147
+ %>
148
+ <%
149
+ if res.properties
150
+ res.properties.each_pair do |name, value|
151
+ if value.instance_of? String
152
+ value = value.dump
153
+ else
154
+ value = value.ai
155
+ end
156
+ %>
157
+ Property(<%= name.dump %>, <%= value %>)
158
+ <%
159
+ end
160
+ end
161
+ %>
162
+ end
163
+ <%
164
+ end
165
+ %>
166
+ <% # Output %>
167
+ <%
168
+ if @cfn.outputs
169
+ @cfn.outputs.each do |out|
170
+ %>
171
+
172
+ Output(<%= out.name.dump %>) do
173
+ <%
174
+ if out.condition
175
+ %>
176
+ Condition(<%= out.condition.dump %>)
177
+ <%
178
+ end
179
+ %>
180
+ <%
181
+ if out.description
182
+ %>
183
+ Description(<%= out.description.dump %>)
184
+ <%
185
+ end
186
+ %>
187
+ <%
188
+ if out.value
189
+ if out.value.instance_of? String
190
+ value = out.value.dump
191
+ else
192
+ value = out.value.ai
193
+ end
194
+ %>
195
+ Value(<%= value %>)
196
+ <%
197
+ end
198
+ %>
199
+ end
200
+ <%
201
+ end
202
+ end
203
+ %>
204
+ end
@@ -0,0 +1,67 @@
1
+ require 'extlib'
2
+ class CloudFormation
3
+
4
+ ELEMENTS = [
5
+ :parameters,
6
+ :resources,
7
+ :conditions,
8
+ :outputs,
9
+ :mappings,
10
+ :description,
11
+ :aws_template_format_version
12
+ ]
13
+
14
+ attr_reader(*ELEMENTS)
15
+
16
+ def initialize(json)
17
+ ELEMENTS.each do |e|
18
+ key = e.to_s.camel_case
19
+ if key =~ /^Aws/
20
+ key = key.sub(/^Aws/, "AWS")
21
+ end
22
+
23
+ if json[key]
24
+ attr = parse_element(e, json[key])
25
+ instance_variable_set("@" + e.to_s, attr)
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+ def parse_element(elm_name, json)
32
+ function = parser(elm_name)
33
+ send(function, elm_name, json)
34
+ end
35
+
36
+ def parser(name)
37
+ case name
38
+ when :description
39
+ :simple_parser
40
+ when :aws_template_format_version
41
+ :simple_parser
42
+ else
43
+ :complex_parser
44
+ end
45
+ end
46
+
47
+ def simple_parser(name, json)
48
+ json
49
+ end
50
+
51
+ def complex_parser(name, json)
52
+ elms = []
53
+ case name
54
+ when :parameters
55
+ json.each_pair { |k, v| elms << Parameter.new(k, v) }
56
+ when :resources
57
+ json.each_pair { |k, v| elms << Resource.new(k, v) }
58
+ when :outputs
59
+ json.each_pair { |k, v| elms << Output.new(k, v) }
60
+ when :mappings
61
+ json.each_pair { |k, v| elms << Mapping.new(k, v) }
62
+ when :conditions
63
+ json.each_pair { |k, v| elms << Condition.new(k, v) }
64
+ end
65
+ return elms
66
+ end
67
+ end
data/lib/condition.rb ADDED
@@ -0,0 +1,9 @@
1
+ class Condition
2
+ include CfnParser
3
+ attr_reader(:name, :evaluations)
4
+
5
+ def initialize(name, eval)
6
+ @name = name
7
+ @evaluations = parse_cfn_json(eval)
8
+ end
9
+ end
@@ -0,0 +1,121 @@
1
+ class IntrinsicFunction
2
+ attr_reader :name, :parameters
3
+
4
+ def initialize(name, parameters)
5
+ @name = name
6
+ @parameters = parameters
7
+ end
8
+
9
+ def to_s
10
+ function_name = @name.delete(':').snake_case
11
+ send(function_name)
12
+ end
13
+
14
+ alias_method :inspect, :to_s
15
+
16
+ def ==(o)
17
+ o.instance_of?(IntrinsicFunction) and o.name == @name and @parameters == o.parameters
18
+ end
19
+
20
+ private
21
+ def fn_base64
22
+ if @parameters.instance_of? String
23
+ value = '"' + @parameters.gsub('"'){'\\"'} + '"'
24
+ else
25
+ value = @parameters.ai
26
+ end
27
+ return "FnBase64(#{value})"
28
+ end
29
+
30
+ def fn_select
31
+ return "FnSelect(#{@parameters[0]}, #{@parameters[1..@parameters.size].ai})"
32
+ end
33
+
34
+ def ref
35
+ return "Ref(\"#{@parameters.gsub('"'){'\\"'}}\")"
36
+ end
37
+
38
+ def fn_and
39
+ return "FnAnd(#{@parameters.ai})"
40
+ end
41
+
42
+ def fn_equals
43
+ if @parameters[0].instance_of? String
44
+ arg1 = '"' + @parameters[0].gsub('"'){'\\"'} + '"'
45
+ else
46
+ arg1 = @parameters[0].ai
47
+ end
48
+
49
+ if @parameters[1].instance_of? String
50
+ arg2 = '"' + @parameters[1].gsub('"'){'\\"'} + '"'
51
+ else
52
+ arg2 = @parameters[1].ai
53
+ end
54
+
55
+ return "FnEquals(#{arg1}, #{arg2})"
56
+ end
57
+
58
+ def fn_if
59
+ cond_name = '"' + @parameters[0].gsub('"'){'\\"'} + '"'
60
+ if @parameters[1].instance_of? String
61
+ true_value = '"' + @parameters[1].gsub('"'){'\\"'} + '"'
62
+ else
63
+ true_value = @parameters[1].ai
64
+ end
65
+
66
+ if @parameters[2].instance_of? String
67
+ false_value = '"' + @parameters[2].gsub('"'){'\\"'} + '"'
68
+ else
69
+ false_value = @parameters[2].ai
70
+ end
71
+ return "FnIf(#{cond_name}, #{true_value}, #{false_value})"
72
+ end
73
+
74
+ def fn_not
75
+ return "FnNot(#{@parameters.ai})"
76
+ end
77
+
78
+ def fn_or
79
+ return "FnOr(#{@parameters.ai})"
80
+ end
81
+
82
+ def fn_find_in_map
83
+ map_name = '"' + @parameters[0] + '"'
84
+
85
+ if @parameters[1].instance_of? String
86
+ top_level_key = '"' + @parameters[1] + '"'
87
+ else
88
+ top_level_key = @parameters[1].ai
89
+ end
90
+
91
+ if @parameters[2].instance_of? String
92
+ sec_level_key = '"' + @parameters[2] + '"'
93
+ else
94
+ sec_level_key = @parameters[2].ai
95
+ end
96
+
97
+ return "FnFindInMap(#{map_name}, #{top_level_key}, #{sec_level_key})"
98
+ end
99
+
100
+ def fn_get_att
101
+ resource_name = '"' + @parameters[0] + '"'
102
+ attr_name = '"' + @parameters[1] + '"'
103
+ return "FnGetAtt(#{resource_name}, #{attr_name})"
104
+ end
105
+
106
+ def fn_join
107
+ seperator = '"' + @parameters[0].gsub('"'){'\\"'} + '"'
108
+ values = @parameters[1].ai
109
+ return "FnJoin(#{seperator}, #{values})"
110
+ end
111
+
112
+ def fn_get_a_zs
113
+ if @parameters.instance_of? String
114
+ value = '"' + @parameters.gsub('"'){'\\"'} + '"'
115
+ else
116
+ value = @parameters.ai
117
+ end
118
+
119
+ return "FnGetAZs(#{value})"
120
+ end
121
+ end
data/lib/mapping.rb ADDED
@@ -0,0 +1,9 @@
1
+ class Mapping
2
+ include CfnParser
3
+ attr_reader(:name, :values)
4
+
5
+ def initialize(name, values)
6
+ @name = name
7
+ @values = parse_cfn_json(values)
8
+ end
9
+ end
data/lib/output.rb ADDED
@@ -0,0 +1,26 @@
1
+ class Output
2
+ include CfnParser
3
+
4
+ ATTRIBUTES = [
5
+ :value,
6
+ :condition,
7
+ :description
8
+ ]
9
+
10
+ attr_reader(:name, *ATTRIBUTES)
11
+
12
+ def initialize(name, json)
13
+ @name = name
14
+ ATTRIBUTES.each {|a| attribute(a, json)}
15
+ end
16
+
17
+ private
18
+ def attribute(name, json)
19
+ key = name.to_s.camel_case
20
+ if json[key]
21
+ value = parse_cfn_json(json[key])
22
+ instance_variable_set("@" + name.to_s, value)
23
+ end
24
+ end
25
+ end
26
+
data/lib/parameter.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'extlib'
2
+ class Parameter
3
+ ELEMENTS = [
4
+ :name,
5
+ :type,
6
+ :default,
7
+ :description,
8
+ :allowed_values,
9
+ :allowed_pattern,
10
+ :no_echo,
11
+ :max_length,
12
+ :min_length,
13
+ :max_value,
14
+ :min_value,
15
+ :constraint_description
16
+ ]
17
+
18
+ attr_reader(*ELEMENTS)
19
+
20
+ def initialize(name, json)
21
+ @name = name
22
+ ELEMENTS.each do |e|
23
+ key_name = e.to_s.camel_case
24
+ instance_variable_set('@' + e.to_s, json[key_name]) if json[key_name]
25
+ end
26
+ end
27
+ end
data/lib/render.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'erubis'
2
+ class Render
3
+
4
+ attr_reader :cfn
5
+
6
+ def initialize(cfn)
7
+ @cfn = cfn
8
+ end
9
+
10
+ def cfn_to_cfndsl
11
+ input = File.read("#{File.dirname(__FILE__)}/cfndsl.erb")
12
+ context = { :cfn => @cfn }
13
+ Erubis::Eruby.new(input).evaluate(context).to_s
14
+ end
15
+ end
data/lib/resource.rb ADDED
@@ -0,0 +1,54 @@
1
+ class Resource
2
+ include CfnParser
3
+
4
+ ATTRIBUTES = [
5
+ :deletion_policy,
6
+ :depends_on,
7
+ :metadata,
8
+ :update_policy,
9
+ :condition,
10
+ :type,
11
+ :properties,
12
+ :creation_policy
13
+ ]
14
+
15
+ attr_reader(:name, *ATTRIBUTES)
16
+
17
+ def initialize(name, json)
18
+ @name = name
19
+ ATTRIBUTES.each do |a|
20
+ send(attribute_type(a), json, a.to_s)
21
+ end
22
+ end
23
+
24
+ private
25
+ def attribute_type(name)
26
+ type = ''
27
+ case name
28
+ when name == :properties ||
29
+ name == :metadata ||
30
+ name == :update_policy ||
31
+ name == :depends_on ||
32
+ name == :creation_policy
33
+ type = "complex_attribute"
34
+ else
35
+ type = "basic_attribute"
36
+ end
37
+ return type
38
+ end
39
+
40
+ def complex_attribute(json, name)
41
+ if json[name.camel_case]
42
+ values = json[name.camel_case].merge do |k, v|
43
+ parse_cfn_json(v)
44
+ end
45
+ instance_variable_set('@' + name, values)
46
+ end
47
+ end
48
+
49
+ def basic_attribute(json, name)
50
+ if json[name.camel_case]
51
+ instance_variable_set('@' + name, parse_cfn_json(json[name.camel_case]))
52
+ end
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cfn2dsl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - kevin yung (kevin.yung@rea-group.com)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: extlib
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: awesome_print
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: ruby-beautify
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: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: erubis
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: A tool to convert CloudFormation JSON template into a Ruby DSL cfndsl
84
+ email:
85
+ executables:
86
+ - cfn2dsl
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - bin/cfn2dsl
91
+ - lib/cfn2dsl.rb
92
+ - lib/cfn_parser.rb
93
+ - lib/cfndsl.erb
94
+ - lib/cloudformation.rb
95
+ - lib/condition.rb
96
+ - lib/intrinsic_function.rb
97
+ - lib/mapping.rb
98
+ - lib/output.rb
99
+ - lib/parameter.rb
100
+ - lib/render.rb
101
+ - lib/resource.rb
102
+ homepage: https://github.com/realestate-com-au/cfn2dsl.git
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - '>='
113
+ - !ruby/object:Gem::Version
114
+ version: 2.0.0
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.2.2
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: A tool to convert CloudFormation JSON template into a Ruby DSL cfndsl
126
+ test_files: []