lono 4.2.7 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/.cody/README.md +6 -0
  3. data/.cody/acceptance.sh +30 -0
  4. data/.cody/buildspec.yml +21 -0
  5. data/.cody/demo.rb +38 -0
  6. data/.cody/project.rb +12 -0
  7. data/.cody/role.rb +1 -0
  8. data/.gitignore +2 -0
  9. data/.gitmodules +6 -3
  10. data/.travis.yml +7 -0
  11. data/CHANGELOG.md +10 -0
  12. data/Gemfile +0 -1
  13. data/LICENSE.txt +1 -22
  14. data/README.md +46 -55
  15. data/lib/lono.rb +20 -27
  16. data/lib/lono/app_file.rb +5 -0
  17. data/lib/lono/app_file/base.rb +19 -0
  18. data/lib/lono/app_file/build.rb +78 -0
  19. data/lib/lono/app_file/registry.rb +14 -0
  20. data/lib/lono/app_file/registry/item.rb +46 -0
  21. data/lib/lono/app_file/upload.rb +39 -0
  22. data/lib/lono/autoloader.rb +22 -0
  23. data/lib/lono/aws_services.rb +46 -0
  24. data/lib/lono/aws_services/util.rb +49 -0
  25. data/lib/lono/blueprint.rb +113 -0
  26. data/lib/lono/blueprint/find.rb +90 -0
  27. data/lib/lono/blueprint/helper.rb +18 -0
  28. data/lib/lono/blueprint/info.rb +10 -0
  29. data/lib/lono/blueprint/list.rb +14 -0
  30. data/lib/lono/blueprint/root.rb +43 -0
  31. data/lib/lono/cfn.rb +31 -19
  32. data/lib/lono/cfn/aws_service.rb +16 -0
  33. data/lib/lono/cfn/base.rb +244 -261
  34. data/lib/lono/cfn/create.rb +36 -32
  35. data/lib/lono/cfn/current.rb +1 -1
  36. data/lib/lono/cfn/delete.rb +2 -2
  37. data/lib/lono/cfn/deploy.rb +11 -0
  38. data/lib/lono/cfn/diff.rb +1 -1
  39. data/lib/lono/cfn/preview.rb +3 -3
  40. data/lib/lono/cfn/rollback.rb +26 -0
  41. data/lib/lono/cfn/status.rb +2 -203
  42. data/lib/lono/cfn/suffix.rb +67 -0
  43. data/lib/lono/cfn/update.rb +61 -53
  44. data/lib/lono/cli.rb +42 -23
  45. data/lib/lono/completer.rb +0 -2
  46. data/lib/lono/configure.rb +37 -0
  47. data/lib/lono/configure/aws_services.rb +18 -0
  48. data/lib/lono/configure/base.rb +94 -0
  49. data/lib/lono/configure/helpers.rb +128 -0
  50. data/lib/lono/conventions.rb +11 -0
  51. data/lib/lono/core.rb +42 -12
  52. data/lib/lono/core/config.rb +5 -4
  53. data/lib/lono/default/settings.yml +0 -11
  54. data/lib/lono/file_uploader.rb +9 -4
  55. data/lib/lono/help.rb +1 -2
  56. data/lib/lono/help/blueprint.md +46 -0
  57. data/lib/lono/help/cfn.md +5 -4
  58. data/lib/lono/help/cfn/create.md +14 -9
  59. data/lib/lono/help/cfn/deploy.md +92 -0
  60. data/lib/lono/help/cfn/diff.md +0 -1
  61. data/lib/lono/help/cfn/update.md +16 -15
  62. data/lib/lono/help/completion.md +3 -3
  63. data/lib/lono/help/generate.md +0 -1
  64. data/lib/lono/help/new.md +40 -34
  65. data/lib/lono/help/param.md +1 -1
  66. data/lib/lono/help/param/generate.md +1 -1
  67. data/lib/lono/help/template.md +2 -2
  68. data/lib/lono/help/xgraph.md +1 -1
  69. data/lib/lono/inspector.rb +1 -1
  70. data/lib/lono/inspector/base.rb +26 -10
  71. data/lib/lono/inspector/graph.rb +7 -3
  72. data/lib/lono/inspector/summary.rb +15 -3
  73. data/lib/lono/md5.rb +46 -0
  74. data/lib/lono/new.rb +40 -28
  75. data/lib/lono/new/helper.rb +2 -3
  76. data/lib/lono/param.rb +12 -11
  77. data/lib/lono/param/generator.rb +96 -42
  78. data/lib/lono/project_checker.rb +27 -8
  79. data/lib/lono/s3.rb +23 -0
  80. data/lib/lono/s3/bucket.rb +123 -0
  81. data/lib/lono/script.rb +4 -8
  82. data/lib/lono/script/base.rb +7 -2
  83. data/lib/lono/script/build.rb +7 -8
  84. data/lib/lono/script/upload.rb +4 -20
  85. data/lib/lono/sequence.rb +19 -16
  86. data/lib/lono/setting.rb +19 -27
  87. data/lib/lono/template.rb +22 -26
  88. data/lib/lono/template/base.rb +13 -0
  89. data/lib/lono/template/context.rb +4 -56
  90. data/lib/lono/template/context/loader.rb +70 -0
  91. data/lib/lono/template/dsl.rb +15 -151
  92. data/lib/lono/template/dsl/builder.rb +60 -0
  93. data/lib/lono/template/dsl/builder/base.rb +14 -0
  94. data/lib/lono/template/dsl/builder/condition.rb +26 -0
  95. data/lib/lono/template/dsl/builder/fn.rb +114 -0
  96. data/lib/lono/template/dsl/builder/helper.rb +64 -0
  97. data/lib/lono/template/dsl/builder/mapping.rb +24 -0
  98. data/lib/lono/template/dsl/builder/output.rb +37 -0
  99. data/lib/lono/template/dsl/builder/parameter.rb +39 -0
  100. data/lib/lono/template/dsl/builder/resource.rb +38 -0
  101. data/lib/lono/template/dsl/builder/section.rb +12 -0
  102. data/lib/lono/template/dsl/builder/syntax.rb +58 -0
  103. data/lib/lono/template/erb.rb +82 -0
  104. data/lib/lono/template/evaluate.rb +39 -0
  105. data/lib/lono/template/generator.rb +29 -0
  106. data/lib/lono/template/helper.rb +7 -29
  107. data/lib/lono/template/post_processor.rb +69 -0
  108. data/lib/lono/template/template.rb +4 -9
  109. data/lib/lono/template/upload.rb +103 -133
  110. data/lib/lono/template/util.rb +48 -0
  111. data/lib/lono/upgrade.rb +5 -3
  112. data/lib/lono/upgrade/upgrade5.rb +55 -0
  113. data/lib/lono/user_data.rb +4 -4
  114. data/lib/lono/version.rb +1 -1
  115. data/lib/templates/blueprint/%blueprint_name%.gemspec.tt +44 -0
  116. data/lib/templates/blueprint/.gitignore +14 -0
  117. data/lib/templates/blueprint/.lono/config.yml.tt +3 -0
  118. data/lib/templates/blueprint/.meta/config.yml.tt +3 -0
  119. data/lib/templates/blueprint/CHANGELOG.md +7 -0
  120. data/lib/templates/blueprint/Gemfile +4 -0
  121. data/lib/templates/blueprint/README.md +37 -0
  122. data/lib/templates/blueprint/Rakefile +6 -0
  123. data/lib/templates/blueprint/setup/configs.rb +54 -0
  124. data/lib/templates/blueprint_configs/configs/%blueprint_name%/params/base.txt +2 -0
  125. data/lib/{starter_projects/skeleton/app/definitions/base.rb → templates/blueprint_configs/configs/%blueprint_name%/params/development.txt} +0 -0
  126. data/lib/templates/blueprint_configs/configs/%blueprint_name%/variables/base.rb +2 -0
  127. data/lib/templates/blueprint_configs/configs/%blueprint_name%/variables/development.rb +0 -0
  128. data/lib/templates/blueprint_types/dsl/app/templates/%blueprint_name%.rb +37 -0
  129. data/lib/templates/blueprint_types/dsl/app/user_data/bootstrap.sh +2 -0
  130. data/lib/templates/blueprint_types/erb/app/definitions/base.rb.tt +1 -0
  131. data/lib/templates/blueprint_types/erb/app/templates/%blueprint_name%.yml +8 -0
  132. data/lib/{starter_projects/autoscaling → templates/skeleton}/.gitignore +1 -0
  133. data/lib/templates/skeleton/Gemfile +3 -0
  134. data/lib/{starter_projects/autoscaling → templates/skeleton}/Guardfile +2 -2
  135. data/lib/templates/skeleton/README.md +58 -0
  136. data/lib/templates/skeleton/configs/settings.yml +17 -0
  137. data/lib/templates/upgrade5/blueprints/main/.lono/config.yml +3 -0
  138. data/lib/templates/upgrade5/blueprints/main/.meta/config.yml +3 -0
  139. data/lono.gemspec +12 -8
  140. data/vendor/cfn-status/CHANGELOG.md +10 -0
  141. data/vendor/cfn-status/Gemfile +4 -0
  142. data/vendor/cfn-status/LICENSE.txt +21 -0
  143. data/vendor/cfn-status/README.md +56 -0
  144. data/vendor/cfn-status/Rakefile +6 -0
  145. data/vendor/cfn-status/bin/console +14 -0
  146. data/vendor/cfn-status/bin/setup +8 -0
  147. data/vendor/cfn-status/cfn-status.gemspec +30 -0
  148. data/vendor/cfn-status/lib/cfn-status.rb +1 -0
  149. data/vendor/cfn-status/lib/cfn/aws_service.rb +51 -0
  150. data/vendor/cfn-status/lib/cfn/status.rb +219 -0
  151. data/vendor/cfn-status/lib/cfn/status/version.rb +5 -0
  152. data/vendor/cfn-status/spec/cfn/status_spec.rb +81 -0
  153. data/vendor/cfn-status/spec/fixtures/cfn/stack-events-complete.json +1080 -0
  154. data/vendor/cfn-status/spec/fixtures/cfn/stack-events-in-progress.json +1080 -0
  155. data/vendor/cfn-status/spec/fixtures/cfn/stack-events-update-rollback-complete.json +1086 -0
  156. data/vendor/cfn-status/spec/spec_helper.rb +14 -0
  157. data/vendor/cfn_camelizer/CHANGELOG.md +20 -0
  158. data/vendor/cfn_camelizer/Gemfile +4 -0
  159. data/vendor/cfn_camelizer/LICENSE.txt +21 -0
  160. data/vendor/cfn_camelizer/README.md +40 -0
  161. data/vendor/cfn_camelizer/Rakefile +6 -0
  162. data/vendor/cfn_camelizer/bin/console +14 -0
  163. data/vendor/cfn_camelizer/bin/setup +8 -0
  164. data/vendor/cfn_camelizer/cfn_camelizer.gemspec +32 -0
  165. data/vendor/cfn_camelizer/lib/camelizer.yml +37 -0
  166. data/vendor/cfn_camelizer/lib/cfn_camelizer.rb +94 -0
  167. data/vendor/cfn_camelizer/lib/cfn_camelizer/version.rb +3 -0
  168. data/vendor/cfn_camelizer/spec/cfn_camelizer_spec.rb +86 -0
  169. data/vendor/cfn_camelizer/spec/spec_helper.rb +14 -0
  170. metadata +189 -62
  171. data/.circleci/bin/commit_docs.sh +0 -26
  172. data/.circleci/config.yml +0 -72
  173. data/bin/release +0 -9
  174. data/lib/lono/help/import.md +0 -54
  175. data/lib/lono/importer.rb +0 -134
  176. data/lib/lono/new/message.rb +0 -35
  177. data/lib/starter_projects/autoscaling/Gemfile +0 -3
  178. data/lib/starter_projects/autoscaling/README.md +0 -118
  179. data/lib/starter_projects/autoscaling/app/definitions/base.rb +0 -2
  180. data/lib/starter_projects/autoscaling/app/templates/autoscaling.yml +0 -682
  181. data/lib/starter_projects/autoscaling/config/params/base/autoscaling.txt +0 -6
  182. data/lib/starter_projects/autoscaling/config/settings.yml +0 -33
  183. data/lib/starter_projects/ec2/.gitignore +0 -2
  184. data/lib/starter_projects/ec2/Gemfile +0 -3
  185. data/lib/starter_projects/ec2/Guardfile +0 -12
  186. data/lib/starter_projects/ec2/README.md +0 -86
  187. data/lib/starter_projects/ec2/app/definitions/base.rb +0 -2
  188. data/lib/starter_projects/ec2/app/definitions/development.rb +0 -1
  189. data/lib/starter_projects/ec2/app/definitions/production.rb +0 -1
  190. data/lib/starter_projects/ec2/app/helpers/my_custom_helper.rb +0 -17
  191. data/lib/starter_projects/ec2/app/partials/user_data/bootstrap.sh +0 -4
  192. data/lib/starter_projects/ec2/app/templates/example.yml +0 -430
  193. data/lib/starter_projects/ec2/config/params/base/example.txt +0 -2
  194. data/lib/starter_projects/ec2/config/params/development/example.txt +0 -3
  195. data/lib/starter_projects/ec2/config/params/production/example.txt +0 -2
  196. data/lib/starter_projects/ec2/config/settings.yml +0 -33
  197. data/lib/starter_projects/ec2/config/variables/base.rb +0 -3
  198. data/lib/starter_projects/ec2/config/variables/development.rb +0 -2
  199. data/lib/starter_projects/ec2/config/variables/production.rb +0 -2
  200. data/lib/starter_projects/ec2/welcome.txt +0 -8
  201. data/lib/starter_projects/skeleton/.gitignore +0 -2
  202. data/lib/starter_projects/skeleton/Gemfile +0 -3
  203. data/lib/starter_projects/skeleton/Guardfile +0 -12
  204. data/lib/starter_projects/skeleton/README.md +0 -53
  205. data/lib/starter_projects/skeleton/config/settings.yml +0 -33
  206. data/lib/starter_projects/skeleton/welcome.txt +0 -7
  207. data/vendor/plissken/Gemfile +0 -14
  208. data/vendor/plissken/LICENSE.txt +0 -20
  209. data/vendor/plissken/README.md +0 -46
  210. data/vendor/plissken/Rakefile +0 -56
  211. data/vendor/plissken/VERSION +0 -1
  212. data/vendor/plissken/lib/plissken.rb +0 -1
  213. data/vendor/plissken/lib/plissken/ext/hash/to_snake_keys.rb +0 -45
  214. data/vendor/plissken/plissken.gemspec +0 -61
  215. data/vendor/plissken/spec/lib/to_snake_keys_spec.rb +0 -177
  216. data/vendor/plissken/spec/spec_helper.rb +0 -90
  217. data/vendor/plissken/test/helper.rb +0 -20
  218. data/vendor/plissken/test/plissken/ext/hash/to_snake_keys_test.rb +0 -184
  219. data/vendor/plissken/test/test_plissken.rb +0 -2
