lono 6.1.11 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (240) hide show
  1. checksums.yaml +4 -4
  2. data/.cody/acceptance.sh +19 -3
  3. data/.gitignore +2 -2
  4. data/CHANGELOG.md +16 -1
  5. data/README.md +18 -20
  6. data/Rakefile +1 -0
  7. data/lib/lono.rb +7 -5
  8. data/lib/lono/abstract_base.rb +25 -0
  9. data/lib/lono/api/client.rb +30 -0
  10. data/lib/lono/api/proxy.rb +58 -0
  11. data/lib/lono/api/repos.rb +8 -0
  12. data/lib/lono/api/verify.rb +13 -0
  13. data/lib/lono/app_file/base.rb +4 -11
  14. data/lib/lono/app_file/build.rb +1 -1
  15. data/lib/lono/app_file/upload.rb +1 -4
  16. data/lib/lono/autoloader.rb +3 -1
  17. data/lib/lono/aws_services.rb +9 -9
  18. data/lib/lono/aws_services/helper.rb +14 -0
  19. data/lib/lono/aws_services/{util.rb → stack.rb} +1 -9
  20. data/lib/lono/aws_services/stack_set.rb +41 -0
  21. data/lib/lono/blueprint.rb +2 -2
  22. data/lib/lono/blueprint/configset/loader.rb +7 -0
  23. data/lib/lono/blueprint/helper.rb +8 -2
  24. data/lib/lono/blueprint/meta.rb +4 -12
  25. data/lib/lono/blueprint/new.rb +3 -3
  26. data/lib/lono/blueprint/root.rb +6 -26
  27. data/lib/lono/bundle.rb +54 -0
  28. data/lib/lono/cfn.rb +31 -75
  29. data/lib/lono/cfn/base.rb +39 -136
  30. data/lib/lono/cfn/cancel.rb +14 -9
  31. data/lib/lono/cfn/create.rb +15 -19
  32. data/lib/lono/cfn/delete.rb +9 -9
  33. data/lib/lono/cfn/deploy.rb +4 -4
  34. data/lib/lono/cfn/download.rb +27 -9
  35. data/lib/lono/cfn/opts.rb +80 -0
  36. data/lib/lono/cfn/preview/changeset.rb +23 -23
  37. data/lib/lono/cfn/preview/codediff.rb +5 -6
  38. data/lib/lono/cfn/preview/param.rb +10 -10
  39. data/lib/lono/cfn/rollback.rb +5 -5
  40. data/lib/lono/cfn/status.rb +0 -10
  41. data/lib/lono/cfn/update.rb +22 -27
  42. data/lib/lono/clean.rb +3 -3
  43. data/lib/lono/cli.rb +69 -34
  44. data/lib/lono/code.rb +22 -0
  45. data/lib/lono/command.rb +7 -0
  46. data/lib/lono/config_location.rb +6 -13
  47. data/lib/lono/configset.rb +9 -0
  48. data/lib/lono/configset/combiner.rb +128 -0
  49. data/lib/lono/configset/evaluate_file.rb +8 -0
  50. data/lib/lono/configset/list.rb +67 -0
  51. data/lib/lono/configset/loader.rb +98 -0
  52. data/lib/lono/configset/loader/dsl.rb +9 -0
  53. data/lib/lono/configset/materializer/final.rb +10 -0
  54. data/lib/lono/configset/materializer/gems_builder.rb +81 -0
  55. data/lib/lono/configset/materializer/jade.rb +15 -0
  56. data/lib/lono/configset/materializer/source.rb +54 -0
  57. data/lib/lono/configset/meta.rb +19 -0
  58. data/lib/lono/configset/meta/dsl.rb +12 -0
  59. data/lib/lono/configset/new.rb +84 -0
  60. data/lib/lono/configset/preparer.rb +44 -0
  61. data/lib/lono/configset/register/base.rb +121 -0
  62. data/lib/lono/configset/register/blueprint.rb +16 -0
  63. data/lib/lono/configset/register/dsl.rb +15 -0
  64. data/lib/lono/configset/register/project.rb +12 -0
  65. data/lib/lono/configset/registry.rb +34 -0
  66. data/lib/lono/configset/resolver.rb +42 -0
  67. data/lib/lono/conventions.rb +18 -7
  68. data/lib/lono/core.rb +16 -20
  69. data/lib/lono/default/settings.yml +2 -3
  70. data/lib/lono/ext/bundler.rb +7 -0
  71. data/lib/lono/file_uploader.rb +8 -5
  72. data/lib/lono/finder/base.rb +140 -0
  73. data/lib/lono/finder/blueprint.rb +11 -0
  74. data/lib/lono/finder/blueprint/configset.rb +17 -0
  75. data/lib/lono/finder/configset.rb +11 -0
  76. data/lib/lono/generate.rb +93 -0
  77. data/lib/lono/help/blueprint/new.md +0 -1
  78. data/lib/lono/help/cfn/delete.md +1 -1
  79. data/lib/lono/help/cfn/deploy.md +5 -76
  80. data/lib/lono/help/cfn/status.md +0 -4
  81. data/lib/lono/help/cfn/update.md +1 -1
  82. data/lib/lono/help/code/convert.md +51 -0
  83. data/lib/lono/help/code/import.md +30 -0
  84. data/lib/lono/help/configsets.md +24 -0
  85. data/lib/lono/help/generate.md +4 -4
  86. data/lib/lono/help/new.md +1 -2
  87. data/lib/lono/help/sets/delete.md +8 -0
  88. data/lib/lono/help/sets/deploy.md +76 -0
  89. data/lib/lono/help/sets/instances/delete.md +21 -0
  90. data/lib/lono/help/sets/instances/list.md +14 -0
  91. data/lib/lono/help/sets/instances/status.md +15 -0
  92. data/lib/lono/help/sets/instances/sync.md +88 -0
  93. data/lib/lono/help/sets/status.md +23 -0
  94. data/lib/lono/help/upgrade.md +1 -0
  95. data/lib/lono/importer.rb +22 -0
  96. data/lib/lono/importer/base.rb +59 -0
  97. data/lib/lono/importer/converter.rb +19 -0
  98. data/lib/lono/importer/download.rb +46 -0
  99. data/lib/lono/importer/dsl.rb +36 -0
  100. data/lib/lono/importer/erb.rb +31 -0
  101. data/lib/lono/importer/params.rb +56 -0
  102. data/lib/lono/importer/service/coder.rb +81 -0
  103. data/lib/lono/inspector/base.rb +12 -22
  104. data/lib/lono/inspector/graph.rb +1 -1
  105. data/lib/lono/inspector/summary.rb +41 -17
  106. data/lib/lono/jade.rb +103 -0
  107. data/lib/lono/jade/circular.rb +26 -0
  108. data/lib/lono/jadespec.rb +41 -0
  109. data/lib/lono/new.rb +2 -2
  110. data/lib/lono/opts.rb +43 -0
  111. data/lib/lono/output/template.rb +48 -0
  112. data/lib/lono/param.rb +3 -5
  113. data/lib/lono/param/generator.rb +13 -33
  114. data/lib/lono/pro.rb +15 -0
  115. data/lib/lono/pro/base.rb +16 -0
  116. data/lib/lono/pro/repo.rb +27 -0
  117. data/lib/lono/project_checker.rb +4 -29
  118. data/lib/lono/registration.rb +15 -0
  119. data/lib/lono/registration/base.rb +37 -0
  120. data/lib/lono/registration/check.rb +15 -0
  121. data/lib/lono/registration/temp.rb +60 -0
  122. data/lib/lono/registration/user.rb +54 -0
  123. data/lib/lono/script/base.rb +1 -10
  124. data/lib/lono/script/upload.rb +2 -12
  125. data/lib/lono/seed.rb +2 -11
  126. data/lib/lono/seed/base.rb +55 -110
  127. data/lib/lono/sets.rb +38 -0
  128. data/lib/lono/sets/base.rb +45 -0
  129. data/lib/lono/sets/create.rb +30 -0
  130. data/lib/lono/sets/delete.rb +47 -0
  131. data/lib/lono/sets/deploy.rb +11 -0
  132. data/lib/lono/sets/instances.rb +33 -0
  133. data/lib/lono/sets/instances/base.rb +30 -0
  134. data/lib/lono/sets/instances/delete.rb +69 -0
  135. data/lib/lono/sets/instances/list.rb +13 -0
  136. data/lib/lono/sets/instances/opts.rb +29 -0
  137. data/lib/lono/sets/instances/status.rb +12 -0
  138. data/lib/lono/sets/instances/sync.rb +182 -0
  139. data/lib/lono/sets/list.rb +35 -0
  140. data/lib/lono/sets/opts.rb +18 -0
  141. data/lib/lono/sets/preview/codediff.rb +35 -0
  142. data/lib/lono/sets/preview/param.rb +32 -0
  143. data/lib/lono/sets/status.rb +116 -0
  144. data/lib/lono/sets/status/instance.rb +20 -0
  145. data/lib/lono/sets/status/instance/base.rb +120 -0
  146. data/lib/lono/sets/status/instance/completed.rb +35 -0
  147. data/lib/lono/sets/status/instance/deleted.rb +32 -0
  148. data/lib/lono/sets/status/instance/show.rb +7 -0
  149. data/lib/lono/sets/status/instances.rb +111 -0
  150. data/lib/lono/sets/summarize.rb +20 -0
  151. data/lib/lono/sets/time_spent.rb +11 -0
  152. data/lib/lono/sets/update.rb +81 -0
  153. data/lib/lono/template.rb +5 -7
  154. data/lib/lono/template/configset_injector.rb +50 -0
  155. data/lib/lono/template/context.rb +4 -4
  156. data/lib/lono/template/context/loader.rb +4 -16
  157. data/lib/lono/template/evaluate.rb +2 -1
  158. data/lib/lono/template/generator.rb +17 -15
  159. data/lib/lono/template/helper.rb +7 -7
  160. data/lib/lono/template/post_processor.rb +2 -12
  161. data/lib/lono/template/strategy/base.rb +4 -0
  162. data/lib/lono/template/{dsl.rb → strategy/dsl.rb} +4 -6
  163. data/lib/lono/template/{dsl → strategy/dsl}/builder.rb +11 -15
  164. data/lib/lono/template/{dsl → strategy/dsl}/builder/fn.rb +1 -1
  165. data/lib/lono/template/strategy/dsl/builder/helpers.rb +11 -0
  166. data/lib/lono/template/strategy/dsl/builder/helpers/core_helper.rb +14 -0
  167. data/lib/lono/template/strategy/dsl/builder/helpers/file_helper.rb +48 -0
  168. data/lib/lono/template/strategy/dsl/builder/helpers/lookup_helper.rb +27 -0
  169. data/lib/lono/template/strategy/dsl/builder/helpers/s3_helper.rb +13 -0
  170. data/lib/lono/template/strategy/dsl/builder/helpers/tags_helper.rb +39 -0
  171. data/lib/lono/template/{dsl/builder → strategy/dsl/builder/section}/base.rb +6 -17
  172. data/lib/lono/template/{dsl/builder → strategy/dsl/builder/section}/condition.rb +1 -1
  173. data/lib/lono/template/strategy/dsl/builder/section/extensions.rb +9 -0
  174. data/lib/lono/template/{dsl/builder → strategy/dsl/builder/section}/mapping.rb +1 -1
  175. data/lib/lono/template/{dsl/builder/section_methods.rb → strategy/dsl/builder/section/methods.rb} +9 -2
  176. data/lib/lono/template/{dsl/builder → strategy/dsl/builder/section}/output.rb +1 -1
  177. data/lib/lono/template/strategy/dsl/builder/section/parameter.rb +69 -0
  178. data/lib/lono/template/{dsl/builder → strategy/dsl/builder/section}/resource.rb +1 -1
  179. data/lib/lono/template/{dsl/builder → strategy/dsl/builder/section}/resource/property_mover.rb +1 -1
  180. data/lib/lono/template/{dsl/builder → strategy/dsl/builder/section}/section.rb +1 -1
  181. data/lib/lono/template/{dsl → strategy/dsl}/builder/squeezer.rb +1 -1
  182. data/lib/lono/template/strategy/dsl/builder/stringify.rb +15 -0
  183. data/lib/lono/template/{dsl → strategy/dsl}/builder/syntax.rb +3 -2
  184. data/lib/lono/template/strategy/dsl/finalizer.rb +12 -0
  185. data/lib/lono/template/strategy/dsl/finalizer/parameter_groups.rb +56 -0
  186. data/lib/lono/template/{erb.rb → strategy/erb.rb} +5 -5
  187. data/lib/lono/template/strategy/source.rb +8 -0
  188. data/lib/lono/template/template.rb +1 -1
  189. data/lib/lono/template/upload.rb +4 -9
  190. data/lib/lono/template/util.rb +0 -40
  191. data/lib/lono/upgrade.rb +12 -10
  192. data/lib/lono/user_data.rb +4 -4
  193. data/lib/lono/utils/pretty_time.rb +14 -0
  194. data/lib/lono/utils/sure.rb +23 -0
  195. data/lib/lono/version.rb +1 -1
  196. data/lib/lono/yamler/loader.rb +52 -0
  197. data/lib/lono/yamler/validator.rb +51 -0
  198. data/lib/templates/blueprint/%blueprint_name%.gemspec.tt +4 -0
  199. data/lib/templates/blueprint/README.md.tt +1 -1
  200. data/lib/templates/blueprint/seed/configs.rb +2 -2
  201. data/lib/templates/blueprint_types/dsl/app/templates/%blueprint_name%.rb +17 -18
  202. data/lib/templates/blueprint_types/erb/app/templates/%blueprint_name%.yml +63 -4
  203. data/lib/templates/configset/%configset_name%.gemspec.tt +41 -0
  204. data/lib/templates/configset/.gitignore +11 -0
  205. data/lib/templates/configset/CHANGELOG.md +7 -0
  206. data/lib/templates/configset/Gemfile +4 -0
  207. data/lib/templates/configset/README.md.tt +3 -0
  208. data/lib/templates/configset/Rakefile.tt +9 -0
  209. data/lib/templates/configset/lib/configset.yml +20 -0
  210. data/lib/templates/skeleton/.gitignore +1 -0
  211. data/lib/templates/skeleton/Gemfile +0 -1
  212. data/lib/templates/skeleton/README.md +4 -4
  213. data/lib/templates/skeleton/configs/settings.yml +1 -1
  214. data/lono.gemspec +1 -4
  215. metadata +146 -79
  216. data/Guardfile +0 -19
  217. data/lib/lono/app_file.rb +0 -5
  218. data/lib/lono/blueprint/find.rb +0 -90
  219. data/lib/lono/blueprint/info.rb +0 -10
  220. data/lib/lono/blueprint/list.rb +0 -14
  221. data/lib/lono/cfn/current.rb +0 -95
  222. data/lib/lono/cfn/preview.rb +0 -4
  223. data/lib/lono/cfn/suffix.rb +0 -67
  224. data/lib/lono/cfn/util.rb +0 -27
  225. data/lib/lono/help/cfn/current.md +0 -18
  226. data/lib/lono/help/upgrade4.md +0 -25
  227. data/lib/lono/inspector.rb +0 -4
  228. data/lib/lono/output_template.rb +0 -35
  229. data/lib/lono/template/base.rb +0 -13
  230. data/lib/lono/template/dsl/builder/helpers.rb +0 -8
  231. data/lib/lono/template/dsl/builder/helpers/core_helper.rb +0 -107
  232. data/lib/lono/template/dsl/builder/helpers/param_helper.rb +0 -61
  233. data/lib/lono/template/dsl/builder/parameter.rb +0 -39
  234. data/lib/lono/upgrade/upgrade4.rb +0 -175
  235. data/lib/lono/upgrade/upgrade42.rb +0 -36
  236. data/lib/lono/upgrade/upgrade5.rb +0 -55
  237. data/lib/templates/blueprint/.meta/config.yml.tt +0 -4
  238. data/lib/templates/skeleton/Guardfile +0 -12
  239. data/lib/templates/upgrade5/blueprints/main/.lono/config.yml +0 -3
  240. data/lib/templates/upgrade5/blueprints/main/.meta/config.yml +0 -3
