lono 7.4.8 → 7.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -1
  3. data/README.md +2 -0
  4. data/lib/lono/app_file/build/lambda_layer/ruby_packager.rb +2 -10
  5. data/lib/lono/cfn/base.rb +0 -1
  6. data/lib/lono/cli.rb +4 -1
  7. data/lib/lono/help/{sets/instances → set_instances}/delete.md +1 -1
  8. data/lib/lono/help/set_instances/deploy.md +31 -0
  9. data/lib/lono/help/{sets/instances → set_instances}/list.md +1 -1
  10. data/lib/lono/help/{sets/instances → set_instances}/status.md +1 -1
  11. data/lib/lono/help/{sets/instances → set_instances}/sync.md +4 -2
  12. data/lib/lono/inspector/graph.rb +1 -1
  13. data/lib/lono/registration/temp.rb +7 -9
  14. data/lib/lono/set_instances.rb +54 -0
  15. data/lib/lono/{sets/instances → set_instances}/base.rb +1 -1
  16. data/lib/lono/set_instances/changeable.rb +53 -0
  17. data/lib/lono/set_instances/create.rb +7 -0
  18. data/lib/lono/{sets/instances → set_instances}/delete.rb +9 -31
  19. data/lib/lono/set_instances/deploy.rb +52 -0
  20. data/lib/lono/{sets/instances → set_instances}/list.rb +1 -1
  21. data/lib/lono/{sets/instances → set_instances}/opts.rb +9 -1
  22. data/lib/lono/{sets/instances → set_instances}/status.rb +1 -1
  23. data/lib/lono/{sets/instances → set_instances}/sync.rb +4 -3
  24. data/lib/lono/set_instances/update.rb +15 -0
  25. data/lib/lono/sets.rb +0 -4
  26. data/lib/lono/sets/create.rb +0 -3
  27. data/lib/lono/sets/delete.rb +5 -14
  28. data/lib/lono/sets/status.rb +15 -3
  29. data/lib/lono/sets/status/instances.rb +8 -5
  30. data/lib/lono/sets/summarize.rb +2 -0
  31. data/lib/lono/sets/update.rb +6 -13
  32. data/lib/lono/sets/waiter.rb +23 -0
  33. data/lib/lono/template/strategy/dsl/builder/helpers.rb +8 -6
  34. data/lib/lono/template/strategy/dsl/builder/helpers/stack_helper.rb +51 -0
  35. data/lib/lono/version.rb +1 -1
  36. metadata +21 -15
  37. data/lib/lono/sets/instances.rb +0 -33
  38. data/lib/lono/template/strategy/dsl/builder/helpers/lookup_helper.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d747ecd65bb8239ac79bebab231572190de2a39d46d4db692cb449e64abc6f77
4
- data.tar.gz: 609e5aa49b41c5b981b5e62075d41195683a75976cf3db99df6f3e664d00e3d0
3
+ metadata.gz: a9747560fd12e2616a4e4087d00767cdf35ab3af81e5749a405f656277236435
4
+ data.tar.gz: 58ff9d94ad6c554e74f6c1f10cee69ad47084ab0d3353e7ad4f8fd7f0a79ea73
5
5
  SHA512:
6
- metadata.gz: bb81fa313393a78647e218e5d61d53ea0b36c1c6aee29c39fed24036bdefeba2265f5449ca7d894fae173868437d1c64d24626fbe51282de69208cf57f427ba6
7
- data.tar.gz: 29bf3543f1b61a416c2bbe148c5c60227a8cf5cea3e15455b30fcdc4fe8c2f18dc4b3b88a9ee9b0b4f929ee6b6e251518319470fa0af57ec92843c73cc6de728
6
+ metadata.gz: 0eb34584e3bd9836e31e45e2328c41d77b3a06ad09cf5454001bb6f22610c97772d5588839297b6115a492d09bb2394cc0fe904e3bc24ff4b4cdcf4467cd9003
7
+ data.tar.gz: ee471c17de149878638b407316154a773941ee7642a96118cf03c7c9daf3d56e18fdf9a0cf8af3207be7da05864d803813076917ff0c0654d31701391b144ff0
data/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [7.5.1] - 2021-05-03
7
+ - remove registration check
8
+ - fix brew install graphviz message
9
+
10
+ ## [7.5.0]
11
+ - #71 `set_instances deploy` command in favor of `set_instances sync`
12
+
13
+ ## [7.4.11]
14
+ - fix lookup_output
15
+
16
+ ## [7.4.10]
17
+ - #70 fix out-of-sync Gemfile.lock
18
+
19
+ ## [7.4.9]
20
+ - #69 `stack_output` and `stack_resource` helpers
21
+
6
22
  ## [7.4.8]
7
23
  - #68 squeezer: auto clean empty array values
8
24
  - add version numbers to extension gemspec template to remove deprecations
