lono 4.2.7 → 5.0.1

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.
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,82 @@
1
+ class Lono::Template
2
+ class Erb < Base
3
+ include Evaluate
4
+ include Util
5
+
6
+ def initialize(blueprint, options={})
7
+ super
8
+ @templates = []
9
+ @results = {}
10
+ end
11
+
12
+ def run(options={})
13
+ evaluate_templates
14
+ build_templates
15
+ write_output
16
+ end
17
+
18
+ # Instance eval's the template declarations in app/definitions in this order:
19
+ #
20
+ # app/definitions/base.rb
21
+ # app/definitions/base - all files in folder
22
+ # app/definitions/[Lono.env].rb
23
+ # app/definitions/[Lono.env] - all files in folder
24
+ #
25
+ # So Lono.env specific template declarations override base template declarations.
26
+ def evaluate_templates
27
+ evaluate_template("base")
28
+ evaluate_folder("base")
29
+ evaluate_template(Lono.env)
30
+ evaluate_folder(Lono.env)
31
+ end
32
+
33
+ def evaluate_template(name)
34
+ path = "#{Lono.config.definitions_path}/#{name}.rb"
35
+ evaluate_template_path(path)
36
+ end
37
+
38
+ def evaluate_folder(folder)
39
+ paths = Dir.glob("#{Lono.config.definitions_path}/#{folder}/**/*")
40
+ paths.select{ |e| File.file?(e) }.each do |path|
41
+ evaluate_template_path(path)
42
+ end
43
+ end
44
+
45
+ def template(name, &block)
46
+ @templates << {name: name, block: block}
47
+ end
48
+
49
+ def build_templates
50
+ @templates.each do |t|
51
+ @results[t[:name]] = Lono::Template::Template.new(@blueprint, t[:name], t[:block], @options).build
52
+ end
53
+ end
54
+
55
+ def write_output
56
+ output_path = "#{Lono.config.output_path}/#{@blueprint}/templates"
57
+ FileUtils.rm_rf(Lono.config.output_path) if @options[:clean] # removes entire output folder. params and templates
58
+ FileUtils.mkdir_p(output_path)
59
+ puts "Generating CloudFormation templates for blueprint #{@blueprint.color(:green)}:" unless @options[:quiet]
60
+ @results.each do |name,text|
61
+ path = "#{output_path}/#{name}".sub(/^\.\//,'') # strip leading '.'
62
+ path += ".yml"
63
+ unless @options[:quiet]
64
+ pretty_path = path.sub("#{Lono.root}/",'')
65
+ puts " #{pretty_path}"
66
+ end
67
+ ensure_parent_dir(path)
68
+ text = commented(text)
69
+ IO.write(path, text) # write file first so validate method is simpler
70
+ validate_yaml(path)
71
+ end
72
+ end
73
+
74
+ def commented(text)
75
+ comment =<<~EOS
76
+ # This file was generated with lono. Do not edit directly, the changes will be lost.
77
+ # More info: http://lono.cloud
78
+ EOS
79
+ "#{comment}#{text}"
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,39 @@
1
+ class Lono::Template
2
+ module Evaluate
3
+ def evaluate_template_path(path)
4
+ return unless File.exist?(path)
5
+
6
+ begin
7
+ instance_eval(File.read(path), path)
8
+ rescue Exception => e
9
+ template_evaluation_error(e)
10
+ puts "\nFull error:"
11
+ raise
12
+ end
13
+ end
14
+
15
+ # Prints out a user friendly task_definition error message
16
+ def template_evaluation_error(e)
17
+ error_info = e.backtrace.first
18
+ path, line_no, _ = error_info.split(':')
19
+ line_no = line_no.to_i
20
+ puts "Error evaluating #{path}:".color(:red)
21
+ puts e.message
22
+ puts "Here's the line in #{path} with the error:\n\n"
23
+
24
+ contents = IO.read(path)
25
+ content_lines = contents.split("\n")
26
+ context = 5 # lines of context
27
+ top, bottom = [line_no-context-1, 0].max, line_no+context-1
28
+ spacing = content_lines.size.to_s.size
29
+ content_lines[top..bottom].each_with_index do |line_content, index|
30
+ line_number = top+index+1
31
+ if line_number == line_no
32
+ printf("%#{spacing}d %s\n".color(:red), line_number, line_content)
33
+ else
34
+ printf("%#{spacing}d %s\n", line_number, line_content)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,29 @@
1
+ require "yaml"
2
+
3
+ class Lono::Template
4
+ class Generator
5
+ include Lono::Blueprint::Root
6
+
7
+ def initialize(blueprint, options={})
8
+ @blueprint, @options = blueprint, options
9
+ @template = @options[:template] || @blueprint
10
+ Lono::ProjectChecker.check
11
+ set_blueprint_root(@blueprint)
12
+ end
13
+
14
+ def run
15
+ # Examples:
16
+ # Erb.new(b, options.clone).run
17
+ # Dsl.new(b, options.clone).run
18
+ generator_class = "Lono::Template::#{template_type.classify}"
19
+ generator_class = Object.const_get(generator_class)
20
+ generator_class.new(@blueprint, @options.clone).run
21
+ end
22
+
23
+ def template_type
24
+ meta_config = "#{Lono.blueprint_root}/.meta/config.yml"
25
+ data = YAML.load_file(meta_config)
26
+ data["template_type"] || "dsl"
27
+ end
28
+ end
29
+ end
@@ -5,12 +5,10 @@ require "aws-sdk-core"
5
5
  #
6
6
  # @options gets passed into:
7
7
  #
8
- # Lono::Template::Context.new(@options)
8
+ # Lono::Template::Context.new(blueprint, @options)
9
9
  module Lono::Template::Helper
10
10
  # Bash code that is meant to included in user-data
11
11
  def extract_scripts(options={})
12
- check_s3_folder_settings!
13
-
14
12
  settings = setting.data["extract_scripts"] || {}
15
13
  options = settings.merge(options)
16
14
  # defaults also here in case they are removed from settings
@@ -38,40 +36,28 @@ aws s3 cp #{scripts_s3_path} #{to}/
38
36
  BASH_CODE
39
37
  end
40
38
 
41
- def check_s3_folder_settings!
42
- return if setting.s3_folder
43
-
44
- puts "Helper method called that requires the s3_folder to be set at:"
45
- lines = caller.reject { |l| l =~ %r{lib/lono} } # hide internal lono trace
46
- puts " #{lines[0]}"
47
-
48
- puts "Please configure your settings.yml with an s3_folder.".color(:red)
49
- puts "Detected AWS_PROFILE #{ENV['AWS_PROFILE'].inspect}"
50
- exit 1
51
- end
52
-
53
39
  def scripts_name
54
40
  File.basename(scripts_s3_path)
55
41
  end
56
42
 
57
43
  def scripts_s3_path
58
- upload = Lono::Script::Upload.new
44
+ upload = Lono::Script::Upload.new(@blueprint)
59
45
  upload.s3_dest
60
46
  end
61
47
 
62
48
  def template_s3_path(template_name)
63
- check_s3_folder_settings!
64
49
  # high jacking Upload for useful s3_https_url method
65
- template_path = "#{template_name}.yml"
66
- upload = Lono::Template::Upload.new(@options)
50
+ template_path = "output/#{@blueprint}/templates/#{template_name}.yml"
51
+ upload = Lono::Template::Upload.new(@blueprint, @options)
67
52
  upload.s3_https_url(template_path)
68
53
  end
69
54
 
70
55
  def template_params(param_name)
71
56
  generator_options = {
72
- allow_no_file: true
57
+ allow_not_exists: true
73
58
  }.merge(@options)
74
- generator = Lono::Param::Generator.new(param_name, generator_options)
59
+ generator_options["param"] = param_name
60
+ generator = Lono::Param::Generator.new(@blueprint, generator_options)
75
61
  # do not generate because lono cfn calling logic already generated it we only need the values
76
62
  params = generator.params # Returns Array in underscore keys format
77
63
  # convert Array to simplified hash structure
@@ -122,14 +108,6 @@ BASH_CODE
122
108
  path && File.exist?(path)
123
109
  end
124
110
 
125
- def file_s3_key(name)
126
- s3_folder = setting.s3_folder
127
- return nil unless s3_folder
128
-
129
- uploader = Lono::FileUploader.new
130
- uploader.md5_key("#{Lono.root}/app/files/#{name}")
131
- end
132
-
133
111
  def current_region
134
112
  region = Aws.config[:region]
135
113
  region ||= ENV['AWS_REGION']
@@ -0,0 +1,69 @@
1
+ class Lono::Template
2
+ class PostProcessor
3
+ include Lono::Blueprint::Root
4
+ extend Memoist
5
+
6
+ def initialize(blueprint, options={})
7
+ @blueprint, @options = blueprint, options
8
+ @template = @options[:template] || @blueprint
9
+ Lono::ProjectChecker.check
10
+ set_blueprint_root(@blueprint)
11
+ end
12
+
13
+ def run
14
+ replacements.each do |placeholder, replacement|
15
+ update_template!(template)
16
+ end
17
+ write_template!
18
+ end
19
+
20
+ def write_template!
21
+ IO.write(template_path, YAML.dump(template)) # unless ENV['TEST'] # additional safeguard for testing
22
+ end
23
+
24
+ def replacements
25
+ map = {}
26
+ registry_items.each do |item|
27
+ if item.directory? || item.file?
28
+ replacement = item.s3_path
29
+ else
30
+ puts "WARN: PostProcessor replacements Cannot find file: #{item.path}"
31
+ next
32
+ end
33
+
34
+ placeholder = "file://app/files/#{item.name}"
35
+ map[placeholder] = replacement
36
+ end
37
+ map
38
+ end
39
+
40
+ def update_template!(hash)
41
+ hash.each do |k, v|
42
+ if v.is_a?(String)
43
+ if v =~ %r{^file://}
44
+ v.replace(replacements[v]) # replace the placeholder
45
+ end
46
+ elsif v.is_a?(Hash)
47
+ update_template!(v) # recurse
48
+ elsif v.is_a?(Array)
49
+ v.each { |x| update_template!(x) if x.is_a?(Hash) }
50
+ end
51
+ end
52
+ hash
53
+ end
54
+
55
+ # Useful for specs
56
+ def registry_items
57
+ Lono::AppFile::Registry.items
58
+ end
59
+
60
+ def template
61
+ YAML.load_file(template_path)
62
+ end
63
+ memoize :template
64
+
65
+ def template_path
66
+ "#{Lono.config.output_path}/#{@blueprint}/templates/#{@template}.yml"
67
+ end
68
+ end
69
+ end
@@ -5,7 +5,7 @@ require 'base64'
5
5
  class Lono::Template::Template
6
6
  include ERB::Util
7
7
 
8
- # Main template DSL methods are: source and variables
8
+ # Main template Erb methods are: source and variables
9
9
  #
10
10
  # template "example-2" do
11
11
  # source "example"
@@ -13,13 +13,8 @@ class Lono::Template::Template
13
13
  # end
14
14
  #
15
15
  attr_reader :name
16
- def initialize(name, block=nil, options={})
17
- # Taking care to name instance variables with _ in front because we load the
18
- # variables from config/variables and those instance variables can clobber these
19
- # instance variables
20
- @name = name
21
- @block = block
22
- @options = options
16
+ def initialize(blueprint, name, block=nil, options={})
17
+ @blueprint, @name, @block, @options = blueprint, name, block, options
23
18
  @source_path = default_source_path(name)
24
19
  end
25
20
 
@@ -54,6 +49,6 @@ class Lono::Template::Template
54
49
  # Context for ERB rendering.
55
50
  # This is where we control what references get passed to the ERB rendering.
56
51
  def context
57
- @context ||= Lono::Template::Context.new(@options)
52
+ @context ||= Lono::Template::Context.new(@blueprint, @options)
58
53
  end
59
54
  end
@@ -3,150 +3,120 @@ require 'json'
3
3
  require 'base64'
4
4
  require 'digest'
5
5
 
6
- class Lono::Template::Upload
7
- include Lono::Template::AwsService
8
-
9
- def initialize(options={})
10
- @options = options
11
- @checksums = {}
12
- @prefix = "#{folder_key}/#{Lono.env}/templates" # s3://s3-bucket/folder/development/templates
13
- end
6
+ class Lono::Template
7
+ class Upload
8
+ include Lono::Blueprint::Root
9
+ include Lono::AwsServices
10
+
11
+ def initialize(blueprint, options={})
12
+ @blueprint, @options = blueprint, options
13
+ @template = @options[:template] || @blueprint
14
+ Lono::ProjectChecker.check
15
+ set_blueprint_root(@blueprint)
16
+
17
+ @checksums = {}
18
+ @prefix = Lono.env # s3://s3-bucket/development
19
+ end
14
20
 
15
- def run
16
- ensure_s3_setup!
17
- load_checksums!
21
+ def run
22
+ load_checksums!
18
23
 
19
- say "Uploading CloudFormation templates..."
20
- paths = Dir.glob("#{Lono.config.output_path}/templates/**/*")
21
- paths.select { |p| File.file?(p) }.each do |path|
22
- upload(path)
24
+ say "Uploading CloudFormation templates..."
25
+ paths = Dir.glob("#{Lono.config.output_path}/#{@blueprint}/templates/**/*")
26
+ paths.select { |p| File.file?(p) }.each do |path|
27
+ upload(path)
28
+ end
29
+ say "Templates uploaded to s3."
23
30
  end
24
- say "Templates uploaded to s3."
25
- end
26
31
 
27
- # Read existing files on s3 to grab their md5 checksum.
28
- # We do this so we can see if we should avoid re-uploading the s3 child template
29
- # entirely. If we upload a new child template that does not change AWS CloudFormation
30
- # is not smart enough to know that it not has changed. I think all AWS CloudFormation
31
- # does is check if the file's timestamp.
32
- #
33
- # Thought this would result in better AWS Change Set info but AWS still reports child
34
- # stacks being changed even though they should not be reported. Leaving this s3 checksum
35
- # in for now.
36
- def load_checksums!
37
- return if @options[:noop]
38
-
39
- resp = s3.list_objects(bucket: s3_bucket, prefix: @prefix)
40
- resp.contents.each do |object|
41
- # key does not include the bucket name
42
- # full path = s3://my-bucket/s3_folder/templates/production/my-template.yml
43
- # key = s3_folder/templates/production/my-template.yml
44
- # etag is the checksum as long as the file is not a multi-part file upload
45
- # it has extra double quotes wrapped around it.
46
- # etag = "\"9cb437490cee2cc96101baf326e5ca81\""
47
- @checksums[object.key] = strip_surrounding_quotes(object.etag)
32
+ # Read existing files on s3 to grab their md5 checksum.
33
+ # We do this so we can see if we should avoid re-uploading the s3 child template
34
+ # entirely. If we upload a new child template that does not change AWS CloudFormation
35
+ # is not smart enough to know that it not has changed. I think all AWS CloudFormation
36
+ # does is check if the file's timestamp.
37
+ #
38
+ # Thought this would result in better AWS Change Set info but AWS still reports child
39
+ # stacks being changed even though they should not be reported. Leaving this s3 checksum
40
+ # in for now.
41
+ def load_checksums!
42
+ return if @options[:noop]
43
+
44
+ resp = s3.list_objects(bucket: s3_bucket, prefix: @prefix)
45
+ resp.contents.each do |object|
46
+ @checksums[object.key] = strip_surrounding_quotes(object.etag)
47
+ end
48
+ @checksums
48
49
  end
49
- @checksums
50
- end
51
-
52
- def strip_surrounding_quotes(string)
53
- string.sub(/^"/,'').sub(/"$/,'')
54
- end
55
50
 
56
- def upload(path)
57
- pretty_path = path.sub(/^\.\//, '')
58
- key = "#{@prefix}/#{pretty_path.sub(%r{output/templates/},'')}"
59
- s3_full_path = "s3://#{s3_bucket}/#{key}"
60
-
61
- local_checksum = Digest::MD5.hexdigest(IO.read(path))
62
- remote_checksum = remote_checksum(path)
63
- if local_checksum == remote_checksum
64
- say("Not modified: #{pretty_path} to #{s3_full_path}".color(:yellow)) unless @options[:noop]
65
- return # do not upload unless the checksum has changed
51
+ def strip_surrounding_quotes(string)
52
+ string.sub(/^"/,'').sub(/"$/,'')
66
53
  end
67
54
 
68
- resp = s3.put_object(
69
- body: IO.read(path),
70
- bucket: s3_bucket,
71
- key: key,
72
- storage_class: "REDUCED_REDUNDANCY"
73
- ) unless @options[:noop]
74
-
75
- # Example output:
76
- # Uploaded: output/templates/docker.yml to s3://boltops-dev/s3_folder/templates/development/docker.yml
77
- # Uploaded: output/templates/ecs/private.yml to s3://boltops-dev/s3_folder/templates/development/ecs/private.yml
78
- message = "Uploaded: #{pretty_path} to #{s3_full_path}".color(:green)
79
- message = "NOOP: #{message}" if @options[:noop]
80
- say message
81
- end
82
-
83
- # @checksums map has a key format: s3_folder/templates/development/docker.yml
84
- #
85
- # path = ./output/templates/docker.yml
86
- # s3_folder = s3://boltops-dev/s3_folder/templates/development/docker.yml
87
- def remote_checksum(path)
88
- # first convert the local path to the path format that is stored in @checksums keys
89
- # ./output/templates/docker.yml => s3_folder/templates/development/docker.yml
90
- pretty_path = path.sub(/^\.\//, '')
91
- key = "#{@prefix}/#{pretty_path.sub(%r{output/templates/},'')}"
92
- @checksums[key]
93
- end
94
-
95
- # https://s3.amazonaws.com/mybucket/s3_folder/templates/production/parent.yml
96
- def s3_https_url(template_path)
97
- ensure_s3_setup!
98
- "https://s3.amazonaws.com/#{s3_bucket}/#{@prefix}/#{template_path}"
99
- end
100
-
101
- # used for cfn/base.rb def set_template_body!(params)
102
- def s3_presigned_url(template_output_path)
103
- template_path = template_output_path.sub('output/templates/','')
104
- key = "#{@prefix}/#{template_path}"
105
- s3_presigner.presigned_url(:get_object, bucket: s3_bucket, key: key)
106
- end
107
-
108
- def s3_presigner
109
- @signer ||= Aws::S3::Presigner.new
110
- end
111
-
112
- # Parse the s3_folder setting and remove the folder portion to leave the
113
- # "s3_bucket" portion
114
- # Example:
115
- # s3_bucket('s3://mybucket/templates/storage/path')
116
- # => mybucket
117
- def s3_bucket
118
- return nil if @options[:noop] # to get spec passing
119
- return nil unless s3_folder
120
- s3_folder.sub('s3://','').split('/').first
121
- end
55
+ def upload(path)
56
+ return if @options[:noop]
57
+
58
+ path = path.sub("#{Lono.root}/",'')
59
+ pretty_path = path.sub(/^\.\//, '')
60
+ key = "#{@prefix}/#{pretty_path.sub(%r{output/templates/},'')}"
61
+ s3_full_path = "s3://#{s3_bucket}/#{key}"
62
+
63
+ local_checksum = Digest::MD5.hexdigest(IO.read(path))
64
+ remote_checksum = remote_checksum(path)
65
+ if local_checksum == remote_checksum
66
+ say("Not modified: #{pretty_path} to #{s3_full_path}".color(:yellow)) unless @options[:noop]
67
+ return # do not upload unless the checksum has changed
68
+ end
69
+
70
+ resp = s3.put_object(
71
+ body: IO.read(path),
72
+ bucket: s3_bucket,
73
+ key: key,
74
+ storage_class: "REDUCED_REDUNDANCY"
75
+ ) unless @options[:noop]
76
+
77
+ # Example output:
78
+ # Uploaded: output/templates/docker.yml to s3://boltops-dev/s3_folder/templates/development/docker.yml
79
+ # Uploaded: output/templates/ecs/private.yml to s3://boltops-dev/s3_folder/templates/development/ecs/private.yml
80
+ message = "Uploaded: #{pretty_path} to #{s3_full_path}".color(:green)
81
+ message = "NOOP: #{message}" if @options[:noop]
82
+ say message
83
+ end
122
84
 
123
- # The folder_key is the s3_folder setting with the s3 bucket.
124
- #
125
- # Example:
126
- # s3_bucket('s3://mybucket/templates/storage/path')
127
- # => templates/storage/path
128
- def folder_key
129
- return nil if @options[:noop] # to get spec passing
130
- return nil unless s3_folder
131
- s3_folder.sub('s3://','').split('/')[1..-1].join('/')
132
- end
85
+ # @checksums map has a key format: s3_folder/templates/development/docker.yml
86
+ #
87
+ # path = ./output/templates/docker.yml
88
+ # s3_folder = s3://boltops-dev/s3_folder/templates/development/docker.yml
89
+ def remote_checksum(path)
90
+ # first convert the local path to the path format that is stored in @checksums keys
91
+ # ./output/templates/docker.yml => s3_folder/templates/development/docker.yml
92
+ pretty_path = path.sub(/^\.\//, '')
93
+ key = "#{@prefix}/#{pretty_path.sub(%r{output/templates/},'')}"
94
+ @checksums[key]
95
+ end
133
96
 
134
- def s3_folder
135
- settings = Lono::Setting.new
136
- settings.s3_folder
137
- end
97
+ # https://s3.amazonaws.com/mybucket/s3_folder/templates/production/parent.yml
98
+ def s3_https_url(template_path)
99
+ "https://s3.amazonaws.com/#{s3_bucket}/#{@prefix}/#{template_path}"
100
+ end
138
101
 
139
- # nice warning if the s3 path not found
140
- def ensure_s3_setup!
141
- return if @options[:noop]
142
- return if s3_folder
102
+ # used for cfn/base.rb def set_template_body!(params)
103
+ def s3_presigned_url(template_output_path)
104
+ template_path = template_output_path.sub('output/templates/','')
105
+ key = "#{@prefix}/#{template_path}"
106
+ s3_presigner.presigned_url(:get_object, bucket: s3_bucket, key: key)
107
+ end
143
108
 
144
- say "Unable to upload templates to s3 because you have not configured the s3_folder option in lono settings.yml.".color(:red)
145
- say "Please configure settings.yml with s3_folder. For more help: http://lono.cloud/docs/settings/".color(:red)
146
- exit 1
147
- end
109
+ # Parse the s3_folder setting and remove the folder portion to leave the
110
+ # "s3_bucket" portion
111
+ # Example:
112
+ # s3_bucket('s3://mybucket/templates/storage/path')
113
+ # => mybucket
114
+ def s3_bucket
115
+ Lono::S3::Bucket.name
116
+ end
148
117
 
149
- def say(message)
150
- puts message unless @options[:quiet]
118
+ def say(message)
119
+ puts message unless @options[:quiet]
120
+ end
151
121
  end
152
- end
122
+ end