mux_tf 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MuxTf
4
+ module TerraformHelpers
5
+ include PiotrbCliUtils::ShellHelpers
6
+
7
+ def tf_force_unlock(id:)
8
+ run_terraform(tf_prepare_command(['force-unlock', '-force', id], need_auth: true))
9
+ end
10
+
11
+ def tf_apply(filename: nil, targets: [])
12
+ args = []
13
+ args << filename if filename
14
+ if targets && !targets.empty?
15
+ targets.each do |target|
16
+ args << "-target=#{target}"
17
+ end
18
+ end
19
+
20
+ cmd = tf_prepare_command(['apply', *args], need_auth: true)
21
+ run_terraform(cmd)
22
+ end
23
+
24
+ def tf_validate
25
+ cmd = tf_prepare_command(['validate', '-json'], need_auth: true)
26
+ capture_terraform(cmd, json: true)
27
+ end
28
+
29
+ def tf_init(input: nil, upgrade: nil, color: true, &block)
30
+ args = []
31
+ args << "-input=#{input.inspect}" unless input.nil?
32
+ args << '-upgrade' unless upgrade.nil?
33
+ args << '-no-color' unless color
34
+
35
+ cmd = tf_prepare_command(['init', *args], need_auth: true)
36
+ stream_or_run_terraform(cmd, &block)
37
+ end
38
+
39
+ def tf_plan(out:, color: true, detailed_exitcode: nil, compact_warnings: false, input: nil, &block)
40
+ args = []
41
+ args += ['-out', out]
42
+ args << "-input=#{input.inspect}" unless input.nil?
43
+ args << '-compact-warnings' if compact_warnings
44
+ args << '-no-color' unless color
45
+ args << '-detailed-exitcode' if detailed_exitcode
46
+
47
+ cmd = tf_prepare_command(['plan', *args], need_auth: true)
48
+ stream_or_run_terraform(cmd, &block)
49
+ end
50
+
51
+ def tf_show(file, json: false)
52
+ if json
53
+ args = ['show', '-json', file]
54
+ cmd = tf_prepare_command(args, need_auth: true)
55
+ capture_terraform(cmd, json: true)
56
+ else
57
+ args = ['show', file]
58
+ cmd = tf_prepare_command(args, need_auth: true)
59
+ run_terraform(cmd)
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def tf_prepare_command(args, need_auth:)
66
+ if ENV['MUX_TF_AUTH_WRAPPER'] && need_auth
67
+ words = Shellwords.shellsplit(ENV['MUX_TF_AUTH_WRAPPER'])
68
+ [*words, 'terraform', *args]
69
+ else
70
+ ['terraform', *args]
71
+ end
72
+ end
73
+
74
+ def stream_or_run_terraform(args, &block)
75
+ if block_given?
76
+ stream_terraform(args, &block)
77
+ else
78
+ run_terraform(args)
79
+ end
80
+ end
81
+
82
+ # return_status: false, echo_command: true, quiet: false, indent: 0
83
+ def run_terraform(args, **_options)
84
+ status = run_shell(args, return_status: true, echo_command: true, quiet: false)
85
+ OpenStruct.new({
86
+ status: status,
87
+ success?: status == 0
88
+ })
89
+ end
90
+
91
+ def stream_terraform(args, &block)
92
+ status = run_with_each_line(args, &block)
93
+ # status is a Process::Status
94
+ OpenStruct.new({
95
+ status: status.exitstatus,
96
+ success?: status.exitstatus == 0
97
+ })
98
+ end
99
+
100
+ # error: true, echo_command: true, indent: 0, raise_on_error: false, detailed_result: false
101
+ def capture_terraform(args, json: nil)
102
+ result = capture_shell(args, error: true, echo_command: false, raise_on_error: false, detailed_result: true)
103
+ parsed_output = JSON.parse(result.output) if json
104
+ OpenStruct.new({
105
+ status: result.status,
106
+ success?: result.status == 0,
107
+ output: result.output,
108
+ parsed_output: parsed_output
109
+ })
110
+ rescue JSON::ParserError => e
111
+ fail_with "Execution Failed! - #{result.inspect}"
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'shellwords'
4
+
5
+ module MuxTf
6
+ module Tmux
7
+ class << self
8
+ def session_running?(name)
9
+ tmux("has-session -t #{name.inspect} 2>/dev/null", raise_on_error: false)
10
+ end
11
+
12
+ def kill_session(name)
13
+ tmux(%(kill-session -t #{name.inspect}))
14
+ end
15
+
16
+ def find_pane(name)
17
+ panes = `tmux list-panes -F "\#{pane_id},\#{pane_title}"`.strip.split("\n").map do |row|
18
+ x = row.split(',')
19
+ return { id: x[0], name: x[1] }
20
+ end
21
+ panes.find { |pane| pane[:name] == name }
22
+ end
23
+
24
+ def new_session(name)
25
+ tmux %(new-session -s #{name.inspect} -d)
26
+ end
27
+
28
+ def select_pane(name)
29
+ tmux %(select-pane -T #{name.inspect})
30
+ end
31
+
32
+ def set_hook(hook_name, cmd)
33
+ tmux %(set-hook #{hook_name.inspect} #{cmd.inspect})
34
+ end
35
+
36
+ def set(var, value)
37
+ tmux %(set #{var.inspect} #{value.inspect})
38
+ end
39
+
40
+ def tile!
41
+ tmux 'select-layout tiled'
42
+ end
43
+
44
+ def attach(name, cc: false)
45
+ tmux %(#{cc && '-CC' || ''} attach -t #{name.inspect}), raise_on_error: false
46
+ end
47
+
48
+ def kill_pane(pane_id)
49
+ tmux %(kill-pane -t #{pane_id.inspect})
50
+ end
51
+
52
+ def send_keys(cmd, enter: false)
53
+ tmux %(send-keys #{cmd.inspect})
54
+ tmux %(send-keys Enter) if enter
55
+ end
56
+
57
+ def split_window(mode, target_pane, cwd: nil, cmd: nil)
58
+ case mode
59
+ when :horizontal
60
+ mode_part = '-h'
61
+ when :vertical
62
+ mode_part = '-v'
63
+ else
64
+ raise ArgumentError, "invalid mode: #{mode.inspect}"
65
+ end
66
+
67
+ parts = [
68
+ 'split-window',
69
+ cwd && "-c #{cwd}",
70
+ mode_part,
71
+ "-t #{target_pane.inspect}",
72
+ cmd&.inspect
73
+ ].compact
74
+ tmux parts.join(' ')
75
+ end
76
+
77
+ private
78
+
79
+ def tmux_bin
80
+ @tmux_bin ||= `which tmux`.strip
81
+ end
82
+
83
+ def tmux(cmd, raise_on_error: true, mode: :system)
84
+ case mode
85
+ when :system
86
+ # puts " => tmux #{cmd}"
87
+ system("#{tmux_bin} #{cmd}")
88
+ unless $CHILD_STATUS.success?
89
+ if raise_on_error
90
+ fail_with("`tmux #{cmd}' failed with code: #{$CHILD_STATUS.exitstatus}")
91
+ end
92
+
93
+ return false
94
+ end
95
+ true
96
+ when :exec
97
+ exec tmux_bin, *Shellwords.shellwords(cmd)
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MuxTf
4
+ VERSION = '0.1.2'
5
+ end
data/mux_tf.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/mux_tf/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'mux_tf'
7
+ spec.version = MuxTf::VERSION
8
+ spec.authors = ['Piotr Banasik']
9
+ spec.email = ['piotr@jane.app']
10
+
11
+ spec.summary = 'Terraform Multiplexing Scripts'
12
+ # spec.description = 'TODO: Write a longer description or delete this line.'
13
+ spec.homepage = 'https://github.com/piotrb/mux_tf'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
16
+
17
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = spec.homepage
21
+ # spec.metadata['changelog_uri'] = "TODO: Put your gem's CHANGELOG.md URL here."
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ end
28
+ spec.bindir = 'exe'
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ['lib']
31
+
32
+ spec.add_dependency 'activesupport'
33
+ spec.add_dependency 'dotenv'
34
+ spec.add_dependency 'paint'
35
+ spec.add_dependency 'pastel'
36
+ spec.add_dependency 'piotrb_cli_utils', '~> 0.1.0'
37
+ spec.add_dependency 'stateful_parser', '~> 0.1.1'
38
+ spec.add_dependency 'tty-prompt'
39
+ spec.add_dependency 'tty-table'
40
+ end
metadata ADDED
@@ -0,0 +1,178 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mux_tf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Piotr Banasik
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-05-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: paint
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pastel
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: piotrb_cli_utils
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.1.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.1.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: stateful_parser
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.1.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.1.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: tty-prompt
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: tty-table
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description:
126
+ email:
127
+ - piotr@jane.app
128
+ executables:
129
+ - tf_current
130
+ - tf_mux
131
+ - tf_plan_summary
132
+ extensions: []
133
+ extra_rdoc_files: []
134
+ files:
135
+ - ".gitignore"
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - exe/tf_current
141
+ - exe/tf_mux
142
+ - exe/tf_plan_summary
143
+ - lib/mux_tf.rb
144
+ - lib/mux_tf/cli.rb
145
+ - lib/mux_tf/cli/current.rb
146
+ - lib/mux_tf/cli/mux.rb
147
+ - lib/mux_tf/cli/plan_summary.rb
148
+ - lib/mux_tf/plan_formatter.rb
149
+ - lib/mux_tf/terraform_helpers.rb
150
+ - lib/mux_tf/tmux.rb
151
+ - lib/mux_tf/version.rb
152
+ - mux_tf.gemspec
153
+ homepage: https://github.com/piotrb/mux_tf
154
+ licenses:
155
+ - MIT
156
+ metadata:
157
+ homepage_uri: https://github.com/piotrb/mux_tf
158
+ source_code_uri: https://github.com/piotrb/mux_tf
159
+ post_install_message:
160
+ rdoc_options: []
161
+ require_paths:
162
+ - lib
163
+ required_ruby_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: 2.3.0
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ requirements: []
174
+ rubygems_version: 3.1.3
175
+ signing_key:
176
+ specification_version: 4
177
+ summary: Terraform Multiplexing Scripts
178
+ test_files: []