vtk 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f38bf2816e12d02d33715da96ee84b7101f72378daa994e7a09dcf84769d46b7
4
- data.tar.gz: d823b0a548bb2b51d6e945b692c3ee396c556dedd715171d40266a1c3f86a5a8
3
+ metadata.gz: 469019fb5bc0695ac68a0deab5ff68305f62852cbe38207bbb199cfee99f805b
4
+ data.tar.gz: e81be7f9896a0f057bf4c0c5fb55e904ffecd1fbd56951a84ac8fe9d334e9e0e
5
5
  SHA512:
6
- metadata.gz: 0a9f1ab0d6e9b15a5397f277eb1cce487f7b73d7c5aace867c74c443f5c7f16a7edc2985bae32f4e227018601aefeb5e6cf6447064ee000e0968eeabad5bdc51
7
- data.tar.gz: 25f80d204782a2327745b04dfdd76a6708651b941fc0aa73489c92d5c7e706d834cb9e588519e913c9435656ad75fc7c4c8bbba0db67d849f83f6385c35784d5
6
+ metadata.gz: '01898cc5e93c4db7ff791b222f087d64f80730f20388ed35c8fdce2ad4adaec71e4fc417d515876baba10ddf64d38ac9978d1759e10e2418d44f71731f5b616f'
7
+ data.tar.gz: eddd67f1661dd3a0b7eefe49ab8e531ce1c3b26f4bd534cae9583dfee00c4cf721ae64179bbf42de31bf85c3b961b839c85700852401ef21eb8d54e37eb4afc7
data/.rubocop.yml CHANGED
@@ -1,3 +1,5 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
1
3
  AllCops:
2
4
  NewCops: enable
