moonshot 2.0.0.beta6 → 3.0.4

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 (80) 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 +24 -34
  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 +16 -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/tag_arguments.rb +20 -0
  34. data/lib/moonshot/commands/update.rb +8 -1
  35. data/lib/moonshot/commands/version.rb +2 -0
  36. data/lib/moonshot/controller.rb +28 -13
  37. data/lib/moonshot/controller_config.rb +13 -27
  38. data/lib/moonshot/creds_helper.rb +2 -0
  39. data/lib/moonshot/deployment_mechanism/code_deploy.rb +44 -37
  40. data/lib/moonshot/doctor_helper.rb +14 -15
  41. data/lib/moonshot/dynamic_template.rb +76 -0
  42. data/lib/moonshot/interactive_logger_proxy.rb +4 -4
  43. data/lib/moonshot/json_stack_template.rb +3 -0
  44. data/lib/moonshot/parameter_collection.rb +3 -0
  45. data/lib/moonshot/parent_stack_parameter_loader.rb +7 -3
  46. data/lib/moonshot/resources.rb +2 -0
  47. data/lib/moonshot/resources_helper.rb +5 -1
  48. data/lib/moonshot/shell.rb +8 -8
  49. data/lib/moonshot/ssh_command.rb +2 -0
  50. data/lib/moonshot/ssh_command_builder.rb +3 -1
  51. data/lib/moonshot/ssh_config.rb +3 -2
  52. data/lib/moonshot/ssh_fork_executor.rb +2 -0
  53. data/lib/moonshot/ssh_target_selector.rb +3 -1
  54. data/lib/moonshot/stack.rb +73 -55
  55. data/lib/moonshot/stack_asg_printer.rb +14 -12
  56. data/lib/moonshot/stack_config.rb +3 -2
  57. data/lib/moonshot/stack_events_poller.rb +3 -1
  58. data/lib/moonshot/stack_list_printer.rb +2 -0
  59. data/lib/moonshot/stack_lister.rb +6 -2
  60. data/lib/moonshot/stack_output_printer.rb +2 -0
  61. data/lib/moonshot/stack_parameter.rb +5 -9
  62. data/lib/moonshot/stack_parameter_printer.rb +3 -1
  63. data/lib/moonshot/stack_template.rb +2 -0
  64. data/lib/moonshot/task.rb +3 -0
  65. data/lib/moonshot/tools/asg_rollout/asg.rb +22 -21
  66. data/lib/moonshot/tools/asg_rollout/asg_instance.rb +2 -0
  67. data/lib/moonshot/tools/asg_rollout/hook_exec_environment.rb +2 -0
  68. data/lib/moonshot/tools/asg_rollout/instance_health.rb +2 -0
  69. data/lib/moonshot/tools/asg_rollout.rb +16 -14
  70. data/lib/moonshot/tools/asg_rollout_config.rb +2 -0
  71. data/lib/moonshot/unicode_table.rb +5 -3
  72. data/lib/moonshot/yaml_stack_template.rb +2 -0
  73. data/lib/moonshot.rb +13 -1
  74. data/lib/plugins/backup.rb +24 -30
  75. data/lib/plugins/code_deploy_setup.rb +4 -2
  76. data/lib/plugins/dynamic_template.rb +36 -0
  77. data/lib/plugins/encrypted_parameters/kms_key.rb +26 -5
  78. data/lib/plugins/encrypted_parameters/parameter_encrypter.rb +2 -0
  79. data/lib/plugins/encrypted_parameters.rb +6 -2
  80. metadata +189 -51
@@ -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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # Displays information about existing stack parameters to the user, with
3
5
  # information on what a stack update would do.
@@ -18,7 +20,7 @@ module Moonshot
18
20
 
19
21
  def format_value(value)
20
22
  if value.size > 60
21
- value[0..60] + '...'
23
+ "#{value[0..60]}..."
22
24
  else
23
25
  value
24
26
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  # A StackTemplate loads the template from disk and stores information
3
5
  # about it.
data/lib/moonshot/task.rb CHANGED
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  class Task
3
5
  attr_reader :name, :desc, :block
6
+
4
7
  def initialize(name, desc, &block)
5
8
  @name = name.to_sym
6
9
  @desc = desc
@@ -1,3 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-elasticloadbalancing'
4
+ require 'aws-sdk-autoscaling'
5
+
1
6
  module Moonshot
2
7
  module Tools
3
8
  class ASGRollout
