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,60 +1,68 @@
1
- class Lono::Cfn::Update < Lono::Cfn::Base
2
- # save_stack is the interface method
3
- def save_stack(params)
4
- update_stack(params)
5
- end
6
-
7
- # aws cloudformation update-stack --stack-name prod-hi-123456789 --parameters file://output/params/prod-hi-123456789.json --template-body file://output/prod-hi.json
8
- def update_stack(params)
9
- message = "Updating #{@stack_name} stack"
10
- if @options[:noop]
11
- puts "NOOP #{message}"
12
- return
1
+ class Lono::Cfn
2
+ class Update < Base
3
+ # save_stack is the interface method
4
+ def save_stack(params)
5
+ update_stack(params)
13
6
  end
14
7
 
15
- unless stack_exists?(@stack_name)
16
- puts "Cannot update a stack because the #{@stack_name} does not exists."
17
- return
18
- end
19
- exit_unless_updatable!(stack_status(@stack_name))
20
-
21
- options = @options.merge(lono: false, mute_params: true, mute_using: true, keep: true)
22
- # create new copy of preview when update_stack is called because of IAM retry logic
23
- preview = Lono::Cfn::Preview.new(@stack_name, options)
24
-
25
- error = nil
26
- diff.run if @options[:diff]
27
- preview.run if @options[:preview]
28
- are_you_sure?(@stack_name, :update)
29
-
30
- if @options[:change_set] # defaults to this
31
- message << " via change set: #{preview.change_set_name}"
32
- preview.execute_change_set
33
- else
34
- standard_update(params)
8
+ # aws cloudformation update-stack --stack-name prod-hi-123456789 --parameters file://output/params/prod-hi-123456789.json --template-body file://output/prod-hi.json
9
+ def update_stack(params)
10
+ message = "Updating #{@stack_name} stack"
11
+ if @options[:noop]
12
+ puts "NOOP #{message}"
13
+ return
14
+ end
15
+
16
+ deleted = delete_rollback_stack
17
+ if deleted
18
+ Create.new(@stack_name, @options).create_stack(params)
19
+ return
20
+ end
21
+
22
+ unless stack_exists?(@stack_name)
23
+ puts "Cannot update a stack because the #{@stack_name} does not exists."
24
+ return
25
+ end
26
+ exit_unless_updatable!(stack_status(@stack_name))
27
+
28
+ options = @options.merge(mute_params: true, mute_using: true, keep: true)
29
+ # create new copy of preview when update_stack is called because of IAM retry logic
30
+ preview = Lono::Cfn::Preview.new(@stack_name, options)
31
+
32
+ error = nil
33
+ diff.run if @options[:diff]
34
+ preview.run if @options[:preview]
35
+ are_you_sure?(@stack_name, :update)
36
+
37
+ if @options[:change_set] # defaults to this
38
+ message << " via change set: #{preview.change_set_name}"
39
+ preview.execute_change_set
40
+ else
41
+ standard_update(params)
42
+ end
43
+ puts message unless @options[:mute] || error
35
44
  end
36
- puts message unless @options[:mute] || error
37
- end
38
45
 
39
- def standard_update(params)
40
- params = {
41
- stack_name: @stack_name,
42
- parameters: params,
43
- capabilities: capabilities, # ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"]
44
- disable_rollback: !@options[:rollback],
45
- tags: tags,
46
- }
47
- set_template_body!(params)
48
- show_parameters(params, "cfn.update_stack")
49
- begin
50
- cfn.update_stack(params)
51
- rescue Aws::CloudFormation::Errors::ValidationError => e
52
- puts "ERROR: #{e.message}".red
53
- error = true
46
+ def standard_update(params)
47
+ params = {
48
+ stack_name: @stack_name,
49
+ parameters: params,
50
+ capabilities: capabilities, # ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"]
51
+ disable_rollback: !@options[:rollback],
52
+ }
53
+ params[:tags] = tags unless tags.empty?
54
+ set_template_body!(params)
55
+ show_parameters(params, "cfn.update_stack")
56
+ begin
57
+ cfn.update_stack(params)
58
+ rescue Aws::CloudFormation::Errors::ValidationError => e
59
+ puts "ERROR: #{e.message}".red
60
+ error = true
61
+ end
54
62
  end
55
- end
56
63
 
57
- def diff
58
- @diff ||= Lono::Cfn::Diff.new(@stack_name, @options.merge(lono: false, mute_params: true, mute_using: true))
64
+ def diff
65
+ @diff ||= Lono::Cfn::Diff.new(@stack_name, @options.merge(mute_params: true, mute_using: true))
66
+ end
59
67
  end
60
- end
68
+ end
@@ -3,50 +3,64 @@ module Lono
3
3
 
4
4
  long_desc Help.text(:new)
