moonshot 2.0.0.beta6 → 2.0.0.beta7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. checksums.yaml +5 -5
  2. data/bin/moonshot +4 -1
  3. data/lib/default/bin/build.sh +0 -0
  4. data/lib/moonshot/account_context.rb +2 -0
  5. data/lib/moonshot/always_use_default_source.rb +5 -4
  6. data/lib/moonshot/artifact_repository/s3_bucket.rb +11 -5
  7. data/lib/moonshot/artifact_repository/s3_bucket_via_github_releases.rb +7 -7
  8. data/lib/moonshot/ask_user_source.rb +2 -0
  9. data/lib/moonshot/build_mechanism/github_release.rb +9 -2
  10. data/lib/moonshot/build_mechanism/script.rb +8 -7
  11. data/lib/moonshot/build_mechanism/travis_deploy.rb +5 -5
  12. data/lib/moonshot/build_mechanism/version_proxy.rb +13 -0
  13. data/lib/moonshot/change_set.rb +17 -35
  14. data/lib/moonshot/command.rb +3 -1
  15. data/lib/moonshot/command_line.rb +12 -9
  16. data/lib/moonshot/command_line_dispatcher.rb +5 -7
  17. data/lib/moonshot/commands/build.rb +6 -0
  18. data/lib/moonshot/commands/console.rb +2 -0
  19. data/lib/moonshot/commands/create.rb +14 -2
  20. data/lib/moonshot/commands/delete.rb +9 -0
  21. data/lib/moonshot/commands/deploy.rb +4 -8
  22. data/lib/moonshot/commands/doctor.rb +2 -0
  23. data/lib/moonshot/commands/generate_template.rb +46 -0
  24. data/lib/moonshot/commands/interactive_command.rb +15 -0
  25. data/lib/moonshot/commands/list.rb +2 -0
  26. data/lib/moonshot/commands/new.rb +5 -2
  27. data/lib/moonshot/commands/parameter_arguments.rb +5 -4
  28. data/lib/moonshot/commands/parent_stack_option.rb +2 -0
  29. data/lib/moonshot/commands/push.rb +2 -0
  30. data/lib/moonshot/commands/show_all_events_option.rb +2 -0
  31. data/lib/moonshot/commands/ssh.rb +4 -0
  32. data/lib/moonshot/commands/status.rb +2 -0
  33. data/lib/moonshot/commands/update.rb +7 -1
  34. data/lib/moonshot/commands/version.rb +2 -0
  35. data/lib/moonshot/controller.rb +28 -13
  36. data/lib/moonshot/controller_config.rb +12 -27
  37. data/lib/moonshot/creds_helper.rb +2 -0
  38. data/lib/moonshot/deployment_mechanism/code_deploy.rb +44 -37
  39. data/lib/moonshot/doctor_helper.rb +14 -15
  40. data/lib/moonshot/dynamic_template.rb +76 -0
  41. data/lib/moonshot/interactive_logger_proxy.rb +4 -4
  42. data/lib/moonshot/json_stack_template.rb +3 -0
  43. data/lib/moonshot/parameter_collection.rb +3 -0
  44. data/lib/moonshot/parent_stack_parameter_loader.rb +7 -3
  45. data/lib/moonshot/resources.rb +2 -0
  46. data/lib/moonshot/resources_helper.rb +5 -1
  47. data/lib/moonshot/shell.rb +8 -8
  48. data/lib/moonshot/ssh_command.rb +2 -0
  49. data/lib/moonshot/ssh_command_builder.rb +3 -1
  50. data/lib/moonshot/ssh_config.rb +3 -2
  51. data/lib/moonshot/ssh_fork_executor.rb +2 -0
  52. data/lib/moonshot/ssh_target_selector.rb +3 -1
  53. data/lib/moonshot/stack.rb +50 -46
  54. data/lib/moonshot/stack_asg_printer.rb +14 -12
  55. data/lib/moonshot/stack_config.rb +3 -2
  56. data/lib/moonshot/stack_events_poller.rb +3 -1
  57. data/lib/moonshot/stack_list_printer.rb +2 -0
  58. data/lib/moonshot/stack_lister.rb +6 -2
  59. data/lib/moonshot/stack_output_printer.rb +2 -0
  60. data/lib/moonshot/stack_parameter.rb +5 -9
  61. data/lib/moonshot/stack_parameter_printer.rb +3 -1
  62. data/lib/moonshot/stack_template.rb +2 -0
  63. data/lib/moonshot/task.rb +3 -0
  64. data/lib/moonshot/tools/asg_rollout/asg.rb +19 -21
  65. data/lib/moonshot/tools/asg_rollout/asg_instance.rb +2 -0
  66. data/lib/moonshot/tools/asg_rollout/hook_exec_environment.rb +2 -0
  67. data/lib/moonshot/tools/asg_rollout/instance_health.rb +2 -0
  68. data/lib/moonshot/tools/asg_rollout.rb +16 -14
  69. data/lib/moonshot/tools/asg_rollout_config.rb +2 -0
  70. data/lib/moonshot/unicode_table.rb +1 -1
  71. data/lib/moonshot/yaml_stack_template.rb +2 -0
  72. data/lib/moonshot.rb +13 -1
  73. data/lib/plugins/backup.rb +24 -30
  74. data/lib/plugins/code_deploy_setup.rb +4 -2
  75. data/lib/plugins/dynamic_template.rb +36 -0
  76. data/lib/plugins/encrypted_parameters/kms_key.rb +2 -0
  77. data/lib/plugins/encrypted_parameters/parameter_encrypter.rb +2 -0
  78. data/lib/plugins/encrypted_parameters.rb +3 -1
  79. metadata +124 -57
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'erb'
4
+
5
+ module Moonshot
6
+ class TemplateExists < StandardError; end
7
+ class InvalidTemplate < StandardError; end
8
+
9
+ class DynamicTemplate
10
+ # A class to encapsulate template parameters, passing a hash to `process` is
11
+ # only available from Ruby 2.5.
12
+ class Parameters
13
+ def initialize(parameters)
14
+ parameters.each do |k, v|
15
+ instance_variable_set("@#{k}".to_sym, v)
16
+ # Adding an attribute reader for flexibility, this way you can add
17
+ # either `@parameter` or just `parameter` to your template.
18
+ self.class.send(:attr_reader, k.to_sym)
19
+ end
20
+ end
21
+
22
+ def expose_binding
23
+ binding
24
+ end
25
+ end
26
+
27
+ attr_writer :destination
28
+
29
+ def initialize(source:, parameters:, destination:)
30
+ @source = File.read(source)
31
+ @parameters = parameters
32
+ @destination = destination
33
+ end
34
+
35
+ def parameters_obj
36
+ @parameters_obj ||= Parameters.new(parameters_file)
37
+ end
38
+
39
+ def parameters_file
40
+ env_name = Moonshot.config.environment_name
41
+ @parameters.respond_to?(:call) ? @parameters.call(env_name) : @parameters
42
+ end
43
+
44
+ def process
45
+ validate_destination_exists
46
+ new_template = generate_template
47
+
48
+ validate_template(new_template)
49
+ write_output(new_template)
50
+ end
51
+
52
+ private
53
+
54
+ def validate_destination_exists
55
+ return unless File.file?(@destination)
56
+
57
+ raise TemplateExists, "Output file '#{@destination}' already exists."
58
+ end
59
+
60
+ def validate_template(template)
61
+ Aws::CloudFormation::Client.new.validate_template(
62
+ template_body: template
63
+ )
64
+ rescue Aws::CloudFormation::Errors::ValidationError => e
65
+ raise InvalidTemplate, "Invalid template:\n#{e}"
66
+ end
67
+
68
+ def generate_template
69
+ ERB.new(@source).result(parameters_obj.expose_binding)
70
+ end
71
+
72
+ def write_output(content)
73
+ File.write(@destination, content)
74
+ end
75
+ end
76
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
 
