aws-cfn-yats 0.0.3

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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MGUyNmI0YjgwMWY3ZDJkNDQxMjdlNjRkMzBlZWUzNDI5YmNmNDQ1Yg==
5
+ data.tar.gz: !binary |-
6
+ OWYwYWIwYWVjNzI4YzVhNjYxMTk4ZTUxNzZjNTkzYzU1N2Y0YmY5ZA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NjYxMmExYjUwZWJkYjFlNTVmMWJlNTc3MmUwODAzZWU4YWRiMTZlM2I0MjEx
10
+ NTg3MGZhNWEyNTIyMzhlYWZiMzY2NGQ1YjdlYzIwOWJkNTlmZTk0MTM2MGM4
11
+ MjczYWNkMmQwNzUwMTI5ODZlOTIwOTc2NGI0N2UyNWI3MjQ2YzQ=
12
+ data.tar.gz: !binary |-
13
+ NTc2MDFmNDY4N2Q0YzZhYmU4NWIwZDJiNDk3MTRlNWUwMTY3MzU2MjhhY2Y0
14
+ MzUxNWViNDk4ZDgyZjAwM2Y2OWEyNDU3M2JjYTBlZjViNjM5ZTE0ZGI0ODgx
15
+ MzZiM2Q0ZjY5ODRjZDhjYmIxMTc4ZmIyMzk4OTdhMTE0NGE0MjU=
data/.gitignore ADDED
@@ -0,0 +1,49 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ /.config
19
+ /coverage/
20
+ /InstalledFiles
21
+ /pkg/
22
+ /spec/reports/
23
+ /test/tmp/
24
+ /test/version_tmp/
25
+ /tmp/
26
+
27
+ ## Specific to RubyMotion:
28
+ .dat*
29
+ .repl_history
30
+ build/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalisation:
39
+ /.bundle/
40
+ /lib/bundler/man/
41
+
42
+ # for a library or gem, you might want to ignore these files since the code is
43
+ # intended to run in multiple environments; otherwise, check them in:
44
+ Gemfile.lock
45
+ .ruby-version
46
+ .ruby-gemset
47
+
48
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
49
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ #gem 'aws-cfn-compiler', :git => 'https://github.com/dldinternet/aws-cfn-compiler.git', :branch => :master
4
+ gemspec
5
+ gem 'cloudformer'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Christo De Lange
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Christo DeLange
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # Cfn::Yats
2
+
3
+ AWS Cloudformation templates expressed with a Ruby DSL, YAML or JSON in a modular fashion
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'aws-cfn-yats'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install aws-cfn-yats
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Credits
24
+
25
+ Full credit go to the authors and contributors of these project who all inspired and created the ideas used here:
26
+ https://github.com/bazaarvoice/cloudformation-ruby-dsl
27
+ https://github.com/pkinney/aws-cfn-compiler
28
+ https://github.com/kunday/cloudformer
29
+ https://github.com/Optaros/cloud_builder
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it ( http://github.com/<my-github-username>/aws-cfn-yats/fork )
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aws/cfn/yats/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'aws-cfn-yats'
8
+ spec.version = Aws::Cfn::Yats::VERSION
9
+ spec.authors = ['Christo De Lange']
10
+ spec.email = ["rubygems@dldinternet.com"]
11
+ spec.summary = %q{CloudFormation - Yet Another Template System}
12
+ spec.description = %q{AWS Cloudformation templates expressed with a Ruby DSL, YAML or JSON in a modular fashion}
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'aws-cfn-dsl', '>=0.0.2'
22
+ spec.add_dependency 'aws-cfn-decompiler', '>= 0.0.3', '~> 0.0'
23
+ spec.add_dependency 'aws-cfn-compiler', '>= 0.2.1', '~> 0.2'
24
+ spec.add_dependency 'cloud_builder', '> 0'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.5'
27
+ spec.add_development_dependency 'rake'
28
+ end
data/aws-cfn-yats.iml ADDED
@@ -0,0 +1,42 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="CompassSettings">
4
+ <option name="compassSupportEnabled" value="true" />
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
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
16
+ <exclude-output />
17
+ <content url="file://$MODULE_DIR$">
18
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
19
+ </content>
20
+ <orderEntry type="jdk" jdkName="RVM: ruby-2.1.2" jdkType="RUBY_SDK" />
21
+ <orderEntry type="sourceFolder" forTests="false" />
22
+ <orderEntry type="library" scope="PROVIDED" name="activesupport (v4.1.1, RVM: ruby-2.1.2) [gem]" level="application" />
23
+ <orderEntry type="library" scope="PROVIDED" name="awesome_print (v1.2.0, RVM: ruby-2.1.2) [gem]" level="application" />
24
+ <orderEntry type="library" scope="PROVIDED" name="aws-cfn-dsl (v0.0.2, RVM: ruby-2.1.2) [gem]" level="application" />
25
+ <orderEntry type="library" scope="PROVIDED" name="aws-sdk (v1.43.2, RVM: ruby-2.1.2) [gem]" level="application" />
26
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v1.6.2, RVM: ruby-2.1.2) [gem]" level="application" />
27
+ <orderEntry type="library" scope="PROVIDED" name="clamp (v0.6.3, RVM: ruby-2.1.2) [gem]" level="application" />
28
+ <orderEntry type="library" scope="PROVIDED" name="cloud_builder (v0.0.11, RVM: ruby-2.1.2) [gem]" level="application" />
29
+ <orderEntry type="library" scope="PROVIDED" name="cloudformation-ruby-dsl (v0.4.3, RVM: ruby-2.1.2) [gem]" level="application" />
30
+ <orderEntry type="library" scope="PROVIDED" name="cloudformer (v0.0.11, RVM: ruby-2.1.2) [gem]" level="application" />
31
+ <orderEntry type="library" scope="PROVIDED" name="detabulator (v0.1.0, RVM: ruby-2.1.2) [gem]" level="application" />
32
+ <orderEntry type="library" scope="PROVIDED" name="i18n (v0.6.9, RVM: ruby-2.1.2) [gem]" level="application" />
33
+ <orderEntry type="library" scope="PROVIDED" name="mini_portile (v0.6.0, RVM: ruby-2.1.2) [gem]" level="application" />
34
+ <orderEntry type="library" scope="PROVIDED" name="minitest (v5.3.4, RVM: ruby-2.1.2) [gem]" level="application" />
35
+ <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.6.2.1, RVM: ruby-2.1.2) [gem]" level="application" />
36
+ <orderEntry type="library" scope="PROVIDED" name="rake (v10.3.2, RVM: ruby-2.1.2) [gem]" level="application" />
37
+ <orderEntry type="library" scope="PROVIDED" name="slop (v3.5.0, RVM: ruby-2.1.2) [gem]" level="application" />
38
+ <orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.4, RVM: ruby-2.1.2) [gem]" level="application" />
39
+ <orderEntry type="library" scope="PROVIDED" name="tzinfo (v1.2.1, RVM: ruby-2.1.2) [gem]" level="application" />
40
+ </component>
41
+ </module>
42
+
data/bin/cfn-json2rb ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ # Borrowing from "whiches" gem ...
6
+ cmd = File.basename(__FILE__)
7
+ exes = []
8
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
9
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
10
+ exts.each { |ext|
11
+ exe = File.join(path, "#{cmd}#{ext}")
12
+ exes << exe if File.executable? exe
13
+ }
14
+ end
15
+ path = if exes.size > 0
16
+ File.dirname(exes[0])
17
+ else
18
+ File.dirname(__FILE__)
19
+ end
20
+
21
+ add_path = File.expand_path(File.join(path, "..", "lib"))
22
+ $:.unshift(add_path)
23
+
24
+ require 'aws/cfn/yats'
25
+ require 'json'
26
+
27
+ unless (ARGV & %w(-h --help -?)).empty?
28
+ $stderr.puts <<"EOF"
29
+ usage: #{$PROGRAM_NAME} [cloudformation-template.json] ...
30
+
31
+ Converts the specified CloudFormation JSON template or template fragment to
32
+ Ruby DSL syntax. Reads from stdin or from the specified json files. Note
33
+ that the input must be valid JSON.
34
+
35
+ Examples:
36
+
37
+ # Convert a JSON CloudFormation template to Ruby DSL syntax
38
+ #{$PROGRAM_NAME} my-template.json > my-template.rb
39
+ chmod +x my-template.rb
40
+
41
+ # Convert the JSON fragment in the clipboard to Ruby DSL syntax
42
+ pbpaste | #{$PROGRAM_NAME} | less
43
+
44
+ EOF
45
+ exit(2)
46
+ end
47
+
48
+ j2r = Aws::Cfn::Yats::Json2Rb.new
49
+
50
+ if ARGV.empty?
51
+ template = $stdin.read
52
+ j2r.transform(template)
53
+ else
54
+ ARGV.each do |filename|
55
+ template = File.read(filename)
56
+ j2r.transform(template)
57
+ end
58
+ end
59
+ # The user should make the resulting template executable w/chmod +x
data/bin/cfn-json2yaml ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ # Borrowing from "whiches" gem ...
6
+ cmd = File.basename(__FILE__)
7
+ exes = []
8
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
9
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
10
+ exts.each { |ext|
11
+ exe = File.join(path, "#{cmd}#{ext}")
12
+ exes << exe if File.executable? exe
13
+ }
14
+ end
15
+ path = if exes.size > 0
16
+ File.dirname(exes[0])
17
+ else
18
+ File.dirname(__FILE__)
19
+ end
20
+
21
+ add_path = File.expand_path(File.join(path, "..", "lib"))
22
+ $:.unshift(add_path)
23
+
24
+ require 'aws/cfn/yats'
25
+ require 'json'
26
+
27
+ unless (ARGV & %w(-h --help -?)).empty?
28
+ $stderr.puts <<"EOF"
29
+ usage: #{$PROGRAM_NAME} [cloudformation-template.json] ...
30
+
31
+ Converts the specified CloudFormation JSON template or template fragment to
32
+ Ruby DSL syntax. Reads from stdin or from the specified json files. Note
33
+ that the input must be valid JSON.
34
+
35
+ Examples:
36
+
37
+ # Convert a JSON CloudFormation template to Ruby DSL syntax
38
+ #{$PROGRAM_NAME} my-template.json > my-template.rb
39
+ chmod +x my-template.rb
40
+
41
+ # Convert the JSON fragment in the clipboard to Ruby DSL syntax
42
+ pbpaste | #{$PROGRAM_NAME} | less
43
+
44
+ EOF
45
+ exit(2)
46
+ end
47
+
48
+ j2y = Aws::Cfn::Yats::Json2Yaml.new
49
+
50
+ if ARGV.empty?
51
+ template = $stdin.read
52
+ j2y.transform(template)
53
+ else
54
+ ARGV.each do |filename|
55
+ template = File.read(filename)
56
+ j2y.transform(template)
57
+ end
58
+ end
59
+ # The user should make the resulting template executable w/chmod +x
@@ -0,0 +1,5 @@
1
+ require "aws/cfn/yats/version"
2
+ require "aws/cfn/yats/base"
3
+ require "aws/cfn/yats/fncall"
4
+ require "aws/cfn/yats/json2rb"
5
+ require "aws/cfn/yats/json2yaml"
@@ -0,0 +1,127 @@
1
+ unless RUBY_VERSION >= '1.9'
2
+ # Ruby 1.9 preserves order within Hash objects which avoid scrambling the template output.
3
+ $stderr.puts "This script requires ruby 1.9+."
4
+ $stderr.puts "We suggest you use RVM to install ruby 1.9+: See https://rvm.io"
5
+ exit(2)
6
+ end
7
+
8
+ require "aws/cfn/yats/version"
9
+
10
+ module Aws
11
+ module Cfn
12
+ module Yats
13
+ attr_accessor :template
14
+ attr_accessor :json
15
+ attr_accessor :simple
16
+
17
+ class Base
18
+
19
+ def self.abstract_methods(*args)
20
+ args.each do |name|
21
+ class_eval(<<-END, __FILE__, __LINE__)
22
+ def #{name}(*args)
23
+ raise NotImplementedError.new("You must implement #{name}.")
24
+ end
25
+ END
26
+ end
27
+ end
28
+
29
+ def initialize
30
+ end
31
+
32
+
33
+ def transform(template)
34
+ @template = template
35
+ @json = JSON.parse(template)
36
+ @simple = simplify(@json)
37
+ pprint(@simple)
38
+ end
39
+
40
+ def simplify(val)
41
+ if val.is_a?(Hash)
42
+ val = Hash[val.map { |k,v| [k, simplify(v)] }]
43
+ # if val.length != 1
44
+ # val
45
+ # else
46
+ # k, v = val.entries[0]
47
+ # # CloudFormation functions
48
+ # case
49
+ # when k == 'Fn::Base64'
50
+ # FnCall.new 'base64', [v], true
51
+ # when k == 'Fn::FindInMap'
52
+ # FnCall.new 'find_in_map', v
53
+ # when k == 'Fn::GetAtt'
54
+ # FnCall.new 'get_att', v
55
+ # when k == 'Fn::GetAZs'
56
+ # FnCall.new 'get_azs', v != '' ? [v] : []
57
+ # when k == 'Fn::Join'
58
+ # FnCall.new 'join', [v[0]] + v[1], true
59
+ # when k == 'Fn::Select'
60
+ # FnCall.new 'select', v
61
+ # # when k == 'Ref' && v == 'AWS::Region'
62
+ # # FnCall.new 'aws_region', []
63
+ # # when k == 'Ref' && v == 'AWS::StackName'
64
+ # # FnCall.new 'aws_stack_name', []
65
+ # when k == 'Ref'
66
+ # FnCall.new 'ref', [v]
67
+ # else
68
+ # val
69
+ # end
70
+ # end
71
+ elsif val.is_a?(Array)
72
+ val.map { |v| simplify(v) }
73
+ else
74
+ val
75
+ end
76
+ end
77
+
78
+ def pprint(val)
79
+ case detect_type(val)
80
+ when :template
81
+ pprint_cfn_template(val)
82
+ when :parameter
83
+ pprint_cfn_section 'parameter', 'TODO', val
84
+ when :resource
85
+ pprint_cfn_resource 'TODO', val
86
+ when :parameters
87
+ val.each { |k, v| pprint_cfn_section 'parameter', k, v }
88
+ when :resources
89
+ val.each { |k, v| pprint_cfn_resource k, v }
90
+ else
91
+ pprint_value(val, '')
92
+ end
93
+ end
94
+
95
+ protected
96
+
97
+ # Attempt to figure out what fragment of the template we have. This is imprecise and can't
98
+ # detect Mappings and Outputs sections reliably, so it doesn't attempt to.
99
+ def detect_type(val)
100
+ if val.is_a?(Hash) && val['AWSTemplateFormatVersion']
101
+ :template
102
+ elsif val.is_a?(Hash) && /^(String|Number)$/ =~ val['Type']
103
+ :parameter
104
+ elsif val.is_a?(Hash) && val['Type']
105
+ :resource
106
+ elsif val.is_a?(Hash) && val.values.all? { |v| detect_type(v) == :parameter }
107
+ :parameters
108
+ elsif val.is_a?(Hash) && val.values.all? { |v| detect_type(v) == :resource }
109
+ :resources
110
+ end
111
+ end
112
+
113
+ # def method_missing(name, *args)
114
+ # raise "Abstract base class call to missing method #{name}"
115
+ # end
116
+
117
+
118
+ private
119
+
120
+
121
+ end
122
+
123
+ Base::abstract_methods :pprint_cfn_template, :pprint_cfn_section, :pprint_cfn_resource, :pprint_value
124
+
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,17 @@
1
+ module Aws
2
+ module Cfn
3
+ module Yats
4
+
5
+ class FnCall
6
+ attr_reader :name, :arguments, :multiline
7
+
8
+ def initialize(name, arguments, multiline = false)
9
+ @name = name
10
+ @arguments = arguments
11
+ @multiline = multiline
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,203 @@
1
+ require "aws/cfn/yats/base"
2
+
3
+ module Aws
4
+ module Cfn
5
+ module Yats
6
+
7
+ class Json2Rb < Base
8
+
9
+ def initialize
10
+
11
+ end
12
+
13
+ protected
14
+
15
+ def pprint_cfn_template(tpl)
16
+ puts "#!/usr/bin/env ruby"
17
+ puts
18
+ puts "require 'bundler/setup'"
19
+ puts "require 'cloudformation-ruby-dsl/cfntemplate'"
20
+ # puts "require 'cloudformation-ruby-dsl/spotprice'"
21
+ puts "require 'cloudformation-ruby-dsl/table'"
22
+ puts
23
+ puts "template do"
24
+ puts
25
+ tpl.each do |section, v|
26
+ case section
27
+ when 'Parameters'
28
+ v.each { |name, options| pprint_cfn_section 'parameter', name, options }
29
+ when 'Mappings'
30
+ v.each { |name, options| pprint_cfn_section 'mapping', name, options }
31
+ when 'Resources'
32
+ v.each { |name, options| pprint_cfn_resource name, options }
33
+ when 'Outputs'
34
+ v.each { |name, options| pprint_cfn_section 'output', name, options }
35
+ else
36
+ print " value #{fmt_key(section)} => "
37
+ pprint_value v, ' '
38
+ puts
39
+ puts
40
+ end
41
+ end
42
+ puts "end.exec!"
43
+ end
44
+
45
+ def pprint_cfn_section(section, name, options)
46
+ print " #{section} #{fmt_string(name)}"
47
+ indent = ' ' + (' ' * section.length) + ' '
48
+ options.each do |k, v|
49
+ puts ","
50
+ print indent, fmt_key(k), " => "
51
+ pprint_value v, indent
52
+ end
53
+ puts
54
+ puts
55
+ end
56
+
57
+ def pprint_cfn_resource(name, options)
58
+ print " resource #{fmt_string(name)}"
59
+ indent = ' '
60
+ options.each do |k, v|
61
+ unless k == 'Properties'
62
+ print ", #{fmt_key(k)} => #{fmt(v)}"
63
+ end
64
+ end
65
+ if options.key?('Properties')
66
+ print ", #{fmt_key('Properties')} => "
67
+ pprint_value options['Properties'], indent
68
+ end
69
+ puts
70
+ puts
71
+ end
72
+
73
+ def pprint_value(val, indent)
74
+ # Prefer to print the value on a single line if it's reasonable to do so
75
+ single_line = is_single_line(val) || is_single_line_hack(val)
76
+ if single_line && !is_multi_line_hack(val)
77
+ s = fmt(val)
78
+ if s.length < 120 || is_single_line_hack(val)
79
+ print s
80
+ return
81
+ end
82
+ end
83
+
84
+ # Print the value across multiple lines
85
+ if val.is_a?(Hash)
86
+ puts "{"
87
+ val.each do |k, v|
88
+ print "#{indent} #{fmt_key(k)} => "
89
+ pprint_value v, indent + ' '
90
+ puts ","
91
+ end
92
+ print "#{indent}}"
93
+
94
+ elsif val.is_a?(Array)
95
+ puts "["
96
+ val.each do |v|
97
+ print "#{indent} "
98
+ pprint_value v, indent + ' '
99
+ puts ","
100
+ end
101
+ print "#{indent}]"
102
+
103
+ elsif val.is_a?(FnCall) && val.multiline
104
+ print val.name, "("
105
+ args = val.arguments
106
+ sep = ''
107
+ sub_indent = indent + ' '
108
+ if val.name == 'join' && args.length > 1
109
+ pprint_value args[0], indent + ' '
110
+ args = args[1..-1]
111
+ sep = ','
112
+ sub_indent = indent + ' '
113
+ end
114
+ unless args.empty?
115
+ args.each do |v|
116
+ puts sep
117
+ print sub_indent
118
+ pprint_value v, sub_indent
119
+ sep = ','
120
+ end
121
+ if val.name == 'join' && args.length > 1
122
+ print ","
123
+ end
124
+ puts
125
+ print indent
126
+ end
127
+ print ")"
128
+
129
+ else
130
+ print fmt(val)
131
+ end
132
+ end
133
+
134
+ def is_single_line(val)
135
+ if val.is_a?(Hash)
136
+ is_single_line(val.values)
137
+ elsif val.is_a?(Array)
138
+ val.empty? ||
139
+ (val.length == 1 && is_single_line(val[0]) && !val[0].is_a?(Hash)) ||
140
+ val.all? { |v| v.is_a?(String) }
141
+ else
142
+ true
143
+ end
144
+ end
145
+
146
+ # Emo-specific hacks to force the desired output formatting
147
+ def is_single_line_hack(val)
148
+ is_array_of_strings_hack(val)
149
+ end
150
+
151
+ # Emo-specific hacks to force the desired output formatting
152
+ def is_multi_line_hack(val)
153
+ val.is_a?(Hash) && val['email']
154
+ end
155
+
156
+ # Emo-specific hacks to force the desired output formatting
157
+ def is_array_of_strings_hack(val)
158
+ val.is_a?(Array) && val.all? { |v| v.is_a?(String) } && val.grep(/\s/).empty? && (
159
+ val.include?('autoscaling:EC2_INSTANCE_LAUNCH') ||
160
+ val.include?('m1.small')
161
+ )
162
+ end
163
+
164
+ def fmt(val)
165
+ if val == {}
166
+ '{}'
167
+ elsif val == []
168
+ '[]'
169
+ elsif val.is_a?(Hash)
170
+ '{ ' + (val.map { |k,v| fmt_key(k) + ' => ' + fmt(v) }).join(', ') + ' }'
171
+ elsif val.is_a?(Array) && is_array_of_strings_hack(val)
172
+ '%w(' + val.join(' ') + ')'
173
+ elsif val.is_a?(Array)
174
+ '[ ' + (val.map { |v| fmt(v) }).join(', ') + ' ]'
175
+ elsif val.is_a?(FnCall) && val.arguments.empty?
176
+ val.name
177
+ elsif val.is_a?(FnCall)
178
+ val.name + '(' + (val.arguments.map { |v| fmt(v) }).join(', ') + ')'
179
+ elsif val.is_a?(String)
180
+ fmt_string(val)
181
+ elsif val == nil
182
+ 'null'
183
+ else
184
+ val.to_s # number, boolean
185
+ end
186
+ end
187
+
188
+ def fmt_key(s)
189
+ ':' + (/^[a-zA-Z_]\w+$/ =~ s ? s : fmt_string(s)) # returns a symbol like :Foo or :'us-east-1'
190
+ end
191
+
192
+ def fmt_string(s)
193
+ if /[^ -~]/ =~ s
194
+ s.dump # contains, non-ascii or control char, return double-quoted string
195
+ else
196
+ '\'' + s.gsub(/([\\'])/, '\\\\\1') + '\'' # return single-quoted string, escape \ and '
197
+ end
198
+ end
199
+
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,20 @@
1
+ require "aws/cfn/yats/base"
2
+ require 'yaml'
3
+
4
+ module Aws
5
+ module Cfn
6
+ module Yats
7
+
8
+ class Json2Yaml < Base
9
+
10
+ def pprint_cfn_template(tpl)
11
+
12
+ yml = YAML::dump(@json)
13
+
14
+ puts yml
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ module Aws
2
+ module Cfn
3
+ module Yats
4
+ VERSION = "0.0.3"
5
+ end
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aws-cfn-yats
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Christo De Lange
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-cfn-dsl
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-cfn-decompiler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.3
34
+ - - ~>
35
+ - !ruby/object:Gem::Version
36
+ version: '0.0'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 0.0.3
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: '0.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: aws-cfn-compiler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.2.1
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: '0.2'
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: 0.2.1
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: '0.2'
67
+ - !ruby/object:Gem::Dependency
68
+ name: cloud_builder
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ! '>'
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :runtime
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ! '>'
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: bundler
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: '1.5'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: '1.5'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rake
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ description: AWS Cloudformation templates expressed with a Ruby DSL, YAML or JSON
110
+ in a modular fashion
111
+ email:
112
+ - rubygems@dldinternet.com
113
+ executables:
114
+ - cfn-json2rb
115
+ - cfn-json2yaml
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - .gitignore
120
+ - Gemfile
121
+ - LICENSE
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - aws-cfn-yats.gemspec
126
+ - aws-cfn-yats.iml
127
+ - bin/cfn-json2rb
128
+ - bin/cfn-json2yaml
129
+ - lib/aws/cfn/yats.rb
130
+ - lib/aws/cfn/yats/base.rb
131
+ - lib/aws/cfn/yats/fncall.rb
132
+ - lib/aws/cfn/yats/json2rb.rb
133
+ - lib/aws/cfn/yats/json2yaml.rb
134
+ - lib/aws/cfn/yats/version.rb
135
+ homepage: ''
136
+ licenses:
137
+ - MIT
138
+ metadata: {}
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ! '>='
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 2.2.2
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: CloudFormation - Yet Another Template System
159
+ test_files: []