@@ -0,0 +1,33 @@
1
+ class Lono::Sets
2
+ class Instances < Lono::Command
3
+ opts = Opts.new(self)
4
+
5
+ desc "delete STACK_SET", "Delete CloudFormation stack set instances."
6
+ long_desc Lono::Help.text("sets/instances/delete")
7
+ opts.delete
8
+ def delete(stack)
9
+ Delete.new(options.merge(stack: stack)).run
10
+ end
11
+
12
+ desc "sync STACK_SET", "Sync CloudFormation stack set instances."
13
+ long_desc Lono::Help.text("sets/instances/sync")
14
+ opts.sync
15
+ def sync(stack)
16
+ Sync.new(options.merge(stack: stack)).run
17
+ end
18
+
19
+ desc "list STACK_SET", "List CloudFormation stack set instances."
20
+ long_desc Lono::Help.text("sets/instances/list")
21
+ def list(stack)
22
+ List.new(options.merge(stack: stack)).run
23
+ end
24
+
25
+ desc "status STACK_SET", "Show current status of stack instances."
26
+ long_desc Lono::Help.text("sets/instances/status")
27
+ def status(stack)
28
+ instances_status = Status.new(options.merge(stack: stack))
29
+ success = instances_status.run
30
+ exit 3 unless success
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ class Lono::Sets::Instances
2
+ class Base < Lono::Sets::Base
3
+ # Simple structure to help with subtracting logic
4
+ # [["112233445566", "us-west-1"], ["112233445566", "us-west-1"]]
5
+ def requested
6
+ requested = []
7
+ accounts.each do |a|
8
+ regions.each do |r|
9
+ item = [a,r]
10
+ requested << item
11
+ end
12
+ end
13
+ requested.sort.uniq
14
+ end
15
+ memoize :requested
16
+
17
+ def accounts
18
+ @options[:accounts]
19
+ end
20
+
21
+ def regions
22
+ @options[:regions]
23
+ end
24
+
25
+ def stack_instances
26
+ resp = cfn.list_stack_instances(stack_set_name: @stack)
27
+ resp.summaries
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,69 @@
1
+ class Lono::Sets::Instances
2
+ class Delete < Base
3
+ include Lono::AwsServices
4
+ include Lono::Utils::Sure
5
+
6
+ def initialize(options={})
7
+ @options = options
8
+ @stack = options[:stack]
9
+ end
10
+
11
+ def run
12
+ validate!
13
+
14
+ sure?("Are you sure you want to delete the #{@stack} instances?", long_desc)
15
+
16
+ # delete_stack_instances resp has operation_id
17
+ # Could also use that to poll for status with the list_stack_set_operation_results
18
+ # api. Currently, Instance::Status class not using this info. If we need will add the logic.
19
+ resp = cfn.delete_stack_instances(
20
+ options = {
21
+ stack_set_name: @stack,
22
+ accounts: accounts,
23
+ regions: regions,
24
+ retain_stacks: false,
25
+ }
26
+ )
27
+ operation_id = resp.operation_id
28
+
29
+ # Status tailing handled by caller
30
+ o = @options.merge(
31
+ filter: requested,
32
+ start_on_outdated: false,
33
+ operation_id: operation_id,
34
+ )
35
+ Lono::Sets::Status::Instance::Base.show_time_progress = true
36
+ Lono::Sets::Status::Instance::Base.delay_factor = accounts.size * regions.size
37
+ instances_status = Status.new(o)
38
+ instances_status.run(to: "deleted") unless @options[:noop] # returns success: true or false
39
+ end
40
+
41
+ def long_desc
42
+ total = accounts.size * regions.size
43
+ <<~EOL
44
+ These stack instances will be deleted:
45
+
46
+ accounts: #{accounts.join(',')}
47
+ regions: #{regions.join(',')}
48
+
49
+ Number of stack instances to be deleted: #{total}
50
+ EOL
51
+ end
52
+
53
+ def validate!
54
+ invalid = (regions.blank? || accounts.blank?) && !@options[:all]
55
+ if invalid
56
+ puts "ERROR: You must provide --accounts and --regions or --all.".color(:red)
57
+ exit 1
58
+ end
59
+ end
60
+
61
+ def accounts
62
+ @options[:all] ? stack_instances.map(&:account).uniq : @options[:accounts]
63
+ end
64
+
65
+ def regions
66
+ @options[:all] ? stack_instances.map(&:region).uniq : @options[:regions]
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,13 @@
1
+ class Lono::Sets::Instances
2
+ class List
3
+ include Lono::AwsServices
4
+
5
+ def initialize(options={})
6
+ @options = options
7
+ end
8
+
9
+ def run
10
+ Lono::Sets::Status::Instances.new(@options).show
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,29 @@
1
+ class Lono::Sets::Instances
2
+ class Opts < Lono::Sets::Opts
3
+ def delete
4
+ operation_preferences_options
5
+ accounts_options
6
+ with_cli_scope do
7
+ option :all, type: :boolean, desc: "Delete stack all instances. Overrides --accounts and --regions options"
8
+ end
9
+ end
10
+
11
+ def sync
12
+ operation_preferences_options
13
+ accounts_options
14
+ with_cli_scope do
15
+ option :delete, type: :boolean, default: true, desc: "Delete stack instances that are not provided"
16
+ option :blueprint, desc: "override convention and specify the template file to use"
17
+ option :source, desc: "url or path to file with template"
18
+ end
19
+ end
20
+
21
+ def accounts_options
22
+ with_cli_scope do
23
+ option :accounts, type: :array, desc: "List of accounts to apply stack set to. IE: 112233445566 223344556677"
24
+ option :regions, type: :array, desc: "List of regions to apply stack set to. IE: us-west-2 us-east-1"
25
+ option :sure, type: :boolean, desc: "Skip are you sure prompt"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ class Lono::Sets::Instances
2
+ class Status
3
+ def initialize(options={})
4
+ @options = options
5
+ end
6
+
7
+ def run(to: "completed")
8
+ instances = Lono::Sets::Status::Instances.new(@options)
9
+ instances.wait(to)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,182 @@
1
+ class Lono::Sets::Instances
2
+ class Sync < Base
3
+ include Lono::Sets::Summarize
4
+ include Lono::Utils::Sure
5
+
6
+ def initialize(options={})
7
+ super # need conventions so config lookup will work
8
+ @regions, @accounts = [], []
9
+ end
10
+
11
+ def run
12
+ unless stack_set_exists?(@stack)
13
+ puts "ERROR: Cannot update a stack set because #{@stack} does not exists.".color(:red)
14
+ return
15
+ end
16
+ exit_unless_updatable!
17
+
18
+ validate!
19
+
20
+ existing = stack_instances.map do |summary|
21
+ [summary.account, summary.region]
22
+ end
23
+
24
+ creates = requested - existing
25
+ deletes = existing - requested
26
+
27
+ if creates.empty? and deletes.empty?
28
+ puts <<~EOL
29
+ Nothing to be synced. IE: No stack instances need to be added or removed. If you want to update the
30
+ stack set and update all stack instances instead, use the `lono sets deploy` command.
31
+ EOL
32
+ return
33
+ end
34
+ sure?("Are you sure you want to sync stack instances?", long_desc(creates: creates, deletes: deletes))
35
+
36
+ # Note: Not calling update_stack_instances because after deleting stacks it instances in in a weird state
37
+ # where an update_stack_instances fails. Can reproduce this by deleting stacks and then trying an update_stack_instances
38
+ # with the AWS CLI. In theory, we never really should have to call update_stack_instances anyway because
39
+ # updating the stack set at the parent level kicks off an update_stack_instances automatically.
40
+ operation_id = execute(:create_stack_instances, creates)
41
+ summarize(operation_id) if operation_id
42
+ if @options[:delete]
43
+ operation_id = execute(:delete_stack_instances, deletes)
44
+ summarize(operation_id) if operation_id
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ # data:
51
+ # {creates: creates, deletes: deletes}
52
+ # where creates and deletes are instances_data structures:
53
+ # [["112233445566", "us-west-1"], ["112233445566", "us-west-1"]]
54
+ def long_desc(data={})
55
+ desc = "lono will run:\n"
56
+ verbs = [:creates, :deletes]
57
+ verbs.each do |verb|
58
+ accounts = accounts_list(data[verb])
59
+ regions = regions_list(data[verb])
60
+ unless data[verb].empty?
61
+ info = {
62
+ accounts: accounts.join(','),
63
+ regions: regions.join(','),
64
+ }
65
+ change_total = accounts.size * regions.size
66
+ singular_verb = verb.to_s.singularize
67
+ past_verb = verb.to_s.sub(/s$/,'d')
68
+ message = <<~EOL
69
+ #{singular_verb}_stack_instances for:
70
+ accounts: #{info[:accounts]}
71
+ regions: #{info[:regions]}
72
+
73
+ Number of stack instances to be #{past_verb}: #{change_total}
74
+ EOL
75
+ desc << message
76
+ end
77
+ end
78
+ desc
79
+ end
80
+
81
+ # meth:
82
+ # create_stack_set
83
+ # update_stack_set
84
+ # delete_stack_set
85
+ #
86
+ # instances_data:
87
+ # [["112233445566", "us-west-1"], ["112233445566", "us-west-1"]]
88
+ #
89
+ def execute(meth, instances_data)
90
+ accounts = accounts_list(instances_data)
91
+ regions = regions_list(instances_data)
92
+ if accounts.empty? or regions.empty?
93
+ # puts "Cannot have one empty. accounts: #{accounts.size} regions: #{regions.size}. No executing #{meth}." # uncomment to debug
94
+ return # no operation_id
95
+ end
96
+
97
+ options = {
98
+ stack_set_name: @stack,
99
+ accounts: accounts,
100
+ regions: regions,
101
+ }
102
+ options[:retain_stacks] = false if meth == :delete_stack_instances
103
+ puts <<~EOL
104
+ => Running #{meth} on:
105
+ accounts: #{accounts.join(',')}
106
+ regions: #{regions.join(',')}
107
+ EOL
108
+ resp = cfn.send(meth, options) # resp has resp[:operation_id]
109
+ operation_id = resp.operation_id
110
+
111
+ # Status tailing
112
+ o = @options.merge(
113
+ filter: instances_data,
114
+ operation_id: operation_id,
115
+ start_on_outdated: meth != :delete_stack_instances,
116
+ )
117
+ Lono::Sets::Status::Instance::Base.show_time_progress = true
118
+ Lono::Sets::Status::Instance::Base.delay_factor = accounts.size * regions.size
119
+ instances_status = Status.new(o)
120
+ final_status = meth == :delete_stack_instances ? "deleted" : "completed"
121
+ instances_status.run(to: final_status) unless @options[:noop] # returns success: true or false
122
+ operation_id
123
+ end
124
+
125
+ def accounts_list(instances_data)
126
+ instances_data.map { |a| a[0] }.sort.uniq
127
+ end
128
+
129
+ def regions_list(instances_data)
130
+ instances_data.map { |a| a[1] }.sort.uniq
131
+ end
132
+
133
+ # Override accounts and regions
134
+ def accounts
135
+ @options[:accounts] || lookup(:accounts)
136
+ end
137
+
138
+ def regions
139
+ @options[:regions] || lookup(:regions)
140
+ end
141
+
142
+ def lookup(config_type)
143
+ config_type = config_type.to_s
144
+ base_path = lookup_config_location(config_type, "base")
145
+ env_path = lookup_config_location(config_type, Lono.env)
146
+ items = load_config(base_path)
147
+ items += load_config(env_path)
148
+ items = items.sort.uniq
149
+ if config_type == :accounts
150
+ @accounts = items
151
+ else
152
+ @regions = items
153
+ end
154
+ end
155
+
156
+ def load_config(path)
157
+ return [] unless path
158
+
159
+ items = []
160
+ lines = IO.readlines(path)
161
+ lines.map do |l|
162
+ l = l.strip
163
+ l = l.sub(/ #.*/, '') # trailing comment
164
+ items << l unless l.empty? || l.match(/^\s*#/) # dont include empty linnks or commented lines
165
+ end
166
+ items
167
+ end
168
+
169
+ def lookup_config_location(config_type, env)
170
+ location = Lono::ConfigLocation.new(config_type, @options, env)
171
+ env == "base" ? location.lookup_base : location.lookup
172
+ end
173
+
174
+ def validate!
175
+ invalid = regions.blank? || accounts.blank?
176
+ if invalid
177
+ puts "ERROR: You must provide accounts and regions.".color(:red)
178
+ exit 1
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,35 @@
1
+ require "text-table"
2
+
3
+ class Lono::Sets
4
+ class List
5
+ include Lono::AwsServices
6
+
7
+ def initialize(options={})
8
+ @options = options
9
+ end
10
+
11
+ def run
12
+ table = Text::Table.new
13
+ table.head = ["Stack Set Name", "Status"]
14
+ summaries = stack_sets_summaries
15
+ summaries.each do |s|
16
+ table.rows << [s.stack_set_name, s.status]
17
+ end
18
+ puts table
19
+ end
20
+
21
+ private
22
+ def stack_sets_summaries
23
+ next_token, summaries = :start, []
24
+ while next_token
25
+ o = {}
26
+ o[:next_token] = next_token unless next_token == :start or next_token.nil?
27
+ o[:status] = @options[:status].upcase if @options[:status] && @options[:status] != "all"
28
+ resp = cfn.list_stack_sets(o)
29
+ next_token = resp.next_token
30
+ summaries += resp.summaries
31
+ end
32
+ summaries
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ class Lono::Sets
2
+ class Opts < Lono::Cfn::Opts
3
+ def deploy
4
+ super
5
+ operation_preferences_options
6
+ end
7
+
8
+ def operation_preferences_options
9
+ with_cli_scope do
10
+ option :region_order, type: :array, desc: "region_order"
11
+ option :failure_tolerance_count, type: :numeric, desc: "failure_tolerance_count"
12
+ option :failure_tolerance_percentage, type: :numeric, desc: "failure_tolerance_percentage"
13
+ option :max_concurrent_count, type: :numeric, desc: "max_concurrent_count"
14
+ option :max_concurrent_percentage, type: :numeric, desc: "max_concurrent_percentage"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ module Lono::Sets::Preview
2
+ class Codediff < Lono::Sets::Base
3
+ include Lono::Cfn::Preview::DiffViewer
4
+
5
+ def run
6
+ unless stack_set_exists?(@stack)
7
+ puts "WARN: Cannot create a diff for the stack set because the #{@stack} does not exists.".color(:yellow)
8
+ return
9
+ end
10
+
11
+ if @options[:noop]
12
+ puts "NOOP Generating CloudFormation source code diff..."
13
+ else
14
+ generate_all # from Base superclass. Generates the output lono teplates
15
+ puts "Generating CloudFormation source code diff..."
16
+ download_existing_cfn_template
17
+ show_diff(existing_template_path, new_cfn_template)
18
+ end
19
+ end
20
+
21
+ def download_existing_cfn_template
22
+ resp = cfn.describe_stack_set(stack_set_name: @stack)
23
+ IO.write(existing_template_path, resp.stack_set.template_body)
24
+ end
25
+
26
+ # for clarity
27
+ def new_cfn_template
28
+ template_path
29
+ end
30
+
31
+ def existing_template_path
32
+ "/tmp/existing_stack_set.yml"
33
+ end
34
+ end
35
+ end