5
5
  New.cli_options.each do |args|
6
- option *args
6
+ option(*args)
7
7
  end
8
8
  register(New, "new", "new NAME", "Generates new lono project.")
9
9
 
10
- desc "import SOURCE", "Imports CloudFormation template and lono-fies it."
11
- long_desc Help.text(:import)
12
- option :name, default: nil, desc: "final name of downloaded template without extension"
13
- option :casing, default: "dasherize", desc: "camelcase or dasherize the template name"
14
- option :summary, default: true, type: :boolean, desc: "provide template summary after import"
15
- def import(source)
16
- Importer.new(source, options).run
10
+ long_desc Help.text(:blueprint)
11
+ Blueprint.cli_options.each do |args|
12
+ option(*args)
13
+ end
14
+ register(Blueprint, "blueprint", "blueprint NAME", "Generates new lono blueprint.")
15
+
16
+ desc "blueprints", "Lists available blueprints in the project."
17
+ long_desc Help.text(:blueprints)
18
+ def blueprints
19
+ Blueprint::List.available
17
20
  end
18
21
 
19
22
  desc "generate", "Generate both CloudFormation templates and parameters files."
20
23
  long_desc Help.text(:generate)
21
- option :clean, type: :boolean, default: true, desc: "remove all output files before generating"
24
+ option :clean, type: :boolean, default: false, desc: "remove all output files before generating"
22
25
  option :quiet, type: :boolean, desc: "silence the output"
23
- def generate
24
- puts "Generating CloudFormation templates, parameters, and scripts"
25
- Script::Build.new(options).run
26
- Template::DSL.new(options).run
27
- Param::Generator.generate_all(options)
26
+ def generate(blueprint=nil)
27
+ Blueprint::Find.one_or_all(blueprint).each do |b|
28
+ Script::Build.new(b, options).run
29
+ Template::Generator.new(b, options).run
30
+ Param::Generator.new(b, options).generate
31
+ end
28
32
  end
29
33
 
30
34
  desc "user_data NAME", "Generates user_data script for debugging."
31
35
  long_desc Help.text(:user_data)
32
36
  option :clean, type: :boolean, default: true, desc: "remove all output/user_data files before generating"
33
- def user_data(name)
34
- Script::Build.new(options).run
35
- UserData.new(options.merge(name: name)).generate
37
+ def user_data(blueprint, name)
38
+ Script::Build.new(blueprint, options).run
39
+ UserData.new(blueprint, options.merge(name: name)).generate
36
40
  end
37
41
 
38
- desc "summary STACK", "Prints summary of CloudFormation template."
42
+ desc "summary BLUEPRINT TEMPLATE", "Prints summary of CloudFormation templates."
39
43
  long_desc Help.text("summary")
40
- def summary(name)
41
- Lono::Inspector::Summary.new(name, options).run
44
+ def summary(blueprint=nil, template=nil)
45
+ Lono::Inspector::Summary.new(blueprint, template, options).run
42
46
  end
43
47
 
44
48
  desc "xgraph STACK", "Graphs dependencies tree of CloudFormation template resources."
45
49
  long_desc Help.text("xgraph")
46
50
  option :display, type: :string, desc: "graph or text", default: "graph"
47
51
  option :noop, type: :boolean, desc: "noop mode"
48
- def xgraph(name)
49
- Lono::Inspector::Graph.new(name, options).run
52
+ def xgraph(blueprint, template=nil)
53
+ template ||= blueprint
54
+ Lono::Inspector::Graph.new(blueprint, template, options).run
55
+ end
56
+
57
+ desc "configure", "Configure blueprint with starter values."
58
+ option :defaults, type: :boolean, desc: "Bypass prompt and use the blueprints configure default values."
59
+ option :param, desc: "override convention and specify the param file to use"
60
+ option :seed, default: :convention, desc: "path to seed file to allow prompts bypass. yaml format."
61
+ option :template, desc: "override convention and specify the template file to use"
62
+ def configure(blueprint)
63
+ Configure.new(blueprint, options).run
50
64
  end
51
65
 
52
66
  desc "clean", "Removes `output` folder."
@@ -68,7 +82,8 @@ module Lono
68
82
 
69
83
  desc "version", "Prints version"
70
84
  def version
71
- puts VERSION
85
+ puts "Lono: #{VERSION}"
86
+ puts "Lono Pro Addon: #{Lono.pro_version}"
72
87
  end
73
88
 
74
89
  desc "template SUBCOMMAND", "template subcommands"
@@ -90,5 +105,9 @@ module Lono
90
105
  desc "upgrade SUBCOMMAND", "upgrade subcommands"
91
106
  long_desc Help.text(:upgrade)
92
107
  subcommand "upgrade", Upgrade