3
5
  module Moonshot
@@ -10,8 +12,7 @@ module Moonshot
10
12
  @logger = logger
11
13
  end
12
14
 
13
- def blank
14
- end
15
+ def blank; end
15
16
 
16
17
  def continue(str = nil)
17
18
  @logger.info(str) if str
@@ -21,8 +22,7 @@ module Moonshot
21
22
  @logger.error(str)
22
23
  end
23
24
 
24
- def repaint
25
- end
25
+ def repaint; end
26
26
 
27
27
  def success(str = 'Success')
28
28
  @logger.info(str)
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
4
+ require_relative 'stack_template'
2
5
 
3
6
  module Moonshot
4
7
  # Handles JSON formatted AWS template files.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # A Rigid Hash-like structure that only accepts manipulation of
3
5
  # parameters defined in the Stack template. Anything else results in
@@ -6,6 +8,7 @@ module Moonshot
6
8
  extend Forwardable
7
9
 
8
10
  def_delegators :@hash, :key?, :fetch, :[], :keys, :values
11
+ attr_reader :hash
9
12
 
10
13
  def self.from_template(template)
11
14
  obj = new
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  class ParentStackParameterLoader
3
5
  def initialize(config)
@@ -8,30 +10,32 @@ module Moonshot
8
10
  @config.parent_stacks.each do |stack_name|
