moonshot 2.0.0.beta6 → 3.0.4

Sign up to get free protection for your applications and to get access to all the features.
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