mux_tf 0.15.0 → 0.17.0
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 +4 -4
- data/lib/mux_tf/cli/current/plan_command.rb +131 -0
- data/lib/mux_tf/cli/current.rb +172 -206
- data/lib/mux_tf/cli/mux.rb +168 -5
- data/lib/mux_tf/cli/plan_summary.rb +12 -21
- data/lib/mux_tf/error_handling_methods.rb +79 -0
- data/lib/mux_tf/formatter_common.rb +257 -0
- data/lib/mux_tf/handlers/plan_handler.rb +8 -0
- data/lib/mux_tf/handlers.rb +6 -0
- data/lib/mux_tf/init_formatter.rb +306 -0
- data/lib/mux_tf/plan_formatter.rb +285 -602
- data/lib/mux_tf/plan_summary_handler.rb +52 -31
- data/lib/mux_tf/plan_utils.rb +215 -56
- data/lib/mux_tf/resource_tokenizer.rb +1 -1
- data/lib/mux_tf/stderr_line_handler.rb +145 -0
- data/lib/mux_tf/terraform_helpers.rb +46 -7
- data/lib/mux_tf/tmux.rb +55 -6
- data/lib/mux_tf/version.rb +1 -1
- data/lib/mux_tf/yaml_cache.rb +51 -34
- data/lib/mux_tf.rb +6 -12
- data/mux_tf.gemspec +12 -1
- metadata +110 -9
data/lib/mux_tf/cli/current.rb
CHANGED
@@ -11,10 +11,64 @@ module MuxTf
|
|
11
11
|
extend PiotrbCliUtils::CmdLoop
|
12
12
|
include Coloring
|
13
13
|
|
14
|
-
class << self
|
14
|
+
class << self
|
15
|
+
attr_accessor :plan_command
|
16
|
+
|
17
|
+
def detect_tool_type(tool_cmd: nil)
|
18
|
+
tool_cmd ||= ENV.fetch("MUX_TF_BASE_CMD", "terraform")
|
19
|
+
output = `#{tool_cmd} --version`
|
20
|
+
case output
|
21
|
+
when /^Terraform v(.+)$/
|
22
|
+
{
|
23
|
+
tool_name: "terraform",
|
24
|
+
tool_version: ::Regexp.last_match(1)
|
25
|
+
}
|
26
|
+
when /^OpenTofu v(.+)$/
|
27
|
+
{
|
28
|
+
tool_name: "opentofu",
|
29
|
+
tool_version: ::Regexp.last_match(1)
|
30
|
+
}
|
31
|
+
when /^terragrunt version v(.+)$/
|
32
|
+
result = {
|
33
|
+
tool_wrapper: "terragrunt",
|
34
|
+
tool_wrapper_version: ::Regexp.last_match(1)
|
35
|
+
}
|
36
|
+
tg_tool = ENV.fetch("TG_TF_PATH", "tofu")
|
37
|
+
result.merge! detect_tool_type(tool_cmd: tg_tool)
|
38
|
+
result
|
39
|
+
else
|
40
|
+
raise "can't parse tool version from: #{output.inspect}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def init_tool_env
|
45
|
+
info = detect_tool_type
|
46
|
+
|
47
|
+
if %w[terraform opentofu].include?(info[:tool_name])
|
48
|
+
ENV["TF_IN_AUTOMATION"] = "1"
|
49
|
+
ENV["TF_INPUT"] = "0"
|
50
|
+
end
|
51
|
+
|
52
|
+
return unless info[:tool_wrapper] == "terragrunt"
|
53
|
+
|
54
|
+
if Gem::Version.new(info[:tool_wrapper_version]) >= Gem::Version.new("0.70.0")
|
55
|
+
# new syntax
|
56
|
+
ENV["TG_LOG_FORMAT"] = "json"
|
57
|
+
ENV["TG_TF_FORWARD_STDOUT"] = "true"
|
58
|
+
else
|
59
|
+
# old syntax
|
60
|
+
ENV["TERRAGRUNT_JSON_LOG"] = "1"
|
61
|
+
ENV["TERRAGRUNT_FORWARD_TF_STDOUT"] = "1"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
15
65
|
def run(args)
|
16
66
|
version_check
|
17
67
|
|
68
|
+
self.plan_command = PlanCommand.new
|
69
|
+
|
70
|
+
init_tool_env
|
71
|
+
|
18
72
|
if args[0] == "cli"
|
19
73
|
cmd_loop
|
20
74
|
return
|
@@ -27,6 +81,7 @@ module MuxTf
|
|
27
81
|
if args[0] && valid_commands.include?(args[0])
|
28
82
|
stop_reason = catch(:stop) {
|
29
83
|
root_cmd.run(args, {}, hard_exit: true)
|
84
|
+
nil
|
30
85
|
}
|
31
86
|
log pastel.red("Stopped: #{stop_reason}") if stop_reason
|
32
87
|
return
|
@@ -36,17 +91,14 @@ module MuxTf
|
|
36
91
|
folder_name = File.basename(Dir.getwd)
|
37
92
|
log "Processing #{pastel.cyan(folder_name)} ..."
|
38
93
|
|
39
|
-
|
40
|
-
ENV["TF_INPUT"] = "0"
|
41
|
-
|
42
|
-
return launch_cmd_loop(:error) unless run_validate
|
94
|
+
return launch_cmd_loop(:error) unless @plan_command.run_validate
|
43
95
|
|
44
96
|
if ENV["TF_UPGRADE"]
|
45
97
|
upgrade_status, _upgrade_meta = run_upgrade
|
46
98
|
return launch_cmd_loop(:error) unless upgrade_status == :ok
|
47
99
|
end
|
48
100
|
|
49
|
-
plan_status = run_plan
|
101
|
+
plan_status = @plan_command.run_plan
|
50
102
|
|
51
103
|
case plan_status
|
52
104
|
when :ok
|
@@ -60,23 +112,6 @@ module MuxTf
|
|
60
112
|
end
|
61
113
|
end
|
62
114
|
|
63
|
-
def plan_filename
|
64
|
-
PlanFilenameGenerator.for_path
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def version_check
|
70
|
-
return unless VersionCheck.has_updates?
|
71
|
-
|
72
|
-
log pastel.yellow("=" * 80)
|
73
|
-
log "New version of #{pastel.cyan('mux_tf')} is available!"
|
74
|
-
log "You are currently on version: #{pastel.yellow(VersionCheck.current_gem_version)}"
|
75
|
-
log "Latest version found is: #{pastel.green(VersionCheck.latest_gem_version)}"
|
76
|
-
log "Run `#{pastel.green('gem install mux_tf')}` to update!"
|
77
|
-
log pastel.yellow("=" * 80)
|
78
|
-
end
|
79
|
-
|
80
115
|
# block is expected to return a touple, the first element is a list of remedies
|
81
116
|
# the rest are any additional results
|
82
117
|
def remedy_retry_helper(from:, level: 1, attempt: 0, &block)
|
@@ -86,24 +121,65 @@ module MuxTf
|
|
86
121
|
remedies, *results = block.call
|
87
122
|
return results if remedies.empty?
|
88
123
|
|
89
|
-
remedy_status,
|
124
|
+
remedy_status, remedy_results = process_remedies(remedies, from: from, level: level)
|
125
|
+
throw :abort, false if remedy_results[:user_error]
|
90
126
|
return remedy_status if remedy_status
|
91
127
|
end
|
92
128
|
log "!! giving up because attempt: #{attempt}"
|
93
129
|
end
|
94
130
|
end
|
95
131
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
132
|
+
def print_errors_and_warnings(meta)
|
133
|
+
message = []
|
134
|
+
message << pastel.yellow("#{meta[:warnings].length} Warnings") if meta[:warnings]
|
135
|
+
message << pastel.red("#{meta[:errors].length} Errors") if meta[:errors]
|
136
|
+
if message.length.positive?
|
137
|
+
log ""
|
138
|
+
log "Encountered: #{message.join(' and ')}"
|
139
|
+
log ""
|
140
|
+
end
|
141
|
+
|
142
|
+
meta[:warnings]&.each do |warning|
|
143
|
+
next if warning[:printed]
|
144
|
+
|
145
|
+
log "-" * 20
|
146
|
+
log pastel.yellow("Warning: #{warning[:message]}")
|
147
|
+
warning[:body]&.each do |line|
|
148
|
+
log pastel.yellow(line), depth: 1
|
149
|
+
end
|
150
|
+
log ""
|
103
151
|
end
|
152
|
+
|
153
|
+
meta[:errors]&.each do |error|
|
154
|
+
next if error[:printed]
|
155
|
+
|
156
|
+
log "-" * 20
|
157
|
+
log pastel.red("Error: #{error[:message]}")
|
158
|
+
error[:body]&.each do |line|
|
159
|
+
log pastel.red(line), depth: 1
|
160
|
+
end
|
161
|
+
log ""
|
162
|
+
end
|
163
|
+
|
164
|
+
return unless message.length.positive?
|
165
|
+
|
166
|
+
log ""
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
|
171
|
+
def version_check
|
172
|
+
return unless VersionCheck.has_updates?
|
173
|
+
|
174
|
+
log pastel.yellow("=" * 80)
|
175
|
+
log "New version of #{pastel.cyan('mux_tf')} is available!"
|
176
|
+
log "You are currently on version: #{pastel.yellow(VersionCheck.current_gem_version)}"
|
177
|
+
log "Latest version found is: #{pastel.green(VersionCheck.latest_gem_version)}"
|
178
|
+
log "Run `#{pastel.green('gem install mux_tf')}` to update!"
|
179
|
+
log pastel.yellow("=" * 80)
|
104
180
|
end
|
105
181
|
|
106
|
-
def process_remedies(remedies, from: nil, level: 1, retry_count: 0)
|
182
|
+
def process_remedies(remedies, from: nil, level: 1, retry_count: 0)
|
107
183
|
remedies = remedies.dup
|
108
184
|
remedy = nil
|
109
185
|
wrap_log = lambda do |msg, color: nil|
|
@@ -123,12 +199,21 @@ module MuxTf
|
|
123
199
|
log wrap_log["unprocessed remedies: #{remedies.to_a}", color: :red], depth: 1
|
124
200
|
return [false, results]
|
125
201
|
end
|
202
|
+
if remedies.delete? :user_error
|
203
|
+
remedy = :user_error
|
204
|
+
log wrap_log["user error encountered!", color: :red]
|
205
|
+
log wrap_log["-" * 40, color: :red]
|
206
|
+
log wrap_log["!! User Error, Please fix the issue and try again", color: :red]
|
207
|
+
log wrap_log["-" * 40, color: :red]
|
208
|
+
results[:user_error] = true
|
209
|
+
return [false, results]
|
210
|
+
end
|
126
211
|
if remedies.delete? :init
|
127
212
|
remedy = :init
|
128
213
|
log wrap_log["Running terraform init ..."], depth: 2
|
129
|
-
exit_code, meta =
|
214
|
+
exit_code, meta = InitFormatter.run_tf_init
|
130
215
|
print_errors_and_warnings(meta)
|
131
|
-
remedies =
|
216
|
+
remedies = InitFormatter.init_status_to_remedies(exit_code, meta)
|
132
217
|
status, r_results = process_remedies(remedies, from: from, level: level + 1)
|
133
218
|
results.merge!(r_results)
|
134
219
|
return [true, r_results] if status
|
@@ -136,7 +221,7 @@ module MuxTf
|
|
136
221
|
if remedies.delete?(:plan)
|
137
222
|
remedy = :plan
|
138
223
|
log wrap_log["Running terraform plan ..."], depth: 2
|
139
|
-
plan_status = run_plan(retry_count: retry_count)
|
224
|
+
plan_status = @plan_command.run_plan(retry_count: retry_count)
|
140
225
|
results[:plan_status] = plan_status
|
141
226
|
return [false, results] unless [:ok, :changes].include?(plan_status)
|
142
227
|
end
|
@@ -144,9 +229,9 @@ module MuxTf
|
|
144
229
|
remedy = :reconfigure
|
145
230
|
log wrap_log["Running terraform init ..."], depth: 2
|
146
231
|
result = remedy_retry_helper(from: :reconfigure, level: level + 1, attempt: retry_count) {
|
147
|
-
exit_code, meta =
|
232
|
+
exit_code, meta = InitFormatter.run_tf_init(reconfigure: true)
|
148
233
|
print_errors_and_warnings(meta)
|
149
|
-
remedies =
|
234
|
+
remedies = InitFormatter.init_status_to_remedies(exit_code, meta)
|
150
235
|
[remedies, exit_code, meta]
|
151
236
|
}
|
152
237
|
unless result
|
@@ -154,14 +239,6 @@ module MuxTf
|
|
154
239
|
return [false, result]
|
155
240
|
end
|
156
241
|
end
|
157
|
-
if remedies.delete? :user_error
|
158
|
-
remedy = :user_error
|
159
|
-
log wrap_log["user error encountered!", color: :red]
|
160
|
-
log wrap_log["-" * 40, color: :red]
|
161
|
-
log wrap_log["!! User Error, Please fix the issue and try again", color: :red]
|
162
|
-
log wrap_log["-" * 40, color: :red]
|
163
|
-
return [false, results]
|
164
|
-
end
|
165
242
|
if remedies.delete? :auth
|
166
243
|
remedy = :auth
|
167
244
|
log wrap_log["auth error encountered!", color: :red]
|
@@ -182,27 +259,6 @@ module MuxTf
|
|
182
259
|
[true, results]
|
183
260
|
end
|
184
261
|
|
185
|
-
def validate
|
186
|
-
log "Validating module ...", depth: 1
|
187
|
-
tf_validate.parsed_output
|
188
|
-
end
|
189
|
-
|
190
|
-
def create_plan(filename, targets: [])
|
191
|
-
log "Preparing Plan ...", depth: 1
|
192
|
-
exit_code, meta = PlanFormatter.pretty_plan(filename, targets: targets)
|
193
|
-
case exit_code
|
194
|
-
when 0
|
195
|
-
[:ok, meta]
|
196
|
-
when 1
|
197
|
-
[:error, meta]
|
198
|
-
when 2
|
199
|
-
[:changes, meta]
|
200
|
-
else
|
201
|
-
log pastel.yellow("terraform plan exited with an unknown exit code: #{exit_code}")
|
202
|
-
[:unknown, meta]
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
262
|
def launch_cmd_loop(status)
|
207
263
|
return if ENV["NO_CMD"]
|
208
264
|
|
@@ -215,13 +271,26 @@ module MuxTf
|
|
215
271
|
cmd_loop(status)
|
216
272
|
end
|
217
273
|
|
218
|
-
def cmd_loop(
|
274
|
+
def cmd_loop(initial_status = nil)
|
219
275
|
root_cmd = build_root_cmd
|
220
276
|
|
221
277
|
folder_name = File.basename(Dir.getwd)
|
222
278
|
|
223
279
|
puts root_cmd.help
|
224
280
|
|
281
|
+
status = initial_status
|
282
|
+
|
283
|
+
prompt = proc { format_prompt(folder_name, status) }
|
284
|
+
|
285
|
+
run_cmd_loop(prompt) do |cmd|
|
286
|
+
status = nil
|
287
|
+
throw(:stop, :no_input) if cmd == ""
|
288
|
+
args = Shellwords.split(cmd)
|
289
|
+
root_cmd.run(args, {}, hard_exit: false)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
def format_prompt(folder_name, status)
|
225
294
|
prompt = "#{folder_name} => "
|
226
295
|
case status
|
227
296
|
when :error, :unknown
|
@@ -229,18 +298,13 @@ module MuxTf
|
|
229
298
|
when :changes
|
230
299
|
prompt = "[#{pastel.yellow(status.to_s)}] #{prompt}"
|
231
300
|
end
|
232
|
-
|
233
|
-
run_cmd_loop(prompt) do |cmd|
|
234
|
-
throw(:stop, :no_input) if cmd == ""
|
235
|
-
args = Shellwords.split(cmd)
|
236
|
-
root_cmd.run(args, {}, hard_exit: false)
|
237
|
-
end
|
301
|
+
prompt
|
238
302
|
end
|
239
303
|
|
240
304
|
def build_root_cmd
|
241
305
|
root_cmd = define_cmd(nil)
|
242
306
|
|
243
|
-
root_cmd.add_command(plan_cmd)
|
307
|
+
root_cmd.add_command(@plan_command.plan_cmd)
|
244
308
|
root_cmd.add_command(apply_cmd)
|
245
309
|
root_cmd.add_command(shell_cmd)
|
246
310
|
root_cmd.add_command(force_unlock_cmd)
|
@@ -248,41 +312,35 @@ module MuxTf
|
|
248
312
|
root_cmd.add_command(reconfigure_cmd)
|
249
313
|
root_cmd.add_command(interactive_cmd)
|
250
314
|
root_cmd.add_command(plan_details_cmd)
|
315
|
+
root_cmd.add_command(init_cmd)
|
251
316
|
|
252
317
|
root_cmd.add_command(exit_cmd)
|
253
318
|
root_cmd.add_command(define_cmd("help", summary: "Show help for commands") { |_opts, _args, cmd| puts cmd.supercommand.help })
|
254
319
|
root_cmd
|
255
320
|
end
|
256
321
|
|
257
|
-
def plan_summary_text
|
258
|
-
plan_filename = PlanFilenameGenerator.for_path
|
259
|
-
if File.exist?("#{plan_filename}.txt") && File.mtime("#{plan_filename}.txt").to_f >= File.mtime(plan_filename).to_f
|
260
|
-
File.read("#{plan_filename}.txt")
|
261
|
-
else
|
262
|
-
puts "Inspecting Changes ... #{plan_filename}"
|
263
|
-
data = PlanUtils.text_version_of_plan_show(plan_filename)
|
264
|
-
File.write("#{plan_filename}.txt", data)
|
265
|
-
data
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
322
|
def plan_details_cmd
|
270
323
|
define_cmd("details", summary: "Show Plan Details") do |_opts, _args, _cmd|
|
271
|
-
|
272
|
-
|
273
|
-
end
|
324
|
+
plan_filename = PlanFilenameGenerator.for_path
|
325
|
+
plan = PlanSummaryHandler.from_file(plan_filename)
|
274
326
|
|
275
|
-
|
276
|
-
|
277
|
-
|
327
|
+
log plan.plan_text_output
|
328
|
+
|
329
|
+
log ""
|
330
|
+
|
331
|
+
log "Resource Summary:"
|
332
|
+
plan.simple_summary do |line|
|
333
|
+
log line
|
334
|
+
end
|
278
335
|
end
|
279
336
|
end
|
280
337
|
|
281
338
|
def apply_cmd
|
282
339
|
define_cmd("apply", summary: "Apply the current plan") do |_opts, _args, _cmd|
|
340
|
+
plan_filename = PlanFilenameGenerator.for_path
|
283
341
|
status = tf_apply(filename: plan_filename)
|
284
342
|
if status.success?
|
285
|
-
plan_status = run_plan
|
343
|
+
plan_status = @plan_command.run_plan
|
286
344
|
throw :stop, :done if plan_status == :ok
|
287
345
|
else
|
288
346
|
log "Apply Failed!"
|
@@ -302,7 +360,7 @@ module MuxTf
|
|
302
360
|
define_cmd("force-unlock", summary: "Force unlock state after encountering a lock error!") do # rubocop:disable Metrics/BlockLength
|
303
361
|
prompt = TTY::Prompt.new(interrupt: :noop)
|
304
362
|
|
305
|
-
lock_info = @last_lock_info
|
363
|
+
lock_info = @plan_command.last_lock_info
|
306
364
|
|
307
365
|
if lock_info
|
308
366
|
table = TTY::Table.new(header: %w[Field Value])
|
@@ -343,6 +401,17 @@ module MuxTf
|
|
343
401
|
end
|
344
402
|
end
|
345
403
|
|
404
|
+
def init_cmd
|
405
|
+
define_cmd("init", summary: "Re-run init") do |_opts, _args, _cmd|
|
406
|
+
exit_code, meta = InitFormatter.run_tf_init
|
407
|
+
print_errors_and_warnings(meta)
|
408
|
+
if exit_code != 0
|
409
|
+
log meta.inspect unless meta.empty?
|
410
|
+
log "Init Failed!"
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
346
415
|
def upgrade_cmd
|
347
416
|
define_cmd("upgrade", summary: "Upgrade modules/plguins") do |_opts, _args, _cmd|
|
348
417
|
status, meta = run_upgrade
|
@@ -355,7 +424,7 @@ module MuxTf
|
|
355
424
|
|
356
425
|
def reconfigure_cmd
|
357
426
|
define_cmd("reconfigure", summary: "Reconfigure modules/plguins") do |_opts, _args, _cmd|
|
358
|
-
exit_code, meta =
|
427
|
+
exit_code, meta = InitFormatter.run_tf_init(reconfigure: true)
|
359
428
|
print_errors_and_warnings(meta)
|
360
429
|
if exit_code != 0
|
361
430
|
log meta.inspect unless meta.empty?
|
@@ -366,13 +435,18 @@ module MuxTf
|
|
366
435
|
|
367
436
|
def interactive_cmd
|
368
437
|
define_cmd("interactive", summary: "Apply interactively") do |_opts, _args, _cmd|
|
438
|
+
plan_filename = PlanFilenameGenerator.for_path
|
369
439
|
plan = PlanSummaryHandler.from_file(plan_filename)
|
370
440
|
begin
|
371
|
-
abort_message = catch(:abort) {
|
441
|
+
abort_message = catch(:abort) {
|
442
|
+
result = plan.run_interactive
|
443
|
+
log "Re-running apply with the selected resources ..."
|
444
|
+
@plan_command.run_plan(targets: result)
|
445
|
+
}
|
372
446
|
if abort_message
|
373
447
|
log pastel.red("Aborted: #{abort_message}")
|
374
448
|
else
|
375
|
-
run_plan
|
449
|
+
@plan_command.run_plan
|
376
450
|
end
|
377
451
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
378
452
|
log e.full_message
|
@@ -381,104 +455,8 @@ module MuxTf
|
|
381
455
|
end
|
382
456
|
end
|
383
457
|
|
384
|
-
def print_errors_and_warnings(meta) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
|
385
|
-
message = []
|
386
|
-
message << pastel.yellow("#{meta[:warnings].length} Warnings") if meta[:warnings]
|
387
|
-
message << pastel.red("#{meta[:errors].length} Errors") if meta[:errors]
|
388
|
-
if message.length.positive?
|
389
|
-
log ""
|
390
|
-
log "Encountered: #{message.join(' and ')}"
|
391
|
-
log ""
|
392
|
-
end
|
393
|
-
|
394
|
-
meta[:warnings]&.each do |warning|
|
395
|
-
log "-" * 20
|
396
|
-
log pastel.yellow("Warning: #{warning[:message]}")
|
397
|
-
warning[:body]&.each do |line|
|
398
|
-
log pastel.yellow(line), depth: 1
|
399
|
-
end
|
400
|
-
log ""
|
401
|
-
end
|
402
|
-
|
403
|
-
meta[:errors]&.each do |error|
|
404
|
-
log "-" * 20
|
405
|
-
log pastel.red("Error: #{error[:message]}")
|
406
|
-
error[:body]&.each do |line|
|
407
|
-
log pastel.red(line), depth: 1
|
408
|
-
end
|
409
|
-
log ""
|
410
|
-
end
|
411
|
-
|
412
|
-
return unless message.length.positive?
|
413
|
-
|
414
|
-
log ""
|
415
|
-
end
|
416
|
-
|
417
|
-
def detect_remedies_from_plan(meta)
|
418
|
-
remedies = Set.new
|
419
|
-
meta[:errors]&.each do |error|
|
420
|
-
remedies << :plan if error[:message].include?("timeout while waiting for plugin to start")
|
421
|
-
end
|
422
|
-
remedies << :unlock if lock_error?(meta)
|
423
|
-
remedies << :auth if meta[:need_auth]
|
424
|
-
remedies
|
425
|
-
end
|
426
|
-
|
427
|
-
def lock_error?(meta)
|
428
|
-
meta && meta["error"] == "lock"
|
429
|
-
end
|
430
|
-
|
431
|
-
def extract_lock_info(meta)
|
432
|
-
{
|
433
|
-
lock_id: meta["ID"],
|
434
|
-
operation: meta["Operation"],
|
435
|
-
who: meta["Who"],
|
436
|
-
created: meta["Created"]
|
437
|
-
}
|
438
|
-
end
|
439
|
-
|
440
|
-
def run_plan(targets: [], level: 1, retry_count: 0)
|
441
|
-
plan_status, = remedy_retry_helper(from: :plan, level: level, attempt: retry_count) {
|
442
|
-
@last_lock_info = nil
|
443
|
-
|
444
|
-
plan_status, meta = create_plan(plan_filename, targets: targets)
|
445
|
-
|
446
|
-
print_errors_and_warnings(meta)
|
447
|
-
|
448
|
-
remedies = detect_remedies_from_plan(meta)
|
449
|
-
|
450
|
-
if remedies.include?(:unlock)
|
451
|
-
@last_lock_info = extract_lock_info(meta)
|
452
|
-
throw :abort, [plan_status, meta]
|
453
|
-
end
|
454
|
-
|
455
|
-
throw :abort, [plan_status, meta] if remedies.include?(:auth)
|
456
|
-
|
457
|
-
[remedies, plan_status, meta]
|
458
|
-
}
|
459
|
-
|
460
|
-
case plan_status
|
461
|
-
when :ok
|
462
|
-
log "no changes", depth: 1
|
463
|
-
when :error
|
464
|
-
log "something went wrong", depth: 1
|
465
|
-
when :changes
|
466
|
-
unless ENV["JSON_PLAN"]
|
467
|
-
log "Printing Plan Summary ...", depth: 1
|
468
|
-
pretty_plan_summary(plan_filename)
|
469
|
-
end
|
470
|
-
puts plan_summary_text if ENV["JSON_PLAN"]
|
471
|
-
when :unknown
|
472
|
-
# nothing
|
473
|
-
end
|
474
|
-
|
475
|
-
plan_status
|
476
|
-
end
|
477
|
-
|
478
|
-
public :run_plan
|
479
|
-
|
480
458
|
def run_upgrade
|
481
|
-
exit_code, meta =
|
459
|
+
exit_code, meta = InitFormatter.run_tf_init(upgrade: true)
|
482
460
|
print_errors_and_warnings(meta)
|
483
461
|
case exit_code
|
484
462
|
when 0
|
@@ -490,18 +468,6 @@ module MuxTf
|
|
490
468
|
[:unknown, meta]
|
491
469
|
end
|
492
470
|
end
|
493
|
-
|
494
|
-
def pretty_plan_summary(filename)
|
495
|
-
plan = PlanSummaryHandler.from_file(filename)
|
496
|
-
plan.flat_summary.each do |line|
|
497
|
-
log line, depth: 2
|
498
|
-
end
|
499
|
-
plan.output_summary.each do |line|
|
500
|
-
log line, depth: 2
|
501
|
-
end
|
502
|
-
log "", depth: 2
|
503
|
-
log plan.summary, depth: 2
|
504
|
-
end
|
505
471
|
end
|
506
472
|
end
|
507
473
|
end
|