9
11
  count = 0
10
12
 
11
- resp = cf_client.describe_stacks(stack_name: stack_name)
13
+ resp = cf_client.describe_stacks(stack_name:)
12
14
  raise "Parent Stack #{stack_name} not found!" unless resp.stacks.size == 1
13
15
 
14
16
  # If there is an input parameters matching a stack output, pass it.
15
17
  resp.stacks[0].outputs.each do |output|
16
18
  next unless @config.parameters.key?(output.output_key)
19
+
17
20
  # Our Stack has a Parameter matching this output. Set it's
18
21
  # value to the Output's value.
19
22
  count += 1
20
23
  @config.parameters.fetch(output.output_key).set(output.output_value)
21
24
  end
22
25
 
23
- puts "Imported #{count} parameters from parent stack #{stack_name.blue}!" if count > 0
26
+ puts "Imported #{count} parameters from parent stack #{stack_name.blue}!" if count.positive?
24
27
  end
25
28
  end
26
29
 
27
30
  def load_missing_only!
28
31
  @config.parent_stacks.each do |stack_name|
29
- resp = cf_client.describe_stacks(stack_name: stack_name)
32
+ resp = cf_client.describe_stacks(stack_name:)
30
33
  raise "Parent Stack #{stack_name} not found!" unless resp.stacks.size == 1
31
34
 
32
35
  # If there is an input parameters matching a stack output, pass it.
33
36
  resp.stacks[0].outputs.each do |output|
34
37
  next unless @config.parameters.key?(output.output_key)
38
+
35
39
  # Our Stack has a Parameter matching this output. Set it's
36
40
  # value to the Output's value, but only if we don't already
37
41
  # have a previous value we're using.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # Resources is a dependency container that holds references to instances
3
5
  # provided to a Mechanism (build, deploy, etc.).
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # Provides shorthand methods for accessing resources provided by the Resources
3
5
  # container.
@@ -8,16 +10,18 @@ module Moonshot
8
10
 
9
11
  # TODO: Deprecate this interface.
10
12
  def log
11
- @log ||= Logger.new(STDOUT)
13
+ @log ||= Logger.new($stdout)
12
14
  end
13
15
 
14
16
  def stack
15
17
  raise 'Resources not provided to Mechanism!' unless @resources
18
+
16
19
  @resources.stack
17
20
  end
18
21
 
19
22
  def ilog
20
23
  raise 'Resources not provided to Mechanism!' unless @resources
24
+
21
25
  @resources.ilog
22
26
  end
23
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thor'
2
4
  require 'retriable'
3
5
 
@@ -17,7 +19,7 @@ module Moonshot::Shell
17
19
 
18
20
  # Run a command, returning stdout. Stderr is suppressed unless the command
19
21
  # returns non-zero.
20
- def sh_out(cmd, fail: true, stdin: '')
22
+ def sh_out(cmd, fail = true, stdin = '')
21
23
  r_in, w_in = IO.pipe
22
24
  r_out, w_out = IO.pipe
23
25
  r_err, w_err = IO.pipe
@@ -53,13 +55,11 @@ module Moonshot::Shell
53
55
  define_method(meth) { |*args| shell.public_send(meth, *args) }
54
56
  end
55
57
 
56
- def sh_step(cmd, args = {})
58
+ def sh_step(cmd, **args)
57
59
  msg = args.delete(:msg) || cmd
58
- if msg.length > (terminal_width - 18)
59
- msg = "#{msg[0..(terminal_width - 22)]}..."
60
- end
60
+ msg = "#{msg[0..(terminal_width - 22)]}..." if msg.length > (terminal_width - 18)
61
61
  ilog.start_threaded(msg) do |step|
62
- out = sh_out(cmd, args)
62
+ out = sh_out(cmd, **args)
63
63
  yield step, out if block_given?
64
64
  step.success
65
65
  end