108
+
109
+ desc "s3 SUBCOMMAND", "s3 subcommands"
110
+ long_desc Help.text(:s3)
111
+ subcommand "s3", S3
93
112
  end
94
113
  end
@@ -70,8 +70,6 @@ Auto-completion accounts for each of these type of commands.
70
70
  =end
71
71
  module Lono
72
72
  class Completer
73
- autoload :Script, 'lono/completer/script'
74
-
75
73
  def initialize(command_class, *params)
76
74
  @params = params
77
75
  @current_command = @params[0]
@@ -0,0 +1,37 @@
1
+ require "fileutils"
2
+
3
+ module Lono
4
+ class Configure
5
+ include Blueprint::Root
6
+
7
+ def initialize(blueprint, options)
8
+ @blueprint, @options = blueprint, options
9
+ @args = options[:args] # hash
10
+ end
11
+
12
+ def run
13
+ blueprint_root = find_blueprint_root(@blueprint)
14
+ unless blueprint_root
15
+ puts "ERROR: Did not find blueprint: #{@blueprint}".color(:red)
16
+ puts "Are you sure you specified the right blueprint?"
17
+ Blueprint::List.available
18
+ exit 1
19
+ end
20
+
21
+ configs_path = "#{blueprint_root}/setup/configs.rb"
22
+ unless File.exist?(configs_path)
23
+ puts "No #{configs_path} file found. Nothing to configure."
24
+ exit
25
+ end
26
+
27
+ require configs_path
28
+ unless defined?(Configs)
29
+ puts "Configs class not found.\nAre you sure #{configs_path} contains a Configs class?"
30
+ exit 1
31
+ end
32
+ configs = Configs.new(@blueprint, @options)
33
+ # The Configs class implements: setup, params, and variables
34
+ configs.run # setup the instance variables
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ require "aws-sdk-ec2"
2
+ require "aws-sdk-iam"
3
+
4
+ class Lono::Configure
5
+ module AwsServices
6
+ def ec2
7
+ @ec2 ||= Aws::EC2::Client.new
8
+ end
9
+
10
+ def iam
11
+ @iam ||= Aws::IAM::Client.new
12
+ end
13
+
14
+ def sts
15
+ @sts ||= Aws::STS::Client.new # part of aws-sdk-core
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,94 @@
1
+ require "fileutils"
2
+ require "memoist"
3
+ require "yaml"
4
+
5
+ # Subclasses must implement: setup, params, variables
6
+ class Lono::Configure
7
+ class Base
8
+ include Lono::AwsServices
9
+ include Helpers
10
+ include Lono::Conventions
11
+ extend Memoist
12
+
13
+ def initialize(blueprint, options)
14
+ @blueprint, @options = blueprint, options
15
+
16
+ @template, @param = template_param_convention(options)
17
+ @args = options[:args] || {} # hash
18
+ @args.symbolize_keys!
19
+
20
+ @written_files = []
21
+ puts "Setting up starter values for #{@blueprint.color(:green)} blueprint"
22
+ end
23
+
24
+ def run
25
+ setup
26
+ write_configs
27
+ finish
28
+ final_message
29
+ end
30
+
31
+ # Should be implemented in subclass
32
+ def setup; end
33
+ def params; end
34
+ def variables; end
35
+
36
+ # Optionally implemented in subclasses
37
+ def params_form
38
+ :short # can be short, medium, or long
39
+ end
40
+
41
+ def finish; end
42
+
43
+ protected
44
+ def params_path
45
+ case params_form.to_sym
46
+ when :short
47
+ "configs/#{@blueprint}/params/#{Lono.env}.txt"
48
+ when :medium
49
+ "configs/#{@blueprint}/params/#{Lono.env}/#{@param}.txt"
50
+ else
51
+ "configs/#{@blueprint}/params/#{Lono.env}/#{@template}/#{@param}.txt"
52
+ end
53
+ end
54
+
55
+ def variables_path
56
+ "configs/#{@blueprint}/variables/#{Lono.env}.rb"
57
+ end
58
+
59
+ def base_params_path
60
+ params_path.sub("params/#{Lono.env}", "params/base")
61
+ end
62
+
63
+ def base_variables_path
64
+ variables_path.sub("variables/#{Lono.env}", "variables/base")
65
+ end
66
+
67
+ def write_configs
68
+ @params, @variables = params, variables # so it only gets called once
69
+ write_file(params_path, @params) if @params
70
+ write_file(variables_path, @variables) if @variables
71
+ end
72
+
73
+ private
74
+
75
+ def write_file(path, content)
76
+ FileUtils.mkdir_p(File.dirname(path))
77
+ IO.write(path, content)
78
+ @written_files << path
79
+ end
80
+
81
+ def final_message
82
+ config_list = @written_files.map { |i| " * #{i}" }.join("\n")
83
+
84
+ puts <<~EOL
85
+ The #{@blueprint} blueprint configs are in:
86
+
87
+ #{config_list}
88
+
89
+ The starter values are specific to your AWS account. They meant to
90
+ be starter values. Please take a look, you may want to adjust the values.
91
+ EOL
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,128 @@
1
+ class Lono::Configure
2
+ module Helpers
3
+ extend Memoist
4
+
5
+ def get_input(key, default:'')
6
+ value = get_seed(key, default: default, load_default: @options[:defaults])
7
+ return value if value
8
+
9
+ default_text = default.blank? ? '' : "(default: #{default})"
10
+ print "Please provide value for #{key}#{default_text}: "
11
+ value = $stdin.gets.strip
12
+ value.blank? ? load_default(default) : value
13
+ end
14
+
15
+ # Defaults to loading the default
16
+ def get_seed(key, default:, load_default: true)
17
+ seed_value = from_seed(key)
18
+ if seed_value
19
+ puts "For #{key}, using seed value #{seed_value}"
20
+ return seed_value
21
+ end
22
+
23
+ return load_default(default) if load_default
24
+ end
25
+
26
+ def load_default(default)
27
+ if default.is_a?(Symbol)
28
+ send(default) # IE: default_subnet
29
+ else
30
+ default # return the default as is
31
+ end
32
+ end
33
+
34
+ def default_subnet
35
+ subnet_ids.first
36
+ end
37
+
38
+ def default_vpc_id
39
+ vpc = find_vpc
40
+ vpc.vpc_id if vpc # default vpc might have been deleted
41
+ end
42
+
43
+ def default_key_name
44
+ key_name
45
+ end
46
+
47
+ def from_seed(key)
48
+ seed[key.to_s]
49
+ end
50
+
51
+ def seed
52
+ if @options[:seed] == :convention
53
+ convention_path = "seeds/#{@blueprint}/#{Lono.env}.yml"
54
+ seed_file = convention_path
55
+ else
56
+ seed_file = @options[:seed]
57
+ end
58
+
59
+ unless File.exist?(seed_file)
60
+ puts "WARN: unable to find seed file #{seed_file}".color(:yellow) if @options[:seed] != :convention
61
+ return {}
62
+ end
63
+ puts "Using seed file: #{seed_file}"
64
+ YAML.load_file(seed_file)
65
+ end
66
+ memoize :seed
67
+
68
+ def key_name
69
+ resp = ec2.describe_key_pairs
70
+ key = resp.key_pairs.first
71
+
72
+ if key
73
+ key.key_name
74
+ else
75
+ "Please create a keypair and configure it here"
76
+ end
77
+ end
78
+
79
+ def aws_account
80
+ sts.get_caller_identity.account
81
+ end
82
+
83
+ def subnet_ids(vpc_id: nil, regexp: nil)
84
+ vpc = find_vpc(vpc_id)
85
+ unless vpc
86
+ # sometimes even default VPC has been deleted
87
+ abort "ERROR: Cannot find subnets because cannot find vpc #{@vpc_id} Please double check that is the right vpc".color(:red)
88
+ end
89
+
90
+ resp = ec2.describe_subnets(filters: [{name: 'vpc-id', values: [vpc.vpc_id]}])
91
+ subnets = resp.subnets # first subnet
92
+
93
+ # Assume that the subnets have a Name tag with PrivateSubnet1, PrivateSubnet2, etc
94
+ # This is part of the BoltOps blueprint stack.
95
+ selected_subnets = select_subnets(subnets, regexp)
96
+
97
+ # if cannot find selected subnets, then keep all the subnets
98
+ subnets = selected_subnets unless selected_subnets.empty?
99
+ subnets.map(&:subnet_id)
100
+ end
101
+
102
+ def select_subnets(subnets, regexp=nil)
103
+ return subnets unless regexp
104
+
105
+ subnets.select do |subnet|
106
+ tags = subnet.tags
107
+ name_tag = tags.find { |t| t.key == "Name" }
108
+ name_tag && name_tag.value =~ regexp
109
+ end
110
+ end
111
+
112
+ # If not vpc_id is provided, it tries to find the default vpc.
113
+ # If the default vpc doesnt exist, nilt is returned.
114
+ def find_vpc(vpc_id=nil)
115
+ if vpc_id
116
+ resp = ec2.describe_vpcs(vpc_ids: [vpc_id])
117
+ else
118
+ resp = ec2.describe_vpcs(filters: [{name: "isDefault", values: ["true"]}])
119
+ end
120
+
121
+ vpcs = resp.vpcs
122
+ vpcs.first
123
+ rescue Aws::EC2::Errors::InvalidVpcIDNotFound
124
+ nil
125
+ end
126
+ memoize :find_vpc
127
+ end
128
+ end