mux_tf 0.4.6 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/tf_current +2 -1
- data/exe/tf_mux +2 -1
- data/exe/tf_plan_summary +2 -1
- data/lib/mux_tf.rb +1 -2
- data/lib/mux_tf/cli/current.rb +4 -4
- data/lib/mux_tf/plan_formatter.rb +11 -4
- data/lib/mux_tf/plan_summary_handler.rb +59 -9
- data/lib/mux_tf/resource_tokenizer.rb +55 -0
- data/lib/mux_tf/terraform_helpers.rb +7 -2
- data/lib/mux_tf/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1742588983c720769618427118003ad76ab69f8be2035b19f8c779ab1876669
|
4
|
+
data.tar.gz: 12563430cfe99792a995675611a0dbd8aad9582d6ed063c0a38335dec1bac6b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 302ebae8183b41dfb4c7218d95dcdf9d0117df023caf80c6a38ec9969071b6af55d538e73eb08e6ef275816e6dc29220277c4b731202df9f5f30b9f4e3013c5c
|
7
|
+
data.tar.gz: 3af421ee73ec82cb62d0b9e8ae41c9a220b5feae31dda1328b14c71aa8d6e02b5acd858da13fe606ecfcfeaf290f99a9d7b0806b0b2f9ea40e752d5f8d544bc6
|
data/exe/tf_current
CHANGED
data/exe/tf_mux
CHANGED
data/exe/tf_plan_summary
CHANGED
data/lib/mux_tf.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "./deps"
|
4
|
-
|
5
3
|
require "English"
|
6
4
|
|
7
5
|
require "shellwords"
|
@@ -22,6 +20,7 @@ require "tty-table"
|
|
22
20
|
require "dotenv"
|
23
21
|
|
24
22
|
require_relative "./mux_tf/version"
|
23
|
+
require_relative "./mux_tf/resource_tokenizer"
|
25
24
|
require_relative "./mux_tf/cli"
|
26
25
|
require_relative "./mux_tf/tmux"
|
27
26
|
require_relative "./mux_tf/terraform_helpers"
|
data/lib/mux_tf/cli/current.rb
CHANGED
@@ -103,9 +103,9 @@ module MuxTf
|
|
103
103
|
tf_validate.parsed_output
|
104
104
|
end
|
105
105
|
|
106
|
-
def create_plan(filename)
|
106
|
+
def create_plan(filename, targets: [])
|
107
107
|
log "Preparing Plan ...", depth: 1
|
108
|
-
exit_code, meta = PlanFormatter.pretty_plan(filename)
|
108
|
+
exit_code, meta = PlanFormatter.pretty_plan(filename, targets: targets)
|
109
109
|
case exit_code
|
110
110
|
when 0
|
111
111
|
[:ok, meta]
|
@@ -276,8 +276,8 @@ module MuxTf
|
|
276
276
|
end
|
277
277
|
end
|
278
278
|
|
279
|
-
def run_plan
|
280
|
-
plan_status, @plan_meta = create_plan(PLAN_FILENAME)
|
279
|
+
def run_plan(targets: [])
|
280
|
+
plan_status, @plan_meta = create_plan(PLAN_FILENAME, targets: targets)
|
281
281
|
|
282
282
|
case plan_status
|
283
283
|
when :ok
|
@@ -6,7 +6,7 @@ module MuxTf
|
|
6
6
|
extend PiotrbCliUtils::Util
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def pretty_plan(filename)
|
9
|
+
def pretty_plan(filename, targets: [])
|
10
10
|
pastel = Pastel.new
|
11
11
|
|
12
12
|
phase = :init
|
@@ -15,8 +15,8 @@ module MuxTf
|
|
15
15
|
|
16
16
|
parser = StatefulParser.new(normalizer: pastel.method(:strip))
|
17
17
|
parser.state(:info, /^Acquiring state lock/)
|
18
|
-
parser.state(:error, /Error locking state/, %i[none blank info])
|
19
|
-
parser.state(:refreshing, /^.+: Refreshing state... \[id=/, %i[none])
|
18
|
+
parser.state(:error, /(╷|Error locking state|Error:)/, %i[none blank info])
|
19
|
+
parser.state(:refreshing, /^.+: Refreshing state... \[id=/, %i[none info])
|
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])
|
@@ -28,7 +28,7 @@ module MuxTf
|
|
28
28
|
|
29
29
|
parser.state(:plan_error, /^Error: /, %i[refreshing refresh_done])
|
30
30
|
|
31
|
-
status = tf_plan(out: filename, detailed_exitcode: true, compact_warnings: true) { |raw_line|
|
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|
|
33
33
|
case state
|
34
34
|
when :none
|
@@ -126,6 +126,10 @@ module MuxTf
|
|
126
126
|
next
|
127
127
|
end
|
128
128
|
case stripped_line
|
129
|
+
when /^Downloading (?<repo>[^ ]+) (?<version>[^ ]+) for (?<module>[^ ]+)\.\.\./
|
130
|
+
print "D"
|
131
|
+
when /^- (?<module>[^ ]+) in (?<path>.+)$/
|
132
|
+
print "."
|
129
133
|
when ""
|
130
134
|
puts
|
131
135
|
else
|
@@ -182,6 +186,9 @@ module MuxTf
|
|
182
186
|
next
|
183
187
|
end
|
184
188
|
case stripped_line
|
189
|
+
when /^- Reusing previous version of (?<module>.+) from the dependency lock file$/
|
190
|
+
info = $LAST_MATCH_INFO.named_captures
|
191
|
+
log "- [FROM-LOCK] #{info["module"]}", depth: 2
|
185
192
|
when /^- (?<module>.+) is built in to Terraform$/
|
186
193
|
info = $LAST_MATCH_INFO.named_captures
|
187
194
|
log "- [BUILTIN] #{info["module"]}", depth: 2
|
@@ -6,6 +6,8 @@ module MuxTf
|
|
6
6
|
include TerraformHelpers
|
7
7
|
include PiotrbCliUtils::Util
|
8
8
|
|
9
|
+
PLAN_FILENAME = "foo.tfplan"
|
10
|
+
|
9
11
|
def self.from_file(file)
|
10
12
|
data = data_from_file(file)
|
11
13
|
new data
|
@@ -137,11 +139,7 @@ module MuxTf
|
|
137
139
|
|
138
140
|
if !result.empty?
|
139
141
|
log "Re-running apply with the selected resources ..."
|
140
|
-
|
141
|
-
unless status.success?
|
142
|
-
log Paint["Failed! (#{status.status})", :red]
|
143
|
-
throw :abort, "Apply Failed! #{status.status}"
|
144
|
-
end
|
142
|
+
run_plan(targets: result)
|
145
143
|
else
|
146
144
|
throw :abort, "nothing selected"
|
147
145
|
end
|
@@ -151,6 +149,48 @@ module MuxTf
|
|
151
149
|
|
152
150
|
attr_reader :parts
|
153
151
|
|
152
|
+
def create_plan(filename, targets: [])
|
153
|
+
log "Preparing Plan ...", depth: 1
|
154
|
+
exit_code, meta = PlanFormatter.pretty_plan(filename, targets: targets)
|
155
|
+
case exit_code
|
156
|
+
when 0
|
157
|
+
[:ok, meta]
|
158
|
+
when 1
|
159
|
+
[:error, meta]
|
160
|
+
when 2
|
161
|
+
[:changes, meta]
|
162
|
+
else
|
163
|
+
log Paint["terraform plan exited with an unknown exit code: #{exit_code}", :yellow]
|
164
|
+
[:unknown, meta]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def run_plan(targets: [])
|
169
|
+
plan_status, @plan_meta = create_plan(PLAN_FILENAME, targets: targets)
|
170
|
+
|
171
|
+
case plan_status
|
172
|
+
when :ok
|
173
|
+
log "no changes", depth: 1
|
174
|
+
when :error
|
175
|
+
log "something went wrong", depth: 1
|
176
|
+
when :changes
|
177
|
+
log "Printing Plan Summary ...", depth: 1
|
178
|
+
pretty_plan_summary(PLAN_FILENAME)
|
179
|
+
when :unknown
|
180
|
+
# nothing
|
181
|
+
end
|
182
|
+
plan_status
|
183
|
+
end
|
184
|
+
|
185
|
+
def pretty_plan_summary(filename)
|
186
|
+
plan = PlanSummaryHandler.from_file(filename)
|
187
|
+
plan.flat_summary.each do |line|
|
188
|
+
log line, depth: 2
|
189
|
+
end
|
190
|
+
log "", depth: 2
|
191
|
+
log plan.summary, depth: 2
|
192
|
+
end
|
193
|
+
|
154
194
|
def prune_unchanged_deps(parts)
|
155
195
|
valid_addresses = parts.map { |part| part[:address] }
|
156
196
|
|
@@ -250,11 +290,21 @@ module MuxTf
|
|
250
290
|
end
|
251
291
|
|
252
292
|
def format_address(address)
|
253
|
-
|
254
|
-
parts
|
255
|
-
|
293
|
+
result = []
|
294
|
+
parts = ResourceTokenizer.tokenize(address)
|
295
|
+
parts.each_with_index do |(part_type, part_value), index|
|
296
|
+
case part_type
|
297
|
+
when :rt
|
298
|
+
result << "." if index > 0
|
299
|
+
result << Paint[part_value, :cyan]
|
300
|
+
when :rn
|
301
|
+
result << "."
|
302
|
+
result << part_value
|
303
|
+
when :ri
|
304
|
+
result << Paint[part_value, :green]
|
305
|
+
end
|
256
306
|
end
|
257
|
-
|
307
|
+
result.join
|
258
308
|
end
|
259
309
|
end
|
260
310
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class ResourceTokenizer
|
2
|
+
def self.split(resource)
|
3
|
+
tokenize(resource).map(&:last)
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.tokenize(resource)
|
7
|
+
result = []
|
8
|
+
n = 0
|
9
|
+
pn = 0
|
10
|
+
state = :rt
|
11
|
+
until n >= resource.length
|
12
|
+
case state
|
13
|
+
when :rt
|
14
|
+
# looking for .
|
15
|
+
if resource[n] == "."
|
16
|
+
# reached the dot ..
|
17
|
+
result << [:rt, resource[pn...n]]
|
18
|
+
pn = n + 1
|
19
|
+
state = :rn
|
20
|
+
end
|
21
|
+
when :rn
|
22
|
+
# looking for [ or .
|
23
|
+
if resource[n] == "."
|
24
|
+
# reached the dot ..
|
25
|
+
result << [:rn, resource[pn...n]]
|
26
|
+
pn = n + 1
|
27
|
+
state = :rt
|
28
|
+
end
|
29
|
+
if resource[n] == "["
|
30
|
+
# reached the open bracket
|
31
|
+
result << [:rn, resource[pn...n]]
|
32
|
+
pn = n
|
33
|
+
state = :ri
|
34
|
+
end
|
35
|
+
when :ri
|
36
|
+
# looking for ]
|
37
|
+
if resource[n] == "]"
|
38
|
+
# reached the close bracket
|
39
|
+
result << [:ri, resource[pn..n]]
|
40
|
+
pn = n + 1
|
41
|
+
state = :rt
|
42
|
+
if resource[n + 1] == "."
|
43
|
+
pn = n + 2
|
44
|
+
n += 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
else
|
48
|
+
warn "unhandled state: #{state.inspect}"
|
49
|
+
end
|
50
|
+
# p resource[n]
|
51
|
+
n += 1
|
52
|
+
end
|
53
|
+
result
|
54
|
+
end
|
55
|
+
end
|
@@ -37,13 +37,18 @@ module MuxTf
|
|
37
37
|
stream_or_run_terraform(cmd, &block)
|
38
38
|
end
|
39
39
|
|
40
|
-
def tf_plan(out:, color: true, detailed_exitcode: nil, compact_warnings: false, input: nil, &block)
|
40
|
+
def tf_plan(out:, color: true, detailed_exitcode: nil, compact_warnings: false, input: nil, targets: [], &block)
|
41
41
|
args = []
|
42
42
|
args += ["-out", out]
|
43
43
|
args << "-input=#{input.inspect}" unless input.nil?
|
44
44
|
args << "-compact-warnings" if compact_warnings
|
45
45
|
args << "-no-color" unless color
|
46
46
|
args << "-detailed-exitcode" if detailed_exitcode
|
47
|
+
if targets && !targets.empty?
|
48
|
+
targets.each do |target|
|
49
|
+
args << "-target=#{target}"
|
50
|
+
end
|
51
|
+
end
|
47
52
|
|
48
53
|
cmd = tf_prepare_command(["plan", *args], need_auth: true)
|
49
54
|
stream_or_run_terraform(cmd, &block)
|
@@ -73,7 +78,7 @@ module MuxTf
|
|
73
78
|
end
|
74
79
|
|
75
80
|
def stream_or_run_terraform(args, &block)
|
76
|
-
if
|
81
|
+
if block
|
77
82
|
stream_terraform(args, &block)
|
78
83
|
else
|
79
84
|
run_terraform(args)
|
data/lib/mux_tf/version.rb
CHANGED
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.
|
4
|
+
version: 0.5.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:
|
11
|
+
date: 2021-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -143,6 +143,7 @@ files:
|
|
143
143
|
- lib/mux_tf/cli/plan_summary.rb
|
144
144
|
- lib/mux_tf/plan_formatter.rb
|
145
145
|
- lib/mux_tf/plan_summary_handler.rb
|
146
|
+
- lib/mux_tf/resource_tokenizer.rb
|
146
147
|
- lib/mux_tf/terraform_helpers.rb
|
147
148
|
- lib/mux_tf/tmux.rb
|
148
149
|
- lib/mux_tf/version.rb
|
@@ -170,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
171
|
- !ruby/object:Gem::Version
|
171
172
|
version: '0'
|
172
173
|
requirements: []
|
173
|
-
rubygems_version: 3.
|
174
|
+
rubygems_version: 3.1.4
|
174
175
|
signing_key:
|
175
176
|
specification_version: 4
|
176
177
|
summary: Terraform Multiplexing Scripts
|