@@ -73,9 +73,9 @@ module Moonshot::Shell
73
73
  # @param opts [Hash] Options for retriable.
74
74
  #
75
75
  # @return [String] Stdout form the command.
76
- def sh_retry(cmd, fail: true, stdin: '', opts: {})
76
+ def sh_retry(cmd, fail = true, stdin = '', opts: {})
77
77
  Retriable.retriable(DEFAULT_RETRY_OPTIONS.merge(opts)) do
78
- out = sh_out(cmd, stdin: stdin)
78
+ out = sh_out(cmd, stdin:)
79
79
  yield out if block_given?
80
80
  out
81
81
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thor'
2
4
 
3
5
  module Moonshot
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'shellwords'
2
4
 
3
5
  module Moonshot
@@ -25,7 +27,7 @@ module Moonshot
25
27
  @instance_ip ||= Aws::EC2::Client.new
26
28
  .describe_instances(instance_ids: [@instance_id])
27
29
  .reservations.first.instances.first.public_ip_address
28
- rescue
30
+ rescue StandardError
29
31
  raise "Failed to determine public IP address for instance #{@instance_id}!"
30
32
  end
31
33
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  class SSHConfig
3
- attr_accessor :ssh_identity_file
4
- attr_accessor :ssh_user
5
+ attr_accessor :ssh_identity_file, :ssh_user
5
6
 
6
7
  def initialize
7
8
  @ssh_identity_file = ENV['MOONSHOT_SSH_KEY_FILE']
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'open3'
2
4
 
3
5
  module Moonshot
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # Choose a publically accessible instance to run commands on, given a Moonshot::Stack.
3
5
  class SSHTargetSelector
@@ -23,7 +25,7 @@ module Moonshot
23
25
  Aws::AutoScaling::Client.new.describe_auto_scaling_groups(
24
26
  auto_scaling_group_names: [asg.physical_resource_id]
25
27
  ).auto_scaling_groups.first.instances.map(&:instance_id).first
26
- rescue => e
28
+ rescue StandardError => e
27
29
  raise "Failed to select an instance from the Auto Scaling Group: #{e.message}"
28
30
  end
29
31
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'yaml'
2
4
 
3
5
  module Moonshot
@@ -5,12 +7,11 @@ module Moonshot
5
7
  # stores the state of the active stack running on AWS, but contains a
6
8
  # reference to the StackTemplate that would be applied with an update
7
9
  # action.
8
- class Stack # rubocop:disable ClassLength
10
+ class Stack # rubocop:disable Metrics/ClassLength
9
11
  include CredsHelper
10
12
  include DoctorHelper
11
13
 
12
- attr_reader :app_name
13
- attr_reader :name
14
+ attr_reader :app_name, :name
14
15
 
15
16
  def initialize(config)
16
17
  @config = config
@@ -111,7 +112,7 @@ module Moonshot
111
112
  resource_summary = resource_summaries.find do |r|
112
113
  r.logical_resource_id == logical_id
113
114
  end
114
- resource_summary.physical_resource_id if resource_summary
115
+ resource_summary&.physical_resource_id
115
116
  end
116
117
 
117
118
  # @return [Array<Aws::CloudFormation::Types::StackResourceSummary>]
@@ -152,13 +153,23 @@ module Moonshot
152
153
 
153
154
  # Support the legacy file location from Moonshot 1.0.
154
155
  YamlStackTemplate.new(
155
- File.join(@config.project_root, 'cloud_formation', "#{@config.app_name}.yml")),
156
+ File.join(@config.project_root, 'cloud_formation', "#{@config.app_name}.yml")
157
+ ),
156
158
  JsonStackTemplate.new(
157
- File.join(@config.project_root, 'cloud_formation', "#{@config.app_name}.json"))
159
+ File.join(@config.project_root, 'cloud_formation', "#{@config.app_name}.json")
160
+ )
158
161
  ]
159
162
 
163
+ # If a template file has been specified in the config, look there first.
164
+ if @config.template_file
165
+ templates.unshift YamlStackTemplate.new(@config.template_file)
166
+ templates.unshift JsonStackTemplate.new(@config.template_file)
167
+ end
168
+
160
169
  template = templates.find(&:exist?)
170
+
161
171
  raise 'No template found in moonshot/template.{yml,json}!' unless template
172
+
162
173
  template
163
174
  end
164
175
 
