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
@@ -1,47 +1,88 @@
1
1
  class Lono::Param::Generator
2
- def self.generate_all(options)
3
- puts "Generating parameter files:"
2
+ include Lono::Blueprint::Root
3
+ include Lono::Conventions
4
+
5
+ attr_reader :env_path, :base_path # set when generate is called
6
+ def initialize(blueprint, options={})
7
+ @blueprint, @options = blueprint, options
8
+ set_blueprint_root(@blueprint)
9
+ @template, @param = template_param_convention(options)
10
+ end
4
11
 
5
- params = param_names("base") + param_names(Lono.env)
6
- params.uniq.each do |name|
7
- param = Lono::Param::Generator.new(name, options)
8
- param.generate
12
+ def puts_param_message(type)
13
+ path = send("#{type}_path")
14
+ return unless path
15
+ if File.exist?(path)
16
+ pretty_path = path.sub("#{Lono.root}/",'')
17
+ puts "Using param: #{pretty_path}".color(:yellow)
9
18
  end
10
19
  end
11
20
 
12
- # Returns param names
13
- # Example:
14
- # Given params:
15
- # params/base/a.txt params/base/b.txt params/base/c.txt
16
- # Returns:
17
- # param_names("base") => ["a", "b", "c"]
18
- def self.param_names(folder)
19
- base_folder = "#{Lono.config.params_path}/#{folder}" # Example: "./params/base"
20
- Dir.glob("#{base_folder}/**/*.txt").map do |path|
21
- path.sub("#{base_folder}/", '').sub('.txt','')
21
+ # Lookup precedence:
22
+ #
23
+ # configs/BLUEPRINT/params/development/TEMPLATE/PARAM.txt
24
+ # configs/BLUEPRINT/params/development/PARAM.txt
25
+ # configs/BLUEPRINT/params/development.txt
26
+ #
27
+ def lookup_param_file(root: Lono.root, env: Lono.env)
28
+ long_form = "#{root}/configs/#{@blueprint}/params/#{env}/#{@template}/#{@param}.txt"
29
+ medium_form = "#{root}/configs/#{@blueprint}/params/#{env}/#{@param}.txt"
30
+ short_form = "#{root}/configs/#{@blueprint}/params/#{env}.txt"
31
+
32
+ if ENV['LONO_PARAM_DEBUG']
33
+ puts "Lono.blueprint_root #{Lono.blueprint_root}"
34
+ puts "long_form #{long_form}"
35
+ puts "medium_form #{medium_form}"
36
+ puts "short_form #{short_form}"
37
+ end
38
+
39
+ return long_form if File.exist?(long_form) # always consider this first because its so explicit
40
+
41
+ # All 3 are the same
42
+ if @blueprint == @template && @template == @param
43
+ return medium_form if File.exist?(medium_form) # higher precedence between longer but short form should be encouraged
44
+ return short_form if File.exist?(short_form)
45
+ return # cannot find a param file
46
+ end
47
+
48
+ # Only template and param are the same
49
+ if @template == @param
50
+ return medium_form if File.exist?(medium_form) # only consider medium form
51
+ return # cannot find a param file
22
52
  end
23
53
  end
24
54
 
25
- def initialize(name, options)
26
- @name = "#{Lono.env}/#{name}"
27
- @options = options
28
- @env_path = options[:path] || "#{Lono.config.params_path}/#{@name}.txt"
29
- @base_path = @env_path.sub("/#{Lono.env}/", "/base/")
55
+ def lookup_paths
56
+ @base_path = lookup_param_file(env: "base")
57
+ @env_path = lookup_param_file(env: Lono.env)
58
+
59
+ if ENV['LONO_PARAM_DEBUG']
60
+ puts " @base_path #{@base_path.inspect}"
61
+ puts " @env_path #{@env_path.inspect}"
62
+ end
63
+
64
+ [@base_path, @env_path]
30
65
  end
31
66
 
32
67
  def generate
