vtk 0.8.0 → 0.9.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: 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