@@ -177,9 +188,7 @@ module Moonshot
177
188
  end
178
189
 
179
190
  def upload_template_to_s3
180
- unless @config.template_s3_bucket
181
- raise 'The S3 bucket to store the template in is not configured.'
182
- end
191
+ raise 'The S3 bucket to store the template in is not configured.' unless @config.template_s3_bucket
183
192
 
184
193
  s3_object_key = "#{@name}-#{Time.now.getutc.to_i}-#{File.basename(template.filename)}"
185
194
  template_url = "http://#{@config.template_s3_bucket}.s3.amazonaws.com/#{s3_object_key}"
@@ -199,7 +208,7 @@ module Moonshot
199
208
  def create_stack
200
209
  parameters = {
201
210
  stack_name: @name,
202
- capabilities: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM),
211
+ capabilities: %w[CAPABILITY_IAM CAPABILITY_NAMED_IAM],
203
212
  parameters: @config.parameters.values.map(&:to_cf),
204
213
  tags: make_tags
205
214
  }
@@ -221,10 +230,10 @@ module Moonshot
221
230
  ].join('-')
222
231
 
223
232
  parameters = {
224
- change_set_name: change_set_name,
233
+ change_set_name:,
225
234
  description: "Moonshot update command for application '#{Moonshot.config.app_name}'",
226
235
  stack_name: @name,
227
- capabilities: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM),
236
+ capabilities: %w[CAPABILITY_IAM CAPABILITY_NAMED_IAM],
228
237
  parameters: @config.parameters.values.map(&:to_cf)
229
238
  }
230
239
  if @config.template_s3_bucket
@@ -248,36 +257,31 @@ module Moonshot
248
257
  events.show_only_errors unless @config.show_all_stack_events
249
258
 
250
259
  @ilog.start_threaded "Waiting for #{stack_name} to be successfully #{past_tense_verb}." do |s|
251
- begin
252
- cf_client.wait_until(wait_target, stack_name: stack_id) do |w|
253
- w.delay = 10
254
- w.max_attempts = 360 # 60 minutes.
255
- w.before_wait do |attempt, resp|
256
- begin
257
- events.latest_events.each { |e| @ilog.error(format_event(e)) }
258
- # rubocop:disable Lint/HandleExceptions
259
- rescue Aws::CloudFormation::Errors::ValidationError
260
- # Do nothing. The above event logging block may result in
261
- # a ValidationError while waiting for a stack to delete.
262
- end
263
- # rubocop:enable Lint/HandleExceptions
264
-
265
- if attempt == w.max_attempts - 1
266
- s.failure "#{stack_name} was not #{past_tense_verb} after 30 minutes."
267
- result = false
268
-
269
- # We don't want the interactive logger to catch an exception.
270
- throw :success
271
- end
272
- s.continue "Waiting for CloudFormation Stack to be successfully #{past_tense_verb}, current status '#{resp.stacks.first.stack_status}'." # rubocop:disable LineLength
260
+ cf_client.wait_until(wait_target, stack_name: stack_id) do |w|
261
+ w.delay = 10
262
+ w.max_attempts = 360 # 60 minutes.
263
+ w.before_wait do |attempt, resp|
264
+ begin
265
+ events.latest_events.each { |e| @ilog.error(format_event(e)) }
266
+ rescue Aws::CloudFormation::Errors::ValidationError
267
+ # Do nothing. The above event logging block may result in
268
+ # a ValidationError while waiting for a stack to delete.
273
269
  end
274
- end
270
+ if attempt == w.max_attempts - 1
271
+ s.failure "#{stack_name} was not #{past_tense_verb} after 30 minutes."
272
+ result = false
275
273
 
276
- s.success "#{stack_name} successfully #{past_tense_verb}." if result
277
- rescue Aws::Waiters::Errors::FailureStateError
278
- result = false
279
- s.failure "#{stack_name} failed to update."
274
+ # We don't want the interactive logger to catch an exception.
275
+ throw :success
276
+ end
277
+ s.continue "Waiting for CloudFormation Stack to be successfully #{past_tense_verb}, current status '#{resp.stacks.first.stack_status}'." # rubocop:disable Layout/LineLength
278
+ end
280
279
  end
280
+
281
+ s.success "#{stack_name} successfully #{past_tense_verb}." if result
282
+ rescue Aws::Waiters::Errors::FailureStateError
283
+ result = false
284
+ s.failure "#{stack_name} failed to update."
281
285
  end