33
- # useful option for lono cfn
34
- return if @options[:allow_no_file] && !source_exist?
68
+ puts "Generating parameter files for blueprint #{@blueprint.color(:green)}:"
69
+
70
+ @base_path, @env_path = lookup_paths
71
+
72
+ return unless @base_path || @env_path
73
+
74
+ # useful option for lono cfn, since some templates dont require params
75
+ return if @options[:allow_not_exists] && !source_exist?
35
76
 
36
77
  if source_exist?
37
78
  contents = process_erb
38
79
  data = convert_to_cfn_format(contents)
39
80
  json = JSON.pretty_generate(data)
40
81
  write_output(json)
41
- # Example: @name = stag/ecs/private
42
- # pretty_name = ecs/private
43
- pretty_name = @name.sub("#{Lono.env}/", '')
44
- puts " #{output_path}" unless @options[:mute]
82
+ unless @options[:mute]
83
+ short_output_path = output_path.sub("#{Lono.root}/","")
84
+ puts " #{short_output_path}"
85
+ end
45
86
  else
46
87
  puts "#{@base_path} or #{@env_path} could not be found? Are you sure it exist?"
47
88
  exit 1
@@ -49,10 +90,21 @@ class Lono::Param::Generator
49
90
  json
50
91
  end
51
92
 
93
+ # Checks both base and source path for existing of the param file.
94
+ # Example:
95
+ # params/base/mystack.txt - base path
96
+ # params/production/mystack.txt - source path
97
+ def source_exist?
98
+ @base_path && File.exist?(@base_path) ||
99
+ @env_path && File.exist?(@env_path)
100
+ end
101
+
52
102
  # useful for when calling CloudFormation via the aws-sdk gem
53
103
  def params(casing = :underscore)
104
+ @base_path, @env_path = lookup_paths
105
+
54
106
  # useful option for lono cfn
55
- return {} if @options[:allow_no_file] && !source_exist?
107
+ return {} if @options[:allow_not_exists] && !source_exist?
56
108
 
57
109
  contents = process_erb
58
110
  convert_to_cfn_format(contents, casing)
@@ -61,7 +113,7 @@ class Lono::Param::Generator
61
113
  # Reads both the base source and env source and overlay the two
62
114
  # Example 1:
63
115
  # params/base/mystack.txt - base path
64
- # params/prod/mystack.txt - env path
116
+ # params/production/mystack.txt - env path
65
117
  #
66
118
  # the base/mystack.txt gets combined with the prod/mystack.txt
67
119
  # it produces a final prod/mystack.txt
@@ -72,17 +124,21 @@ class Lono::Param::Generator
72
124
  # the base/mystack.txt is used to produced a prod/mystack.txt
73
125
  #
74
126
  # Example 3:
75
- # params/prod/mystack.txt - env path
127
+ # params/production/mystack.txt - env path
76
128
  #
77
129
  # the prod/mystack.txt is used to produced a prod/mystack.txt
78
130
  def process_erb
79
131
  contents = []
80
132
  contents << render_erb(@base_path)
81
133
  contents << render_erb(@env_path)
82
- contents.compact.join("\n")
134
+ result = contents.compact.join("\n")
135
+ # puts "process_erb result".color(:yellow)
136
+ # puts result
137
+ result
83
138
  end
84
139
 
85
140
  def render_erb(path)
141
+ return unless path
86
142
  if File.exist?(path)
87
143
  RenderMePretty.result(path, context: context)
88
144
  end
@@ -91,15 +147,7 @@ class Lono::Param::Generator
91
147
  # Context for ERB rendering.
92
148
  # This is where we control what references get passed to the ERB rendering.
93
149
  def context
94
- @context ||= Lono::Template::Context.new(@options)
95
- end
96
-
97
- # Checks both base and source path for existing of the param file.
98
- # Example:
99
- # params/base/mystack.txt - base path
100
- # params/prod/mystack.txt - source path
101
- def source_exist?
102
- File.exist?(@base_path) || File.exist?(@env_path)
150
+ @context ||= Lono::Template::Context.new(@blueprint, @options)
103
151
  end