@@ -20,14 +25,15 @@ module Moonshot
20
25
  autoscaling.update_auto_scaling_group(
21
26
  auto_scaling_group_name: @name,
22
27
  max_size: max,
23
- desired_capacity: desired)
28
+ desired_capacity: desired
29
+ )
24
30
  end
25
31
 
26
32
  def non_conforming_instances
27
33
  asg = load_asg
28
34
 
29
35
  asg.instances
30
- .select { |i| i.launch_configuration_name != asg.launch_configuration_name }
36
+ .reject { |i| i.launch_configuration_name == asg.launch_configuration_name }
31
37
  .map(&:instance_id)
32
38
  end
33
39
 
@@ -59,17 +65,17 @@ module Moonshot
59
65
  resp = autoscaling.detach_instances(
60
66
  auto_scaling_group_name: @name,
61
67
  instance_ids: [id],
62
- should_decrement_desired_capacity: decrement)
68
+ should_decrement_desired_capacity: decrement
69
+ )
63
70
 
64
71
  activity = resp.activities.first
65
- unless activity
66
- raise 'Did not receive Activity from DetachInstances call!'
67
- end
72
+ raise 'Did not receive Activity from DetachInstances call!' unless activity
68
73
 
69
74
  # Wait for the detach activity to complete:
70
75
  loop do
71
76
  resp = autoscaling.describe_scaling_activities(
72
- auto_scaling_group_name: @name)
77
+ auto_scaling_group_name: @name
78
+ )
73
79
 
74
80
  current_status = resp.activities
75
81
  .find { |a| a.activity_id == activity.activity_id }
@@ -97,7 +103,8 @@ module Moonshot
97
103
 
98
104
  def asg_instance_state(id)
99
105
  resp = autoscaling.describe_auto_scaling_instances(
100
- instance_ids: [id])
106
+ instance_ids: [id]
107
+ )
101
108
 
102
109
  instance_info = resp.auto_scaling_instances.first
103
110
  return 'Missing' unless instance_info
@@ -108,14 +115,11 @@ module Moonshot
108
115
  def elb_instance_state(id)
109
116
  resp = loadbalancing.describe_instance_health(
110
117
  load_balancer_name: elb_name,
111
- instances: [
112
- { instance_id: id }
113
- ])
118
+ instances: [{ instance_id: id }]
119
+ )
114
120
 
115
121
  instance_info = resp.instance_states.first
116
- unless instance_info
117
- raise "Failed to call DescribeInstanceHealth for #{id}!"
118
- end
122
+ raise "Failed to call DescribeInstanceHealth for #{id}!" unless instance_info
119
123
 
120
124
  instance_info.state
121
125
  rescue Aws::ElasticLoadBalancing::Errors::InvalidInstance
@@ -133,11 +137,10 @@ module Moonshot
133
137
 
134
138
  def load_asg
135
139
  resp = autoscaling.describe_auto_scaling_groups(
136
- auto_scaling_group_names: [@name])
140
+ auto_scaling_group_names: [@name]
141
+ )
137
142
 
138
- if resp.auto_scaling_groups.empty?
139
- raise "Failed to call DescribeAutoScalingGroups for #{@name}!"
140
- end
143
+ raise "Failed to call DescribeAutoScalingGroups for #{@name}!" if resp.auto_scaling_groups.empty?
141
144
 
142
145
  asg = resp.auto_scaling_groups.first
143
146
  @last_seen_ids = asg.instances.map(&:instance_id)
@@ -149,9 +152,7 @@ module Moonshot
149
152
  return @elb_name if @elb_name
150
153
 
151
154
  asg = load_asg
152
- if asg.load_balancer_names.size > 1
153
- raise 'ASGRollout does not support configurations with multiple ELBs!'
154
- end
155
+ raise 'ASGRollout does not support configurations with multiple ELBs!' if asg.load_balancer_names.size > 1
155
156
 
156
157
  @elb_name ||= asg.load_balancer_names.first
157
158
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  module Tools
3
5
  class ASGRollout
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'moonshot/ssh_fork_executor'
2
4
 
3
5
  module Moonshot
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  module Tools
3
5
  class ASGRollout
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  module Tools
3
- class ASGRollout # rubocop:disable ClassLength
5
+ class ASGRollout # rubocop:disable Metrics/ClassLength
4
6
  attr_accessor :config
5
7
 
6
8
  def initialize(controller:, logical_id:)
@@ -16,7 +18,7 @@ module Moonshot
16
18
  new_instance = wait_for_new_instance
17
19
  begin
18
20
  wait_for_in_service(new_instance)
19
- rescue
21
+ rescue StandardError
20
22
  next
21
23
  end