282
286
 
283
287
  result
@@ -289,9 +293,7 @@ module Moonshot
289
293
  { key: 'moonshot_environment', value: @config.environment_name }
290
294
  ]
291
295
 
292
- if @config.additional_tag
293
- default_tags << { key: @config.additional_tag, value: @name }
294
- end
296
+ default_tags << { key: @config.additional_tag, value: @name } if @config.additional_tag
295
297
 
296
298
  default_tags
297
299
  end
@@ -320,14 +322,15 @@ module Moonshot
320
322
  end
321
323
 
322
324
  def doctor_check_template_against_aws
325
+ validate_params = {}
323
326
  if @config.template_s3_bucket
324
- parameters[:template_url] = upload_template_to_s3
327
+ validate_params[:template_url] = upload_template_to_s3
325
328
  else
326
- parameters[:template_body] = template.body
329
+ validate_params[:template_body] = template.body
327
330
  end
328
- cf_client.validate_template(parameters)
331
+ cf_client.validate_template(validate_params)
329
332
  success('CloudFormation template is valid.')
330
- rescue => e
333
+ rescue StandardError => e
331
334
  critical('Invalid CloudFormation template!', e.message)
332
335
  end
333
336
 
@@ -351,6 +354,7 @@ module Moonshot
351
354
 
352
355
  success = wait_for_stack_state(:stack_update_complete, 'updated')
353
356
  raise 'Failed to update the CloudFormation Stack.' unless success
357
+
354
358
  success
355
359
  end
356
360
  end
@@ -1,4 +1,5 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'colorize'
3
4
  require 'ruby-duration'
4
5
 
@@ -16,8 +17,8 @@ module Moonshot
16
17
  def print
17
18
  asgs.each do |asg|
18
19
  asg_info = as_client.describe_auto_scaling_groups(
19
- auto_scaling_group_names: [asg.physical_resource_id])
20
- .auto_scaling_groups.first
20
+ auto_scaling_group_names: [asg.physical_resource_id]
21
+ ).auto_scaling_groups.first
21
22
  t_asg_info = @table.add_leaf("ASG: #{asg.logical_resource_id}")
22
23
 
23
24
  add_asg_info(t_asg_info, asg_info)
@@ -70,7 +71,7 @@ module Moonshot
70
71
 
71
72
  # Get additional information about instances not returned by the ASG API.
72
73
  def get_addl_info(instance_ids)
73
- resp = ec2_client.describe_instances(instance_ids: instance_ids)
74
+ resp = ec2_client.describe_instances(instance_ids:)
74
75
 
75
76
  data = {}
76
77
  resp.reservations.map(&:instances).flatten.each do |instance|
@@ -85,7 +86,7 @@ module Moonshot
85
86
 
86
87
  hc = asg_info.health_check_type.blue
87
88
  gp = (asg_info.health_check_grace_period.to_s << 's').blue
88
- table.add_line "Using #{hc} health checks, with a #{gp} health check grace period." # rubocop:disable LineLength
89
+ table.add_line "Using #{hc} health checks, with a #{gp} health check grace period."
89
90
 
90
91
  dc = asg_info.desired_capacity.to_s.blue
91
92
  min = asg_info.min_size.to_s.blue
@@ -93,7 +94,7 @@ module Moonshot
93
94
  table.add_line "Desired Capacity is #{dc} (Min: #{min}, Max: #{max})."
94
95
 
95
96
  lbs = asg_info.load_balancer_names
96
- table.add_line "Has #{lbs.count.to_s.blue} Load Balancer(s): #{lbs.map(&:blue).join(', ')}" # rubocop:disable LineLength
97
+ table.add_line "Has #{lbs.count.to_s.blue} Load Balancer(s): #{lbs.map(&:blue).join(', ')}"
97
98
  end
98
99
 
99
100
  def create_instance_table(asg_info)
@@ -112,11 +113,11 @@ module Moonshot
112
113
 
113
114
  def instance_row(asg_instance, ec2_instance)
114
115
  if ec2_instance
115
- if ec2_instance.public_ip_address
116
- ip_address = "#{ec2_instance.public_ip_address} (#{ec2_instance.private_ip_address})"
117
- else
118
- ip_address = "#{ec2_instance.private_ip_address} (PRV)"
119
- end
116
+ ip_address = if ec2_instance.public_ip_address
117
+ "#{ec2_instance.public_ip_address} (#{ec2_instance.private_ip_address})"
118
+ else
119
+ "#{ec2_instance.private_ip_address} (PRV)"
120
+ end
120
121
  uptime = uptime_format(ec2_instance.launch_time)
