mux_tf 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1742588983c720769618427118003ad76ab69f8be2035b19f8c779ab1876669
4
- data.tar.gz: 12563430cfe99792a995675611a0dbd8aad9582d6ed063c0a38335dec1bac6b0
3
+ metadata.gz: 86f905c9dcd8264222677f830925cff18e3258d10319be26c339705866ef8118
4
+ data.tar.gz: e61638e5a1d0a104debdd034cd7aecb9da34bcdd64fee57444967ba516d21f1b
5
5
  SHA512:
6
- metadata.gz: 302ebae8183b41dfb4c7218d95dcdf9d0117df023caf80c6a38ec9969071b6af55d538e73eb08e6ef275816e6dc29220277c4b731202df9f5f30b9f4e3013c5c
7
- data.tar.gz: 3af421ee73ec82cb62d0b9e8ae41c9a220b5feae31dda1328b14c71aa8d6e02b5acd858da13fe606ecfcfeaf290f99a9d7b0806b0b2f9ea40e752d5f8d544bc6
6
+ metadata.gz: 120652ac965f70a186dd189a0cd0fd6fba14c2dc2c9421fe654d209e98432a70298079e86ea33107e61d0b163078db72a9d963971af43d4cddb3df499d2a76b9
7
+ data.tar.gz: dd063677d9d1f65b8c7e3a4a4d48c7c4bbefec455eda0ce021ddf020c17cb4d4230e0eae17914edec02d3c27a014a97456f4612a46bc11dbbff56fe023d100d5
@@ -313,6 +313,9 @@ module MuxTf
313
313
  plan.flat_summary.each do |line|
314
314
  log line, depth: 2
315
315
  end
316
+ plan.output_summary.each do |line|
317
+ log line, depth: 2
318
+ end
316
319
  log "", depth: 2
317
320
  log plan.summary, depth: 2
318
321
  end
@@ -49,6 +49,9 @@ module MuxTf
49
49
  plan.flat_summary.each do |line|
50
50
  puts line
51
51
  end
52
+ plan.output_summary.each do |line|
53
+ puts line
54
+ end
52
55
  end
53
56
  puts
54
57
  puts plan.summary
@@ -20,13 +20,13 @@ module MuxTf
20
20
  parser.state(:refreshing, /Refreshing Terraform state in-memory prior to plan.../, %i[none blank info])
21
21
  parser.state(:refresh_done, /^----------+$/, [:refreshing])
22
22
  parser.state(:refresh_done, /^$/, [:refreshing])
23
- parser.state(:plan_info, /Terraform will perform the following actions:/, [:refresh_done])
23
+ parser.state(:plan_info, /Terraform will perform the following actions:/, [:refresh_done, :none])
24
24
  parser.state(:plan_summary, /^Plan:/, [:plan_info])
25
25
 
26
26
  parser.state(:error_lock_info, /Lock Info/, [:error])
27
27
  parser.state(:error, /^$/, [:error_lock_info])
28
28
 
29
- parser.state(:plan_error, /^Error: /, %i[refreshing refresh_done])
29
+ parser.state(:plan_error, /^╷|Error: /, %i[refreshing refresh_done])
30
30
 