22
24
  break
@@ -74,6 +76,7 @@ module Moonshot
74
76
  raise "Instance #{new_instance.blue} went OutOfService while waiting to join..."
75
77
  end
76
78
  break if instance_health.in_service?
79
+
77
80
  s.continue "Instance #{new_instance.blue} is #{instance_health}..."
78
81
  sleep @config.instance_health_delay
79
82
  end
@@ -83,22 +86,22 @@ module Moonshot
83
86
  end
84
87
 
85
88
  def run_pre_detach(instance)
86
- if @config.pre_detach
87
- log.start_threaded "Running PreDetach hook on #{instance.blue}..." do |s|
88
- he = HookExecEnvironment.new(@controller.config, instance)
89
- if false == @config.pre_detach.call(he)
90
- s.failure "PreDetach hook failed for #{instance.blue}!"
91
- raise "PreDetach hook failed for #{instance.blue}!"
92
- end
89
+ return unless @config.pre_detach
93
90
 
94
- s.success "PreDetach hook complete for #{instance.blue}!"
91
+ log.start_threaded "Running PreDetach hook on #{instance.blue}..." do |s|
92
+ he = HookExecEnvironment.new(@controller.config, instance)
93
+ if @config.pre_detach.call(he) == false
94
+ s.failure "PreDetach hook failed for #{instance.blue}!"
95
+ raise "PreDetach hook failed for #{instance.blue}!"
95
96
  end
97
+
98
+ s.success "PreDetach hook complete for #{instance.blue}!"
96
99
  end
97
100
  end
98
101
 
99
102
  def detach(instance, decrement:)
100
103
  log.start_threaded "Detaching instance #{instance.blue}..." do |s|
101
- asg.detach_instance(instance, decrement: decrement)
104
+ asg.detach_instance(instance, decrement:)
102
105
 
103
106
  if decrement
104
107
  s.success "Detached instance #{instance.blue}, and decremented DesiredCapacity."
@@ -115,6 +118,7 @@ module Moonshot
115
118
  loop do
116
119
  instance_health = asg.instance_health(instance)
117
120
  break if instance_health.out_of_service?
121
+
118
122
  s.continue "Instance #{instance.blue} is #{instance_health}..."
119
123
  sleep @config.instance_health_delay
120
124
  end
@@ -155,9 +159,7 @@ module Moonshot
155
159
  return @asg if @asg
156
160
 
157
161
  asg_name = @controller.stack.physical_id_for(@logical_id)
158
- unless asg_name
159
- raise "Could not find Auto Scaling Group #{@logical_id}!"
160
- end
162
+ raise "Could not find Auto Scaling Group #{@logical_id}!" unless asg_name
161
163
 
162
164
  @asg ||= ASGRollout::ASG.new(asg_name)
163
165
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  module Tools
3
5
  class ASGRolloutConfig
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'colorize'
4
4
 
@@ -37,12 +37,14 @@ module Moonshot
37
37
  end
38
38
 
39
39
  def draw(depth = 1, first = true)
40
+ space = ' '
41
+ pipe = '|'
40
42
  print first ? '┌' : '├'
41
43
  print '─' * depth
42
- puts ' ' << @name.light_black
44
+ puts "#{space}" << @name.light_black # rubocop:disable Style/RedundantInterpolation
43
45
  @lines = [''] + @lines + ['']
44
46
  @lines.each do |line|
45
- puts '│' << (' ' * depth) << line
47
+ puts "#{pipe}" << (' ' * depth) << line # rubocop:disable Style/RedundantInterpolation
46
48
  end
47
49
  @children.each do |child|
48
50
  child.draw(depth + 1, false)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'yaml'
2
4
 
3
5
  module Moonshot
data/lib/moonshot.rb CHANGED
@@ -1,5 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'English'
2
- require 'aws-sdk'
4
+
5
+ require 'aws-sdk-cloudformation'
6
+ require 'aws-sdk-codedeploy'
7
+ require 'aws-sdk-ec2'
8
+ require 'aws-sdk-iam'
9
+ require 'aws-sdk-autoscaling'
10
+ require 'aws-sdk-s3'
11
+
3
12
  require 'logger'
4
13
  require 'thor'
5
14
  require 'interactive-logger'
@@ -16,10 +25,13 @@ module Moonshot
16
25
 
17
26
  module ArtifactRepository
18
27
  end
28
+
19
29
  module BuildMechanism
20
30
  end
31
+
21
32
  module DeploymentMechanism
22
33
  end
34
+
23
35
  module Plugins
24
36
  end
25
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems/package'
2
4
  require 'zlib'
3
5
  require 'yaml'
@@ -20,7 +22,7 @@ module Moonshot
20
22
  def initialize
21
23
  yield self if block_given?
22
24
  validate_configuration
23
- @target_name ||= '%{app_name}_%{timestamp}_%{user}.tar.gz'
25
+ @target_name ||= '%<app_name>s_%<timestamp>s_%<user>s.tar.gz'
24
26
  end
25
27
 
26
28
  # Factory method to create preconfigured Backup plugins. Uploads current
@@ -29,11 +31,12 @@ module Moonshot
29
31
  # @return [Backup] configured backup object
30
32
  def self.to_bucket(bucket)
31
33
  raise ArgumentError if bucket.nil? || bucket.empty?
34
+
32
35
  Moonshot::Plugins::Backup.new do |b|
33
36
  b.bucket = bucket
34
37
  b.backup_parameters = true
35
38
  b.backup_template = true
36
- b.hooks = [:post_create, :post_update]
39
+ b.hooks = %i[post_create post_update]
37
40
  end
38
41
  end
39
42
 
@@ -53,18 +56,16 @@ module Moonshot
53
56
  return if @target_bucket.nil?
54
57
 
55
58
  resources.ilog.start("#{log_message} in progress.") do |s|
56
- begin
57
- tar_out = tar(@files)
58
- zip_out = zip(tar_out)
59
- upload(zip_out)
60
-
61
- s.success("#{log_message} succeeded.")
62
- rescue => e
63
- s.failure("#{log_message} failed: #{e}")
64
- ensure
65
- tar_out.close unless tar_out.nil?
66
- zip_out.close unless zip_out.nil?
67
- end
59
+ tar_out = tar(@files)
60
+ zip_out = zip(tar_out)
61
+ upload(zip_out)
62
+
63
+ s.success("#{log_message} succeeded.")
64
+ rescue StandardError => e
65
+ s.failure("#{log_message} failed: #{e}")
66
+ ensure
67
+ tar_out&.close
68
+ zip_out&.close
68
69
  end
69
70
  end
70
71
 
@@ -110,7 +111,7 @@ module Moonshot
110
111
 
111
112
  # adding template file
112
113
  if @backup_template
113
- template_file_path = render('cloud_formation/%{app_name}.json')
114
+ template_file_path = render('cloud_formation/%<app_name>s.json')
114
115
  add_file_to_tar(writer, template_file_path)
115
116
  end
116
117
  end
@@ -123,12 +124,10 @@ module Moonshot
123
124
  # @param writer [TarWriter]
124
125
  # @param file_name [String]
125
126
  def add_file_to_tar(writer, file_name)
126
- writer.add_file(File.basename(file_name), 0644) do |io|
127
- begin
128
- File.open(file_name, 'r') { |f| io.write(f.read) }
129
- rescue Errno::ENOENT
130
- warn "'#{file_name}' was not found."
131
- end
127
+ writer.add_file(File.basename(file_name), 0o644) do |io|
128
+ File.open(file_name, 'r') { |f| io.write(f.read) }
129
+ rescue Errno::ENOENT
130
+ warn "'#{file_name}' was not found."
132
131
  end
133
132
  end
134
133
 
@@ -139,7 +138,7 @@ module Moonshot
139
138
  # @param target_filename [String]
140
139
  # @param content [String]
141
140
  def add_str_to_tar(writer, target_filename, content)
142
- writer.add_file(File.basename(target_filename), 0644) do |io|
141
+ writer.add_file(File.basename(target_filename), 0o644) do |io|
143
142
  io.write(content.to_yaml)
144
143
  end
145
144
  end
@@ -196,17 +195,12 @@ module Moonshot
196
195
  end
197
196
 
198
197
  def define_bucket
199
- case
200
198
  # returning already calculated bucket name
201
- when @target_bucket
202
- @target_bucket
199
+ return @target_bucket if @target_bucket
203
200
  # single bucket for all accounts
204
- when @bucket
205
- @bucket
201
+ return @bucket if @bucket
206
202
  # calculating bucket based on account name
207
- when @buckets
208
- bucket_by_account(iam_account)
209
- end
203
+ return bucket_by_account(iam_account) if @buckets # rubocop:disable Style/RedundantReturn
210
204
  end
211
205
 
212
206
  def bucket_by_account(account)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moonshot
2
4
  module Plugins
3
5
  # Plugin to ensure CodeDeploy has all necessary S3 buckets created.
@@ -33,11 +35,11 @@ module Moonshot
33
35
  # Create an S3 bucket in each supported region for CodeDeploy