121
122
  else
122
123
  # We've seen race conditions where ASG tells us about instances that EC2 is no longer
@@ -142,7 +143,8 @@ module Moonshot
142
143
  def add_recent_activity_leaf(table, asg_name)
143
144
  recent = table.add_leaf('Recent Activity')
144
145
  resp = as_client.describe_scaling_activities(
145
- auto_scaling_group_name: asg_name).activities
146
+ auto_scaling_group_name: asg_name
147
+ ).activities
146
148
 
147
149
  rows = resp.sort_by(&:start_time).reverse.first(10).map do |activity|
148
150
  row_for_activity(activity)
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # Configuration for the Moonshot::Stack class.
3
5
  class StackConfig
4
- attr_accessor :parent_stacks
5
- attr_accessor :show_all_events
6
+ attr_accessor :parent_stacks, :show_all_events
6
7
 
7
8
  def initialize
8
9
  @parent_stacks = []
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # The StackEventsPoller queries DescribeStackEvents every time #latest_events
3
5
  # is invoked, filtering out events that have already been returned. It can
@@ -32,7 +34,7 @@ module Moonshot
32
34
  def filter_events(events)
33
35
  if @errors_only
34
36
  events.select do |event|
35
- %w(CREATE_FAILED UPDATE_FAILED DELETE_FAILED).include?(event.resource_status)
37
+ %w[CREATE_FAILED UPDATE_FAILED DELETE_FAILED].include?(event.resource_status)
36
38
  end
37
39
  else
38
40
  events
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  class StackListPrinter
3
5
  attr_accessor :stacks
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # The StackLister is world renoun for it's ability to list stacks.
3
5
  class StackLister
@@ -13,7 +15,7 @@ module Moonshot
13
15
  result = []
14
16
  next_token = nil
15
17
  loop do
16
- resp = cf_client.describe_stacks(next_token: next_token)
18
+ resp = cf_client.describe_stacks(next_token:)
17
19
  resp.stacks.each do |stack|
18
20
  app_tag = stack.tags.find { |t| t.key == 'moonshot_application' }
19
21
  env_tag = stack.tags.find { |t| t.key == 'moonshot_environment' }
@@ -22,15 +24,17 @@ module Moonshot
22
24
  if app_tag && app_tag.value == Moonshot.config.app_name
23
25
  result <<
24
26
  EnvironmentDescription.new(env_tag.value, stack.creation_time, stack.stack_status)
25
- elsif legacy_tag && legacy_tag.value.start_with?(Moonshot.config.app_name)
27
+ elsif legacy_tag&.value&.start_with?(Moonshot.config.app_name)
26
28
  result <<
27
29
  EnvironmentDescription.new(legacy_tag.value, stack.creation_time, stack.stack_status)
28
30
  end
29
31
  end
30
32
  break unless resp.next_token
33
+
31
34
  next_token = resp.next_token
32
35
  end
33
36
  result.sort_by(&:name)
34
37
  end
38
+ # rubocop:enable Metrics/AbcSize
35
39
  end
36
40
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # Display the stack outputs to the user.
3
5
  class StackOutputPrinter
@@ -1,8 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  class StackParameter
3
- attr_reader :name
4
- attr_reader :default
5
- attr_reader :description
5
+ attr_reader :name, :default, :description
6
6
 
7
7
  def initialize(name, default: nil, use_previous: false, description: '')
8
8
  @default = default
@@ -32,9 +32,7 @@ module Moonshot
32
32
  end
33
33
 
34
34
  def use_previous!(value)
35
- if @value
36
- raise "Value already set for StackParameter #{@name}, cannot use previous value!"
37
- end
35
+ raise "Value already set for StackParameter #{@name}, cannot use previous value!" if @value
38
36
 
39
37
  # Make the current value available to plugins.
40
38
  @value = value
@@ -42,9 +40,7 @@ module Moonshot
42
40
  end
43
41
 
44
42
  def value
45
- unless @value || default?
46
- raise "No value set and no default for StackParameter #{@name}!"
47
- end
43
+ raise "No value set and no default for StackParameter #{@name}!" unless @value || default?
48
44
 
49
45
  @value || default
50
46
  end