31
31
  status = tf_plan(out: filename, detailed_exitcode: true, compact_warnings: true, targets: targets) { |raw_line|
32
32
  parser.parse(raw_line.rstrip) do |state, line|
@@ -32,77 +32,174 @@ module MuxTf
32
32
  def initialize(data)
33
33
  @parts = []
34
34
 
35
- data["resource_changes"].each do |v|
36
- next unless v["change"]
37
-
38
- case v["change"]["actions"]
39
- when ["no-op"]
40
- # do nothing
41
- when ["create"]
42
- parts << {
43
- action: "create",
44
- address: v["address"],
45
- deps: find_deps(data, v["address"])
46
- }
47
- when ["update"]
48
- parts << {
49
- action: "update",
50
- address: v["address"],
51
- deps: find_deps(data, v["address"])
52
- }
53
- when ["delete"]
54
- parts << {
55
- action: "delete",
56
- address: v["address"],
57
- deps: find_deps(data, v["address"])
58
- }
59
- when %w[delete create]
60
- parts << {
61
- action: "replace",
62
- address: v["address"],
63
- deps: find_deps(data, v["address"])
64
- }
65
- when ["read"]
66
- parts << {
67
- action: "read",
68
- address: v["address"],
69
- deps: find_deps(data, v["address"])
70
- }
71
- else
72
- puts "[??] #{v["address"]}"
73
- puts "UNKNOWN ACTIONS: #{v["change"]["actions"].inspect}"
74
- puts "TODO: update plan_summary to support this!"
35
+ if data["output_changes"]
36
+ data["output_changes"].each do |output_name, v|
37
+ case v["actions"]
38
+ when ["no-op"]
39
+ # do nothing
40
+ when ["create"]
41
+ parts << {
42
+ type: "output",
43
+ action: "create",
44
+ after_unknown: v["after_unknown"],
45
+ sensitive: [v["before_sensitive"], v["after_sensitive"]],
46
+ address: output_name
47
+ }
48
+ when ["update"]
49
+ parts << {
50
+ type: "output",
51
+ action: "update",
52
+ after_unknown: v["after_unknown"],
53
+ sensitive: [v["before_sensitive"], v["after_sensitive"]],
54
+ address: output_name
55
+ }
56
+ when ["delete"]
57
+ parts << {
58
+ type: "output",
59
+ action: "delete",
60
+ after_unknown: v["after_unknown"],
61
+ sensitive: [v["before_sensitive"], v["after_sensitive"]],
62
+ address: output_name
63
+ }
64
+ else
65
+ puts "[??] #{output_name}"
66
+ puts "UNKNOWN ACTIONS: #{v["actions"].inspect}"
67
+ puts "TODO: update plan_summary to support this!"
68
+ end
69
+ end
70
+ end
71
+
72
+ if data["resource_changes"]
73
+ data["resource_changes"].each do |v|
74
+ next unless v["change"]
75
+
76
+ case v["change"]["actions"]
77
+ when ["no-op"]
78
+ # do nothing
79
+ when ["create"]
80
+ parts << {
81
+ type: "resource",
82
+ action: "create",
83
+ address: v["address"],
84
+ deps: find_deps(data, v["address"])
85
+ }
86
+ when ["update"]
87
+ parts << {
88
+ type: "resource",
89
+ action: "update",
90
+ address: v["address"],
91
+ deps: find_deps(data, v["address"])
92
+ }
93
+ when ["delete"]
94
+ parts << {
95
+ type: "resource",
96
+ action: "delete",
97
+ address: v["address"],
98
+ deps: find_deps(data, v["address"])
99
+ }
100
+ when %w[delete create]
101
+ parts << {
102
+ type: "resource",
103
+ action: "replace",
104
+ address: v["address"],
105
+ deps: find_deps(data, v["address"])
106
+ }
107
+ when ["read"]
108
+ parts << {
109
+ type: "resource",
110
+ action: "read",
111
+ address: v["address"],
112
+ deps: find_deps(data, v["address"])
113
+ }
114
+ else
115
+ puts "[??] #{v["address"]}"
116
+ puts "UNKNOWN ACTIONS: #{v["change"]["actions"].inspect}"
117
+ puts "TODO: update plan_summary to support this!"
118
+ end
75
119
  end
76
120
  end
77
121
 
78
122
  prune_unchanged_deps(parts)
79
123
  end
80
124
 
125
+ def resource_parts
126
+ parts.select { |part| part[:type] == "resource" }
127
+ end
128
+
129
+ def output_parts
130
+ parts.select { |part| part[:type] == "output" }
131
+ end
132
+
81
133
  def summary
82
- summary = {}
83
- parts.each do |part|
84
- summary[part[:action]] ||= 0
85
- summary[part[:action]] += 1
134
+ # resources
135
+ resource_summary = {}
136
+ resource_parts.each do |part|
137
+ resource_summary[part[:action]] ||= 0
138
+ resource_summary[part[:action]] += 1
86
139
  end
87
- pieces = summary.map { |k, v|
140
+ resource_pieces = resource_summary.map { |k, v|
88
141
  color = color_for_action(k)
89
142
  "#{Paint[v, :yellow]} to #{Paint[k, color]}"
90
143
  }
91
144
 
92
- "Plan Summary: #{pieces.join(Paint[", ", :gray])}"
145
+ # outputs
146
+ output_summary = {}
147
+ output_parts.each do |part|
148
+ output_summary[part[:action]] ||= 0
149
+ output_summary[part[:action]] += 1
150
+ end
151
+ output_pieces = output_summary.map { |k, v|
152
+ color = color_for_action(k)
153
+ "#{Paint[v, :yellow]} to #{Paint[k, color]}"
154
+ }
155
+
156
+ if resource_pieces.any? || output_pieces.any?
157
+ [
158
+ "Plan Summary:",
159
+ resource_pieces.any? ? resource_pieces.join(Paint[", ", :gray]) : nil,
160
+ output_pieces.any? ? "Outputs: #{output_pieces.join(Paint[", ", :gray])}" : nil
161
+ ].compact.join(" ")
162
+ else
163
+ "Plan Summary: no changes"
164
+ end
93
165
  end
94
166
 
95
167
  def flat_summary
96
168
  result = []
97
- parts.each do |part|
169
+ resource_parts.each do |part|
98
170
  result << "[#{format_action(part[:action])}] #{format_address(part[:address])}"
99
171
  end
100
172
  result
101
173
  end
102
174
 
175
+ def sensitive_summary(bv, av)
176
+ # before vs after
177
+ if bv && av
178
+ "(#{Paint["sensitive", :yellow]})"
179
+ elsif bv
180
+ "(#{Paint["-sensitive", :red]})"
181
+ elsif av
182
+ "(#{Paint["+sensitive", :cyan]})"
183
+ end
184
+ end
185
+
186
+ def output_summary
187
+ result = []
188
+ output_parts.each do |part|
189
+ pieces = [
190
+ "[#{format_action(part[:action])}]",
191
+ format_address("output.#{part[:address]}"),
192
+ part[:after_unknown] ? "(unknown)" : nil,
193
+ sensitive_summary(*part[:sensitive])
194
+ ].compact
195
+ result << pieces.join(" ")
196
+ end
197
+ result
198
+ end
199
+
103
200
  def nested_summary
104
201
  result = []
105
- parts = parts.deep_dup
202
+ parts = resource_parts.deep_dup
106
203
  until parts.empty?
107
204
  part = parts.shift
108
205
  if part[:deps] == []
@@ -131,7 +228,7 @@ module MuxTf
131
228
  def run_interactive
132
229
  prompt = TTY::Prompt.new
133
230
  result = prompt.multi_select("Update resources:", per_page: 99, echo: false) { |menu|
134
- parts.each do |part|
231
+ resource_parts.each do |part|
135
232
  label = "[#{format_action(part[:action])}] #{format_address(part[:address])}"
136
233
  menu.choice label, part[:address]
137
234
  end
@@ -187,14 +284,17 @@ module MuxTf
187
284
  plan.flat_summary.each do |line|
188
285
  log line, depth: 2
189
286
  end
287
+ plan.output_summary.each do |line|
288
+ log line, depth: 2
289
+ end
190
290
  log "", depth: 2
191
291
  log plan.summary, depth: 2
192
292
  end
193
293
 
194
294
  def prune_unchanged_deps(parts)
195
- valid_addresses = parts.map { |part| part[:address] }
295
+ valid_addresses = resource_parts.map { |part| part[:address] }
196
296
 
197
- parts.each do |part|
297
+ resource_parts.each do |part|
198
298
  part[:deps].select! { |dep| valid_addresses.include?(dep) }
199
299
  end
200
300
  end
@@ -32,6 +32,13 @@ class ResourceTokenizer
32
32
  pn = n
33
33
  state = :ri
34
34
  end
35
+ if n == resource.length - 1
36
+ # last character .. close the current group
37
+ # the last thing should only ever be an index or a name
38
+ result << [:rn, resource[pn..n]]
39
+ pn = n
40
+ state = :done
41
+ end
35
42
  when :ri
36
43
  # looking for ]
37
44
  if resource[n] == "]"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MuxTf
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mux_tf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Banasik
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-23 00:00:00.000000000 Z
11
+ date: 2021-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport