Class: Lono::Cfn::Base
Instance Method Summary
collapse
Methods included from Util
#are_you_sure?
Methods included from AwsService
#cfn, #stack_exists?, #testing_update?
Constructor Details
#initialize(stack_name, options = {}) ⇒ Base
Returns a new instance of Base.
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# File 'lib/lono/cfn/base.rb', line 7
def initialize(stack_name, options={})
@options = options stack_name = switch_current(stack_name)
@stack_name = append_suffix(stack_name)
Lono::ProjectChecker.check unless options[:lono]
@template_name = options[:template] || remove_suffix(@stack_name)
@param_name = options[:param] || @template_name
@template_path = get_source_path(@template_name, :template)
@param_path = get_source_path(@param_name, :param)
puts "Using template: #{@template_path}" unless @options[:mute_using]
puts "Using parameters: #{@param_path}" unless @options[:mute_using]
end
|
Instance Method Details
#append_suffix(stack_name) ⇒ Object
Appends a short suffix at the end of a stack name. Lono internally strips this same suffix for the template name. Makes it convenient for the development flow.
lono cfn current --suffix 1
lono cfn create demo => demo-1
lono cfn update demo-1
Instead of typing:
lono cfn create demo-1 --template demo
lono cfn update demo-1 --template demo
The suffix can be specified at the CLI but can also be saved as a preference.
A random suffix can be specified with random. Example:
lono cfn current --suffix random
lono cfn create demo => demo-[RANDOM], example: demo-abc
lono cfn update demo-abc
It is not a default setting because it might confuse new lono users.
221
222
223
224
|
# File 'lib/lono/cfn/base.rb', line 221
def append_suffix(stack_name)
suffix = Lono.suffix == 'random' ? random_suffix : Lono.suffix
[stack_name, suffix].compact.join('-')
end
|
#build_scripts ⇒ Object
84
85
86
|
# File 'lib/lono/cfn/base.rb', line 84
def build_scripts
Lono::Script::Build.new.run
end
|
#capabilities ⇒ Object
255
256
257
258
259
260
|
# File 'lib/lono/cfn/base.rb', line 255
def capabilities
return @options[:capabilities] if @options[:capabilities]
if @options[:iam]
["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"]
end
end
|
#check_files ⇒ Object
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
# File 'lib/lono/cfn/base.rb', line 131
def check_files
errors, warns = [], []
unless File.exist?(@template_path)
errors << "Template file missing: could not find #{@template_path}"
end
output_param_path = @param_path.sub(/\.txt/, '.json')
output_param_path = "#{Lono.config.output_path}/#{output_param_path}"
if @options[:param] && !File.exist?(output_param_path)
warns << "Parameters file missing: could not find #{output_param_path}"
end
[errors, warns]
end
|
#check_for_errors ⇒ Object
118
119
120
121
122
123
124
125
126
127
128
129
|
# File 'lib/lono/cfn/base.rb', line 118
def check_for_errors
errors, warns = check_files
unless errors.empty?
puts "Please double check the command you ran. There were some errors."
puts "ERROR: #{errors.join("\n")}".colorize(:red)
exit
end
unless warns.empty?
puts "Please double check the command you ran. There were some warnings."
puts "WARN: #{warns.join("\n")}".colorize(:yellow)
end
end
|
#command_with_iam(capabilities) ⇒ Object
65
66
67
|
# File 'lib/lono/cfn/base.rb', line 65
def command_with_iam(capabilities)
"#{File.basename($0)} #{ARGV.join(' ')} --capabilities #{capabilities}"
end
|
#convention_path(name, type) ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
|
# File 'lib/lono/cfn/base.rb', line 161
def convention_path(name, type)
path = case type
when :template
"#{Lono.config.output_path}/templates/#{name}.yml"
when :param
"#{Lono.config.params_path}/#{Lono.env}/#{name}.txt"
else
raise "hell: dont come here"
end
path.sub(/^\.\//, '')
end
|
#exit_unless_updatable!(status) ⇒ Object
183
184
185
186
187
188
189
190
191
|
# File 'lib/lono/cfn/base.rb', line 183
def exit_unless_updatable!(status)
return true if testing_update?
return false if @options[:noop]
unless status =~ /_COMPLETE$/
puts "Cannot create a change set for the stack because the #{@stack_name} is not in an updatable state. Stack status: #{status}".colorize(:red)
quit(1)
end
end
|
#generate_all ⇒ Object
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/lono/cfn/base.rb', line 69
def generate_all
if @options[:lono]
build_scripts
generate_templates
unless @options[:noop]
upload_scripts
upload_files
upload_templates
end
end
params = generate_params(mute: @options[:mute_params])
check_for_errors
params
end
|
#generate_params(options = {}) ⇒ Object
108
109
110
111
112
113
114
115
116
|
# File 'lib/lono/cfn/base.rb', line 108
def generate_params(options={})
generator_options = {
path: @param_path,
allow_no_file: true
}.merge(options)
generator = Lono::Param::Generator.new(@param_name, generator_options)
generator.generate generator.params end
|
#generate_templates ⇒ Object
#get_source_path(path, type) ⇒ Object
if existing in params path then use that if it doesnt assume it is a full path and check that else fall back to convention, which also eventually gets checked in check_for_errors
Type - :param or :template
152
153
154
155
156
157
158
159
|
# File 'lib/lono/cfn/base.rb', line 152
def get_source_path(path, type)
if path.nil?
convention_path(@stack_name, type) else
convention_path(path, type)
end
end
|
#prompt_for_iam(capabilities) ⇒ Object
57
58
59
60
61
62
63
|
# File 'lib/lono/cfn/base.rb', line 57
def prompt_for_iam(capabilities)
puts "This stack will create IAM resources. Please approve to run the command again with #{capabilities} capabilities."
puts " #{command_with_iam(capabilities)}"
puts "Please confirm (y/n)"
$stdin.gets
end
|
#quit(signal) ⇒ Object
To allow mocking in specs
194
195
196
|
# File 'lib/lono/cfn/base.rb', line 194
def quit(signal)
exit signal
end
|
#random_suffix ⇒ Object
only generate random suffix for Lono::Cfn::Create class
240
241
242
243
|
# File 'lib/lono/cfn/base.rb', line 240
def random_suffix
return nil unless self.class.name.to_s =~ /Create/
(0...3).map { (65 + rand(26)).chr }.join.downcase end
|
#remove_suffix(stack_name) ⇒ Object
226
227
228
229
230
231
232
233
234
235
236
237
|
# File 'lib/lono/cfn/base.rb', line 226
def remove_suffix(stack_name)
return stack_name unless Lono.suffix
if stack_name_suffix == 'random'
stack_name.sub(/-(\w{3})$/,'') elsif stack_name_suffix
pattern = Regexp.new("-#{stack_name_suffix}$",'')
stack_name.sub(pattern, '') else
stack_name
end
end
|
#run ⇒ Object
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
# File 'lib/lono/cfn/base.rb', line 31
def run
starting_message
params = generate_all
begin
save_stack(params) rescue Aws::CloudFormation::Errors::InsufficientCapabilitiesException => e
capabilities = e.message.match(/\[(.*)\]/)[1]
confirm = prompt_for_iam(capabilities)
if confirm =~ /^y/
@options.merge!(capabilities: [capabilities])
puts "Re-running: #{command_with_iam(capabilities).colorize(:green)}"
retry
else
puts "Exited"
exit 1
end
end
return unless @options[:wait]
status.wait
end
|
#s3_folder ⇒ Object
270
271
272
273
|
# File 'lib/lono/cfn/base.rb', line 270
def s3_folder
setting = Lono::Setting.new
setting.s3_folder
end
|
#set_template_body!(params) ⇒ Object
284
285
286
287
288
289
290
291
292
293
294
295
|
# File 'lib/lono/cfn/base.rb', line 284
def set_template_body!(params)
if s3_folder upload = Lono::Template::Upload.new
url = upload.s3_presigned_url(@template_path)
params[:template_url] = url
else
params[:template_body] = IO.read(@template_path)
end
params
end
|
#show_parameters(params, meth = nil) ⇒ Object
262
263
264
265
266
267
268
|
# File 'lib/lono/cfn/base.rb', line 262
def show_parameters(params, meth=nil)
params = params.clone.compact
params[:template_body] = "Hidden due to size... View at: #{@template_path}"
to = meth || "AWS API"
puts "Parameters passed to #{to}:"
puts YAML.dump(params.deep_stringify_keys)
end
|
#stack_name_suffix ⇒ Object
245
246
247
248
249
250
251
252
253
|
# File 'lib/lono/cfn/base.rb', line 245
def stack_name_suffix
if @options[:suffix] && !@options[:suffix].nil?
return @options[:suffix] end
settings = Lono::Setting.new
settings.data['stack_name_suffix']
end
|
#stack_status(stack_name) ⇒ Object
175
176
177
178
179
180
181
|
# File 'lib/lono/cfn/base.rb', line 175
def stack_status(stack_name)
return true if testing_update?
return false if @options[:noop]
resp = cfn.describe_stacks(stack_name: stack_name)
resp.stacks[0].stack_status
end
|
#starting_message ⇒ Object
25
26
27
28
29
|
# File 'lib/lono/cfn/base.rb', line 25
def starting_message
action = self.class.to_s.split('::').last
action = action[0..-2] + 'ing' puts "#{action} #{@stack_name.colorize(:green)} stack..."
end
|
#status ⇒ Object
53
54
55
|
# File 'lib/lono/cfn/base.rb', line 53
def status
@status ||= Lono::Cfn::Status.new(@stack_name)
end
|
#switch_current(stack_name) ⇒ Object
21
22
23
|
# File 'lib/lono/cfn/base.rb', line 21
def switch_current(stack_name)
Lono::Cfn::Current.name!(stack_name)
end
|
#upload_scripts ⇒ Object
only upload templates if s3_folder configured in settings
98
99
100
101
|
# File 'lib/lono/cfn/base.rb', line 98
def upload_scripts
return unless s3_folder
Lono::Script::Upload.new.run
end
|
#upload_templates ⇒ Object
only upload templates if s3_folder configured in settings