@@ -94,7 +110,7 @@ This project *tries* to adhere to [Semantic Versioning](http://semver.org/), eve
94
110
  - #36 lono v7
95
111
  - Breaking: project `blueprints` moved to `app/blueprints`. Use `lono upgrade` to update.
96
112
  - Introduce configsets concept.
97
- - Introduce lono sets concept: `lono sets`, `lono sets deploy`, `lono sets instances sync`
113
+ - Introduce lono sets concept: `lono sets`, `lono sets deploy`, `lono set_instances sync`
98
114
  - Merge lono-pro into lono. Deprecate lono-pro gem.
99
115
  - Add lono registration.
100
116
  - Major refactoring:
data/README.md CHANGED
@@ -10,6 +10,8 @@
10
10
 
11
11
  [![BoltOps Badge](https://img.boltops.com/boltops/badges/boltops-badge.png)](https://www.boltops.com)
12
12
 
13
+ Please **watch/star** this repo to help grow and support the project.
14
+
13
15
  Lono is a CloudFormation framework. It builds, manages, and deploys CloudFormation templates.
14
16
 
15
17
  ## Lono Features
@@ -90,10 +90,8 @@ class Lono::AppFile::Build::LambdaLayer
90
90
  end
91
91
 
92
92
  remove_bundled_with("#{cache_area}/Gemfile.lock")
93
-
94
- # Copy the Gemfile.lock back to the project in case it was updated.
95
- # For example we add the jets-rails to the Gemfile.
96
- copy_back_gemfile_lock
93
+ # Fixes really tricky bug where Gemfile and Gemfile.lock is out-of-sync. Details: https://gist.github.com/tongueroo/b5b0d0c924a4a1633eee514795e4b04b
94
+ FileUtils.cp("#{cache_area}/Gemfile.lock", "#{Lono.config.output_path}/#{@blueprint}/files/#{@registry_name}/Gemfile.lock")
97
95
 
98
96
  puts 'Bundle install success.'
99
97
  end
@@ -120,12 +118,6 @@ class Lono::AppFile::Build::LambdaLayer
120
118
  IO.write(gemfile_lock, content)
121
119
  end
122
120
 
123
- def copy_back_gemfile_lock
124
- src = "#{cache_area}/Gemfile.lock"
125
- dest = "#{@app_root}/Gemfile.lock"
126
- FileUtils.cp(src, dest)
127
- end
128
-
129
121
  def setup_bundle_config(dir)
130
122
  text =<<-EOL
131
123
  ---
data/lib/lono/cfn/base.rb CHANGED
@@ -39,7 +39,6 @@ class Lono::Cfn
39
39
 
40
40
  # exit code for cfn.rb cli, so there's less duplication
41
41
  exit 1 unless success
42
- Lono::Registration.check
43
42
  success
44
43
  end
45
44
 
data/lib/lono/cli.rb CHANGED
@@ -13,7 +13,6 @@ module Lono
13
13
  long_desc Help.text(:blueprints)
14
14
  def blueprints
15
15
  Finder::Blueprint.list
16
- Lono::Registration.check
17
16
  end
18
17
 
19
18
  desc "configsets [BLUEPRINT]", "Lists configsets"
@@ -162,6 +161,10 @@ module Lono
162
161
  long_desc Help.text(:sets)
163
162
  subcommand "sets", Sets
164
163
 
164
+ desc "set_instances SUBCOMMAND", "set_instances subcommands"
165
+ long_desc Help.text(:set_instances)
166
+ subcommand "set_instances", SetInstances
167
+
165
168
  desc "template SUBCOMMAND", "template subcommands"
166
169
  long_desc Help.text(:template)
167
170
  subcommand "template", Template
@@ -1,6 +1,6 @@
1
1
  ## Example
2
2
 
3
- $ lono sets instances delete my-set --accounts 112233445566 --regions us-west-1 us-west-2
3
+ $ lono set_instances delete my-set --accounts 112233445566 --regions us-west-1 us-west-2
4
4
  Are you sure you want to delete the my-set instances?
5
5
  These stack instances will be deleted:
6
6
 
@@ -0,0 +1,31 @@
1
+ The deploy command delegates to the `lono set_instances create` or `lono set_instances update` commands. This spares you from having to manually figuring out which stack instances need to be created and updated.
2
+
3
+ ## Example
4
+
5
+ $ lono set_instances deploy enable-aws-config --accounts 111111111111 222222222222 --regions us-west-2 us-east-2Running lono set_instances create on account: 111111111111 regions: us-west-2,us-east-2
6
+ Deploying enable-aws-config stack set
7
+ Stack Set Operation Status: RUNNING
8
+ Stack Instance statuses... (takes a while)
9
+ You can also check with StackSets console at the Operations Tab.
10
+ Here is also the cli command to check:
11
+
12
+ aws cloudformation describe-stack-set-operation --stack-set-name enable-aws-config --operation-id 44a50065-1b10-49f0-b6b9-853092a0cb09
13
+
14
+ 2020-04-25 10:58:32PM Stack Instance: account 222222222222 region us-east-2 status CURRENT
15
+ 2020-04-25 10:58:32PM Stack Instance: account 111111111111 region us-west-2 status OUTDATED reason User initiated operation
16
+ 2020-04-25 10:58:32PM Stack Instance: account 222222222222 region us-west-2 status CURRENT
17
+ 2020-04-25 10:58:32PM Stack Instance: account 111111111111 region us-east-2 status OUTDATED reason User initiated operation
18
+ Stack Set Operation Status: SUCCEEDED
19
+ Time took to complete stack set operation: 1m 23s
20
+ Stack Set Operation Summary:
21
+ account 111111111111 region us-west-2 status SUCCEEDED
22
+ account 111111111111 region us-east-2 status SUCCEEDED
23
+ Running lono set_instances update on account: 222222222222 regions: us-west-2,us-east-2
24
+ Deploying enable-aws-config stack set
25
+ Stack Set Operation Status: RUNNING
26
+ Stack Set Operation Status: SUCCEEDED
27
+ Time took to complete stack set operation: 23s
28
+ Stack Set Operation Summary:
29
+ account 222222222222 region us-west-2 status SUCCEEDED
30
+ account 222222222222 region us-east-2 status SUCCEEDED
31
+ $
@@ -1,6 +1,6 @@
1
1
  ## Example
2
2
 
3
- $ lono sets instances list my-set
3
+ $ lono set_instances list my-set
4
4
  Stack Instance: account 112233445566 region ap-northeast-1 status CURRENT
5
5
  Stack Instance: account 223344556677 region us-west-1 status CURRENT
6
6
  Stack Instance: account 223344556677 region ap-northeast-1 status CURRENT
@@ -1,6 +1,6 @@
1
1
  ## Example
2
2
 
3
- $ lono sets instances status my-set
3
+ $ lono set_instances status my-set
4
4
  Stack Instance statuses... (takes a while)
5
5
  Stack Instance: account 112233445566 region ap-northeast-1 status CURRENT
6
6
  Stack Instance: account 112233445566 region us-west-1 status CURRENT
@@ -1,3 +1,5 @@
1
+ IMPORTANT: The `lono set_instances sync` command is deprecated in favor of `lono set_instances deploy`. With stack sets, found more success with explicitness.
2
+
1
3
  Lono uses the `config/accounts` and `config/regions` to calculate whether `create-stack-set` or `delete-stack-set` need to be called and calls them accordingly. You use this instead of `lono sets deploy` when only configs have been adjust and you want to keep the existing template.
2
4
 
3
5
  Provided:
@@ -23,9 +25,9 @@ configs/demo/regions/development/my-set.txt
23
25
  ap-northeast-1
24
26
  ap-northeast-2
25
27
 
26
- Running `lono sets instances sync` will delete and add the stack instances accordingly.
28
+ Running `lono set_instances sync` will delete and add the stack instances accordingly.
27
29
 
28
- $ lono sets instances sync my-set --blueprint demo
30
+ $ lono set_instances sync my-set --blueprint demo
29
31
  Using regions for development: configs/demo/regions/development/my-set.sh
30
32
  Using accounts for development: configs/demo/accounts/development/my-set.sh
31
33
  Are you sure you want to sync stack instances?
@@ -102,7 +102,7 @@ module Lono::Inspector
102
102
  puts "It appears that the Graphviz is not installed. Please install it to generate the graph."
103
103
  if RUBY_PLATFORM =~ /darwin/
104
104
  puts "You can install Graphviz with homebrew:"
105
- puts " brew install brew install graphviz"
105
+ puts " brew install graphviz"
106
106
  end
107
107
  exit 1
108
108
  end
@@ -21,13 +21,6 @@ class Lono::Registration
21
21
  def prompt
22
22
  return if ENV['LONO_TEST']
23
23
 
24
- # We get the api first before the prompt to check if api is up
25
- resp = get_temp_key
26
- # resp nil means non-200 http response. Failsafe behavior is to continue.
27
- if resp.nil?
28
- return true
29
- end
30
-
31
24
  puts <<~EOL
32
25
 
33
26
  Looks like lono is not registered. Lono registration is optional and free.
@@ -35,12 +28,17 @@ class Lono::Registration
35
28
 
36
29
  https://register.lono.cloud
37
30
 
38
- Registration removes this message. Registered users can also optionally receive
39
- updates and special offers, including discounts to BoltOps Pro:
31
+ This prompt appears every 24 hours when lono is not registered. Registration removes
32
+ this message. Registered users can also optionally receive updates and special offers,
33
+ including discounts to BoltOps Pro:
40
34
 
41
35
  https://lono.cloud/docs/boltops-pro/
42
36
 
43
37
  EOL
38
+
39
+ # resp nil means non-200 http response
40
+ resp = get_temp_key
41
+ save_temp_key(resp) unless resp.nil? # save temp key so prompt only happens periodically
44
42
  end
45
43
 
46
44
  def save_temp_key(info)
@@ -0,0 +1,54 @@
1
+ module Lono
2
+ class SetInstances < Lono::Command
3
+ opts = Opts.new(self)
4
+
5
+ desc "create STACK_SET", "Create CloudFormation stack set instances."
6
+ long_desc Lono::Help.text("set_instances/create")
7
+ opts.create
8
+ def create(stack)
9
+ Create.new(options.merge(stack: stack)).run
10
+ end
11
+
12
+ desc "update STACK_SET", "Update CloudFormation stack set instances."
13
+ long_desc Lono::Help.text("set_instances/update")
14
+ opts.update
15
+ def update(stack)
16
+ Update.new(options.merge(stack: stack)).run
17
+ end
18
+
19
+ desc "deploy STACK_SET", "Deploy CloudFormation stack set instances"
20
+ long_desc Lono::Help.text("set_instances/deploy")
21
+ opts.deploy
22
+ def deploy(stack)
23
+ Deploy.new(options.merge(stack: stack)).run
24
+ end
25
+
26
+ desc "delete STACK_SET", "Delete CloudFormation stack set instances."
27
+ long_desc Lono::Help.text("set_instances/delete")
28
+ opts.delete
29
+ def delete(stack)
30
+ Delete.new(options.merge(stack: stack)).run
31
+ end
32
+
33
+ desc "sync STACK_SET", "Sync CloudFormation stack set instances."
34
+ long_desc Lono::Help.text("set_instances/sync")
35
+ opts.sync
36
+ def sync(stack)
37
+ Sync.new(options.merge(stack: stack)).run
38
+ end
39
+
40
+ desc "list STACK_SET", "List CloudFormation stack set instances."
41
+ long_desc Lono::Help.text("set_instances/list")
42
+ def list(stack)
43
+ List.new(options.merge(stack: stack)).run
44
+ end
45
+
46
+ desc "status STACK_SET", "Show current status of stack instances."
47
+ long_desc Lono::Help.text("set_instances/status")
48
+ def status(stack)
49
+ instances_status = Status.new(options.merge(stack: stack))
50
+ success = instances_status.run
51
+ exit 3 unless success
52
+ end
53
+ end
54
+ end
@@ -1,4 +1,4 @@
1
- class Lono::Sets::Instances
1
+ class Lono::SetInstances
2
2
  class Base < Lono::Sets::Base
3
3
  # Simple structure to help with subtracting logic
4
4
  # [["112233445566", "us-west-1"], ["112233445566", "us-west-1"]]
@@ -0,0 +1,53 @@
1
+ class Lono::SetInstances
2
+ class Changeable < Base
3
+ include Lono::AwsServices
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
+ validate!
13
+
14
+ unless stack_set_exists?(@stack)
15
+ puts "ERROR: Cannot update a stack set because #{@stack} does not exists.".color(:red)
16
+ return
17
+ end
18
+ exit_unless_updatable!
19
+
20
+ options = {
21
+ stack_set_name: @stack,
22
+ accounts: accounts,
23
+ regions: regions,
24
+ }
25
+ begin
26
+ resp = perform(options)
27
+ rescue Aws::CloudFormation::Errors::ValidationError => e
28
+ # IE: Aws::CloudFormation::Errors::ValidationError: Region eu-north-1 is not supported
29
+ puts "#{e.class}: #{e.message}".color(:red)
30
+ exit 1
31
+ end
32
+
33
+ return true if @options[:noop]
34
+ Lono::Sets::Waiter.new(@options).run(resp[:operation_id])
35
+ end
36
+
37
+ def validate!
38
+ invalid = (regions.blank? || accounts.blank?) && !@options[:all]
39
+ if invalid
40
+ puts "ERROR: You must provide --accounts and --regions or --all.".color(:red)
41
+ exit 1
42
+ end
43
+ end
44
+
45
+ def accounts
46
+ @options[:all] ? stack_instances.map(&:account).uniq : @options[:accounts]
47
+ end
48
+
49
+ def regions
50
+ @options[:all] ? stack_instances.map(&:region).uniq : @options[:regions]
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,7 @@
1
+ class Lono::SetInstances
2
+ class Create < Changeable
3
+ def perform(options)
4
+ cfn.create_stack_instances(options)
5
+ end
6
+ end
7
+ end
@@ -1,28 +1,24 @@
1
- class Lono::Sets::Instances
2
- class Delete < Base
3
- include Lono::AwsServices
4
- include Lono::Utils::Sure
5
-
1
+ class Lono::SetInstances
2
+ class Delete < Changeable
6
3
  def initialize(options={})
7
- @options = options
4
+ super
8
5
  @stack = options[:stack]
9
6
  end
10
7
 
11
8
  def run
12
9
  validate!
13
10
 
14
- sure?("Are you sure you want to delete the #{@stack} instances?", long_desc)
11
+ sure?("Are you sure you want to delete the #{@stack} stack instances?", long_desc)
15
12
 
16
13
  # delete_stack_instances resp has operation_id
17
14
  # Could also use that to poll for status with the list_stack_set_operation_results
18
15
  # api. Currently, Instance::Status class not using this info. If we need will add the logic.
16
+ retain_stacks = @options[:retain_stacks] ? @options[:retain_stacks] : false
19
17
  resp = cfn.delete_stack_instances(
20
- options = {
21
- stack_set_name: @stack,
22
- accounts: accounts,
23
- regions: regions,
24
- retain_stacks: false,
25
- }
18
+ stack_set_name: @stack,
19
+ accounts: accounts,
20
+ regions: regions,
21
+ retain_stacks: retain_stacks,
26
22
  )
27
23
  operation_id = resp.operation_id
28
24
 
@@ -32,8 +28,6 @@ class Lono::Sets::Instances
32
28
  start_on_outdated: false,
33
29
  operation_id: operation_id,
34
30
  )
35
- Lono::Sets::Status::Instance::Base.show_time_progress = true
36
- Lono::Sets::Status::Instance::Base.delay_factor = accounts.size * regions.size
37
31
  instances_status = Status.new(o)
38
32
  instances_status.run(to: "deleted") unless @options[:noop] # returns success: true or false
39
33
  end
@@ -49,21 +43,5 @@ class Lono::Sets::Instances
49
43
  Number of stack instances to be deleted: #{total}
50
44
  EOL
51
45
  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
46
  end
69
47
  end
@@ -0,0 +1,52 @@
1
+ class Lono::SetInstances
2
+ class Deploy < Changeable
3
+ def run
4
+ # computes whether create or update should be ran for stack instances within each account
5
+ updates, creates = Hash.new([]), Hash.new([])
6
+ accounts.each do |account|
7
+ regions.each do |region|
8
+ if stack_instance_exists?(account, region)
9
+ updates[account] += [region] # += [item] works, << item doesnt seem to work
10
+ else
11
+ creates[account] += [region] # += [item] works, << item doesnt seem to work
12
+ end
13
+ end
14
+ end
15
+
16
+ deploy(:create, creates)
17
+ deploy(:update, updates)
18
+ end
19
+
20
+ def deploy(type, changes)
21
+ changes.each do |account, regions|
22
+ run_action(type, account, regions)
23
+ end
24
+ end
25
+
26
+ def run_action(type, account, regions)
27
+ klass = "Lono::SetInstances::#{type.to_s.camelize}"
28
+ klass = klass.constantize
29
+ command = lono_command(klass)
30
+ puts "Running #{command.color(:green)} on account: #{account} regions: #{regions.join(',')}"
31
+
32
+ options = @options.dup
33
+ options[:accounts] = [account]
34
+ options[:regions] = regions
35
+ klass.new(options).run
36
+ end
37
+
38
+ def lono_command(klass)
39
+ klass = klass.to_s
40
+ klass.split('::').map(&:underscore).join(' ')
41
+ end
42
+
43
+ def stack_instance_exists?(account, region)
44
+ existing = stack_instances.map do |summary|
45
+ [summary.account, summary.region]
46
+ end
47
+ intersect = existing & [[account, region]]
48
+ !intersect.empty?
49
+ end
50
+
51
+ end
52
+ end
@@ -1,4 +1,4 @@
1
- class Lono::Sets::Instances
1
+ class Lono::SetInstances
2
2
  class List
3
3
  include Lono::AwsServices
4
4
 
@@ -1,5 +1,13 @@
1
- class Lono::Sets::Instances
1
+ class Lono::SetInstances
2
2
  class Opts < Lono::Sets::Opts
3
+ def update
4
+ delete
5
+ end
6
+
7
+ def create
8
+ delete
9
+ end
10
+
3
11
  def delete
4
12
  operation_preferences_options
5
13
  accounts_options
@@ -1,4 +1,4 @@
1
- class Lono::Sets::Instances
1
+ class Lono::SetInstances
2
2
  class Status
3
3
  def initialize(options={})
4
4
  @options = options
@@ -1,4 +1,4 @@
1
- class Lono::Sets::Instances
1
+ class Lono::SetInstances
2
2
  class Sync < Base
3
3
  include Lono::Sets::Summarize
4
4
  include Lono::Utils::Sure
@@ -9,6 +9,9 @@ class Lono::Sets::Instances
9
9
  end
10
10
 
11
11
  def run
12
+ puts "DEPRECATED: The sync command is deprecated, in favor of the deploy command.".color(:yellow)
13
+ puts "Found more success with an explicit approach. sync may be removed in future versions of lono."
14
+
12
15
  unless stack_set_exists?(@stack)
13
16
  puts "ERROR: Cannot update a stack set because #{@stack} does not exists.".color(:red)
14
17
  return
@@ -114,8 +117,6 @@ class Lono::Sets::Instances
114
117
  operation_id: operation_id,
115
118
  start_on_outdated: meth != :delete_stack_instances,
116
119
  )
117
- Lono::Sets::Status::Instance::Base.show_time_progress = true
118
- Lono::Sets::Status::Instance::Base.delay_factor = accounts.size * regions.size
119
120
  instances_status = Status.new(o)
120
121
  final_status = meth == :delete_stack_instances ? "deleted" : "completed"
121
122
  instances_status.run(to: final_status) unless @options[:noop] # returns success: true or false
@@ -0,0 +1,15 @@
1
+ class Lono::SetInstances
2
+ class Update < Changeable
3
+ def perform(options)
4
+ cfn.update_stack_instances(options)
5
+ rescue Aws::CloudFormation::Errors::StackInstanceNotFoundException => e
6
+ puts "#{e.class}: #{e.message}".color(:red)
7
+ puts <<~EOL
8
+ One of the provided stack instance was not found. Unable to update the stack instances unless all stack instances
9
+ already exist. It may be helpful to check the StackSet console Instances Tab. You can also use the
10
+ `lono set_instances deploy` command instead.
11
+ EOL
12
+ exit 1
13
+ end
14
+ end
15
+ end
data/lib/lono/sets.rb CHANGED
@@ -30,9 +30,5 @@ module Lono
30
30
  def list
31
31
  List.new(options).run
32
32
  end
33
-
34
- desc "instances SUBCOMMAND", "instances subcommands"
35
- long_desc Help.text("sets/instances")
36
- subcommand "instances", Instances
37
33
  end
38
34
  end
@@ -19,9 +19,6 @@ class Lono::Sets
19
19
 
20
20
  options = build_options
21
21
  show_options(options, "cfn.create_stack_set")
22
-
23
- sure?("Are you sure you want to create the #{@stack} stack set?")
24
-
25
22
  cfn.create_stack_set(options) # resp.stack_set_id => String. There is no resp.operation_id
26
23
  puts message unless @options[:mute]
27
24
  true # There is no resp.operation_id
@@ -6,7 +6,7 @@ class Lono::Sets
6
6
 
7
7
  def initialize(options={})
8
8
  @options = options
9
- @stack = options.delete(:stack)
9
+ @stack = options[:stack]
10
10
  end
11
11
 
12
12
  def run
@@ -16,35 +16,26 @@ class Lono::Sets
16
16
  else
17
17
  desc =<<~EOL
18
18
  Be sure that the emptied StackSet instances is emptied first.
19
- You can empty it with a separate command: lono sets instances delete #{@stack} --all
20
- This command will only delete the StackSet itself after it's been emptied.
19
+ You can empty it with a separate command: lono set_instances delete #{@stack} --all
20
+ This command will only delete the StackSet itself after its been emptied.
21
21
  EOL
22
22
  sure?("Are you sure you want to delete the #{@stack} stack set?", desc)
23
23
 
24
24
  if stack_set_exists?(@stack)
25
- cfn.delete_stack_set(stack_set_name: @stack) # resp is an Empty structure, so much get operation_id from status
25
+ cfn.delete_stack_set(stack_set_name: @stack) # resp is an Empty structure, so must get operation_id from status
26
26
  puts message
27
27
  else
28
28
  puts "#{@stack.inspect} stack set does not exist".color(:red)
29
29
  return
30
30
  end
31
31
  end
32
-
33
- return true if @options[:noop] || !@options[:wait]
34
-
35
- status = Status.new(@options)
36
- success = status.wait
37
- operation_id = status.operation_id # getting operation_id from status because cfn.delete_stack_set resp is an Empty structure
38
- summarize(operation_id)
39
- exit 1 unless success
40
-
41
32
  rescue Aws::CloudFormation::Errors::StackSetNotEmptyException => e
42
33
  puts "ERROR: #{e.class}: #{e.message}".color(:red)
43
34
  puts <<~EOL
44
35
  The stack set must be empty before deleting. Cannot delete stack set until all stack instances are first
45
36
  deleted. If you want to delete all stack instances you can use:
46
37
 
47
- lono sets instances delete #{@stack} --all
38
+ lono set_instances delete #{@stack} --all
48
39
 
49
40
  EOL
50
41
  end
@@ -14,6 +14,9 @@ class Lono::Sets
14
14
  end
15
15
 
16
16
  def wait
17
+ Lono::Sets::Status::Instance::Base.show_time_progress = true
18
+ Lono::Sets::Status::Instance::Base.delay_factor = stack_instances.size
19
+
17
20
  status = nil
18
21
  until completed?(status)
19
22
  resp = display_one
@@ -42,9 +45,14 @@ class Lono::Sets
42
45
  end
43
46
 
44
47
  def show
48
+ if summaries.empty?
49
+ puts "No stack operations have been done with this stack set. So there is no status to report."
50
+ return
51
+ end
52
+
45
53
  display_one
46
54
  o = @options.merge(show_time_spent: false)
47
- instances_status = Lono::Sets::Instances::Status.new(o)
55
+ instances_status = Lono::SetInstances::Status.new(o)
48
56
  instances_status.run
49
57
  summarize(operation_id)
50
58
  end
@@ -60,7 +68,7 @@ class Lono::Sets
60
68
  Thread.new do
61
69
  # show_time_spent because we already show it in this status class. Dont want it to show twice.
62
70
  o = @options.merge(start_on_outdated: true, show_time_spent: false)
63
- instances_status = Lono::Sets::Instances::Status.new(o)
71
+ instances_status = Lono::SetInstances::Status.new(o)
64
72
  instances_status.run
65
73
  end
66
74
  @@instances_status_waiter_started = true
@@ -101,11 +109,15 @@ class Lono::Sets
101
109
  end
102
110
 
103
111
  def latest_operation_id
112
+ summaries.first.operation_id
113
+ end
114
+
115
+ def summaries
104
116
  resp = cfn.list_stack_set_operations(
105
117
  stack_set_name: @stack,
106
118
  max_results: 1,
107
119
  )
108
- resp.summaries.first.operation_id
120
+ resp.summaries
109
121
  end
110
122
 
111
123
  def stack_instances
@@ -11,7 +11,7 @@ class Lono::Sets::Status
11
11
 
12
12
  def wait(to="completed")
13
13
  puts "Stack Instance statuses... (takes a while)"
14
- puts "You can check on the StackSetsole Operations Tab for the operation status."
14
+ puts "You can also check with StackSets console at the Operations Tab."
15
15
  wait_until_outdated if @options[:start_on_outdated]
16
16
 
17
17
  threads = start_wait_for_instances_threads
@@ -23,8 +23,11 @@ class Lono::Sets::Status
23
23
  if stack_instances.empty?
24
24
  # Note: no access to @blueprint here
25
25
  puts <<~EOL
26
- There are 0 stack instances associated with the #{@stack} stack set. Add files
27
- Add accounts and regions configs use `lono sets instances sync` to add stack instances.
26
+ There are 0 stack instances associated with the #{@stack} stack set.
27
+ Use `lono set_instances deploy` to add stack instances. Example:
28
+
29
+ lono set_instances deploy #{@stack} --accounts 111 --regions us-west-2 us-east-2
30
+
28
31
  EOL
29
32
  return
30
33
  end
@@ -64,7 +67,7 @@ class Lono::Sets::Status
64
67
  sleep 5
65
68
  end
66
69
  end
67
- if @show_time_spent # or else it double shows from `lono sets deploy`. Do want it to show for `lono sets instances sync` though
70
+ if @show_time_spent # or else it double shows from `lono sets deploy`. Do want it to show for `lono set_instances sync` though
68
71
  show_time_spent(stack_set_operation)
69
72
  puts "Stack set operation completed."
70
73
  end
@@ -108,7 +111,7 @@ class Lono::Sets::Status
108
111
  resp = cfn.list_stack_instances(stack_set_name: @stack)
109
112
  summaries = resp.summaries
110
113
  # filter is really only used internally. So it's fine to keep it as complex data structure since that's what we
111
- # build it up as in Lono::Sets::Instances::Deploy
114
+ # build it up as in Lono::SetInstances::Deploy
112
115
  filter = @options[:filter] # [["112233445566", "us-west-1"],["112233445566", "us-west-2"]]
113
116
  return summaries unless filter
114
117
 
@@ -1,5 +1,7 @@
1
1
  class Lono::Sets
2
2
  module Summarize
3
+ include Lono::AwsServices
4
+
3
5
  def summarize(operation_id)
4
6
  puts "Stack Set Operation Summary:"
5
7
  resp = cfn.list_stack_set_operation_results(stack_set_name: @stack, operation_id: operation_id)
@@ -26,26 +26,19 @@ class Lono::Sets
26
26
  puts <<~EOL
27
27
  NOTE: There are 0 stack instances associated with the #{@stack} stack set.
28
28
  Will update the stack set template but there no instances to be updated.
29
- Add `configs/#{@blueprint}/accounts` and `configs/#{@blueprint}/regions` settings
30
- and use `lono sets instances sync` to add stack instances.
29
+
30
+ Use `lono set_instances deploy` to add stack instances. Example:
31
+
32
+ lono set_instances deploy #{@stack} --accounts 111 --regions us-west-2 us-east-2
33
+
31
34
  EOL
32
35
  else
33
36
  sure?("Are you sure you want to update the #{@stack} stack set?", long_desc)
34
37
  end
35
38
 
36
39
  resp = cfn.update_stack_set(options)
37
- operation_id = resp[:operation_id]
38
- puts message unless @options[:mute]
39
-
40
- return true if @options[:noop] || !@options[:wait]
41
40
 
42
- Lono::Sets::Status::Instance::Base.show_time_progress = true
43
- Lono::Sets::Status::Instance::Base.delay_factor = stack_instances.size
44
- status = Status.new(@options.merge(operation_id: operation_id))
45
- success = status.wait
46
- summarize(operation_id)
47
- exit 1 unless success
48
- success
41
+ Lono::Sets::Waiter.new(@options).run(resp[:operation_id])
49
42
  end
50
43
 
51
44
  def stack_instances
@@ -0,0 +1,23 @@
1
+ class Lono::Sets
2
+ class Waiter
3
+ include Lono::Sets::Summarize
4
+
5
+ def initialize(options)
6
+ @options = options
7
+ @stack = options[:stack]
8
+ @wait = @options[:wait].nil? ? true : @options[:wait]
9
+ end
10
+
11
+ def run(operation_id)
12
+ message = "Deploying #{@stack} stack set"
13
+ puts message unless @options[:mute]
14
+ return unless @wait
15
+
16
+ status = Status.new(@options.merge(operation_id: operation_id))
17
+ success = status.wait
18
+ summarize(operation_id)
19
+ exit 1 unless success
20
+ success
21
+ end
22
+ end
23
+ end
@@ -2,12 +2,14 @@
2
2
  class Lono::Template::Strategy::Dsl::Builder
3
3
  module Helpers
4
4
  extend Memoist
5
- include CoreHelper
6
- include Ec2Helper
7
- include FileHelper
8
- include LookupHelper
9
- include S3Helper
10
- include TagsHelper
5
+
6
+ # Auto include all modules in helpers folder
7
+ helpers_dir = File.expand_path("helpers", __dir__)
8
+ Dir.glob("#{helpers_dir}/**/*").each do |path|
9
+ next unless File.file?(path)
10
+ klass = path.gsub(%r{.*/lib/},'').sub(".rb",'').camelize
11
+ include klass.constantize
12
+ end
11
13
 
12
14
  include Lono::Template::Strategy::Common::Helpers
13
15
  end
@@ -0,0 +1,51 @@
1
+ module Lono::Template::Strategy::Dsl::Builder::Helpers
2
+ module StackHelper
3
+ extend Memoist
4
+ include Lono::AwsServices
5
+
6
+ def stack_output(name)
7
+ stack_name, key = name.split(".")
8
+ resp = describe_stacks(stack_name: stack_name)
9
+ stack = resp.stacks.first
10
+ if stack
11
+ o = stack.outputs.detect { |h| h.output_key == key }
12
+ end
13
+
14
+ if o
15
+ o.output_value
16
+ else
17
+ "NOT FOUND: output #{key} for stack #{stack_name}"
18
+ end
19
+ end
20
+
21
+ def stack_resource(name)
22
+ stack_name, logical_id = name.split(".")
23
+ resp = describe_stack_resources(stack_name: stack_name)
24
+ resources = resp.stack_resources
25
+ resource = resources.find { |r| r.logical_resource_id == logical_id }
26
+ if resource
27
+ resource.physical_resource_id
28
+ else
29
+ "NOT FOUND: logical_id #{logical_id} for stack #{stack_name}"
30
+ end
31
+ end
32
+
33
+ def lookup_output(name)
34
+ result = stack_output(name)
35
+ return unless ENV['LONO_DEPRECATION_SOFT']
36
+ puts "DEPRECATION WARNING: lookup_output is deprecated. Please use stack_output instead".color(:yellow)
37
+ result
38
+ end
39
+
40
+ private
41
+ def describe_stacks(options={})
42
+ cfn.describe_stacks(options)
43
+ end
44
+ memoize :describe_stacks
45
+
46
+ def describe_stack_resources(options={})
47
+ cfn.describe_stack_resources(options)
48
+ end
49
+ memoize :describe_stack_resources
50
+ end
51
+ end
data/lib/lono/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Lono
2
- VERSION = "7.4.8"
2
+ VERSION = "7.5.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lono
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.4.8
4
+ version: 7.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-11 00:00:00.000000000 Z
11
+ date: 2021-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -577,12 +577,13 @@ files:
577
577
  - lib/lono/help/script/build.md
578
578
  - lib/lono/help/script/upload.md
579
579
  - lib/lono/help/seed.md
580
+ - lib/lono/help/set_instances/delete.md
581
+ - lib/lono/help/set_instances/deploy.md
582
+ - lib/lono/help/set_instances/list.md
583
+ - lib/lono/help/set_instances/status.md
584
+ - lib/lono/help/set_instances/sync.md
580
585
  - lib/lono/help/sets/delete.md
581
586
  - lib/lono/help/sets/deploy.md
582
- - lib/lono/help/sets/instances/delete.md
583
- - lib/lono/help/sets/instances/list.md
584
- - lib/lono/help/sets/instances/status.md
585
- - lib/lono/help/sets/instances/sync.md
586
587
  - lib/lono/help/sets/status.md
587
588
  - lib/lono/help/summary.md
588
589
  - lib/lono/help/template.md
@@ -639,18 +640,22 @@ files:
639
640
  - lib/lono/seed/base.rb
640
641
  - lib/lono/seed/service_role.rb
641
642
  - lib/lono/sequence.rb
643
+ - lib/lono/set_instances.rb
644
+ - lib/lono/set_instances/base.rb
645
+ - lib/lono/set_instances/changeable.rb
646
+ - lib/lono/set_instances/create.rb
647
+ - lib/lono/set_instances/delete.rb
648
+ - lib/lono/set_instances/deploy.rb
649
+ - lib/lono/set_instances/list.rb
650
+ - lib/lono/set_instances/opts.rb
651
+ - lib/lono/set_instances/status.rb
652
+ - lib/lono/set_instances/sync.rb
653
+ - lib/lono/set_instances/update.rb
642
654
  - lib/lono/sets.rb
643
655
  - lib/lono/sets/base.rb
644
656
  - lib/lono/sets/create.rb
645
657
  - lib/lono/sets/delete.rb
646
658
  - lib/lono/sets/deploy.rb
647
- - lib/lono/sets/instances.rb
648
- - lib/lono/sets/instances/base.rb
649
- - lib/lono/sets/instances/delete.rb
650
- - lib/lono/sets/instances/list.rb
651
- - lib/lono/sets/instances/opts.rb
652
- - lib/lono/sets/instances/status.rb
653
- - lib/lono/sets/instances/sync.rb
654
659
  - lib/lono/sets/list.rb
655
660
  - lib/lono/sets/opts.rb
656
661
  - lib/lono/sets/preview/codediff.rb
@@ -665,6 +670,7 @@ files:
665
670
  - lib/lono/sets/summarize.rb
666
671
  - lib/lono/sets/time_spent.rb
667
672
  - lib/lono/sets/update.rb
673
+ - lib/lono/sets/waiter.rb
668
674
  - lib/lono/setting.rb
669
675
  - lib/lono/template.rb
670
676
  - lib/lono/template/aws_service.rb
@@ -688,8 +694,8 @@ files:
688
694
  - lib/lono/template/strategy/dsl/builder/helpers/core_helper.rb
689
695
  - lib/lono/template/strategy/dsl/builder/helpers/ec2_helper.rb
690
696
  - lib/lono/template/strategy/dsl/builder/helpers/file_helper.rb
691
- - lib/lono/template/strategy/dsl/builder/helpers/lookup_helper.rb
692
697
  - lib/lono/template/strategy/dsl/builder/helpers/s3_helper.rb
698
+ - lib/lono/template/strategy/dsl/builder/helpers/stack_helper.rb
693
699
  - lib/lono/template/strategy/dsl/builder/helpers/tags_helper.rb
694
700
  - lib/lono/template/strategy/dsl/builder/section/base.rb
695
701
  - lib/lono/template/strategy/dsl/builder/section/condition.rb
@@ -804,7 +810,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
804
810
  - !ruby/object:Gem::Version
805
811
  version: '0'
806
812
  requirements: []
807
- rubygems_version: 3.1.2
813
+ rubygems_version: 3.2.5
808
814
  signing_key:
809
815
  specification_version: 4
810
816
  summary: The CloudFormation Framework
@@ -1,33 +0,0 @@
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
@@ -1,27 +0,0 @@
1
- module Lono::Template::Strategy::Dsl::Builder::Helpers
2
- module LookupHelper
3
- extend Memoist
4
- include Lono::AwsServices
5
-
6
- def lookup_output(name)
7
- stack_name, key = name.split(".")
8
- resp = describe_stacks(stack_name: stack_name)
9
- stack = resp.stacks.first
10
- if stack
11
- o = stack.outputs.detect { |h| h.output_key == key }
12
- end
13
-
14
- if o
15
- o.output_value
16
- else
17
- "NOT FOUND: Did not lookup_output #{name} for stack #{stack}"
18
- end
19
- end
20
-
21
- private
22
- def describe_stacks(options={})
23
- cfn.describe_stacks(options)
24
- end
25
- memoize :describe_stacks
26
- end
27
- end