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.
- checksums.yaml +5 -5
- data/bin/moonshot +4 -1
- data/lib/default/bin/build.sh +0 -0
- data/lib/moonshot/account_context.rb +2 -0
- data/lib/moonshot/always_use_default_source.rb +5 -4
- data/lib/moonshot/artifact_repository/s3_bucket.rb +11 -5
- data/lib/moonshot/artifact_repository/s3_bucket_via_github_releases.rb +7 -7
- data/lib/moonshot/ask_user_source.rb +2 -0
- data/lib/moonshot/build_mechanism/github_release.rb +9 -2
- data/lib/moonshot/build_mechanism/script.rb +8 -7
- data/lib/moonshot/build_mechanism/travis_deploy.rb +5 -5
- data/lib/moonshot/build_mechanism/version_proxy.rb +13 -0
- data/lib/moonshot/change_set.rb +24 -34
- data/lib/moonshot/command.rb +3 -1
- data/lib/moonshot/command_line.rb +12 -9
- data/lib/moonshot/command_line_dispatcher.rb +5 -7
- data/lib/moonshot/commands/build.rb +6 -0
- data/lib/moonshot/commands/console.rb +2 -0
- data/lib/moonshot/commands/create.rb +16 -2
- data/lib/moonshot/commands/delete.rb +9 -0
- data/lib/moonshot/commands/deploy.rb +4 -8
- data/lib/moonshot/commands/doctor.rb +2 -0
- data/lib/moonshot/commands/generate_template.rb +46 -0
- data/lib/moonshot/commands/interactive_command.rb +15 -0
- data/lib/moonshot/commands/list.rb +2 -0
- data/lib/moonshot/commands/new.rb +5 -2
- data/lib/moonshot/commands/parameter_arguments.rb +5 -4
- data/lib/moonshot/commands/parent_stack_option.rb +2 -0
- data/lib/moonshot/commands/push.rb +2 -0
- data/lib/moonshot/commands/show_all_events_option.rb +2 -0
- data/lib/moonshot/commands/ssh.rb +4 -0
- data/lib/moonshot/commands/status.rb +2 -0
- data/lib/moonshot/commands/tag_arguments.rb +20 -0
- data/lib/moonshot/commands/update.rb +8 -1
- data/lib/moonshot/commands/version.rb +2 -0
- data/lib/moonshot/controller.rb +28 -13
- data/lib/moonshot/controller_config.rb +13 -27
- data/lib/moonshot/creds_helper.rb +2 -0
- data/lib/moonshot/deployment_mechanism/code_deploy.rb +44 -37
- data/lib/moonshot/doctor_helper.rb +14 -15
- data/lib/moonshot/dynamic_template.rb +76 -0
- data/lib/moonshot/interactive_logger_proxy.rb +4 -4
- data/lib/moonshot/json_stack_template.rb +3 -0
- data/lib/moonshot/parameter_collection.rb +3 -0
- data/lib/moonshot/parent_stack_parameter_loader.rb +7 -3
- data/lib/moonshot/resources.rb +2 -0
- data/lib/moonshot/resources_helper.rb +5 -1
- data/lib/moonshot/shell.rb +8 -8
- data/lib/moonshot/ssh_command.rb +2 -0
- data/lib/moonshot/ssh_command_builder.rb +3 -1
- data/lib/moonshot/ssh_config.rb +3 -2
- data/lib/moonshot/ssh_fork_executor.rb +2 -0
- data/lib/moonshot/ssh_target_selector.rb +3 -1
- data/lib/moonshot/stack.rb +73 -55
- data/lib/moonshot/stack_asg_printer.rb +14 -12
- data/lib/moonshot/stack_config.rb +3 -2
- data/lib/moonshot/stack_events_poller.rb +3 -1
- data/lib/moonshot/stack_list_printer.rb +2 -0
- data/lib/moonshot/stack_lister.rb +6 -2
- data/lib/moonshot/stack_output_printer.rb +2 -0
- data/lib/moonshot/stack_parameter.rb +5 -9
- data/lib/moonshot/stack_parameter_printer.rb +3 -1
- data/lib/moonshot/stack_template.rb +2 -0
- data/lib/moonshot/task.rb +3 -0
- data/lib/moonshot/tools/asg_rollout/asg.rb +22 -21
- data/lib/moonshot/tools/asg_rollout/asg_instance.rb +2 -0
- data/lib/moonshot/tools/asg_rollout/hook_exec_environment.rb +2 -0
- data/lib/moonshot/tools/asg_rollout/instance_health.rb +2 -0
- data/lib/moonshot/tools/asg_rollout.rb +16 -14
- data/lib/moonshot/tools/asg_rollout_config.rb +2 -0
- data/lib/moonshot/unicode_table.rb +5 -3
- data/lib/moonshot/yaml_stack_template.rb +2 -0
- data/lib/moonshot.rb +13 -1
- data/lib/plugins/backup.rb +24 -30
- data/lib/plugins/code_deploy_setup.rb +4 -2
- data/lib/plugins/dynamic_template.rb +36 -0
- data/lib/plugins/encrypted_parameters/kms_key.rb +26 -5
- data/lib/plugins/encrypted_parameters/parameter_encrypter.rb +2 -0
- data/lib/plugins/encrypted_parameters.rb +6 -2
- metadata +189 -51
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Moonshot
|
4
|
+
module Commands
|
5
|
+
class GenerateTemplate < Moonshot::Command
|
6
|
+
self.usage = 'generate-template [options]'
|
7
|
+
self.description = 'Processes an ERB formatted CloudFormation template.'
|
8
|
+
|
9
|
+
def initialize(*)
|
10
|
+
super
|
11
|
+
@parameters = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def parser
|
15
|
+
parser = super
|
16
|
+
|
17
|
+
parser.on('--source SOURCE_FILE', 'The ERB template file.') do |v|
|
18
|
+
@source = v
|
19
|
+
end
|
20
|
+
|
21
|
+
parser.on('--parameter KEY=VALUE', '-PKEY=VALUE',
|
22
|
+
'Specify Stack Parameter on the command line') do |v|
|
23
|
+
data = v.split('=', 2)
|
24
|
+
unless data.size == 2
|
25
|
+
raise "Invalid parameter format '#{v}',"\
|
26
|
+
'expected KEY=VALUE (e.g. MyTemplateParameter=12)'
|
27
|
+
end
|
28
|
+
|
29
|
+
@parameters[data[0]] = data[1]
|
30
|
+
end
|
31
|
+
|
32
|
+
parser.on('--destination DESTINATION_FILE', 'Destionation file.') do |v|
|
33
|
+
@destination = v
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute
|
38
|
+
::Moonshot::DynamicTemplate.new(
|
39
|
+
source: @source,
|
40
|
+
parameters: @parameters,
|
41
|
+
destination: @destination
|
42
|
+
).process
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Moonshot
|
4
|
+
module Commands
|
5
|
+
module InteractiveCommand
|
6
|
+
def parser
|
7
|
+
parser = super
|
8
|
+
|
9
|
+
parser.on('--[no-]interactive', TrueClass, 'Use interactive prompts.') do |v|
|
10
|
+
Moonshot.config.interactive = v
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moonshot
|
2
4
|
module Commands
|
3
5
|
class New < Moonshot::Command
|
@@ -25,6 +27,7 @@ module Moonshot
|
|
25
27
|
def create_project_dir
|
26
28
|
raise "Directory '#{@application_name}' already exists!" \
|
27
29
|
if Dir.exist?(project_path)
|
30
|
+
|
28
31
|
Dir.mkdir(project_path)
|
29
32
|
end
|
30
33
|
|
@@ -49,7 +52,7 @@ Moonshot.config do |m|
|
|
49
52
|
m.build_mechanism = Script.new('bin/build.sh')
|
50
53
|
m.deployment_mechanism = CodeDeploy.new(asg: 'AutoScalingGroup')
|
51
54
|
end
|
52
|
-
EOF
|
55
|
+
EOF
|
53
56
|
end
|
54
57
|
|
55
58
|
def print_success_message
|
@@ -69,7 +72,7 @@ You will also need to ensure your Amazon account is configured for
|
|
69
72
|
CodeDeploy by creating a role that allows deployments.
|
70
73
|
|
71
74
|
See: http://moonshot.readthedocs.io/en/latest/mechanisms/deployment/
|
72
|
-
EOF
|
75
|
+
EOF
|
73
76
|
end
|
74
77
|
end
|
75
78
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Layout/LineLength
|
2
4
|
module Moonshot
|
3
5
|
module Commands
|
4
6
|
module ParameterArguments
|
@@ -15,9 +17,7 @@ module Moonshot
|
|
15
17
|
|
16
18
|
parser.on('--parameter KEY=VALUE', '-PKEY=VALUE', 'Specify Stack Parameter on the command line') do |v|
|
17
19
|
data = v.split('=', 2)
|
18
|
-
unless data.size == 2
|
19
|
-
raise "Invalid parameter format '#{v}', expected KEY=VALUE (e.g. MyStackParameter=12)"
|
20
|
-
end
|
20
|
+
raise "Invalid parameter format '#{v}', expected KEY=VALUE (e.g. MyStackParameter=12)" unless data.size == 2
|
21
21
|
|
22
22
|
Moonshot.config.parameter_overrides[data[0]] = data[1]
|
23
23
|
end
|
@@ -25,3 +25,4 @@ module Moonshot
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
+
# rubocop:enable Layout/LineLength
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Moonshot
|
4
|
+
module Commands
|
5
|
+
module TagArguments
|
6
|
+
def parser
|
7
|
+
parser = super
|
8
|
+
|
9
|
+
parser.on('--tag KEY=VALUE', '-TKEY=VALUE', 'Specify Stack Tag on the command line') do |v|
|
10
|
+
data = v.split('=', 2)
|
11
|
+
unless data.size == 2
|
12
|
+
raise "Invalid tag format '#{v}', expected KEY=VALUE (e.g. MyStackTag=12)"
|
13
|
+
end
|
14
|
+
|
15
|
+
Moonshot.config.extra_tags << { key: data[0], value: data[1] }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moonshot
|
2
4
|
module Commands
|
3
5
|
class Update < Moonshot::Command
|
4
6
|
include ParameterArguments
|
7
|
+
include TagArguments
|
5
8
|
include ShowAllEventsOption
|
6
9
|
include ParentStackOption
|
7
10
|
|
@@ -11,7 +14,7 @@ module Moonshot
|
|
11
14
|
def parser
|
12
15
|
parser = super
|
13
16
|
|
14
|
-
parser.on('--dry-run', TrueClass, 'Show the changes that would be applied, but do not execute them') do |v|
|
17
|
+
parser.on('--dry-run', TrueClass, 'Show the changes that would be applied, but do not execute them') do |v|
|
15
18
|
@dry_run = v
|
16
19
|
end
|
17
20
|
|
@@ -22,6 +25,10 @@ module Moonshot
|
|
22
25
|
parser.on('--refresh-parameters', TrueClass, 'Update parameters from parent stacks') do |v|
|
23
26
|
@refresh_parameters = v
|
24
27
|
end
|
28
|
+
|
29
|
+
parser.on('--template-file=FILE', 'Override the path to the CloudFormation template.') do |v|
|
30
|
+
Moonshot.config.template_file = v
|
31
|
+
end
|
25
32
|
end
|
26
33
|
|
27
34
|
def execute
|
data/lib/moonshot/controller.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moonshot
|
2
4
|
# The Controller coordinates and performs all Moonshot actions.
|
3
|
-
class Controller # rubocop:disable ClassLength
|
5
|
+
class Controller # rubocop:disable Metrics/ClassLength
|
4
6
|
attr_accessor :config
|
5
7
|
|
6
8
|
def initialize(config)
|
@@ -11,7 +13,8 @@ module Moonshot
|
|
11
13
|
Moonshot::StackLister.new(@config.app_name).list
|
12
14
|
end
|
13
15
|
|
14
|
-
def create # rubocop:disable AbcSize
|
16
|
+
def create # rubocop:disable Metrics/AbcSize
|
17
|
+
run_plugins(:setup_create)
|
15
18
|
# Scan the template for all required parameters and configure
|
16
19
|
# the ParameterCollection.
|
17
20
|
@config.parameters = ParameterCollection.from_template(stack.template)
|
@@ -34,7 +37,7 @@ module Moonshot
|
|
34
37
|
|
35
38
|
# Interview the user for missing parameters, using the
|
36
39
|
# appropriate prompts.
|
37
|
-
@config.parameters.
|
40
|
+
@config.parameters.hash.each_value do |sp|
|
38
41
|
next if sp.set?
|
39
42
|
|
40
43
|
parameter_source = @config.parameter_sources.fetch(sp.name,
|
@@ -50,12 +53,12 @@ module Moonshot
|
|
50
53
|
# Fail if any parameters are still missing without defaults.
|
51
54
|
missing_parameters = @config.parameters.missing_for_create
|
52
55
|
unless missing_parameters.empty?
|
53
|
-
raise "The following parameters were not provided: #{missing_parameters.map(&:name).join(', ')}"
|
56
|
+
raise "The following parameters were not provided: #{missing_parameters.map(&:name).join(', ')}"
|
54
57
|
end
|
55
58
|
|
56
59
|
run_hook(:deploy, :pre_create)
|
57
60
|
stack_ok = stack.create
|
58
|
-
if stack_ok # rubocop:disable GuardClause
|
61
|
+
if stack_ok # rubocop:disable Style/GuardClause
|
59
62
|
run_hook(:deploy, :post_create)
|
60
63
|
run_plugins(:post_create)
|
61
64
|
else
|
@@ -63,7 +66,8 @@ module Moonshot
|
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
66
|
-
def update(dry_run:, force:, refresh_parameters:) # rubocop:disable AbcSize
|
69
|
+
def update(dry_run:, force:, refresh_parameters:) # rubocop:disable Metrics/AbcSize
|
70
|
+
run_plugins(:setup_update)
|
67
71
|
# Scan the template for all required parameters and configure
|
68
72
|
# the ParameterCollection.
|
69
73
|
@config.parameters = ParameterCollection.from_template(stack.template)
|
@@ -106,16 +110,17 @@ module Moonshot
|
|
106
110
|
# Fail if any parameters are still missing without defaults.
|
107
111
|
missing_parameters = @config.parameters.missing_for_update
|
108
112
|
unless missing_parameters.empty?
|
109
|
-
raise "The following parameters were not provided: #{missing_parameters.map(&:name).join(', ')}"
|
113
|
+
raise "The following parameters were not provided: #{missing_parameters.map(&:name).join(', ')}"
|
110
114
|
end
|
111
115
|
|
112
116
|
run_hook(:deploy, :pre_update)
|
113
|
-
stack.update(dry_run
|
117
|
+
stack.update(dry_run:, force:)
|
114
118
|
run_hook(:deploy, :post_update)
|
115
119
|
run_plugins(:post_update)
|
116
120
|
end
|
117
121
|
|
118
122
|
def status
|
123
|
+
run_plugins(:setup_status)
|
119
124
|
run_plugins(:pre_status)
|
120
125
|
run_hook(:deploy, :status)
|
121
126
|
stack.status
|
@@ -129,6 +134,7 @@ module Moonshot
|
|
129
134
|
end
|
130
135
|
|
131
136
|
def build_version(version_name)
|
137
|
+
run_plugins(:setup_build)
|
132
138
|
run_plugins(:pre_build)
|
133
139
|
run_hook(:build, :pre_build, version_name)
|
134
140
|
run_hook(:build, :build, version_name)
|
@@ -138,12 +144,14 @@ module Moonshot
|
|
138
144
|
end
|
139
145
|
|
140
146
|
def deploy_version(version_name)
|
147
|
+
run_plugins(:setup_deploy)
|
141
148
|
run_plugins(:pre_deploy)
|
142
149
|
run_hook(:deploy, :deploy, @config.artifact_repository, version_name)
|
143
150
|
run_plugins(:post_deploy)
|
144
151
|
end
|
145
152
|
|
146
153
|
def delete
|
154
|
+
run_plugins(:setup_delete)
|
147
155
|
# Populate the current values of parameters, for use by plugins.
|
148
156
|
@config.parameters = ParameterCollection.from_template(stack.template)
|
149
157
|
stack.parameters.each do |key, value|
|
@@ -153,7 +161,7 @@ module Moonshot
|
|
153
161
|
run_plugins(:pre_delete)
|
154
162
|
run_hook(:deploy, :pre_delete)
|
155
163
|
stack_ok = stack.delete
|
156
|
-
if stack_ok # rubocop:disable GuardClause
|
164
|
+
if stack_ok # rubocop:disable Style/GuardClause
|
157
165
|
run_hook(:deploy, :post_delete)
|
158
166
|
run_plugins(:post_delete)
|
159
167
|
else
|
@@ -176,7 +184,8 @@ module Moonshot
|
|
176
184
|
def ssh
|
177
185
|
run_plugins(:pre_ssh)
|
178
186
|
@config.ssh_instance ||= SSHTargetSelector.new(
|
179
|
-
stack, asg_name: @config.ssh_auto_scaling_group_name
|
187
|
+
stack, asg_name: @config.ssh_auto_scaling_group_name
|
188
|
+
).choose!
|
180
189
|
cb = SSHCommandBuilder.new(@config.ssh_config, @config.ssh_instance)
|
181
190
|
result = cb.build(@config.ssh_command)
|
182
191
|
|
@@ -192,14 +201,14 @@ module Moonshot
|
|
192
201
|
|
193
202
|
def resources
|
194
203
|
@resources ||=
|
195
|
-
Resources.new(stack
|
204
|
+
Resources.new(stack:, ilog: @config.interactive_logger, controller: self)
|
196
205
|
end
|
197
206
|
|
198
207
|
def run_hook(type, name, *args)
|
199
208
|
mech = get_mechanism(type)
|
200
209
|
name = name.to_s << '_hook'
|
201
210
|
|
202
|
-
return unless mech
|
211
|
+
return unless mech.respond_to?(name)
|
203
212
|
|
204
213
|
mech.resources = resources
|
205
214
|
mech.send(name, *args)
|
@@ -209,7 +218,13 @@ module Moonshot
|
|
209
218
|
results = {}
|
210
219
|
@config.plugins.each do |plugin|
|
211
220
|
next unless plugin.respond_to?(type)
|
212
|
-
|
221
|
+
|
222
|
+
results[plugin] =
|
223
|
+
if type =~ /^setup_/
|
224
|
+
plugin.send(type)
|
225
|
+
else
|
226
|
+
plugin.send(type, resources)
|
227
|
+
end
|
213
228
|
end
|
214
229
|
|
215
230
|
results
|
@@ -1,32 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moonshot
|
2
4
|
# Holds configuration for Moonshot::Controller
|
3
5
|
class ControllerConfig
|
4
6
|
attr_reader :account_alias
|
5
7
|
|
6
|
-
attr_accessor :additional_tag
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
attr_accessor :deployment_mechanism
|
13
|
-
attr_accessor :dev_build_name_proc
|
14
|
-
attr_accessor :environment_name
|
15
|
-
attr_accessor :interactive
|
16
|
-
attr_accessor :interactive_logger
|
17
|
-
attr_accessor :parameter_overrides
|
18
|
-
attr_accessor :parameters
|
19
|
-
attr_accessor :parent_stacks
|
20
|
-
attr_accessor :default_parameter_source
|
21
|
-
attr_accessor :parameter_sources
|
22
|
-
attr_accessor :plugins
|
23
|
-
attr_accessor :project_root
|
24
|
-
attr_accessor :show_all_stack_events
|
25
|
-
attr_accessor :ssh_auto_scaling_group_name
|
26
|
-
attr_accessor :ssh_command
|
27
|
-
attr_accessor :ssh_config
|
28
|
-
attr_accessor :ssh_instance
|
29
|
-
attr_accessor :template_s3_bucket
|
8
|
+
attr_accessor :additional_tag, :answer_file, :app_name, :artifact_repository, :build_mechanism,
|
9
|
+
:changeset_wait_time, :deployment_mechanism, :dev_build_name_proc, :environment_name,
|
10
|
+
:interactive, :interactive_logger, :parameter_overrides, :parameters, :parent_stacks,
|
11
|
+
:default_parameter_source, :parameter_sources, :plugins, :project_root,
|
12
|
+
:show_all_stack_events, :ssh_auto_scaling_group_name, :ssh_command, :ssh_config,
|
13
|
+
:ssh_instance, :template_file, :template_s3_bucket, :extra_tags
|
30
14
|
|
31
15
|
def initialize
|
32
16
|
@default_parameter_source = AskUserSource.new
|
@@ -42,6 +26,7 @@ module Moonshot
|
|
42
26
|
@project_root = Dir.pwd
|
43
27
|
@show_all_stack_events = false
|
44
28
|
@ssh_config = SSHConfig.new
|
29
|
+
@extra_tags = []
|
45
30
|
|
46
31
|
@dev_build_name_proc = lambda do |c|
|
47
32
|
['dev', c.app_name, c.environment_name, Time.now.to_i].join('/')
|
@@ -60,9 +45,10 @@ module Moonshot
|
|
60
45
|
def update_for_account!
|
61
46
|
# Evaluated any account-specific configuration.
|
62
47
|
@account_alias = Moonshot::AccountContext.get
|
63
|
-
|
64
|
-
|
65
|
-
|
48
|
+
return unless @account_alias
|
49
|
+
return unless @per_account_config.key?(@account_alias)
|
50
|
+
|
51
|
+
@per_account_config[@account_alias].call(self)
|
66
52
|
end
|
67
53
|
end
|
68
54
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'colorize'
|
2
4
|
|
3
5
|
# This mechanism is used to deploy software to an auto-scaling group within
|
@@ -8,12 +10,12 @@ require 'colorize'
|
|
8
10
|
# self.artifact_repository = S3Bucket.new('foobucket')
|
9
11
|
# self.deployment_mechanism = CodeDeploy.new(asg: 'AutoScalingGroup')
|
10
12
|
# end
|
11
|
-
class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
13
|
+
class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable Metrics/ClassLength
|
12
14
|
include Moonshot::ResourcesHelper
|
13
15
|
include Moonshot::CredsHelper
|
14
16
|
include Moonshot::DoctorHelper
|
15
17
|
|
16
|
-
DEFAULT_ROLE_NAME = 'CodeDeployRole'
|
18
|
+
DEFAULT_ROLE_NAME = 'CodeDeployRole'
|
17
19
|
|
18
20
|
# @param asg [Array, String]
|
19
21
|
# The logical name of the AutoScalingGroup to create and manage a Deployment
|
@@ -37,12 +39,13 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
37
39
|
# CodeDeployDefault.OneAtATime.
|
38
40
|
# rubocop:disable Metrics/ParameterLists
|
39
41
|
def initialize(
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
asg: [],
|
43
|
+
optional_asg: [],
|
44
|
+
role: DEFAULT_ROLE_NAME,
|
45
|
+
app_name: nil,
|
46
|
+
group_name: nil,
|
47
|
+
config_name: 'CodeDeployDefault.OneAtATime'
|
48
|
+
)
|
46
49
|
@asg_logical_ids = Array(asg)
|
47
50
|
@optional_asg_logical_ids = Array(optional_asg)
|
48
51
|
@app_name = app_name
|
@@ -51,6 +54,7 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
51
54
|
@codedeploy_config = config_name
|
52
55
|
@ignore_app_stop_failures = false
|
53
56
|
end
|
57
|
+
# rubocop:enable Metrics/ParameterLists
|
54
58
|
|
55
59
|
def post_create_hook
|
56
60
|
create_application_if_needed
|
@@ -62,7 +66,7 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
62
66
|
def post_update_hook
|
63
67
|
post_create_hook
|
64
68
|
|
65
|
-
unless deployment_group_ok? # rubocop:disable GuardClause
|
69
|
+
unless deployment_group_ok? # rubocop:disable Style/GuardClause
|
66
70
|
delete_deployment_group
|
67
71
|
create_deployment_group_if_needed
|
68
72
|
end
|
@@ -101,7 +105,7 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
101
105
|
end
|
102
106
|
|
103
107
|
def deploy_cli_hook(parser)
|
104
|
-
parser.on('--ignore-app-stop-failures', TrueClass, 'Continue deployment on ApplicationStop failures') do |v|
|
108
|
+
parser.on('--ignore-app-stop-failures', TrueClass, 'Continue deployment on ApplicationStop failures') do |v|
|
105
109
|
puts "ignore = #{v}"
|
106
110
|
@ignore_app_stop_failures = v
|
107
111
|
end
|
@@ -178,27 +182,24 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
178
182
|
autoscaling_groups = []
|
179
183
|
@asg_logical_ids.each do |asg_logical_id|
|
180
184
|
asg_name = stack.physical_id_for(asg_logical_id)
|
181
|
-
unless asg_name
|
182
|
-
raise "Could not find #{asg_logical_id} resource in Stack."
|
183
|
-
end
|
185
|
+
raise "Could not find #{asg_logical_id} resource in Stack." unless asg_name
|
184
186
|
|
185
187
|
groups = as_client.describe_auto_scaling_groups(
|
186
|
-
auto_scaling_group_names: [asg_name]
|
187
|
-
|
188
|
-
|
189
|
-
|
188
|
+
auto_scaling_group_names: [asg_name]
|
189
|
+
)
|
190
|
+
|
191
|
+
raise "Could not find ASG #{asg_name}." if groups.auto_scaling_groups.empty?
|
190
192
|
|
191
193
|
autoscaling_groups.push(groups.auto_scaling_groups.first)
|
192
194
|
end
|
193
195
|
@optional_asg_logical_ids.each do |asg_logical_id|
|
194
196
|
asg_name = stack.physical_id_for(asg_logical_id)
|
195
197
|
next unless asg_name
|
198
|
+
|
196
199
|
groups = as_client.describe_auto_scaling_groups(
|
197
200
|
auto_scaling_group_names: [asg_name]
|
198
201
|
)
|
199
|
-
unless groups.auto_scaling_groups.empty?
|
200
|
-
autoscaling_groups.push(groups.auto_scaling_groups.first)
|
201
|
-
end
|
202
|
+
autoscaling_groups.push(groups.auto_scaling_groups.first) unless groups.auto_scaling_groups.empty?
|
202
203
|
end
|
203
204
|
autoscaling_groups
|
204
205
|
end
|
@@ -220,13 +221,16 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
220
221
|
|
221
222
|
def deployment_group
|
222
223
|
cd_client.get_deployment_group(
|
223
|
-
application_name: app_name,
|
224
|
-
|
224
|
+
application_name: app_name,
|
225
|
+
deployment_group_name: group_name
|
226
|
+
).deployment_group_info
|
225
227
|
end
|
226
228
|
|
227
229
|
def deployment_group_exists?
|
228
230
|
cd_client.get_deployment_group(
|
229
|
-
application_name: app_name,
|
231
|
+
application_name: app_name,
|
232
|
+
deployment_group_name: group_name
|
233
|
+
)
|
230
234
|
true
|
231
235
|
rescue Aws::CodeDeploy::Errors::ApplicationDoesNotExistException,
|
232
236
|
Aws::CodeDeploy::Errors::DeploymentGroupDoesNotExistException
|
@@ -235,13 +239,13 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
235
239
|
|
236
240
|
def deployment_group_ok?
|
237
241
|
return false unless deployment_group_exists?
|
242
|
+
|
238
243
|
asgs = deployment_group.auto_scaling_groups
|
239
244
|
return false unless asgs
|
240
245
|
return false unless asgs.count == auto_scaling_groups.count
|
246
|
+
|
241
247
|
asgs.each do |asg|
|
242
|
-
if (auto_scaling_groups.find_index { |a| a.auto_scaling_group_name == asg.name }).nil?
|
243
|
-
return false
|
244
|
-
end
|
248
|
+
return false if (auto_scaling_groups.find_index { |a| a.auto_scaling_group_name == asg.name }).nil?
|
245
249
|
end
|
246
250
|
true
|
247
251
|
end
|
@@ -284,7 +288,8 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
284
288
|
ilog.start "Deleting #{pretty_deploy_group}." do |s|
|
285
289
|
cd_client.delete_deployment_group(
|
286
290
|
application_name: app_name,
|
287
|
-
deployment_group_name: group_name
|
291
|
+
deployment_group_name: group_name
|
292
|
+
)
|
288
293
|
s.success
|
289
294
|
end
|
290
295
|
end
|
@@ -294,7 +299,8 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
294
299
|
application_name: app_name,
|
295
300
|
deployment_group_name: group_name,
|
296
301
|
service_role_arn: role.arn,
|
297
|
-
auto_scaling_groups: asg_names
|
302
|
+
auto_scaling_groups: asg_names
|
303
|
+
)
|
298
304
|
end
|
299
305
|
|
300
306
|
def wait_for_asg_capacity
|
@@ -306,10 +312,11 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
306
312
|
count = asg.instances.count { |i| i.lifecycle_state == 'InService' }
|
307
313
|
if asg.desired_capacity == count
|
308
314
|
asgs_at_capacity += 1
|
309
|
-
s.continue "#{asg.auto_scaling_group_name} DesiredCapacity is #{asg.desired_capacity}, currently #{count} instance(s) are InService." # rubocop:disable LineLength
|
315
|
+
s.continue "#{asg.auto_scaling_group_name} DesiredCapacity is #{asg.desired_capacity}, currently #{count} instance(s) are InService." # rubocop:disable Layout/LineLength
|
310
316
|
end
|
311
317
|
end
|
312
318
|
break if asgs.count == asgs_at_capacity
|
319
|
+
|
313
320
|
sleep 5
|
314
321
|
end
|
315
322
|
|
@@ -327,7 +334,7 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
327
334
|
|
328
335
|
case status
|
329
336
|
when 'Created', 'Queued', 'InProgress'
|
330
|
-
step.continue "Waiting for Deployment #{id.blue} to complete, current status is '#{status}'."
|
337
|
+
step.continue "Waiting for Deployment #{id.blue} to complete, current status is '#{status}'."
|
331
338
|
when 'Succeeded'
|
332
339
|
step.success "Deployment #{id.blue} completed successfully!"
|
333
340
|
break
|
@@ -342,10 +349,10 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
342
349
|
end
|
343
350
|
|
344
351
|
def handle_deployment_failure(deployment_id)
|
345
|
-
instances = cd_client.list_deployment_instances(deployment_id:
|
352
|
+
instances = cd_client.list_deployment_instances(deployment_id:)
|
346
353
|
.instances_list.map do |instance_id|
|
347
|
-
cd_client.get_deployment_instance(deployment_id
|
348
|
-
instance_id:
|
354
|
+
cd_client.get_deployment_instance(deployment_id:,
|
355
|
+
instance_id:)
|
349
356
|
end
|
350
357
|
|
351
358
|
instances.map(&:instance_summary).each do |inst_summary|
|
@@ -373,7 +380,7 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
373
380
|
when Moonshot::ArtifactRepository::S3Bucket
|
374
381
|
s3_revision_for(artifact_repo, version_name)
|
375
382
|
when NilClass
|
376
|
-
raise 'Must specify an ArtifactRepository with CodeDeploy. Take a look at the S3Bucket example.'
|
383
|
+
raise 'Must specify an ArtifactRepository with CodeDeploy. Take a look at the S3Bucket example.'
|
377
384
|
else
|
378
385
|
raise "Cannot use #{artifact_repo.class} to deploy with CodeDeploy."
|
379
386
|
end
|
@@ -404,7 +411,7 @@ class Moonshot::DeploymentMechanism::CodeDeploy # rubocop:disable ClassLength
|
|
404
411
|
def doctor_check_code_deploy_role
|
405
412
|
role
|
406
413
|
success("#{@codedeploy_role} exists.")
|
407
|
-
rescue => e
|
414
|
+
rescue StandardError => e
|
408
415
|
help = <<-EOF
|
409
416
|
Error: #{e.message}
|
410
417
|
|
@@ -417,9 +424,9 @@ http://docs.aws.amazon.com/codedeploy/latest/userguide/how-to-create-service-rol
|
|
417
424
|
def doctor_check_auto_scaling_resource_defined
|
418
425
|
@asg_logical_ids.each do |asg_logical_id|
|
419
426
|
if stack.template.resource_names.include?(asg_logical_id)
|
420
|
-
success("Resource '#{asg_logical_id}' exists in the CloudFormation template.")
|
427
|
+
success("Resource '#{asg_logical_id}' exists in the CloudFormation template.")
|
421
428
|
else
|
422
|
-
critical("Resource '#{asg_logical_id}' does not exist in the CloudFormation template!")
|
429
|
+
critical("Resource '#{asg_logical_id}' does not exist in the CloudFormation template!")
|
423
430
|
end
|
424
431
|
end
|
425
432
|
end
|