34
36
  def setup_code_deploy_s3_buckets
35
37
  @regions.uniq.each do |region|
36
- client = s3_client(region: region)
38
+ client = s3_client(region:)
37
39
  name = bucket_name(region)
38
40
  bucket = Aws::S3::Bucket.new(
39
41
  name,
40
- client: client
42
+ client:
41
43
  )
42
44
  bucket.create unless bucket.exists?
43
45
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Moonshot
4
+ module Plugins
5
+ class DynamicTemplate
6
+ def initialize(source:, parameters:, destination:)
7
+ @dynamic_template = ::Moonshot::DynamicTemplate.new(
8
+ source:,
9
+ parameters:,
10
+ destination:
11
+ )
12
+ end
13
+
14
+ def run_hook
15
+ @dynamic_template.process
16
+ end
17
+
18
+ def cli_hook(parser)
19
+ parser.on('--template-file=FILE', 'Override the path to the CloudFormation template.') do |v|
20
+ @dynamic_template.destination = v
21
+ Moonshot.config.template_file = v
22
+ end
23
+ end
24
+
25
+ # Moonshot hooks to trigger this plugin.
26
+ alias setup_create run_hook
27
+ alias setup_update run_hook
28
+ alias setup_delete run_hook
29
+
30
+ # Moonshot hooks to add CLI options.
31
+ alias create_cli_hook cli_hook
32
+ alias delete_cli_hook cli_hook
33
+ alias update_cli_hook cli_hook
34
+ end
35
+ end
36
+ end
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../moonshot/stack'
4
+
1
5
  module Moonshot
2
6
  module Plugins
3
7
  class EncryptedParameters
@@ -5,16 +9,33 @@ module Moonshot
5
9
  class KmsKey
6
10
  attr_reader :arn
7
11
 
12
+ class << self
13
+ def create
14
+ standard_tags = stack_tags
15
+ resp = Aws::KMS::Client.new.create_key({
16
+ tags: standard_tags # An array of tags.
17
+ })
18
+ arn = resp.key_metadata.arn
19
+ new(arn)
20
+ end
21
+
22
+ def stack_tags
23
+ tags = Moonshot::Stack.make_tags(Moonshot.config)
24
+ tags.map { |tag| { tag_key: tag[:key], tag_value: tag[:value] } }
25
+ end
26
+ end
27
+
8
28
  def initialize(arn)
9
29
  @arn = arn
10
30
  @kms_client = Aws::KMS::Client.new
11
31
  end
12
32
 
13
- def self.create
14
- resp = Aws::KMS::Client.new.create_key
15
- arn = resp.key_metadata.arn
16
-
17
- new(arn)
33
+ def update
34
+ standard_tags = self.class.stack_tags
35
+ @kms_client.tag_resource({
36
+ key_id: @arn, # arn of the CMK being tagged
37
+ tags: standard_tags # An array of tags.
38
+ })
18
39
  end
19
40
 
20
41
  def delete
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'base64'
2
4
  module Moonshot
3
5
  module Plugins
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This plugin encrypts parameters of the stack using a KMS Key,
2
4
  # storing and passing the key used to the stack as a parameter as
3
5
  # well. The resources in the stack can then use that KMS Key to
@@ -96,13 +98,15 @@ module Moonshot
96
98
 
97
99
  @ilog.start_threaded "Checking for KMS Key #{@kms_key_parameter_name}" do |s|
98
100
  if Moonshot.config.parameters.key?(@kms_key_parameter_name)
99
- if 'Auto' == Moonshot.config.parameters[@kms_key_parameter_name].value
101
+ if Moonshot.config.parameters[@kms_key_parameter_name].value == 'Auto'
100
102
  s.continue "Auto-generating KMS Key for #{@kms_key_parameter_name.blue}... "
101
103
  key_arn = KmsKey.create.arn
102
104
  Moonshot.config.parameters[@kms_key_parameter_name].set(key_arn)
103
105
  s.success "Created a new KMS Key for #{@kms_key_parameter_name.blue}!"
104
106
  else
105
- key_arn = KmsKey.new(Moonshot.config.parameters[@kms_key_parameter_name].value).arn
107
+ kms=KmsKey.new(Moonshot.config.parameters[@kms_key_parameter_name].value) # rubocop:disable Style/SpaceAroundOperators
108
+ key_arn = kms.arn
109
+ kms.update
106
110
  s.success "Using existing KMS Key for #{@kms_key_parameter_name.blue}!"
107
111
  end
108
112
  end