aws-cfn-dsl 0.0.4 → 0.1.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 +5 -13
- data/Gemfile +7 -0
- data/aws-cfn-dsl.gemspec +4 -6
- data/aws-cfn-dsl.iml +9 -15
- data/bin/cfn-dsl +31 -0
- data/lib/aws/cfn/dsl.rb +6 -8
- data/lib/aws/cfn/dsl/base.rb +355 -0
- data/lib/aws/cfn/dsl/fncall.rb +21 -0
- data/lib/aws/cfn/dsl/main.rb +30 -0
- data/lib/aws/cfn/dsl/template.rb +242 -0
- data/lib/aws/cfn/dsl/version.rb +1 -1
- data/test/Mappings/AWSRegion2AMI.rb +10 -0
- data/test/Outputs/ChefSecurityGroup.rb +4 -0
- data/test/Outputs/ServerURL.rb +13 -0
- data/test/Outputs/ValidationKeyBucket.rb +4 -0
- data/test/Parameters/CookbookLocation.rb +5 -0
- data/test/Parameters/InstanceType.rb +7 -0
- data/test/Parameters/KeyName.rb +8 -0
- data/test/Parameters/RoleLocation.rb +5 -0
- data/test/Parameters/SSHLocation.rb +9 -0
- data/test/Resources/BucketPolicy.rb +28 -0
- data/test/Resources/ChefClientSecurityGroup.rb +2 -0
- data/test/Resources/ChefServer.rb +57 -0
- data/test/Resources/ChefServerSecurityGroup.rb +19 -0
- data/test/Resources/ChefServerUser.rb +18 -0
- data/test/Resources/ChefServerWaitCondition.rb +5 -0
- data/test/Resources/ChefServerWaitHandle.rb +2 -0
- data/test/Resources/HostKeys.rb +4 -0
- data/test/Resources/PrivateKeyBucket.rb +2 -0
- data/test/chef-server.json +392 -0
- data/test/chef-server.rb +40 -0
- metadata +67 -49
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZWFiMGM1NzE2NTExNDliMDVkZDA3NzliNmY2ZmY3NzBkYzkwMWRhYQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c40097a8abb684000122cdd14227aec38bcc416b
|
4
|
+
data.tar.gz: eaf401cf08d69d21f74d40de25f97474aa73d696
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MzcyOGFlOGFhNTEzZjU3YTdmMDg0N2Q0NjYxODUwYTI4ZGI5OGNkOGExM2Yw
|
11
|
-
YzA5YjY3YjgxYzZjMTNkNjIyYmNiNTRhMjZlNmI1MmY5ODQ2ZjU=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZDIzMTkxNzkzMzFmNTljMjJhNjA1MGI2Yzk2NTFkZmZhYjI2ZGMwZjNhZGRm
|
14
|
-
YzY0NmU2YWU1MWE4NThjMjRhZDFhZTI5MDU4NWE5NjI3NmFmMWU0ZGRiNjVi
|
15
|
-
Y2RmZjgxZDNkNjIyZDMwNDk1NDEyZmU1ZjhlZDE4MGZhZDQ5OWU=
|
6
|
+
metadata.gz: d80906483c8db621505162efbe96531e6c73b73b158b76e1e59a09687b8039a02dd45696006a8887502c07eee5404dc426ba6a96f2d2d90b377484b927219615
|
7
|
+
data.tar.gz: a413157cbdad632905f84e0f034bef262ebbaafd8cc00a128a4b8897ed65e4b648544c2e40a5006feebe6ef4ba99247ba5891de4f617347f4491f1bef3e1b664
|
data/Gemfile
CHANGED
@@ -2,3 +2,10 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in aws-cfn-dsl.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
gem 'cloudformation-ruby-dsl', :path => '../cloudformation-ruby-dsl', :group => :development
|
7
|
+
gem 'slop', :group => :development
|
8
|
+
|
9
|
+
gem 'json_pure', :group => :development
|
10
|
+
gem 'bundler', '~> 1.5', :group => :development
|
11
|
+
gem 'rake', :group => :development
|
data/aws-cfn-dsl.gemspec
CHANGED
@@ -18,11 +18,9 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency
|
22
|
-
spec.add_dependency
|
23
|
-
spec.add_dependency 'cloudformation-ruby-dsl',
|
21
|
+
spec.add_dependency 'awesome_print'
|
22
|
+
spec.add_dependency 'json'
|
23
|
+
spec.add_dependency 'cloudformation-ruby-dsl', '~> 0.4', '>= 0.4.3'
|
24
|
+
spec.add_dependency "slop"
|
24
25
|
|
25
|
-
spec.add_development_dependency "json_pure"
|
26
|
-
spec.add_development_dependency 'bundler', "~> 1.5"
|
27
|
-
spec.add_development_dependency 'rake'
|
28
26
|
end
|
data/aws-cfn-dsl.iml
CHANGED
@@ -3,24 +3,18 @@
|
|
3
3
|
<component name="CompassSettings">
|
4
4
|
<option name="compassSupportEnabled" value="true" />
|
5
5
|
</component>
|
6
|
-
<component name="FacetManager">
|
7
|
-
<facet type="gem" name="Ruby Gem">
|
8
|
-
<configuration>
|
9
|
-
<option name="GEM_APP_ROOT_PATH" value="$MODULE_DIR$" />
|
10
|
-
<option name="GEM_APP_TEST_PATH" value="$MODULE_DIR$/test" />
|
11
|
-
<option name="GEM_APP_LIB_PATH" value="$MODULE_DIR$/lib" />
|
12
|
-
</configuration>
|
13
|
-
</facet>
|
14
|
-
</component>
|
15
6
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
16
7
|
<exclude-output />
|
17
|
-
<content url="file://$MODULE_DIR$"
|
18
|
-
|
19
|
-
</content>
|
20
|
-
<orderEntry type="jdk" jdkName="RVM: ruby-1.9.3-p545 [aws-cfn-dsl]" jdkType="RUBY_SDK" />
|
8
|
+
<content url="file://$MODULE_DIR$" />
|
9
|
+
<orderEntry type="inheritedJdk" />
|
21
10
|
<orderEntry type="sourceFolder" forTests="false" />
|
22
|
-
<orderEntry type="
|
23
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
11
|
+
<orderEntry type="module" module-name="cloudformation-ruby-dsl" />
|
12
|
+
<orderEntry type="library" scope="PROVIDED" name="awesome_print (v1.2.0, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
13
|
+
<orderEntry type="library" scope="PROVIDED" name="detabulator (v0.1.0, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
14
|
+
<orderEntry type="library" scope="PROVIDED" name="json (v1.8.1, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
15
|
+
<orderEntry type="library" scope="PROVIDED" name="json_pure (v1.8.1, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
16
|
+
<orderEntry type="library" scope="PROVIDED" name="rake (v10.3.2, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
17
|
+
<orderEntry type="library" scope="PROVIDED" name="slop (v3.5.0, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
24
18
|
</component>
|
25
19
|
</module>
|
26
20
|
|
data/bin/cfn-dsl
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
path = File.dirname(__FILE__)
|
6
|
+
if File.exists?("#{path}/../.gitignore")
|
7
|
+
%w(aws-cfn-decompiler aws-cfn-compiler cloudformation-ruby-dsl).each do |mod|
|
8
|
+
add_path = File.expand_path(File.join(path, "../../#{mod}", "lib"))
|
9
|
+
$:.unshift(add_path)
|
10
|
+
end
|
11
|
+
else
|
12
|
+
# Borrowing from "whiches" gem ...
|
13
|
+
cmd = File.basename(__FILE__, '.rb')
|
14
|
+
exes = []
|
15
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
16
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
17
|
+
exts.each { |ext|
|
18
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
19
|
+
exes << exe if File.executable? exe
|
20
|
+
}
|
21
|
+
end
|
22
|
+
if exes.size > 0
|
23
|
+
path = File.dirname(exes[0])
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
add_path = File.expand_path(File.join(path, "..", "lib"))
|
28
|
+
$:.unshift(add_path)
|
29
|
+
|
30
|
+
require 'aws/cfn/dsl'
|
31
|
+
Aws::Cfn::Dsl::Main.new.run
|
data/lib/aws/cfn/dsl.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require 'json'
|
2
|
+
require 'ap'
|
3
|
+
require 'yaml'
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Your code goes here...
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
5
|
+
require "aws/cfn/dsl/version"
|
6
|
+
require "aws/cfn/dsl/base"
|
7
|
+
require "aws/cfn/dsl/main"
|
@@ -0,0 +1,355 @@
|
|
1
|
+
require "aws/cfn/decompiler"
|
2
|
+
require "aws/cfn/dsl/fncall"
|
3
|
+
|
4
|
+
module Aws
|
5
|
+
module Cfn
|
6
|
+
module Dsl
|
7
|
+
class Base < Aws::Cfn::DeCompiler::Base
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@output = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def simplify(val)
|
14
|
+
if val.is_a?(Hash)
|
15
|
+
val = Hash[val.map { |k,v| [k, simplify(v)] }]
|
16
|
+
if val.length != 1
|
17
|
+
val
|
18
|
+
else
|
19
|
+
k, v = val.entries[0]
|
20
|
+
case
|
21
|
+
# CloudFormation functions
|
22
|
+
# when k == 'Fn::Base64'
|
23
|
+
# FnCall.new 'base64', [v], true
|
24
|
+
# when k == 'Fn::FindInMap'
|
25
|
+
# FnCall.new 'find_in_map', v
|
26
|
+
# when k == 'Fn::GetAtt'
|
27
|
+
# FnCall.new 'get_att', v
|
28
|
+
# when k == 'Fn::GetAZs'
|
29
|
+
# FnCall.new 'get_azs', v != '' ? [v] : []
|
30
|
+
# when k == 'Fn::Join'
|
31
|
+
# FnCall.new 'join', [v[0]] + v[1], true
|
32
|
+
# when k == 'Fn::Select'
|
33
|
+
# FnCall.new 'select', v
|
34
|
+
# when k == 'Ref' && v == 'AWS::Region'
|
35
|
+
# FnCall.new 'aws_region', []
|
36
|
+
# when k == 'Ref' && v == 'AWS::StackName'
|
37
|
+
# FnCall.new 'aws_stack_name', []
|
38
|
+
# CloudFormation internal references
|
39
|
+
# when k == 'Ref'
|
40
|
+
# FnCall.new 'ref', [v]
|
41
|
+
# Aws::Cfn::DSL functions
|
42
|
+
when k.match(%r'^Aws::Cfn::DSL')
|
43
|
+
FnCall.new k, [v]
|
44
|
+
else
|
45
|
+
val
|
46
|
+
end
|
47
|
+
end
|
48
|
+
elsif val.is_a?(Array)
|
49
|
+
val.map { |v| simplify(v) }
|
50
|
+
else
|
51
|
+
val
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def pprint(val)
|
56
|
+
case detect_type(val)
|
57
|
+
when :template
|
58
|
+
pprint_cfn_template(val)
|
59
|
+
when :parameter
|
60
|
+
pprint_cfn_section 'parameter', 'TODO', val, 'Parameters'
|
61
|
+
when :resource
|
62
|
+
pprint_cfn_resource 'TODO', val
|
63
|
+
when :parameters
|
64
|
+
val.each { |k, v| pprint_cfn_section 'parameter', k, v, 'Parameters' }
|
65
|
+
when :resources
|
66
|
+
val.each { |k, v| pprint_cfn_resource k, v }
|
67
|
+
else
|
68
|
+
pprint_value(val, '')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
|
74
|
+
def write(*s)
|
75
|
+
if s.is_a?(Array)
|
76
|
+
s = s.join('')
|
77
|
+
end
|
78
|
+
if @output.size > 0
|
79
|
+
@output[0].write s
|
80
|
+
else
|
81
|
+
print s
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def writeln(s='')
|
86
|
+
if @output.size > 0
|
87
|
+
@output[0].puts s
|
88
|
+
else
|
89
|
+
puts s
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Attempt to figure out what fragment of the template we have. This is imprecise and can't
|
94
|
+
# detect Mappings and Outputs sections reliably, so it doesn't attempt to.
|
95
|
+
def detect_type(val)
|
96
|
+
if val.is_a?(Hash) && val['AWSTemplateFormatVersion']
|
97
|
+
:template
|
98
|
+
elsif val.is_a?(Hash) && /^(String|Number)$/ =~ val['Type']
|
99
|
+
:parameter
|
100
|
+
elsif val.is_a?(Hash) && val['Type']
|
101
|
+
:resource
|
102
|
+
elsif val.is_a?(Hash) && val.values.all? { |v| detect_type(v) == :parameter }
|
103
|
+
:parameters
|
104
|
+
elsif val.is_a?(Hash) && val.values.all? { |v| detect_type(v) == :resource }
|
105
|
+
:resources
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def pprint_cfn_template(tpl)
|
110
|
+
open_output('',File.basename(@opts[:template].gsub(%r'\.(json|yaml|rb)'i,'')))
|
111
|
+
writeln "#!/usr/bin/env ruby"
|
112
|
+
writeln
|
113
|
+
if @opts[:output]
|
114
|
+
writeln "$:.unshift(File.dirname(__FILE__))"
|
115
|
+
# noinspection RubyExpressionInStringInspection
|
116
|
+
writeln '$:.unshift File.absolute_path("#{File.dirname(__FILE__)}/../lib")'
|
117
|
+
end
|
118
|
+
writeln "require 'bundler/setup'"
|
119
|
+
writeln "require 'aws/cfn/dsl/template'"
|
120
|
+
#writeln "require 'cloudformation-ruby-dsl/spotprice'"
|
121
|
+
# writeln "require 'cloudformation-ruby-dsl/table'"
|
122
|
+
writeln
|
123
|
+
writeln "template do"
|
124
|
+
writeln
|
125
|
+
tpl.each do |section, v|
|
126
|
+
case section
|
127
|
+
when 'Parameters'
|
128
|
+
when 'Mappings'
|
129
|
+
when 'Resources'
|
130
|
+
when 'Outputs'
|
131
|
+
else
|
132
|
+
write " value #{fmt_key(section)} => "
|
133
|
+
pprint_value v, ' '
|
134
|
+
writeln
|
135
|
+
writeln
|
136
|
+
end
|
137
|
+
end
|
138
|
+
%w(Mappings Parameters Resources Outputs).each do |section|
|
139
|
+
writeln " # #{section}"
|
140
|
+
v = tpl[section]
|
141
|
+
case section
|
142
|
+
when 'Parameters'
|
143
|
+
v.each { |name, options| pprint_cfn_section 'parameter', name, options, 'Parameters' }
|
144
|
+
when 'Mappings'
|
145
|
+
v.each { |name, options| pprint_cfn_section 'mapping', name, options, 'Mappings' }
|
146
|
+
when 'Resources'
|
147
|
+
v.each { |name, options| pprint_cfn_resource name, options }
|
148
|
+
when 'Outputs'
|
149
|
+
v.each { |name, options| pprint_cfn_section 'output', name, options, 'Outputs' }
|
150
|
+
else
|
151
|
+
raise "Internal Error: Unexpected section '#{section}'"
|
152
|
+
end
|
153
|
+
writeln
|
154
|
+
end
|
155
|
+
writeln "end.exec!"
|
156
|
+
end
|
157
|
+
|
158
|
+
def open_output(subdir,name)
|
159
|
+
if @opts[:output]
|
160
|
+
file = rb_file(subdir, name)
|
161
|
+
|
162
|
+
@output.unshift File.open(file, 'w')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def add_brick(subdir,name)
|
167
|
+
if @opts[:output]
|
168
|
+
#file = rb_file(subdir, name).gsub(%r'^#{@opts[:output]}/','')
|
169
|
+
#writeln " file '#{file}'"
|
170
|
+
s = subdir.downcase.gsub(%r's$','')
|
171
|
+
writeln " #{s} '#{name}'"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def rb_file(subdir, name)
|
176
|
+
path = File.join(@opts[:output], subdir)
|
177
|
+
unless File.directory? path
|
178
|
+
Dir.mkdir path
|
179
|
+
end
|
180
|
+
file = File.join(path, "#{name}.rb")
|
181
|
+
end
|
182
|
+
|
183
|
+
def close_output()
|
184
|
+
if @opts[:output] and @output.size > 0
|
185
|
+
fp = @output.shift
|
186
|
+
fp.close
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def pprint_cfn_section(section, name, options, subdir)
|
191
|
+
open_output(subdir,name)
|
192
|
+
write " #{section} #{fmt_string(name)}"
|
193
|
+
indent = ' ' + (' ' * section.length) + ' '
|
194
|
+
options.each do |k, v|
|
195
|
+
writeln ","
|
196
|
+
write indent, fmt_key(k), " => "
|
197
|
+
pprint_value v, indent
|
198
|
+
end
|
199
|
+
writeln
|
200
|
+
writeln
|
201
|
+
close_output
|
202
|
+
add_brick(subdir,name)
|
203
|
+
end
|
204
|
+
|
205
|
+
def pprint_cfn_resource(name, options)
|
206
|
+
subdir = 'Resources'
|
207
|
+
open_output(subdir,name)
|
208
|
+
write " resource #{fmt_string(name)}"
|
209
|
+
indent = ' '
|
210
|
+
options.each do |k, v|
|
211
|
+
unless k == 'Properties'
|
212
|
+
write ", #{fmt_key(k)} => #{fmt(v)}"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
if options.key?('Properties')
|
216
|
+
write ", #{fmt_key('Properties')} => "
|
217
|
+
pprint_value options['Properties'], indent
|
218
|
+
end
|
219
|
+
writeln
|
220
|
+
writeln
|
221
|
+
close_output
|
222
|
+
add_brick(subdir,name)
|
223
|
+
end
|
224
|
+
|
225
|
+
def pprint_value(val, indent)
|
226
|
+
# Prefer to write the value on a single line if it's reasonable to do so
|
227
|
+
single_line = is_single_line(val) || is_single_line_hack(val)
|
228
|
+
if single_line && !is_multi_line_hack(val)
|
229
|
+
s = fmt(val)
|
230
|
+
if s.length < 120 || is_single_line_hack(val)
|
231
|
+
write s
|
232
|
+
return
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# Print the value across multiple lines
|
237
|
+
if val.is_a?(Hash)
|
238
|
+
writeln "{"
|
239
|
+
val.each do |k, v|
|
240
|
+
write "#{indent} #{fmt_key(k)} => "
|
241
|
+
pprint_value v, indent + ' '
|
242
|
+
writeln ","
|
243
|
+
end
|
244
|
+
write "#{indent}}"
|
245
|
+
|
246
|
+
elsif val.is_a?(Array)
|
247
|
+
writeln "["
|
248
|
+
val.each do |v|
|
249
|
+
write "#{indent} "
|
250
|
+
pprint_value v, indent + ' '
|
251
|
+
writeln ","
|
252
|
+
end
|
253
|
+
write "#{indent}]"
|
254
|
+
|
255
|
+
elsif val.is_a?(FnCall) && val.multiline
|
256
|
+
write val.name, "("
|
257
|
+
args = val.arguments
|
258
|
+
sep = ''
|
259
|
+
sub_indent = indent + ' '
|
260
|
+
if val.name == 'join' && args.length > 1
|
261
|
+
pprint_value args[0], indent + ' '
|
262
|
+
args = args[1..-1]
|
263
|
+
sep = ','
|
264
|
+
sub_indent = indent + ' '
|
265
|
+
end
|
266
|
+
unless args.empty?
|
267
|
+
args.each do |v|
|
268
|
+
writeln sep
|
269
|
+
write sub_indent
|
270
|
+
pprint_value v, sub_indent
|
271
|
+
sep = ','
|
272
|
+
end
|
273
|
+
if val.name == 'join' && args.length > 1
|
274
|
+
write ","
|
275
|
+
end
|
276
|
+
writeln
|
277
|
+
write indent
|
278
|
+
end
|
279
|
+
write ")"
|
280
|
+
|
281
|
+
else
|
282
|
+
write fmt(val)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def is_single_line(val)
|
287
|
+
if val.is_a?(Hash)
|
288
|
+
is_single_line(val.values)
|
289
|
+
elsif val.is_a?(Array)
|
290
|
+
val.empty? ||
|
291
|
+
(val.length == 1 && is_single_line(val[0]) && !val[0].is_a?(Hash)) ||
|
292
|
+
val.all? { |v| v.is_a?(String) }
|
293
|
+
else
|
294
|
+
true
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# Emo-specific hacks to force the desired output formatting
|
299
|
+
def is_single_line_hack(val)
|
300
|
+
is_array_of_strings_hack(val)
|
301
|
+
end
|
302
|
+
|
303
|
+
# Emo-specific hacks to force the desired output formatting
|
304
|
+
def is_multi_line_hack(val)
|
305
|
+
val.is_a?(Hash) && val['email']
|
306
|
+
end
|
307
|
+
|
308
|
+
# Emo-specific hacks to force the desired output formatting
|
309
|
+
def is_array_of_strings_hack(val)
|
310
|
+
val.is_a?(Array) && val.all? { |v| v.is_a?(String) } && val.grep(/\s/).empty? && (
|
311
|
+
val.include?('autoscaling:EC2_INSTANCE_LAUNCH') ||
|
312
|
+
val.include?('m1.small')
|
313
|
+
)
|
314
|
+
end
|
315
|
+
|
316
|
+
def fmt(val)
|
317
|
+
if val == {}
|
318
|
+
'{}'
|
319
|
+
elsif val == []
|
320
|
+
'[]'
|
321
|
+
elsif val.is_a?(Hash)
|
322
|
+
'{ ' + (val.map { |k,v| fmt_key(k) + ' => ' + fmt(v) }).join(', ') + ' }'
|
323
|
+
elsif val.is_a?(Array) && is_array_of_strings_hack(val)
|
324
|
+
'%w(' + val.join(' ') + ')'
|
325
|
+
elsif val.is_a?(Array)
|
326
|
+
'[ ' + (val.map { |v| fmt(v) }).join(', ') + ' ]'
|
327
|
+
elsif val.is_a?(FnCall) && val.arguments.empty?
|
328
|
+
val.name
|
329
|
+
elsif val.is_a?(FnCall)
|
330
|
+
val.name + '(' + (val.arguments.map { |v| fmt(v) }).join(', ') + ')'
|
331
|
+
elsif val.is_a?(String)
|
332
|
+
fmt_string(val)
|
333
|
+
elsif val == nil
|
334
|
+
'null'
|
335
|
+
else
|
336
|
+
val.to_s # number, boolean
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
def fmt_key(s)
|
341
|
+
':' + (/^[a-zA-Z_]\w+$/ =~ s ? s : fmt_string(s)) # returns a symbol like :Foo or :'us-east-1'
|
342
|
+
end
|
343
|
+
|
344
|
+
def fmt_string(s)
|
345
|
+
if /[^ -~]/ =~ s
|
346
|
+
s.dump # contains, non-ascii or control char, return double-quoted string
|
347
|
+
else
|
348
|
+
'\'' + s.gsub(/([\\'])/, '\\\\\1') + '\'' # return single-quoted string, escape \ and '
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|