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
@@ -17,7 +17,7 @@ module MuxTf
|
|
17
17
|
if File.exist?("#{file}.json") && File.mtime("#{file}.json").to_f >= File.mtime(file).to_f
|
18
18
|
JSON.parse(File.read("#{file}.json"))
|
19
19
|
else
|
20
|
-
puts "Analyzing changes ..."
|
20
|
+
puts "Analyzing changes ... #{file}"
|
21
21
|
result = tf_show(file, json: true)
|
22
22
|
data = result.parsed_output
|
23
23
|
File.write("#{file}.json", JSON.dump(data))
|
@@ -33,7 +33,7 @@ module MuxTf
|
|
33
33
|
case action
|
34
34
|
when "create", "add"
|
35
35
|
:green
|
36
|
-
when "update", "change"
|
36
|
+
when "update", "change", "import-update"
|
37
37
|
:yellow
|
38
38
|
when "delete", "remove"
|
39
39
|
:red
|
@@ -43,7 +43,7 @@ module MuxTf
|
|
43
43
|
:red
|
44
44
|
when "read"
|
45
45
|
:cyan
|
46
|
-
when "import" # rubocop:disable Lint/DuplicateBranch
|
46
|
+
when "import", "forget" # rubocop:disable Lint/DuplicateBranch
|
47
47
|
:cyan
|
48
48
|
else
|
49
49
|
:reset
|
@@ -64,6 +64,12 @@ module MuxTf
|
|
64
64
|
"±"
|
65
65
|
when "read"
|
66
66
|
">"
|
67
|
+
when "import"
|
68
|
+
"→"
|
69
|
+
when "import-update"
|
70
|
+
"↗︎"
|
71
|
+
when "forget"
|
72
|
+
"↺"
|
67
73
|
else
|
68
74
|
action
|
69
75
|
end
|
@@ -94,7 +100,8 @@ module MuxTf
|
|
94
100
|
end
|
95
101
|
end
|
96
102
|
|
97
|
-
def initialize(data)
|
103
|
+
def initialize(data)
|
104
|
+
@data = data
|
98
105
|
@parts = []
|
99
106
|
|
100
107
|
data["output_changes"]&.each do |output_name, v|
|
@@ -138,6 +145,14 @@ module MuxTf
|
|
138
145
|
case v["change"]["actions"]
|
139
146
|
when ["no-op"]
|
140
147
|
# do nothing
|
148
|
+
if v["change"]["importing"]
|
149
|
+
parts << {
|
150
|
+
type: "resource",
|
151
|
+
action: "import",
|
152
|
+
address: v["address"],
|
153
|
+
deps: find_deps(data, v["address"])
|
154
|
+
}
|
155
|
+
end
|
141
156
|
when ["create"]
|
142
157
|
parts << {
|
143
158
|
type: "resource",
|
@@ -146,9 +161,10 @@ module MuxTf
|
|
146
161
|
deps: find_deps(data, v["address"])
|
147
162
|
}
|
148
163
|
when ["update"]
|
164
|
+
# ap [v["change"]["actions"], v["change"]["importing"]]
|
149
165
|
parts << {
|
150
166
|
type: "resource",
|
151
|
-
action: "update",
|
167
|
+
action: v["change"]["importing"] ? "import-update" : "update",
|
152
168
|
address: v["address"],
|
153
169
|
deps: find_deps(data, v["address"])
|
154
170
|
}
|
@@ -180,6 +196,13 @@ module MuxTf
|
|
180
196
|
address: v["address"],
|
181
197
|
deps: find_deps(data, v["address"])
|
182
198
|
}
|
199
|
+
when ["forget"]
|
200
|
+
parts << {
|
201
|
+
type: "resource",
|
202
|
+
action: "forget",
|
203
|
+
address: v["address"],
|
204
|
+
deps: find_deps(data, v["address"])
|
205
|
+
}
|
183
206
|
else
|
184
207
|
puts "[??] #{v['address']}"
|
185
208
|
puts "UNKNOWN RESOURCE ACTIONS: #{v['change']['actions'].inspect}"
|
@@ -198,7 +221,7 @@ module MuxTf
|
|
198
221
|
parts.select { |part| part[:type] == "output" }
|
199
222
|
end
|
200
223
|
|
201
|
-
def summary
|
224
|
+
def summary
|
202
225
|
# resources
|
203
226
|
resource_summary = {}
|
204
227
|
resource_parts.each do |part|
|
@@ -233,11 +256,9 @@ module MuxTf
|
|
233
256
|
end
|
234
257
|
|
235
258
|
def flat_summary
|
236
|
-
|
237
|
-
|
238
|
-
result << "[#{self.class.format_action(part[:action])}] #{self.class.format_address(part[:address])}"
|
259
|
+
resource_parts.map do |part|
|
260
|
+
"[#{self.class.format_action(part[:action])}] #{self.class.format_address(part[:address])}"
|
239
261
|
end
|
240
|
-
result
|
241
262
|
end
|
242
263
|
|
243
264
|
def sensitive_summary(before_value, after_value)
|
@@ -265,7 +286,20 @@ module MuxTf
|
|
265
286
|
result
|
266
287
|
end
|
267
288
|
|
268
|
-
def
|
289
|
+
def simple_summary(&printer)
|
290
|
+
printer = method(:puts) if printer.nil?
|
291
|
+
|
292
|
+
flat_summary.each do |line|
|
293
|
+
printer.call line
|
294
|
+
end
|
295
|
+
output_summary.each do |line|
|
296
|
+
printer.call line
|
297
|
+
end
|
298
|
+
printer.call ""
|
299
|
+
printer.call summary
|
300
|
+
end
|
301
|
+
|
302
|
+
def nested_summary
|
269
303
|
result = []
|
270
304
|
parts = resource_parts.deep_dup
|
271
305
|
until parts.empty?
|
@@ -305,31 +339,18 @@ module MuxTf
|
|
305
339
|
if result.empty?
|
306
340
|
throw :abort, "nothing selected"
|
307
341
|
else
|
308
|
-
|
309
|
-
MuxTf::Cli::Current.run_plan(targets: result)
|
342
|
+
result
|
310
343
|
end
|
311
344
|
end
|
312
345
|
|
346
|
+
def plan_text_output
|
347
|
+
PlanUtils.text_version_of_plan_show_from_data(@data)
|
348
|
+
end
|
349
|
+
|
313
350
|
private
|
314
351
|
|
315
352
|
attr_reader :parts
|
316
353
|
|
317
|
-
def create_plan(filename, targets: [])
|
318
|
-
log "Preparing Plan ...", depth: 1
|
319
|
-
exit_code, meta = PlanFormatter.pretty_plan(filename, targets: targets)
|
320
|
-
case exit_code
|
321
|
-
when 0
|
322
|
-
[:ok, meta]
|
323
|
-
when 1
|
324
|
-
[:error, meta]
|
325
|
-
when 2
|
326
|
-
[:changes, meta]
|
327
|
-
else
|
328
|
-
log pastel.yellow("terraform plan exited with an unknown exit code: #{exit_code}")
|
329
|
-
[:unknown, meta]
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
354
|
def prune_unchanged_deps(_parts)
|
334
355
|
valid_addresses = resource_parts.map { |part| part[:address] }
|
335
356
|
|
@@ -338,7 +359,7 @@ module MuxTf
|
|
338
359
|
end
|
339
360
|
end
|
340
361
|
|
341
|
-
def find_deps(data, address)
|
362
|
+
def find_deps(data, address)
|
342
363
|
result = []
|
343
364
|
|
344
365
|
m = address.match(/\[(.+)\]$/)
|
@@ -358,7 +379,7 @@ module MuxTf
|
|
358
379
|
resource, parent_address = find_config(data["configuration"], "root_module", address, [])
|
359
380
|
if resource
|
360
381
|
deps = []
|
361
|
-
resource["expressions"]&.
|
382
|
+
resource["expressions"]&.each_value do |v|
|
362
383
|
deps << v["references"] if v.is_a?(Hash) && v["references"]
|
363
384
|
end
|
364
385
|
result += deps.map { |s| (parent_address + [s]).join(".") }
|
data/lib/mux_tf/plan_utils.rb
CHANGED
@@ -12,16 +12,21 @@ module MuxTf
|
|
12
12
|
class << self
|
13
13
|
def warning(message, binding_arg: binding)
|
14
14
|
stack = binding_arg.send(:caller)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
stack_match = stack[0].match(/^(?<path>.+):(?<ln>\d+):in [`'](?<method>.+)'$/)
|
16
|
+
msg = []
|
17
|
+
if stack_match
|
18
|
+
stack_line = stack_match.named_captures
|
19
|
+
stack_line["path"].gsub!(MuxTf::ROOT, pastel.gray("{mux_tf}"))
|
20
|
+
msg << "#{pastel.orange('WARNING')}: #{message}"
|
21
|
+
msg << "at #{pastel.cyan(stack_line['path'])}:#{pastel.white(stack_line['ln'])}:in `#{pastel.cyan(stack_line['method'])}'"
|
22
|
+
else
|
23
|
+
p [stack_match, stack[0]]
|
24
|
+
msg << "#{pastel.orange('WARNING')}: #{message}"
|
25
|
+
end
|
21
26
|
puts msg.join(" - ")
|
22
27
|
end
|
23
28
|
|
24
|
-
def update_placeholders(dst, src, placeholder)
|
29
|
+
def update_placeholders(dst, src, placeholder)
|
25
30
|
return unless src
|
26
31
|
|
27
32
|
case src
|
@@ -104,8 +109,11 @@ module MuxTf
|
|
104
109
|
else
|
105
110
|
false
|
106
111
|
end
|
107
|
-
rescue Psych::
|
108
|
-
ap e
|
112
|
+
rescue Psych::DisallowedClass => _e
|
113
|
+
# ap e
|
114
|
+
false
|
115
|
+
rescue Psych::SyntaxError => _e # rubocop:disable Lint/DuplicateBranch
|
116
|
+
# ap e
|
109
117
|
false
|
110
118
|
end
|
111
119
|
|
@@ -115,6 +123,16 @@ module MuxTf
|
|
115
123
|
pastel.green(symbol)
|
116
124
|
when "~"
|
117
125
|
pastel.yellow(symbol)
|
126
|
+
when "-"
|
127
|
+
pastel.red(symbol)
|
128
|
+
when "?"
|
129
|
+
pastel.orange(symbol)
|
130
|
+
when "±"
|
131
|
+
pastel.bright_red(symbol)
|
132
|
+
when ">"
|
133
|
+
pastel.blue(symbol)
|
134
|
+
when " "
|
135
|
+
symbol
|
118
136
|
else
|
119
137
|
warning "Unknown symbol: #{symbol.inspect}"
|
120
138
|
symbol
|
@@ -143,7 +161,7 @@ module MuxTf
|
|
143
161
|
}.join("\n")
|
144
162
|
end
|
145
163
|
|
146
|
-
def in_display_representation(value)
|
164
|
+
def in_display_representation(value)
|
147
165
|
if valid_json?(value)
|
148
166
|
json_body = JSON.pretty_generate(JSON.parse(value))
|
149
167
|
wrap(json_body, prefix: "json(", suffix: ")", color: :gray)
|
@@ -223,40 +241,26 @@ module MuxTf
|
|
223
241
|
format_value_diff(mode, value_arg)
|
224
242
|
end
|
225
243
|
|
226
|
-
# def format_value(value_arg, symbol)
|
227
|
-
# case value_arg
|
228
|
-
# when Array
|
229
|
-
# mode = :both
|
230
|
-
# case symbol
|
231
|
-
# when "+"
|
232
|
-
# mode = :right
|
233
|
-
# when "~"
|
234
|
-
# mode = :both
|
235
|
-
# else
|
236
|
-
# warning "Unknown symbol: #{symbol.inspect}"
|
237
|
-
# end
|
238
|
-
|
239
|
-
# format_value_diff(mode, value_arg)
|
240
|
-
# when Hash
|
241
|
-
# if value_arg.keys.all? { |k| k.is_a?(Integer) }
|
242
|
-
# # assuming its a hash notation of array keys changes
|
243
|
-
# value_arg.keys.sort.map { |k| "[#{k}] #{format_value(value_arg[k], symbol)[0]}" }
|
244
|
-
# else
|
245
|
-
# [value_arg.inspect]
|
246
|
-
# end
|
247
|
-
# else
|
248
|
-
# [value_arg.inspect]
|
249
|
-
# end
|
250
|
-
# end
|
251
|
-
|
252
244
|
def get_pretty_action_and_symbol(actions)
|
253
245
|
case actions
|
246
|
+
when ["delete"]
|
247
|
+
pretty_action = "delete"
|
248
|
+
symbol = "-"
|
254
249
|
when ["update"]
|
255
250
|
pretty_action = "updated in-place"
|
256
251
|
symbol = "~"
|
257
252
|
when ["create"]
|
258
253
|
pretty_action = "created"
|
259
254
|
symbol = "+"
|
255
|
+
when %w[delete create]
|
256
|
+
pretty_action = "replaced (delete first)"
|
257
|
+
symbol = "±"
|
258
|
+
when ["read"]
|
259
|
+
pretty_action = "read"
|
260
|
+
symbol = ">"
|
261
|
+
when ["no-op"]
|
262
|
+
pretty_action = "no-op"
|
263
|
+
symbol = " "
|
260
264
|
else
|
261
265
|
warning "Unknown action: #{actions.inspect}"
|
262
266
|
pretty_action = actions.inspect
|
@@ -286,7 +290,7 @@ module MuxTf
|
|
286
290
|
# EOT
|
287
291
|
# # (12 unchanged attributes hidden)
|
288
292
|
# }
|
289
|
-
def tf_show_json_resource(resource)
|
293
|
+
def tf_show_json_resource(resource)
|
290
294
|
pretty_action, symbol = get_pretty_action_and_symbol(resource["change"]["actions"])
|
291
295
|
|
292
296
|
output = []
|
@@ -295,44 +299,188 @@ module MuxTf
|
|
295
299
|
|
296
300
|
output << ""
|
297
301
|
output << "#{global_indent}#{pastel.bold("# #{resource['address']}")} will be #{pretty_action}"
|
302
|
+
output << "#{global_indent} >> #{action_reason_to_text(resource['action_reason'])}" if resource["action_reason"]
|
298
303
|
output << "#{global_indent}#{colorize_symbol(symbol)} resource \"#{resource['type']}\" \"#{resource['name']}\" {"
|
299
304
|
diff = tf_show_json_resource_diff(resource)
|
300
305
|
max_diff_key_length = diff.map { |change| change[1].length }.max
|
306
|
+
|
307
|
+
fields_which_caused_replacement = []
|
308
|
+
|
309
|
+
if resource["change"]["replace_paths"]
|
310
|
+
if resource["change"]["replace_paths"].length != 1
|
311
|
+
warning "Multiple replace paths found for resource #{resource['address']}: #{resource['change']['replace_paths'].inspect}"
|
312
|
+
elsif resource["change"]["replace_paths"][0].length != 1
|
313
|
+
warning "Multiple fields found to be replaced for resource #{resource['address']}: #{resource['change']['replace_paths'].inspect}"
|
314
|
+
else
|
315
|
+
fields_which_caused_replacement << resource["change"]["replace_paths"][0][0]
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
301
319
|
diff.each do |change|
|
302
320
|
change_symbol, key, *_values = change
|
303
321
|
prefix = format("#{global_indent} #{colorize_symbol(change_symbol)} %s = ", key.ljust(max_diff_key_length))
|
322
|
+
suffix = ""
|
323
|
+
suffix = " (forces replacement)" if fields_which_caused_replacement.include?(key)
|
304
324
|
blank_prefix = " " * pastel.strip(prefix).length
|
305
325
|
format_value(change).each_with_index do |line, index|
|
306
326
|
output << if index.zero?
|
307
|
-
"#{prefix}#{line}"
|
327
|
+
"#{prefix}#{line}#{suffix}"
|
308
328
|
else
|
309
|
-
"#{blank_prefix}#{line}"
|
329
|
+
"#{blank_prefix}#{line}#{suffix}"
|
310
330
|
end
|
311
331
|
end
|
312
332
|
end
|
313
|
-
# max_diff_key_length = diff.keys.map(&:length).max
|
314
|
-
# diff.each do |key, value|
|
315
|
-
# prefix = format("#{global_indent} #{colorize_symbol(symbol)} %s = ", key.ljust(max_diff_key_length))
|
316
|
-
# blank_prefix = " " * pastel.strip(prefix).length
|
317
|
-
# format_value(value, symbol).each_with_index do |line, index|
|
318
|
-
# output << if index.zero?
|
319
|
-
# "#{prefix}#{line}"
|
320
|
-
# else
|
321
|
-
# "#{blank_prefix}#{line}"
|
322
|
-
# end
|
323
|
-
# end
|
324
|
-
# end
|
325
333
|
output << "#{global_indent}}"
|
326
334
|
|
327
335
|
output.join("\n")
|
328
336
|
end
|
329
337
|
|
330
|
-
def
|
331
|
-
|
332
|
-
|
338
|
+
def format_output_value_diff(mode, value_arg)
|
339
|
+
case mode
|
340
|
+
when :both
|
341
|
+
vleft = in_display_representation(value_arg[0])
|
342
|
+
vright = in_display_representation(value_arg[1])
|
343
|
+
if [vleft, vright].any? { |v| v.is_a?(String) && v.include?("\n") }
|
344
|
+
if pastel.strip(vright) == KNOWN_AFTER_APPLY
|
345
|
+
"#{vleft} -> #{vright}".split("\n")
|
346
|
+
else
|
347
|
+
string_diff(pastel.strip(vleft), pastel.strip(vright))
|
348
|
+
end
|
349
|
+
else
|
350
|
+
"#{vleft} -> #{vright}".split("\n")
|
351
|
+
end
|
352
|
+
when :right
|
353
|
+
vright = in_display_representation(value_arg[1])
|
354
|
+
vright.split("\n")
|
355
|
+
when :left, :first
|
356
|
+
vleft = in_display_representation(value_arg[0])
|
357
|
+
vleft.split("\n")
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
def get_x_type(key, change)
|
362
|
+
return :hash if change[key].is_a?(Hash) || change["#{key}_sensitive"].is_a?(Hash) || change["#{key}_unknown"].is_a?(Hash)
|
363
|
+
return :array if change[key].is_a?(Array) || change["#{key}_sensitive"].is_a?(Array) || change["#{key}_unknown"].is_a?(Array)
|
364
|
+
|
365
|
+
:scalar
|
366
|
+
end
|
367
|
+
|
368
|
+
def get_value_type(change)
|
369
|
+
case change["actions"]
|
370
|
+
when ["create"]
|
371
|
+
get_x_type("after", change)
|
372
|
+
when ["delete"]
|
373
|
+
get_x_type("before", change)
|
374
|
+
when ["update"]
|
375
|
+
bt = get_x_type("before", change)
|
376
|
+
at = get_x_type("after", change)
|
377
|
+
raise "Type mismatch before vs after: #{bt} != #{at}" if bt != at
|
378
|
+
|
379
|
+
at
|
380
|
+
when ["no-op"]
|
381
|
+
:none
|
382
|
+
else
|
383
|
+
raise "Unknown action: #{change['actions'].inspect}"
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
def prep_before_after(change)
|
388
|
+
before = change["before"]
|
389
|
+
after = change["after"]
|
390
|
+
before = KNOWN_AFTER_APPLY if change["before_unknown"]
|
391
|
+
before = SENSITIVE if change["before_sensitive"]
|
392
|
+
after = KNOWN_AFTER_APPLY if change["after_unknown"]
|
393
|
+
after = SENSITIVE if change["after_sensitive"]
|
394
|
+
|
395
|
+
[before, after]
|
396
|
+
end
|
397
|
+
|
398
|
+
def tf_show_json_output(output_key, output_change, max_outer_key_length)
|
399
|
+
_pretty_action, symbol = get_pretty_action_and_symbol(output_change["actions"])
|
400
|
+
|
401
|
+
output = []
|
402
|
+
|
403
|
+
global_indent = " " * 2
|
404
|
+
|
405
|
+
value_type = get_value_type(output_change)
|
406
|
+
|
407
|
+
start_prefix = format("#{global_indent}#{colorize_symbol(symbol)} %s = ", output_key.ljust(max_outer_key_length))
|
408
|
+
blank_start_prefix = " " * pastel.strip(start_prefix).length
|
409
|
+
outer_mode = :both
|
410
|
+
outer_mode = :right if ["+"].include?(symbol)
|
411
|
+
outer_mode = :left if ["-"].include?(symbol)
|
412
|
+
outer_mode = :right if [" "].include?(symbol)
|
413
|
+
|
414
|
+
case value_type
|
415
|
+
when :hash
|
416
|
+
output << "#{start_prefix}{"
|
417
|
+
|
418
|
+
fake_resource = {
|
419
|
+
"change" => output_change
|
420
|
+
}
|
421
|
+
diff = tf_show_json_resource_diff(fake_resource)
|
422
|
+
max_diff_key_length = diff.map { |change| change[1].length }.max
|
423
|
+
|
424
|
+
diff.each do |change|
|
425
|
+
change_symbol, key, *_values = change
|
426
|
+
prefix = format("#{global_indent} #{colorize_symbol(change_symbol)} %s = ", key.ljust(max_diff_key_length))
|
427
|
+
suffix = ""
|
428
|
+
blank_prefix = " " * pastel.strip(prefix).length
|
429
|
+
format_value(change).each_with_index do |line, index|
|
430
|
+
output << if index.zero?
|
431
|
+
"#{prefix}#{line}#{suffix}"
|
432
|
+
else
|
433
|
+
"#{blank_prefix}#{line}#{suffix}"
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
output << "#{global_indent} }"
|
439
|
+
when :array, :scalar, :none
|
440
|
+
before, after = prep_before_after(output_change)
|
441
|
+
format_value_diff(outer_mode, [before, after]).each_with_index do |line, index|
|
442
|
+
output << if index.zero?
|
443
|
+
"#{start_prefix}#{line}"
|
444
|
+
else
|
445
|
+
"#{blank_start_prefix}#{line}"
|
446
|
+
end
|
447
|
+
end
|
448
|
+
else
|
449
|
+
raise "Unknown value type: #{value_type.inspect}"
|
450
|
+
end
|
451
|
+
|
452
|
+
output.join("\n")
|
453
|
+
end
|
333
454
|
|
334
|
-
|
455
|
+
# See https://developer.hashicorp.com/terraform/internals/json-format
|
456
|
+
def action_reason_to_text(action_reason)
|
457
|
+
case action_reason
|
458
|
+
when "replace_because_tainted"
|
459
|
+
"because the object is tainted in the prior state"
|
460
|
+
when "replace_because_cannot_update"
|
461
|
+
"because the provider does not support updating the object, or the changed attributes"
|
462
|
+
when "replace_by_request"
|
463
|
+
"because the user requested the object to be replaced"
|
464
|
+
when "delete_because_no_resource_config"
|
465
|
+
"because the object is no longer in the configuration"
|
466
|
+
when "delete_because_no_module"
|
467
|
+
"because the module this object belongs to is no longer in the configuration"
|
468
|
+
when "delete_because_wrong_repetition"
|
469
|
+
"because of the repetition mode has changed"
|
470
|
+
when "delete_because_count_index"
|
471
|
+
"because the repetition count has changed"
|
472
|
+
when "delete_because_each_key"
|
473
|
+
"because the repetition key has changed"
|
474
|
+
when "read_because_config_unknown"
|
475
|
+
"because reading this will only be possible during apply"
|
476
|
+
when "read_because_dependency_pending"
|
477
|
+
"because reading this will only be possible after a dependency is available"
|
478
|
+
else
|
479
|
+
"because #{action_reason}"
|
480
|
+
end
|
481
|
+
end
|
335
482
|
|
483
|
+
def text_version_of_plan_show_from_data(data)
|
336
484
|
output = []
|
337
485
|
|
338
486
|
output << "Terraform will perform the following actions:"
|
@@ -349,7 +497,18 @@ module MuxTf
|
|
349
497
|
output << ""
|
350
498
|
output << "Resource Changes:"
|
351
499
|
data["resource_changes"].each do |resource|
|
352
|
-
|
500
|
+
next if resource["change"]["actions"] == ["no-op"]
|
501
|
+
|
502
|
+
output << tf_show_json_resource(resource)
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
if data["output_changes"]
|
507
|
+
output << ""
|
508
|
+
output << "Changes to Outputs:"
|
509
|
+
max_outer_key_length = data["output_changes"].keys.map(&:length).max || 0
|
510
|
+
data["output_changes"].each do |key, output_change|
|
511
|
+
output << tf_show_json_output(key, output_change, max_outer_key_length)
|
353
512
|
end
|
354
513
|
end
|
355
514
|
|