@@ -0,0 +1,60 @@
1
+ class Lono::Template::Dsl
2
+ class Builder
3
+ include Lono::Template::Util
4
+ include Lono::Template::Context::Loader
5
+
6
+ include Fn
7
+ include Helper # built-in helpers
8
+ include Lono::Template::Evaluate
9
+ include Syntax
10
+
11
+ def initialize(path, blueprint, options={})
12
+ @path, @blueprint, @options = path, blueprint, options
13
+ @template = @path.sub("#{Lono.config.templates_path}/",'').sub(/\.rb$/,'')
14
+ @cfn = {}
15
+ end
16
+
17
+ def build
18
+ load_context
19
+ evaluate_template_path(@path)
20
+ build_template
21
+ write_output
22
+ end
23
+
24
+ def build_template
25
+ @results = YAML.dump(camelize(@cfn))
26
+ end
27
+
28
+ def write_output
29
+ output_path = "#{Lono.config.output_path}/#{@blueprint}/templates"
30
+ FileUtils.mkdir_p(output_path)
31
+
32
+ path = "#{output_path}/#{@template}.yml"
33
+ ensure_parent_dir(path)
34
+ IO.write(path, @results)
35
+
36
+ validate_yaml(path)
37
+
38
+ unless @options[:quiet]
39
+ pretty_path = path.sub("#{Lono.root}/",'')
40
+ puts " #{pretty_path}"
41
+ end
42
+ end
43
+
44
+ def camelize(data)
45
+ CfnCamelizer.transform(data)
46
+ end
47
+
48
+ # Not using Lono::Template::Context because that works differently.
49
+ # That is used to load a context object that is passed to RenderMePretty's context.
50
+ # So that we can load context for params files and erb templates.
51
+ #
52
+ # In this case builder is actually the dsl context.
53
+ # We want to load variables and helpers into this builder context directly.
54
+ # This loads additional context. It looks very similar to Lono::Template::Context
55
+ def load_context
56
+ load_variables
57
+ load_project_helpers
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,14 @@
1
+ class Lono::Template::Dsl::Builder
2
+ class Base
3
+ include Fn
4
+ include Helper
5
+
6
+ def initialize(*definition)
7
+ @definition = definition.flatten
8
+ end
9
+
10
+ def camelize(attributes)
11
+ CfnCamelizer.transform(attributes)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ # Implements:
2
+ #
3
+ # template - uses @definition to build a CloudFormation template section
4
+ #
5
+ class Lono::Template::Dsl::Builder
6
+ class Condition < Base
7
+ def template
8
+ camelize(standarize(@definition))
9
+ end
10
+
11
+ # There are only 2 forms for condition: long and medium
12
+ #
13
+ # Type is the only required property: https://amzn.to/2x8W5aD
14
+ def standarize(definition)
15
+ first, second, _ = definition
16
+ if definition.size == 1 && first.is_a?(Hash) # long form
17
+ first # pass through
18
+ elsif definition.size == 2 && second.is_a?(Hash) # medium form
19
+ logical_id, properties = first, second
20
+ { logical_id => properties }
21
+ else # I dont know what form
22
+ raise "Invalid form provided. definition #{definition.inspect}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,114 @@
1
+ class Lono::Template::Dsl::Builder
2
+ module Fn
3
+ # Also act as documentation on the method signatures
4
+ # Also used in Coder crafting so should always list all the functions here
5
+ # even if they are overriden with specific implementations below
6
+ FUNCTIONS = {
7
+ base64: :simple,
8
+ cidr: :array,
9
+ find_in_map: :array,
10
+ get_att: :array, # special case
11
+ # get_azs: :simple, # special map to GetAZs, and default region=''
12
+ import_value: :simple,
13
+ # join: :array, # special case
14
+ select: :array,
15
+ split: :array,
16
+ # sub: :array, # special case
17
+ transform: :simple,
18
+ # Conditional methods
19
+ # Most of the condition methods need to be accessed via the modulde
20
+ # since they are Ruby keywords. So Fn::if , also builder has an fn method
21
+ # so they can also be called via fn::if
22
+ and: :array,
23
+ equals: :array,
24
+ if: :array, # special case, if is a Ruby keyword , we'll use fn_if instead
25
+ not: :array,
26
+ or: :array,
27
+ ref: :simple,
28
+ }
29
+ # These are also Ruby keywords
30
+ # keywords: and if not or
31
+
32
+ # Note, for if function, do not flatten the args. Its arguments can be Arrays. Example:
33
+ #
34
+ # SecurityGroups:
35
+ # Fn::If:
36
+ # - ExistingSecurityGroupIsBlank
37
+ # - - GroupId:
38
+ # Ref: SecurityGroup
39
+ # - - GroupId:
40
+ # Ref: SecurityGroup
41
+ # - GroupId:
42
+ # Ref: ExistingSecurityGroup
43
+ FUNCTIONS.each do |name, type|
44
+ if type == :simple
45
+ define_method(name) do |arg|
46
+ id = fn_id(name)
47
+ arg = arg.is_a?(Symbol) ? CfnCamelizer.camelize(arg) : arg
48
+ { id => arg }
49
+ end
50
+ else # array
51
+ define_method(name) do |*args|
52
+ id = fn_id(name)
53
+ # Note, do not flatten args for if statement as it can have Array as arguments.
54
+ args = args.flatten unless name == :if
55
+ args = args.map do |arg|
56
+ arg.is_a?(Symbol) ? CfnCamelizer.camelize(arg) : arg
57
+ end
58
+ { id => args }
59
+ end
60
+ end
61
+ end
62
+
63
+ def fn_id(name)
64
+ "Fn::#{CfnCamelizer.camelize(name)}"
65
+ end
66
+
67
+ # special cases
68
+ def ref(name)
69
+ name = CfnCamelizer.camelize(name)
70
+ { "Ref" => name }
71
+ end
72
+
73
+ # Examples:
74
+ # get_attr("logical_id.attribute")
75
+ # get_attr("logical_id", "attribute")
76
+ # get_attr(["logical_id", "attribute"])
77
+ def get_att(*item)
78
+ item = item.flatten
79
+ options = item.last.is_a?(Hash) ? item.pop : {}
80
+
81
+ # list is an Array
82
+ list = if item.size == 1
83
+ item.first.split('.')
84
+ else
85
+ item
86
+ end
87
+ list.map!(&:camelize) unless options[:autoformat] == false
88
+ { "Fn::GetAtt" => list }
89
+ end
90
+
91
+ def join(delimiter, *list)
92
+ list = list.flatten
93
+ { "Fn::Join" => [delimiter, list] }
94
+ end
95
+
96
+ def get_azs(region='')
97
+ { "Fn::GetAZs" => region }
98
+ end
99
+
100
+ def sub(str, vals={})
101
+ { "Fn::Sub" => [str, vals] }
102
+ end
103
+
104
+ # for fn::if and fn.if to work
105
+ def fn
106
+ Fn
107
+ end
108
+ extend self # for Fn::if and Fn.if
109
+
110
+ def self.included(base)
111
+ base.extend(Fn)
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,64 @@
1
+ # Built-in helpers for the DSL form
2
+ class Lono::Template::Dsl::Builder
3
+ module Helper
4
+ extend Memoist
5
+
6
+ def tags(hash, casing: :camelize)
7
+ hash.map do |k,v|
8
+ k = k.to_s
9
+ k = case casing
10
+ when :camelize
11
+ CfnCamelizer.camelize(k)
12
+ when :underscore
13
+ k.underscore
14
+ when :dasherize
15
+ k.dasherize
16
+ else # leave alone
17
+ k
18
+ end
19
+
20
+ {key: k, value: v}
21
+ end
22
+ end
23
+
24
+ def dimensions(hash, casing: :camelize)
25
+ tags(hash, casing: casing).map { |h|
26
+ h[:name] = h.delete(:key)
27
+ h
28
+ }
29
+ end
30
+
31
+ def user_data(path)
32
+ path = "#{Lono.config.user_data_path}/#{path}"
33
+ if File.exist?(path)
34
+ render_path(path)
35
+ else
36
+ message = "WARNING: user-data path #{path} not found"
37
+ puts message.color(:yellow)
38
+ puts "Called from:"
39
+ puts caller[1]
40
+ message
41
+ end
42
+ end
43
+ memoize :user_data
44
+
45
+ def render_path(path)
46
+ RenderMePretty.result(path, context: self)
47
+ end
48
+
49
+ def s3_bucket
50
+ Lono::S3::Bucket.name
51
+ end
52
+
53
+ def file_s3_key(name, options={})
54
+ Lono::AppFile::Registry.register(name, @blueprint, options)
55
+ "file://app/files/#{name}" # placeholder for post processing
56
+ end
57
+ alias_method :s3_key, :file_s3_key
58
+
59
+ def setting
60
+ Lono::Setting.new
61
+ end
62
+ memoize :setting
63
+ end
64
+ end
@@ -0,0 +1,24 @@
1
+ # Implements:
2
+ #
3
+ # template - uses @definition to build a CloudFormation template section
4
+ #
5
+ class Lono::Template::Dsl::Builder
6
+ class Mapping < Base
7
+ def template
8
+ camelize(standarize(@definition))
9
+ end
10
+
11
+ # Type is the only required property: https://amzn.to/2x8W5aD
12
+ def standarize(definition)
13
+ first, second, _ = definition
14
+ if definition.size == 1 && first.is_a?(Hash) # long form
15
+ first # pass through
16
+ elsif definition.size == 2 && second.is_a?(Hash) # medium form
17
+ logical_id, maps = first, second
18
+ { logical_id => maps }
19
+ else # I dont know what form
20
+ raise "Invalid form provided. definition #{definition.inspect}"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ # Implements:
2
+ #
3
+ # template - uses @definition to build a CloudFormation template section
4
+ #
5
+ class Lono::Template::Dsl::Builder
6
+ class Output < Base
7
+ def template
8
+ camelize(standarize(@definition))
9
+ end
10
+
11
+ # Value is the only required property: https://amzn.to/2xbhmk3
12
+ def standarize(definition)
13
+ first, second, _ = definition
14
+ if definition.size == 1 && first.is_a?(Hash) # long form
15
+ first # pass through
16
+ elsif definition.size == 2 && second.is_a?(Hash) # medium form
17
+ if second.key?(:value)
18
+ logical_id, properties = first, second
19
+ else
20
+ logical_id = first
21
+ properties = {value: second}
22
+ end
23
+ { logical_id => properties }
24
+ elsif definition.size == 2 && second.is_a?(String) # short form
25
+ logical_id = first
26
+ properties = second.is_a?(String) ? { value: second } : {}
27
+ { logical_id => properties }
28
+ elsif definition.size == 1
29
+ logical_id = first.to_s
30
+ properties = {value: ref(logical_id) }
31
+ { logical_id => properties }
32
+ else # I dont know what form
33
+ raise "Invalid form provided. definition #{definition.inspect}"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ # Implements:
2
+ #
3
+ # template - uses @definition to build a CloudFormation template section
4
+ #
5
+ class Lono::Template::Dsl::Builder
6
+ class Parameter < Base
7
+ def template
8
+ camelize(add_required(standarize(@definition)))
9
+ end
10
+
11
+ # Type is the only required property: https://amzn.to/2x8W5aD
12
+ def standarize(definition)
13
+ first, second, _ = definition
14
+ if definition.size == 1 && first.is_a?(Hash) # long form
15
+ first # pass through
16
+ elsif definition.size == 2 && second.is_a?(Hash) # medium form
17
+ logical_id, properties = first, second
18
+ { logical_id => properties }
19
+ elsif (definition.size == 2 && num_or_str?(second)) || # short form
20
+ definition.size == 1
21
+ logical_id = first
22
+ properties = num_or_str?(second) ? { default: second } : {}
23
+ { logical_id => properties }
24
+ else # I dont know what form
25
+ raise "Invalid form provided. definition #{definition.inspect}"
26
+ end
27
+ end
28
+
29
+ def add_required(attributes)
30
+ properties = attributes.values.first
31
+ properties[:type] ||= 'String'
32
+ attributes
33
+ end
34
+
35
+ def num_or_str?(o)
36
+ o.is_a?(Float) || o.is_a?(Integer) || o.is_a?(String)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,38 @@
1
+ # Implements:
2
+ #
3
+ # template - uses @definition to build a CloudFormation template section
4
+ #
5
+ class Lono::Template::Dsl::Builder
6
+ class Resource < Base
7
+ def template
8
+ camelize(standarize(@definition))
9
+ end
10
+
11
+ # Type is the only required property: https://amzn.to/2x8W5aD
12
+ def standarize(definition)
13
+ first, second, third, _ = definition
14
+ if definition.size == 1 && first.is_a?(Hash) # long form
15
+ first # pass through
16
+ elsif definition.size == 2 && second.is_a?(Hash) # medium form
17
+ logical_id, attributes = first, second
18
+ attributes.delete(:properties) if attributes[:properties].nil? || attributes[:properties].empty?
19
+ { logical_id => attributes }
20
+ elsif definition.size == 2 && second.is_a?(String) # short form
21
+ logical_id, type = first, second
22
+ { logical_id => {
23
+ type: type
24
+ }}
25
+ elsif definition.size == 3 && (second.is_a?(String) || second.is_a?(NilClass))# short form
26
+ logical_id, type, properties = first, second, third
27
+ template = { logical_id => {
28
+ type: type
29
+ }}
30
+ attributes = template.values.first
31
+ attributes[:properties] = properties unless properties.empty?
32
+ template
33
+ else # Dont understand this form
34
+ raise "Invalid form provided. definition #{definition.inspect}"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,12 @@
1
+ # Implements:
2
+ #
3
+ # template - uses @definition to build a CloudFormation template section
4
+ #
5
+ class Lono::Template::Dsl::Builder
6
+ class Section < Base
7
+ def template
8
+ hash, _ = @definition
9
+ camelize(hash)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,58 @@
1
+ # Organize core syntax here
2
+ class Lono::Template::Dsl::Builder
3
+ module Syntax
4
+ def aws_template_format_version(version_date)
5
+ @cfn["AWSTemplateFormatVersion"] = version_date
6
+ end
7
+
8
+ def description(text)
9
+ @cfn["Description"] = text
10
+ end
11
+
12
+ def metadata(data)
13
+ @cfn["Metadata"] = data
14
+ end
15
+
16
+ def transform(*definition)
17
+ definition = definition.flatten
18
+ definition.map! { |x| CfnCamelizer.camelize(x) }
19
+ @cfn["Transform"] = definition.size == 1 ? definition.first : definition
20
+ end
21
+
22
+ def parameter(*definition)
23
+ @cfn["Parameters"] ||= {}
24
+ param = Parameter.new(definition)
25
+ @cfn["Parameters"].merge!(param.template)
26
+ end
27
+
28
+ def mapping(*definition)
29
+ @cfn["Mappings"] ||= {}
30
+ mapping = Mapping.new(definition)
31
+ @cfn["Mappings"].merge!(mapping.template)
32
+ end
33
+
34
+ def resource(*definition)
35
+ @cfn["Resources"] ||= {}
36
+ resource = Resource.new(definition)
37
+ @cfn["Resources"].merge!(resource.template)
38
+ end
39
+
40
+ def condition(*definition)
41
+ @cfn["Conditions"] ||= {}
42
+ condition = Condition.new(definition)
43
+ @cfn["Conditions"].merge!(condition.template)
44
+ end
45
+
46
+ def output(*definition)
47
+ @cfn["Outputs"] ||= {}
48
+ output = Output.new(definition)
49
+ @cfn["Outputs"].merge!(output.template)
50
+ end
51
+
52
+ # Generic section method in case CloudFormation adds a new future section.
53
+ # The generic section method adds a new top-level key
54
+ def section(key, definition)
55
+ @cfn[key] = Section.new(definition).template
56
+ end
57
+ end
58
+ end