104
152
 
105
153
  def parse_contents(contents)
@@ -147,8 +195,14 @@ class Lono::Param::Generator
147
195
  end
148
196
 
149
197
  def output_path
150
- name = @name.sub("#{Lono.env}/", "") # remove the Lono.env from the output path
151
- "#{Lono.config.output_path}/params/#{name}.json".sub(/\.\//,'')
198
+ output = Lono.config.output_path.sub("#{Lono.root}/","")
199
+ path = if @base_path && !@env_path
200
+ # Handle case when base config exist but the env config does not
201
+ @base_path.sub("configs", output).sub("base", Lono.env)
202
+ else
203
+ @env_path.sub("configs", output)
204
+ end
205
+ path.sub(/\.txt$/,'.json')
152
206
  end
153
207
 
154
208
  def write_output(json)
@@ -4,24 +4,43 @@ module Lono
4
4
  # If not, provide a friendly message and possibly exit.
5
5
  class ProjectChecker
6
6
  class << self
7
+ # 2 ways to use lono.
8
+ #
9
+ # 1. A standalone project - not available below version 5
10
+ # 2. A multimode project - available after version 5
11
+ #
12
+ @@checked = false
7
13
  def check
8
- check_lono_project
14
+ return if @@checked
15
+
16
+ unless standalone? or multimode?
17
+ puts "ERROR: Was unable to detect that you are within a lono project. Are you sure you are in lono project?".color(:red)
18
+ quit 1
19
+ end
20
+
21
+ @@mode = standalone? ? :standalone : :multimode
22
+
23
+ @@checked = true
9
24
  end
10
25
 
11
- def check_lono_project
26
+ def mode
27
+ @@mode
28
+ end
29
+
30
+ def standalone?
12
31
  paths = %w[
13
- config/settings.yml
14
32
  app/definitions
15
33
  app/templates
16
34
  ]
17
- paths.each do |path|
18
- unless File.exist?("#{Lono.root}/#{path}")
19
- puts "ERROR: The #{path} does not exist in this project. Are you sure you are in lono project?".color(:red)
20
- quit 1
21
- end
35
+ paths.all? do |path|
36
+ File.exist?("#{Lono.root}/#{path}")
22
37
  end
23
38
  end
24
39
 
40
+ def multimode?
41
+ File.exist?("#{Lono.root}/configs/settings.yml")
42
+ end
43
+
25
44
  # Dont exit for this one. It's okay. But show a warning.
26
45
  def empty_templates
27
46
  if Dir["#{Lono.config.templates_path}/**/*"].empty?
@@ -0,0 +1,23 @@
1
+ module Lono
2
+ class S3 < Command
3
+ desc "deploy", "deploys lono managed s3 bucket"
4
+ long_desc Help.text("s3/deploy")
5
+ def deploy
6
+ Bucket.new(options).deploy
7
+ end
8
+
9
+ desc "show", "shows lono managed s3 bucket"
10
+ long_desc Help.text("s3/show")
11
+ option :sure, type: :boolean, desc: "Bypass are you sure prompt"
12
+ def show
13
+ Bucket.new(options).show
14
+ end
15
+
16
+ desc "delete", "deletes lono managed s3 bucket"
17
+ long_desc Help.text("s3/delete")
18
+ option :sure, type: :boolean, desc: "Bypass are you sure prompt"
19
+ def delete
20
+ Bucket.new(options).delete
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,123 @@
1
+ class Lono::S3
2
+ class Bucket
3
+ STACK_NAME = ENV['LONO_STACK_NAME'] || "lono"
4
+ include Lono::AwsServices
5
+ extend Lono::AwsServices
6
+
7
+ class << self
8
+ @@name = nil
9
+ def name
10
+ return @@name if @@name # only memoize once bucket has been created
11
+
12
+ stack = new.find_stack
13
+ return unless stack
14
+
15
+ resp = cfn.describe_stack_resources(stack_name: STACK_NAME)
16
+ bucket = resp.stack_resources.find { |r| r.logical_resource_id == "Bucket" }
17
+ @@name = bucket.physical_resource_id # actual bucket name
18
+ end
19
+ end
20
+
21
+ def initialize(options={})
22
+ @options = options
23
+ end
24
+
25
+ def deploy
26
+ stack = find_stack
27
+ if stack
28
+ update
29
+ else
30
+ create
31
+ end
32
+ end
33
+
34
+ def exist?
35
+ !!bucket_name
36
+ end
37
+
38
+ def bucket_name
39
+ self.class.name
40
+ end
41
+
42
+ def show
43
+ if bucket_name
44
+ puts "Lono bucket name: #{bucket_name}"
45
+ else
46
+ puts "Lono bucket does not exist yet."
47
+ end
48
+ end
49
+
50
+ # Launches a cloudformation to create an s3 bucket
51
+ def create
52
+ puts "Creating #{STACK_NAME} stack with the s3 bucket"
53
+ cfn.create_stack(stack_name: STACK_NAME, template_body: template_body)
54
+ status = ::Cfn::Status.new(STACK_NAME)
55
+ status.wait
56
+ end
57
+
58
+ def update
59
+ puts "Updating #{STACK_NAME} stack with the s3 bucket"
60
+ cfn.update_stack(stack_name: STACK_NAME, template_body: template_body)
61
+ rescue Aws::CloudFormation::Errors::ValidationError => e
62
+ raise unless e.message.include?("No updates are to be performed")
63
+ end
64
+
65
+ def delete
66
+ are_you_sure?
67
+
68
+ puts "Deleting #{STACK_NAME} stack with the s3 bucket"
69
+ empty_bucket!
70
+ cfn.delete_stack(stack_name: STACK_NAME)
71
+ end
72
+
73
+ def find_stack
74
+ resp = cfn.describe_stacks(stack_name: STACK_NAME)
75
+ resp.stacks.first
76
+ rescue Aws::CloudFormation::Errors::ValidationError
77
+ nil
78
+ end
79
+
80
+ private
81
+
82
+ def empty_bucket!
83
+ resp = s3.list_objects(bucket: bucket_name)
84
+ if resp.contents.size > 0
85
+ # IE: objects = [{key: "objectkey1"}, {key: "objectkey2"}]
86
+ objects = resp.contents.map { |item| {key: item.key} }
87
+ s3.delete_objects(
88
+ bucket: bucket_name,
89
+ delete: {
90
+ objects: objects,
91
+ quiet: false,
92
+ }
93
+ )
94
+ empty_bucket! # keep deleting objects until bucket is empty
95
+ end
96
+ end
97
+
98
+
99
+ def are_you_sure?
100
+ return true if @options[:sure]
101
+
102
+ puts "Are you sure you want the lono bucket #{bucket_name.color(:green)} to be emptied and deleted? (y/N)"
103
+ sure = $stdin.gets.strip
104
+ yes = sure =~ /^Y/i
105
+ unless yes
106
+ puts "Phew that was close."
107
+ exit
108
+ end
109
+ end
110
+
111
+ def template_body
112
+ <<~YAML
113
+ Resources:
114
+ Bucket:
115
+ Type: AWS::S3::Bucket
116
+ Properties:
117
+ Tags:
118
+ - Key: Name
119
+ Value: lono
120
+ YAML
121
+ end
122
+ end
123
+ end
@@ -1,19 +1,15 @@
1
1
  module Lono
2
2
  class Script < Command
3
- autoload :Base, "lono/script/base"
4
- autoload :Build, "lono/script/build"
5
- autoload :Upload, "lono/script/upload"
6
-
7
3
  desc "build", "Builds `output/scripts/scripts-md5sum.tgz` from `app/script` folder"
8
4
  long_desc Help.text("script/build")
9
- def build
10
- Build.new(options).run
5
+ def build(blueprint)
6
+ Build.new(blueprint, options).run
11
7
  end
12
8
 
13
9
  desc "upload", "Uploads `output/scripts/scripts-md5sum.tgz` to s3"
14
10
  long_desc Help.text("script/upload")
15
- def upload
16
- Upload.new(options).run
11
+ def upload(blueprint)
12
+ Upload.new(blueprint, options).run
17
13
  end
18
14
  end
19
15
  end
@@ -1,9 +1,14 @@
1
1
  class Lono::Script
2
2
  class Base
3
3
  SCRIPTS_INFO_PATH = "#{Lono.config.output_path}/data/scripts_info.txt"
4
+ include Lono::Blueprint::Root
4
5
 
5
- def initialize(options = {})
6
- @options = options
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
+ Lono::ProjectChecker.empty_templates
7
12
  end
8
13
  end
9
14
  end
@@ -11,11 +11,10 @@ class Lono::Script
11
11
  def run
12
12
  Lono::ProjectChecker.check
13
13
  reset
14
- if Dir["#{Lono.root}/app/scripts/*"].empty?
15
- puts "No detected app/scripts"
14
+ if Dir["#{Lono.blueprint_root}/app/scripts/*"].empty?
16
15
  return
17
16
  else
18
- puts "Detected app/scripts"
17
+ puts "Detected app/scripts for blueprint #{@blueprint}"
19
18
  end
20
19
 
21
20
  puts "Tarballing app/scripts folder to scripts.tgz"
@@ -36,12 +35,12 @@ class Lono::Script
36
35
  def create_tarball
37
36
  # https://apple.stackexchange.com/questions/14980/why-are-dot-underscore-files-created-and-how-can-i-avoid-them
38
37
  # using system to avoid displaying command
39
- system "cd app && dot_clean ." if system("type dot_clean > /dev/null 2>&1")
38
+ system "cd #{Lono.blueprint_root}/app && dot_clean ." if system("type dot_clean > /dev/null 2>&1")
40
39
 
41
40
  # https://serverfault.com/questions/110208/different-md5sums-for-same-tar-contents
42
41
  # Using tar czf directly results in a new m5sum each time because the gzip
43
42
  # timestamp is included. So using: tar -c ... | gzip -n
44
- sh "cd app && tar -c scripts | gzip -n > scripts.tgz" # temporary app/scripts.tgz file
43
+ sh "cd #{Lono.blueprint_root}/app && tar -c scripts | gzip -n > scripts.tgz" # temporary app/scripts.tgz file
45
44
 
46
45
  rename_with_md5!
47
46
  end
@@ -49,9 +48,9 @@ class Lono::Script
49
48
  # Apppend a md5 to file after it's been created and moves it to
50
49
  # output/scripts/scripts-[MD5].tgz
51
50
  def rename_with_md5!
52
- md5_path = "output/scripts/scripts-#{md5sum}.tgz"
51
+ md5_path = "output/#{@blueprint}/scripts/scripts-#{md5sum}.tgz"
53
52
  FileUtils.mkdir_p(File.dirname(md5_path))
54
- FileUtils.mv("app/scripts.tgz", md5_path)
53
+ FileUtils.mv("#{Lono.blueprint_root}/app/scripts.tgz", md5_path)
55
54
  md5_path
56
55
  end
57
56
 
@@ -62,7 +61,7 @@ class Lono::Script
62
61
 
63
62
  # cache this because the file will get removed
64
63
  def md5sum
65
- @md5sum ||= Digest::MD5.file("app/scripts.tgz").to_s[0..7]
64
+ @md5sum ||= Digest::MD5.file("#{Lono.blueprint_root}/app/scripts.tgz").to_s[0..7]
66
65
  end
67
66
 
68
67
  def sh(command)