3
5
  TargetRubyVersion: 2.5
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,12 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2021-07-29 22:40:06 UTC using RuboCop version 1.8.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Configuration parameters: CountComments, CountAsOne.
11
+ Metrics/ClassLength:
12
+ Max: 351
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased](https://github.com/department-of-veterans-affairs/vtk/tree/HEAD)
4
+
5
+ [Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/v0.8.0...HEAD)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - Command Analytics [\#8](https://github.com/department-of-veterans-affairs/vtk/pull/8) ([ericboehs](https://github.com/ericboehs))
10
+
11
+ ## [v0.8.0](https://github.com/department-of-veterans-affairs/vtk/tree/v0.8.0) (2021-03-01)
12
+
13
+ [Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/v0.7.0...v0.8.0)
14
+
15
+ **Merged pull requests:**
16
+
17
+ - Updating name [\#17](https://github.com/department-of-veterans-affairs/vtk/pull/17) ([alexpappasoddball](https://github.com/alexpappasoddball))
18
+ - Made changes to how the arguments are handled [\#15](https://github.com/department-of-veterans-affairs/vtk/pull/15) ([thilton-oddball](https://github.com/thilton-oddball))
19
+
20
+ ## [v0.7.0](https://github.com/department-of-veterans-affairs/vtk/tree/v0.7.0) (2021-03-01)
21
+
22
+ [Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/v0.5.0...v0.7.0)
23
+
3
24
  ## [v0.5.0](https://github.com/department-of-veterans-affairs/vtk/tree/v0.5.0) (2021-02-19)
4
25
 
5
26
  [Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/v0.4.0...v0.5.0)
@@ -59,6 +80,7 @@
59
80
  **Merged pull requests:**
60
81
 
61
82
  - fixing markdown in README … [\#3](https://github.com/department-of-veterans-affairs/vtk/pull/3) ([thilton-oddball](https://github.com/thilton-oddball))
83
+ - Open Jenkins [\#1](https://github.com/department-of-veterans-affairs/vtk/pull/1) ([cvalarida](https://github.com/cvalarida))
62
84
 
63
85
  ## [v0.1.0](https://github.com/department-of-veterans-affairs/vtk/tree/v0.1.0) (2021-01-04)
64
86
 
@@ -72,10 +94,6 @@
72
94
 
73
95
  [Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/79143038509757799edb2bb9be2f925b7d985221...oclif)
74
96
 
75
- **Merged pull requests:**
76
-
77
- - Open Jenkins [\#1](https://github.com/department-of-veterans-affairs/vtk/pull/1) ([cvalarida](https://github.com/cvalarida))
78
-
79
97
 
80
98
 
81
99
  \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/README.md CHANGED
@@ -35,6 +35,25 @@ This above command runs a custom rails generator. For more information see the [
35
35
 
36
36
  Handles connecting to VA network via SOCKS.
37
37
 
38
+ ---
39
+
40
+ ```
41
+ $ vtk socks setup
42
+ ```
43
+
44
+ The **setup subcommand** will do the following:
45
+ - Download the recommended `.ssh/config` if missing.
46
+ - Generate a VA SSH key if missing (and opens the access request form).
47
+ - Add your VA SSH key to your ssh agent and keychain.
48
+ - Test the SOCKS tunnel via SSH and HTTP
49
+ - Configure your system to start the SOCKS tunnel on boot
50
+ - Configure your system proxy for use on VA.gov domains (all other traffic bypasses the proxy).
51
+ - Allow you to troubleshoot your SOCKS connection by running it again.
52
+
53
+ **NOTE**: Running `vtk socks on` and/or `vtk socks off` is not necessary when using `vtk socks setup`.
54
+
55
+ ---
56
+
38
57
  ```
39
58
  $ vtk socks on
40
59
  ----> Connecting...
data/exe/vtk CHANGED
@@ -6,7 +6,7 @@ $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
6
6
  require 'vtk/cli'
7
7
 
8
8
  Signal.trap('INT') do
9
- warn("\n#{caller.join("\n")}: interrupted")
9
+ warn("\n#{caller.join("\n")}: interrupted") if ENV['DEBUG']
10
10
  exit(1)
11
11
  end
12
12
 
@@ -8,6 +8,24 @@ module Vtk
8
8
  class Socks < Thor
9
9
  namespace :socks
10
10
 
11
+ desc 'setup', 'Configures local machine for VA SOCKS access'
12
+ method_option :help, aliases: '-h', type: :boolean,
13
+ desc: 'Display usage information'
14
+ method_option :boot_script_path, type: :string, desc: 'Path to install boot script (e.g. ~/Library)'
15
+ method_option :ssh_key_path, type: :string, desc: 'Path to SSH key (e.g. ~/.ssh/id_rsa_vagov)'
16
+ method_option :ssh_config_path, type: :string, desc: 'Path to SSH config (e.g. ~/.ssh/config)'
17
+ method_option :port, aliases: '-p', type: :string,
18
+ desc: 'Port that SOCKS server is running on'
19
+ method_option :skip_test, type: :boolean, desc: 'Skip testing SOCKS connection'
20
+ def setup(*)
21
+ if options[:help]
22
+ invoke :help, ['setup']
23
+ else
24
+ require_relative 'socks/setup'
25
+ Vtk::Commands::Socks::Setup.new(options).execute
26
+ end
27
+ end
28
+
11
29
  desc 'off', 'Disconnects from VA SOCKS'
12
30
  method_option :help, aliases: '-h', type: :boolean,
13
31
  desc: 'Display usage information'
@@ -50,7 +50,7 @@ module Vtk
50
50
  return output.puts "\r----> Connected to SOCKS."
51
51
  end
52
52
 
53
- output.puts "\r----> ERROR: Could not connect to SOCKS."
53
+ output.puts "\r----> ERROR: Could not connect to SOCKS. Try running `vtk socks setup` first."
54
54
  output.puts "----> Verbose Output from SSH log:\n\n"
55
55
 
56
56
  output.puts File.read '/tmp/socks.log'
@@ -0,0 +1,469 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../command'
4
+ require 'tty-prompt'
5
+ require 'fileutils'
6
+ require 'erb'
7
+
8
+ module Vtk
9
+ module Commands
10
+ class Socks
11
+ # Sets up socks access to the VA network
12
+ class Setup < Vtk::Command
13
+ PROXY_URL = 'https://raw.githubusercontent.com/department-of-veterans-affairs/va.gov-team/master/' \
14
+ 'scripts/socks/proxy.pac'
15
+
16
+ attr_reader :ssh_config_path, :input, :output, :boot_script_path, :ssh_key_path, :prompt, :port, :skip_test
17
+
18
+ def initialize(options)
19
+ @options = options
20
+ @prompt = TTY::Prompt.new interrupt: :exit
21
+ @port = options['port'] || '2001'
22
+ @boot_script_path = options['boot_script_path'] || "#{ENV['HOME']}/Library"
23
+ @ssh_key_path = options['ssh_key_path'] || "#{ENV['HOME']}/.ssh/id_rsa_vagov"
24
+ @ssh_config_path = options['ssh_config_path'] || "#{ENV['HOME']}/.ssh/config"
25
+ @skip_test = options['skip_test'] || false
26
+
27
+ super()
28
+ end
29
+
30
+ def execute(input: $stdin, output: $stdout)
31
+ @input = input
32
+ @output = output
33
+
34
+ setup_ssh_config
35
+ check_ssh_key
36
+ ssh_agent_add
37
+
38
+ test_ssh_connection unless skip_test
39
+
40
+ configure_system_boot
41
+ configure_system_proxy
42
+
43
+ test_http_connection unless skip_test
44
+
45
+ log 'SOCKS setup complete.'
46
+ end
47
+
48
+ private
49
+
50
+ def check_ssh_key
51
+ return true if key_exists?
52
+
53
+ generate_key_and_open_key_access_request
54
+ end
55
+
56
+ def key_exists?
57
+ File.exist? ssh_key_path
58
+ end
59
+
60
+ def public_key_exists?
61
+ File.exist? "#{ssh_key_path}.pub"
62
+ end
63
+
64
+ def generate_key_and_open_key_access_request
65
+ log 'VA key missing. Generating now...'
66
+ system "ssh-keygen -f #{ssh_key_path} #{'-N ""' if ENV['TEST']}"
67
+
68
+ if prompt.yes?(copy_and_open_gh)
69
+ copy_key_to_clipboard
70
+ `#{'xdg-' unless macos?}open "#{access_request_template_url}" 2> /dev/null`
71
+ else
72
+ log "You'll need to submit ~/.ssh/id_rsa_vagov.pub for approval to: #{access_request_template_url}."
73
+ end
74
+ end
75
+
76
+ def copy_key_to_clipboard
77
+ ssh_key_contents = File.read "#{ssh_key_path}.pub"
78
+
79
+ if macos?
80
+ copy_command = 'pbcopy'
81
+ elsif ubuntu_like?
82
+ system 'sudo apt-get install -y xsel' if `which xsel`.empty?
83
+ copy_command = 'xsel --clipboard'
84
+ end
85
+
86
+ IO.popen(copy_command, 'w') { |f| f << ssh_key_contents }
87
+ end
88
+
89
+ def access_request_template_url
90
+ 'https://github.com/department-of-veterans-affairs/va.gov-team/issues/new?' \
91
+ 'assignees=&labels=external-request%2C+operations&template=Environment-Access-Request-Template.md&' \
92
+ 'title=Access+for+%5Bindividual%5D'
93
+ end
94
+
95
+ def copy_and_open_gh
96
+ '----> An SSH key has been created. Would you like to copy the key to your clipboard and open the access ' \
97
+ 'request issue in GitHub now?'
98
+ end
99
+
100
+ def setup_ssh_config
101
+ create_ssh_directory
102
+ install_ssh_config
103
+ configure_ssh_config_with_keychain
104
+ ssh_config_clean_up
105
+ end
106
+
107
+ def install_ssh_config
108
+ return true if ssh_config_configured?
109
+
110
+ if ssh_config_exists? && !prompt.yes?("----> #{pretty_ssh_config_path} incomplete. Backup and replace now?")
111
+ return false
112
+ end
113
+
114
+ log 'Installing SSH config...'
115
+
116
+ download_ssh_config unless File.exist? '/tmp/dova-devops'
117
+ backup_existing_ssh_config
118
+ FileUtils.cp '/tmp/dova-devops/ssh/config', ssh_config_path
119
+ FileUtils.chmod 0o600, "#{File.dirname ssh_config_path}/config"
120
+ end
121
+
122
+ def ssh_config_configured?
123
+ return false unless ssh_config_exists?
124
+
125
+ download_ssh_config
126
+ ssh_config_local = File.read ssh_config_path
127
+ ssh_config = File.read '/tmp/dova-devops/ssh/config'
128
+ ssh_config_local.include? ssh_config
129
+ end
130
+
131
+ def ssh_config_exists?
132
+ File.exist? ssh_config_path
133
+ end
134
+
135
+ def download_ssh_config
136
+ install_git
137
+
138
+ ssh_config_clean_up
139
+
140
+ ssh_agent_add
141
+ cloned = system(
142
+ "git clone --quiet#{' --depth 1' if macos?} --no-checkout --filter=blob:none #{repo_url} '/tmp/dova-devops'"
143
+ )
144
+ exit 1 unless cloned
145
+
146
+ `cd /tmp/dova-devops; git checkout master -- ssh/config`
147
+ end
148
+
149
+ def install_git
150
+ if macos?
151
+ install_brew
152
+ elsif ubuntu_like?
153
+ return true unless `which git`.empty?
154
+
155
+ system 'sudo apt-get install -y git'
156
+ end
157
+ end
158
+
159
+ def install_brew
160
+ return false unless macos?
161
+
162
+ installed = !`which brew`.empty?
163
+ return true if installed
164
+
165
+ log 'Homebrew not installed. Installing now...'
166
+ system '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
167
+ end
168
+
169
+ def ssh_config_clean_up
170
+ FileUtils.rm_rf '/tmp/dova-devops'
171
+ end
172
+
173
+ def repo_url
174
+ @repo_url ||= begin
175
+ keyscan_github_com
176
+
177
+ if github_ssh_configured
178
+ 'git@github.com:department-of-veterans-affairs/devops.git'
179
+ else
180
+ 'https://github.com/department-of-veterans-affairs/devops.git'
181
+ end
182
+ end
183
+ end
184
+
185
+ def keyscan_github_com
186
+ return true if File.exist?('~/.ssh/known_hosts') && !`ssh-keygen -F github.com`.empty?
187
+
188
+ `ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2> /dev/null`
189
+ end
190
+
191
+ def github_ssh_configured
192
+ !`ssh -T git@github.com 2>&1`.include?('Permission denied')
193
+ end
194
+
195
+ def backup_existing_ssh_config
196
+ return true unless ssh_config_exists?
197
+
198
+ if File.exist? "#{ssh_config_path}.bak"
199
+ log "!!! ERROR: Could not make backup of #{pretty_ssh_config_path} as #{pretty_ssh_config_path}.bak " \
200
+ 'exists. Aborting.'
201
+ exit 1
202
+ end
203
+
204
+ FileUtils.mv ssh_config_path, "#{ssh_config_path}.bak"
205
+ end
206
+
207
+ def create_ssh_directory
208
+ ssh_dir = File.dirname ssh_config_path
209
+ FileUtils.mkdir_p ssh_dir
210
+ FileUtils.chmod 0o700, ssh_dir
211
+ end
212
+
213
+ def configure_ssh_config_with_keychain
214
+ return unless macos?
215
+ return if ssh_config_configured_with_keychain?
216
+
217
+ keychain_config = <<~CFG
218
+
219
+ # Maintain SSH keys in macOS Keychain
220
+ Host *
221
+ UseKeychain yes
222
+ AddKeysToAgent yes
223
+ IdentityFile #{pretty_ssh_key_path}
224
+ CFG
225
+
226
+ IO.write ssh_config_path, keychain_config, mode: 'a'
227
+ end
228
+
229
+ def ssh_config_configured_with_keychain?
230
+ return false unless ssh_config_exists?
231
+
232
+ ssh_config_local = File.readlines ssh_config_path
233
+ ssh_config_local.grep(/UseKeychain yes/).size.positive?
234
+ end
235
+
236
+ def ssh_agent_add
237
+ FileUtils.chmod 0o600, ssh_key_path if key_exists?
238
+ FileUtils.chmod 0o600, "#{ssh_key_path}.pub" if public_key_exists?
239
+
240
+ if macos?
241
+ `ssh-add -AK 2> /dev/null; ssh-add -AK #{ssh_key_path} 2> /dev/null`
242
+ elsif ubuntu_like?
243
+ `[ -z "$SSH_AUTH_SOCK" ] && eval "$(ssh-agent -s)";
244
+ ssh-add 2> /dev/null; ssh-add #{ssh_key_path} 2> /dev/null`
245
+ end
246
+ end
247
+
248
+ def test_ssh_connection
249
+ output.print '----> Testing SOCKS SSH connection...'
250
+
251
+ add_ip_to_known_hosts
252
+
253
+ ssh_output = `ssh -i #{ssh_key_path} -F #{ssh_config_path} -o ConnectTimeout=5 -q socks -D #{port} exit 2>&1`
254
+
255
+ if ssh_output.include? 'This account is currently not available.'
256
+ output.puts ' ✅'
257
+ else
258
+ check_ssh_error ssh_output
259
+ exit 1
260
+ end
261
+ end
262
+
263
+ def add_ip_to_known_hosts
264
+ jump_box_ip = `grep -A 2 'Host socks' ~/.ssh/config | grep ProxyCommand | awk '{print $6}'`.chomp
265
+ socks_ip = `grep -A 2 'Host socks' ~/.ssh/config | grep HostName | awk '{print $2}'`.chomp
266
+
267
+ return unless `ssh-keygen -F #{socks_ip}`.empty?
268
+
269
+ `ssh-keyscan -H #{jump_box_ip} >> ~/.ssh/known_hosts 2> /dev/null`
270
+ `ssh -i #{ssh_key_path} dsva@#{jump_box_ip} 'ssh-keyscan -H #{socks_ip}' >> ~/.ssh/known_hosts 2> /dev/null`
271
+ end
272
+
273
+ def check_ssh_error(ssh_output)
274
+ if ssh_output.include? 'Permission denied (publickey)'
275
+ @skip_test = true
276
+ output.puts '⚠️ WARN: SSH key is not approved yet. Once it is, re-run `vtk socks setup`.'
277
+ else
278
+ ssh_command = "ssh -i #{ssh_key_path} -F #{ssh_config_path} -o ConnectTimeout=5 -vvv socks -D #{port} -N"
279
+ output.puts ' ❌ ERROR: SSH Connection to SOCKS server unsuccessful. Error message:'
280
+ output.puts ssh_command
281
+ output.puts `#{ssh_command}`
282
+ end
283
+ end
284
+
285
+ def configure_system_boot
286
+ log 'Configuring SOCKS tunnel to run on system boot...' do
287
+ install_autossh && (install_launch_agent || install_systemd_service)
288
+ end
289
+ end
290
+
291
+ def launch_agent_label
292
+ @launch_agent_label ||= begin
293
+ launch_agent_label = 'gov.va.socks'
294
+ launch_agent_label += "-test-#{rand 1000}" if ENV['TEST'] == 'test'
295
+ launch_agent_label
296
+ end
297
+ end
298
+
299
+ def install_autossh
300
+ installed = !`which autossh`.empty?
301
+ return true if installed
302
+
303
+ if macos?
304
+ system 'brew install autossh'
305
+ elsif ubuntu_like?
306
+ system 'sudo apt-get install -y autossh'
307
+ end
308
+ end
309
+
310
+ def install_launch_agent
311
+ return false unless macos?
312
+
313
+ unless File.exist? "#{boot_script_path}/LaunchAgents/gov.va.socks.plist"
314
+ FileUtils.mkdir_p "#{boot_script_path}/Logs/gov.va.socks"
315
+ FileUtils.mkdir_p "#{boot_script_path}/LaunchAgents"
316
+
317
+ write_launch_agent
318
+ end
319
+
320
+ system "launchctl unload #{boot_script_path}/LaunchAgents/gov.va.socks.plist 2> /dev/null"
321
+ system "launchctl load -w #{boot_script_path}/LaunchAgents/gov.va.socks.plist"
322
+ end
323
+
324
+ def write_launch_agent
325
+ erb_template = File.read File.realpath "#{__dir__}/../../templates/socks/setup/gov.va.socks.plist.erb"
326
+ erb = ERB.new erb_template
327
+ launch_agent_contents = erb.result(
328
+ launch_agent_variables.instance_eval { binding }
329
+ )
330
+ File.write "#{boot_script_path}/LaunchAgents/gov.va.socks.plist", launch_agent_contents
331
+ end
332
+
333
+ def launch_agent_variables
334
+ OpenStruct.new(
335
+ label: launch_agent_label,
336
+ autossh_path: `which autossh`.chomp,
337
+ port: @port,
338
+ boot_script_path: File.realpath(boot_script_path),
339
+ user: ENV['USER']
340
+ )
341
+ end
342
+
343
+ def install_systemd_service
344
+ return false unless ubuntu_like?
345
+
346
+ write_systemd_service unless File.exist? '/etc/systemd/system/va_gov_socks.service'
347
+
348
+ system 'sudo systemctl daemon-reload'
349
+ system 'sudo systemctl enable va_gov_socks'
350
+ system 'sudo systemctl start va_gov_socks'
351
+ end
352
+
353
+ def write_systemd_service
354
+ erb_template = File.read File.realpath "#{__dir__}/../../templates/socks/setup/va_gov_socks.service.erb"
355
+ erb = ERB.new erb_template
356
+ systemd_service_contents = erb.result(
357
+ systemd_service_variables.instance_eval { binding }
358
+ )
359
+ File.write '/tmp/va_gov_socks.service', systemd_service_contents
360
+ system 'sudo mv /tmp/va_gov_socks.service /etc/systemd/system/va_gov_socks.service'
361
+ end
362
+
363
+ def systemd_service_variables
364
+ OpenStruct.new(
365
+ autossh_path: `which autossh`.chomp,
366
+ port: @port,
367
+ ssh_key_path: ssh_key_path,
368
+ user: ENV['USER']
369
+ )
370
+ end
371
+
372
+ def configure_system_proxy
373
+ return log 'Skipping system proxy configuration as custom --port was used.' unless port == '2001'
374
+
375
+ if macos?
376
+ mac_configure_system_proxy
377
+ elsif ubuntu_like?
378
+ ubuntu_configure_system_proxy
379
+ end
380
+ end
381
+
382
+ def mac_configure_system_proxy
383
+ return true if mac_system_proxy_already_configured?
384
+
385
+ log 'Configuring system proxy to use SOCKS tunnel...' do
386
+ network_interfaces.map do |network_interface|
387
+ system %(networksetup -setautoproxyurl "#{network_interface}" "#{PROXY_URL}")
388
+ end.all?
389
+ end
390
+ end
391
+
392
+ def ubuntu_configure_system_proxy
393
+ return true if `gsettings get org.gnome.system.proxy mode` == "'auto'\n"
394
+
395
+ log 'Configuring system proxy to use SOCKS tunnel...' do
396
+ `gsettings set org.gnome.system.proxy mode 'auto'` &&
397
+ `gsettings set org.gnome.system.proxy autoconfig-url "#{PROXY_URL}"`
398
+ end
399
+ end
400
+
401
+ def mac_system_proxy_already_configured?
402
+ network_interfaces.map do |network_interface|
403
+ output = `networksetup -getautoproxyurl "#{network_interface}"`
404
+ output == "URL: #{PROXY_URL}\nEnabled: Yes\n"
405
+ end.all?
406
+ end
407
+
408
+ def network_interfaces
409
+ @network_interfaces ||= begin
410
+ `networksetup -listallnetworkservices`.split("\n").drop(1).select do |network_interface|
411
+ `networksetup -getautoproxyurl "#{network_interface}"`.start_with?('URL: (null)')
412
+ end
413
+ end
414
+ end
415
+
416
+ def test_http_connection
417
+ output.print '----> Testing SOCKS HTTP connection...'
418
+
419
+ success = 5.times.map do
420
+ sleep 1
421
+ not_connected = system "nscurl http://grafana.vfs.va.gov 2>&1 | grep -q 'hostname could not be found'"
422
+
423
+ break [true] unless not_connected
424
+ end.all?
425
+
426
+ output.puts success ? ' ✅' : ' ❌ ERROR: SOCKS connection failed HTTP test. Try running setup again.'
427
+
428
+ exit 1 unless success
429
+ end
430
+
431
+ def macos?
432
+ RUBY_PLATFORM.include? 'darwin'
433
+ end
434
+
435
+ def ubuntu_like?
436
+ return false if `which apt-get`.empty? && `which gsettings`.empty?
437
+
438
+ true
439
+ end
440
+
441
+ def pretty_ssh_config_path
442
+ pretty_path ssh_config_path
443
+ end
444
+
445
+ def pretty_ssh_key_path
446
+ pretty_path ssh_key_path
447
+ end
448
+
449
+ def pretty_path(path)
450
+ path.gsub ENV['HOME'], '~'
451
+ end
452
+
453
+ def log(message)
454
+ if block_given?
455
+ output.print "----> #{message}"
456
+
457
+ return_value = yield
458
+
459
+ output.puts return_value ? ' ✅' : ' ❌'
460
+
461
+ return_value
462
+ else
463
+ output.puts "----> #{message}"
464
+ end
465
+ end
466
+ end
467
+ end
468
+ end
469
+ end
@@ -0,0 +1 @@
1
+ #
@@ -0,0 +1,35 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Label</key>
6
+ <string><%= label %></string>
7
+
8
+ <key>RunAtLoad</key>
9
+ <true/>
10
+
11
+ <key>ProgramArguments</key>
12
+ <array>
13
+ <string><%= autossh_path %></string>
14
+ <string>-v</string>
15
+ <string>-M</string>
16
+ <string>0</string>
17
+ <string>-D</string>
18
+ <string><%= port %></string>
19
+ <string>socks</string>
20
+ <string>-N</string>
21
+ </array>
22
+
23
+ <key>StandardOutPath</key>
24
+ <string><%= boot_script_path %>/Logs/gov.va.socks/autossh.stdout</string>
25
+
26
+ <key>StandardErrorPath</key>
27
+ <string><%= boot_script_path %>/Logs/gov.va.socks/autossh.stderr</string>
28
+
29
+ <key>User</key>
30
+ <string><%= user %></string>
31
+
32
+ <key>ThrottleInterval</key>
33
+ <integer>30</integer>
34
+ </dict>
35
+ </plist>
@@ -0,0 +1,12 @@
1
+ [Unit]
2
+ Description=VA SOCKS Tunnel
3
+ After=network.target
4
+
5
+ [Service]
6
+ Environment="AUTOSSH_GATETIME=0"
7
+ ExecStart=<%= autossh_path %> -v -M 0 -D <%= port %> -i <%= ssh_key_path %> socks -N
8
+ Restart=always
9
+ User=<%= user %>
10
+
11
+ [Install]
12
+ WantedBy=multi-user.target
data/lib/vtk/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vtk
4
- VERSION = '0.8.0'
4
+ VERSION = '0.9.0'
5
5
  end
data/vtk.gemspec CHANGED
@@ -29,6 +29,8 @@ Gem::Specification.new do |spec|
29
29
  spec.require_paths = ['lib']
30
30
 
31
31
  spec.add_dependency 'thor', '> 0.20.3'
32
+ spec.add_dependency 'tty-command', '~> 0.10.0'
33
+ spec.add_dependency 'tty-prompt', '~> 0.23.0'
32
34
 
33
35
  spec.add_development_dependency 'github_changelog_generator', '~> 1.15.0'
34
36
  spec.add_development_dependency 'pry', '~> 0.13.0'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vtk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Boehs
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2021-03-01 00:00:00.000000000 Z
13
+ date: 2021-08-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: thor
@@ -26,6 +26,34 @@ dependencies:
26
26
  - - ">"
27
27
  - !ruby/object:Gem::Version
28
28
  version: 0.20.3
29
+ - !ruby/object:Gem::Dependency
30
+ name: tty-command
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: 0.10.0
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: 0.10.0
43
+ - !ruby/object:Gem::Dependency
44
+ name: tty-prompt
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 0.23.0
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: 0.23.0
29
57
  - !ruby/object:Gem::Dependency
30
58
  name: github_changelog_generator
31
59
  requirement: !ruby/object:Gem::Requirement
@@ -139,6 +167,7 @@ files:
139
167
  - ".gitignore"
140
168
  - ".rspec"
141
169
  - ".rubocop.yml"
170
+ - ".rubocop_todo.yml"
142
171
  - ".tool-versions"
143
172
  - CHANGELOG.md
144
173
  - Gemfile
@@ -163,8 +192,12 @@ files:
163
192
  - lib/vtk/commands/socks.rb
164
193
  - lib/vtk/commands/socks/off.rb
165
194
  - lib/vtk/commands/socks/on.rb
195
+ - lib/vtk/commands/socks/setup.rb
166
196
  - lib/vtk/templates/.gitkeep
167
197
  - lib/vtk/templates/module/add/.gitkeep
198
+ - lib/vtk/templates/socks/setup/.gitkeep
199
+ - lib/vtk/templates/socks/setup/gov.va.socks.plist.erb
200
+ - lib/vtk/templates/socks/setup/va_gov_socks.service.erb
168
201
  - lib/vtk/version.rb
169
202
  - vtk.gemspec
170
203
  homepage: https://github.com/department-of-veterans-affairs/vtk