vtk 0.7.0 → 0.9.2
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 +4 -4
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +12 -0
- data/CHANGELOG.md +32 -4
- data/README.md +21 -2
- data/exe/vtk +1 -1
- data/lib/vtk/analytics.rb +57 -0
- data/lib/vtk/command.rb +6 -0
- data/lib/vtk/commands/socks.rb +18 -0
- data/lib/vtk/commands/socks/on.rb +1 -1
- data/lib/vtk/commands/socks/setup.rb +531 -0
- data/lib/vtk/templates/socks/setup/.gitkeep +1 -0
- data/lib/vtk/templates/socks/setup/gov.va.socks.plist.erb +35 -0
- data/lib/vtk/templates/socks/setup/va_gov_socks.service.erb +12 -0
- data/lib/vtk/version.rb +1 -1
- data/vtk.gemspec +4 -2
- metadata +43 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 10024b4fc2040cdd70705ce7c5260b16b6b8c5d27a9d2c8476634ce3799d0142
|
|
4
|
+
data.tar.gz: 0edb9d47c87a76ec6d4e2dc2bbfb37df1dfb3a15cf996dfee92530f3b2f917af
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88ca8fd76885f2dd527d6ab23595f3fc6323b6fe8b22cd5ba1412cc3d9d5640d5662aa3c9065f0ff664e8e11a647244c2fe9832cbf58028990ed56b26f923084
|
|
7
|
+
data.tar.gz: 06e3698a16e959732bccea4305915043986cb2a7077eed050c76ecf0bfc99f9cd882e621e91f6715b9f4b16bd61dbfaa2f0312a915b9a7dc53f5caa2c4c652cc
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2021-08-06 20:18:41 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: 405
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v0.9.1](https://github.com/department-of-veterans-affairs/vtk/tree/v0.9.1) (2021-08-06)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/v0.9.0...v0.9.1)
|
|
6
|
+
|
|
7
|
+
**Merged pull requests:**
|
|
8
|
+
|
|
9
|
+
- VTK Socks Setup for Windows \(via WSL\) [\#19](https://github.com/department-of-veterans-affairs/vtk/pull/19) ([ericboehs](https://github.com/ericboehs))
|
|
10
|
+
- Add ops-access-request label to new issue [\#18](https://github.com/department-of-veterans-affairs/vtk/pull/18) ([jeff2d2](https://github.com/jeff2d2))
|
|
11
|
+
|
|
12
|
+
## [v0.9.0](https://github.com/department-of-veterans-affairs/vtk/tree/v0.9.0) (2021-08-02)
|
|
13
|
+
|
|
14
|
+
[Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/v0.8.0...v0.9.0)
|
|
15
|
+
|
|
16
|
+
**Merged pull requests:**
|
|
17
|
+
|
|
18
|
+
- SOCKS Setup Command [\#11](https://github.com/department-of-veterans-affairs/vtk/pull/11) ([ericboehs](https://github.com/ericboehs))
|
|
19
|
+
- Command Analytics [\#8](https://github.com/department-of-veterans-affairs/vtk/pull/8) ([ericboehs](https://github.com/ericboehs))
|
|
20
|
+
- Open Jenkins [\#1](https://github.com/department-of-veterans-affairs/vtk/pull/1) ([cvalarida](https://github.com/cvalarida))
|
|
21
|
+
|
|
22
|
+
## [v0.8.0](https://github.com/department-of-veterans-affairs/vtk/tree/v0.8.0) (2021-03-01)
|
|
23
|
+
|
|
24
|
+
[Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/v0.7.0...v0.8.0)
|
|
25
|
+
|
|
26
|
+
**Merged pull requests:**
|
|
27
|
+
|
|
28
|
+
- Updating name [\#17](https://github.com/department-of-veterans-affairs/vtk/pull/17) ([alexpappasoddball](https://github.com/alexpappasoddball))
|
|
29
|
+
- 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))
|
|
30
|
+
|
|
31
|
+
## [v0.7.0](https://github.com/department-of-veterans-affairs/vtk/tree/v0.7.0) (2021-03-01)
|
|
32
|
+
|
|
33
|
+
[Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/v0.5.0...v0.7.0)
|
|
34
|
+
|
|
3
35
|
## [v0.5.0](https://github.com/department-of-veterans-affairs/vtk/tree/v0.5.0) (2021-02-19)
|
|
4
36
|
|
|
5
37
|
[Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/v0.4.0...v0.5.0)
|
|
@@ -72,10 +104,6 @@
|
|
|
72
104
|
|
|
73
105
|
[Full Changelog](https://github.com/department-of-veterans-affairs/vtk/compare/79143038509757799edb2bb9be2f925b7d985221...oclif)
|
|
74
106
|
|
|
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
107
|
|
|
80
108
|
|
|
81
109
|
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# VFS Toolkit
|
|
2
2
|
|
|
3
|
-
The purpose of this gem is to allow
|
|
3
|
+
The purpose of this gem is to allow engineers to quickly begin developing on VA.gov. It does this by providing a command line interface that allows the use of simple commands and parameters to do everything from setting up a development environment to building out a directory structure and creating necessary files for separating code into its own module.
|
|
4
4
|
|
|
5
5
|
*The following assumes you have Ruby 2.6.6 or higher installed*
|
|
6
6
|
|
|
@@ -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
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
require 'open-uri'
|
|
6
|
+
require 'uri'
|
|
7
|
+
|
|
8
|
+
module Vtk
|
|
9
|
+
# Provides command analytics to VTK team
|
|
10
|
+
class Analytics
|
|
11
|
+
attr_reader :name, :args, :hostname
|
|
12
|
+
|
|
13
|
+
def initialize(name:, args: nil, hostname: nil)
|
|
14
|
+
@name = name
|
|
15
|
+
@args = args || ARGV.join('_')
|
|
16
|
+
@hostname = hostname || `hostname -f`.chomp
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def log
|
|
20
|
+
return if ENV['CI'] || ENV['TEST'] || ENV['VTK_DISABLE_ANALYTICS']
|
|
21
|
+
|
|
22
|
+
Process.fork do
|
|
23
|
+
exit unless internet?
|
|
24
|
+
|
|
25
|
+
emit_point
|
|
26
|
+
rescue StandardError
|
|
27
|
+
false # Silently error
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def emit_point
|
|
32
|
+
uri = URI.parse 'https://dev.va.gov/_vfs/vtk-analytics/record'
|
|
33
|
+
Net::HTTP.start uri.host, uri.port, use_ssl: uri.scheme == 'https' do |http|
|
|
34
|
+
request = Net::HTTP::Post.new uri, 'Content-Type' => 'application/json'
|
|
35
|
+
request.body = { series: [point] }.to_json
|
|
36
|
+
http.request request
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def point
|
|
41
|
+
{
|
|
42
|
+
metric: 'vtk.command_executed',
|
|
43
|
+
type: 'count',
|
|
44
|
+
interval: 1,
|
|
45
|
+
tags: ["name:#{name}", "args:#{args}"],
|
|
46
|
+
host: hostname,
|
|
47
|
+
points: [[Time.now.utc.to_i, '1']]
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def internet?
|
|
52
|
+
true if URI.open 'http://www.google.com/'
|
|
53
|
+
rescue SocketError
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/vtk/command.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'forwardable'
|
|
4
|
+
require 'vtk/analytics'
|
|
4
5
|
|
|
5
6
|
module Vtk
|
|
6
7
|
# Command class that all command inherit from
|
|
@@ -9,6 +10,11 @@ module Vtk
|
|
|
9
10
|
|
|
10
11
|
def_delegators :command, :run
|
|
11
12
|
|
|
13
|
+
def initialize
|
|
14
|
+
command_name = self.class.to_s.split('::').last(2).join('_').downcase
|
|
15
|
+
Vtk::Analytics.new(name: command_name).log
|
|
16
|
+
end
|
|
17
|
+
|
|
12
18
|
# Execute this command
|
|
13
19
|
#
|
|
14
20
|
# @api public
|
data/lib/vtk/commands/socks.rb
CHANGED
|
@@ -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,531 @@
|
|
|
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
|
+
define_stdin_out_vars input: input, output: output
|
|
32
|
+
|
|
33
|
+
setup_ssh_config
|
|
34
|
+
check_ssh_key
|
|
35
|
+
ssh_agent_add
|
|
36
|
+
|
|
37
|
+
unless @ssh_key_created
|
|
38
|
+
test_ssh_connection unless skip_test
|
|
39
|
+
configure_system_boot
|
|
40
|
+
configure_system_proxy
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
log "SOCKS setup complete. #{'Re-run `vtk socks setup` after your key is approved.' if @ssh_key_created}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def define_stdin_out_vars(input:, output:)
|
|
49
|
+
@input = input
|
|
50
|
+
@output = output
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def check_ssh_key
|
|
54
|
+
return true if key_exists? && private_and_public_keys_match?
|
|
55
|
+
|
|
56
|
+
@ssh_key_created = generate_key_and_open_key_access_request
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def key_exists?
|
|
60
|
+
File.exist? ssh_key_path
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def private_and_public_keys_match?
|
|
64
|
+
return true unless public_key_exists?
|
|
65
|
+
|
|
66
|
+
pub_key_from_private = `ssh-keygen -y -e -f #{ssh_key_path}`
|
|
67
|
+
pub_key_from_public = `ssh-keygen -y -e -f #{ssh_key_path}.pub`
|
|
68
|
+
return true if pub_key_from_private == pub_key_from_public
|
|
69
|
+
|
|
70
|
+
log "❌ ERROR: #{ssh_key_path}.pub is not the public key for #{ssh_key_path}."
|
|
71
|
+
exit 1
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def public_key_exists?
|
|
75
|
+
File.exist? "#{ssh_key_path}.pub"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def generate_key_and_open_key_access_request
|
|
79
|
+
log 'VA key missing. Generating now...'
|
|
80
|
+
system "ssh-keygen -f #{ssh_key_path} #{'-N ""' if ENV['TEST']}"
|
|
81
|
+
|
|
82
|
+
if prompt.yes?(copy_and_open_gh)
|
|
83
|
+
copy_key_to_clipboard
|
|
84
|
+
open_command access_request_template_url
|
|
85
|
+
else
|
|
86
|
+
key_contents = File.read "#{ssh_key_path}.pub"
|
|
87
|
+
log "Copy this key & submit into the access request form (#{access_request_template_url}):\n#{key_contents}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def copy_key_to_clipboard
|
|
92
|
+
ssh_key_contents = File.read "#{ssh_key_path}.pub"
|
|
93
|
+
|
|
94
|
+
if copy_command
|
|
95
|
+
IO.popen(copy_command, 'w') { |f| f << ssh_key_contents }
|
|
96
|
+
elsif wsl?
|
|
97
|
+
system %(powershell.exe Set-Clipboard -Value "'#{ssh_key_contents}'")
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def copy_command
|
|
102
|
+
if macos?
|
|
103
|
+
'pbcopy'
|
|
104
|
+
elsif ubuntu_like? && !wsl?
|
|
105
|
+
system 'sudo apt-get install -y xsel' if `which xsel`.empty?
|
|
106
|
+
'xsel --clipboard'
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def open_command(url)
|
|
111
|
+
if macos?
|
|
112
|
+
`open "#{url}"`
|
|
113
|
+
elsif wsl?
|
|
114
|
+
`powershell.exe Start '"#{url}"'`
|
|
115
|
+
elsif ubuntu_like?
|
|
116
|
+
`xdg-open "#{url}"`
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def access_request_template_url
|
|
121
|
+
'https://github.com/department-of-veterans-affairs/va.gov-team/issues/new?' \
|
|
122
|
+
'assignees=&labels=external-request%2C+operations%2C+ops-access-request&' \
|
|
123
|
+
'template=Environment-Access-Request-Template.md&title=Access+for+%5Bindividual%5D'
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def copy_and_open_gh
|
|
127
|
+
'----> An SSH key has been created. Would you like to copy the key to your clipboard and open the access ' \
|
|
128
|
+
'request issue in GitHub now?'
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def setup_ssh_config
|
|
132
|
+
create_ssh_directory
|
|
133
|
+
install_ssh_config
|
|
134
|
+
configure_ssh_config_with_keychain
|
|
135
|
+
ssh_config_clean_up
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def install_ssh_config
|
|
139
|
+
return true if ssh_config_configured?
|
|
140
|
+
|
|
141
|
+
if ssh_config_exists? && !prompt.yes?("----> #{pretty_ssh_config_path} incomplete. Backup and replace now?")
|
|
142
|
+
return false
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
log 'Installing SSH config...'
|
|
146
|
+
|
|
147
|
+
download_ssh_config unless File.exist? '/tmp/dova-devops'
|
|
148
|
+
backup_existing_ssh_config
|
|
149
|
+
FileUtils.cp '/tmp/dova-devops/ssh/config', ssh_config_path
|
|
150
|
+
FileUtils.chmod 0o600, "#{File.dirname ssh_config_path}/config"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def ssh_config_configured?
|
|
154
|
+
return false unless ssh_config_exists?
|
|
155
|
+
|
|
156
|
+
download_ssh_config
|
|
157
|
+
ssh_config_local = File.read ssh_config_path
|
|
158
|
+
ssh_config = File.read '/tmp/dova-devops/ssh/config'
|
|
159
|
+
ssh_config_local.include? ssh_config
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def ssh_config_exists?
|
|
163
|
+
File.exist? ssh_config_path
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def download_ssh_config
|
|
167
|
+
install_git
|
|
168
|
+
|
|
169
|
+
ssh_config_clean_up
|
|
170
|
+
|
|
171
|
+
ssh_agent_add
|
|
172
|
+
system 'git config --global credential.helper > /dev/null || ' \
|
|
173
|
+
"git config --global credential.helper 'cache --timeout=600'"
|
|
174
|
+
cloned = system(
|
|
175
|
+
"git clone --quiet#{' --depth 1' if macos?} --no-checkout --filter=blob:none #{repo_url} '/tmp/dova-devops'"
|
|
176
|
+
)
|
|
177
|
+
exit 1 unless cloned
|
|
178
|
+
|
|
179
|
+
`cd /tmp/dova-devops; git checkout master -- ssh/config`
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def install_git
|
|
183
|
+
if macos?
|
|
184
|
+
install_brew
|
|
185
|
+
elsif ubuntu_like?
|
|
186
|
+
return true unless `which git`.empty?
|
|
187
|
+
|
|
188
|
+
system 'sudo apt-get install -y git'
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def install_brew
|
|
193
|
+
return false unless macos?
|
|
194
|
+
|
|
195
|
+
installed = !`which brew`.empty?
|
|
196
|
+
return true if installed
|
|
197
|
+
|
|
198
|
+
log 'Homebrew not installed. Installing now...'
|
|
199
|
+
system '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def ssh_config_clean_up
|
|
203
|
+
FileUtils.rm_rf '/tmp/dova-devops'
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def repo_url
|
|
207
|
+
@repo_url ||= begin
|
|
208
|
+
keyscan_github_com
|
|
209
|
+
|
|
210
|
+
if github_ssh_configured
|
|
211
|
+
'git@github.com:department-of-veterans-affairs/devops.git'
|
|
212
|
+
else
|
|
213
|
+
'https://github.com/department-of-veterans-affairs/devops.git'
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def keyscan_github_com
|
|
219
|
+
return true if File.exist?('~/.ssh/known_hosts') && !`ssh-keygen -F github.com`.empty?
|
|
220
|
+
|
|
221
|
+
`ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2> /dev/null`
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def github_ssh_configured
|
|
225
|
+
!`ssh -T git@github.com 2>&1`.include?('Permission denied')
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def backup_existing_ssh_config
|
|
229
|
+
return true unless ssh_config_exists?
|
|
230
|
+
|
|
231
|
+
if File.exist? "#{ssh_config_path}.bak"
|
|
232
|
+
log "!!! ERROR: Could not make backup of #{pretty_ssh_config_path} as #{pretty_ssh_config_path}.bak " \
|
|
233
|
+
'exists. Aborting.'
|
|
234
|
+
exit 1
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
FileUtils.mv ssh_config_path, "#{ssh_config_path}.bak"
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def create_ssh_directory
|
|
241
|
+
ssh_dir = File.dirname ssh_config_path
|
|
242
|
+
FileUtils.mkdir_p ssh_dir
|
|
243
|
+
FileUtils.chmod 0o700, ssh_dir
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def configure_ssh_config_with_keychain
|
|
247
|
+
return unless macos?
|
|
248
|
+
return if ssh_config_configured_with_keychain?
|
|
249
|
+
|
|
250
|
+
keychain_config = <<~CFG
|
|
251
|
+
|
|
252
|
+
# Maintain SSH keys in macOS Keychain
|
|
253
|
+
Host *
|
|
254
|
+
UseKeychain yes
|
|
255
|
+
AddKeysToAgent yes
|
|
256
|
+
IdentityFile #{pretty_ssh_key_path}
|
|
257
|
+
CFG
|
|
258
|
+
|
|
259
|
+
IO.write ssh_config_path, keychain_config, mode: 'a'
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def ssh_config_configured_with_keychain?
|
|
263
|
+
return false unless ssh_config_exists?
|
|
264
|
+
|
|
265
|
+
ssh_config_local = File.readlines ssh_config_path
|
|
266
|
+
ssh_config_local.grep(/UseKeychain yes/).any?
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def ssh_agent_add
|
|
270
|
+
FileUtils.chmod 0o600, ssh_key_path if key_exists?
|
|
271
|
+
FileUtils.chmod 0o600, "#{ssh_key_path}.pub" if public_key_exists?
|
|
272
|
+
|
|
273
|
+
if macos?
|
|
274
|
+
`ssh-add -AK 2> /dev/null; ssh-add -AK #{ssh_key_path} 2> /dev/null`
|
|
275
|
+
elsif ubuntu_like?
|
|
276
|
+
`[ -z "$SSH_AUTH_SOCK" ] && eval "$(ssh-agent -s)";
|
|
277
|
+
ssh-add 2> /dev/null; ssh-add #{ssh_key_path} 2> /dev/null`
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def test_ssh_connection
|
|
282
|
+
output.print '----> Testing SOCKS SSH connection...'
|
|
283
|
+
|
|
284
|
+
add_ip_to_known_hosts
|
|
285
|
+
|
|
286
|
+
if proxy_running? || ssh_output.include?('This account is currently not available.')
|
|
287
|
+
output.puts ' ✅ DONE'
|
|
288
|
+
else
|
|
289
|
+
check_ssh_error ssh_output
|
|
290
|
+
exit 1
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def ssh_output
|
|
295
|
+
`ssh -i #{ssh_key_path} -F #{ssh_config_path} -o ConnectTimeout=5 -q socks -D #{port} exit 2>&1`
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def add_ip_to_known_hosts
|
|
299
|
+
jump_box_ip = `grep -A 2 'Host socks' ~/.ssh/config | grep ProxyCommand | awk '{print $6}'`.chomp
|
|
300
|
+
socks_ip = `grep -A 2 'Host socks' ~/.ssh/config | grep HostName | awk '{print $2}'`.chomp
|
|
301
|
+
|
|
302
|
+
return unless `ssh-keygen -F #{socks_ip}`.empty?
|
|
303
|
+
|
|
304
|
+
`ssh-keyscan -H #{jump_box_ip} >> ~/.ssh/known_hosts 2> /dev/null`
|
|
305
|
+
`ssh -i #{ssh_key_path} dsva@#{jump_box_ip} 'ssh-keyscan -H #{socks_ip}' >> ~/.ssh/known_hosts 2> /dev/null`
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def check_ssh_error(ssh_output)
|
|
309
|
+
if ssh_output.include? 'Permission denied (publickey)'
|
|
310
|
+
output.puts '⚠️ WARN: SSH key is not approved yet. Once it is, re-run `vtk socks setup`.'
|
|
311
|
+
copy_key_to_clipboard if prompt.yes? 'Would you like to copy your VA public key to your clipboard again?'
|
|
312
|
+
else
|
|
313
|
+
ssh_command = "ssh -i #{ssh_key_path} -F #{ssh_config_path} -o ConnectTimeout=5 -vvv socks -D #{port} -N"
|
|
314
|
+
output.puts ' ❌ ERROR: SSH Connection to SOCKS server unsuccessful. Error message:'
|
|
315
|
+
output.puts ssh_command
|
|
316
|
+
output.puts `#{ssh_command}`
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def configure_system_boot
|
|
321
|
+
log 'Configuring SOCKS tunnel to run on system boot...' do
|
|
322
|
+
if wsl?
|
|
323
|
+
wsl_configure_system_boot && wsl_start_socks_proxy
|
|
324
|
+
else
|
|
325
|
+
install_autossh && (install_launch_agent || install_systemd_service)
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def wsl_configure_system_boot
|
|
331
|
+
return true if File.exist? socks_bat
|
|
332
|
+
|
|
333
|
+
IO.write socks_bat, 'wsl nohup bash -c "/usr/bin/ssh socks -N &" < nul > nul 2>&1', mode: 'a'
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def socks_bat
|
|
337
|
+
"#{socks_bat_dir}/gov.va.socks.bat"
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def socks_bat_dir
|
|
341
|
+
profile_path = `wslpath "$(wslvar USERPROFILE)"`.chomp
|
|
342
|
+
"#{profile_path}/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup"
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def wsl_start_socks_proxy
|
|
346
|
+
return true if proxy_running?
|
|
347
|
+
|
|
348
|
+
system "cd '#{socks_bat_dir}'; cmd.exe /c gov.va.socks.bat > /dev/null"
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def proxy_running?
|
|
352
|
+
system("lsof -i:#{port}", out: '/dev/null') || system('lsof -nP | grep ssh | grep -q sock')
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def launch_agent_label
|
|
356
|
+
@launch_agent_label ||= begin
|
|
357
|
+
launch_agent_label = 'gov.va.socks'
|
|
358
|
+
launch_agent_label += "-test-#{rand 1000}" if ENV['TEST'] == 'test'
|
|
359
|
+
launch_agent_label
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
def install_autossh
|
|
364
|
+
installed = !`which autossh`.empty?
|
|
365
|
+
return true if installed
|
|
366
|
+
|
|
367
|
+
if macos?
|
|
368
|
+
system 'brew install autossh'
|
|
369
|
+
elsif ubuntu_like?
|
|
370
|
+
system 'sudo apt-get install -y autossh'
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def install_launch_agent
|
|
375
|
+
return false unless macos?
|
|
376
|
+
|
|
377
|
+
unless File.exist? "#{boot_script_path}/LaunchAgents/gov.va.socks.plist"
|
|
378
|
+
FileUtils.mkdir_p "#{boot_script_path}/Logs/gov.va.socks"
|
|
379
|
+
FileUtils.mkdir_p "#{boot_script_path}/LaunchAgents"
|
|
380
|
+
|
|
381
|
+
write_launch_agent
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
system "launchctl unload #{boot_script_path}/LaunchAgents/gov.va.socks.plist 2> /dev/null"
|
|
385
|
+
system "launchctl load -w #{boot_script_path}/LaunchAgents/gov.va.socks.plist"
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def write_launch_agent
|
|
389
|
+
erb_template = File.read File.realpath "#{__dir__}/../../templates/socks/setup/gov.va.socks.plist.erb"
|
|
390
|
+
erb = ERB.new erb_template
|
|
391
|
+
launch_agent_contents = erb.result(
|
|
392
|
+
launch_agent_variables.instance_eval { binding }
|
|
393
|
+
)
|
|
394
|
+
File.write "#{boot_script_path}/LaunchAgents/gov.va.socks.plist", launch_agent_contents
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def launch_agent_variables
|
|
398
|
+
OpenStruct.new(
|
|
399
|
+
label: launch_agent_label,
|
|
400
|
+
autossh_path: `which autossh`.chomp,
|
|
401
|
+
port: @port,
|
|
402
|
+
boot_script_path: File.realpath(boot_script_path),
|
|
403
|
+
user: ENV['USER']
|
|
404
|
+
)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def install_systemd_service
|
|
408
|
+
return false unless ubuntu_like?
|
|
409
|
+
|
|
410
|
+
write_systemd_service unless File.exist? '/etc/systemd/system/va_gov_socks.service'
|
|
411
|
+
|
|
412
|
+
system 'sudo systemctl daemon-reload'
|
|
413
|
+
system 'sudo systemctl enable va_gov_socks'
|
|
414
|
+
system 'sudo systemctl start va_gov_socks'
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def write_systemd_service
|
|
418
|
+
erb_template = File.read File.realpath "#{__dir__}/../../templates/socks/setup/va_gov_socks.service.erb"
|
|
419
|
+
erb = ERB.new erb_template
|
|
420
|
+
systemd_service_contents = erb.result(
|
|
421
|
+
systemd_service_variables.instance_eval { binding }
|
|
422
|
+
)
|
|
423
|
+
File.write '/tmp/va_gov_socks.service', systemd_service_contents
|
|
424
|
+
system 'sudo mv /tmp/va_gov_socks.service /etc/systemd/system/va_gov_socks.service'
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def systemd_service_variables
|
|
428
|
+
OpenStruct.new(
|
|
429
|
+
autossh_path: `which autossh`.chomp,
|
|
430
|
+
port: @port,
|
|
431
|
+
ssh_key_path: ssh_key_path,
|
|
432
|
+
user: ENV['USER']
|
|
433
|
+
)
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def configure_system_proxy
|
|
437
|
+
return log 'Skipping system proxy configuration as custom --port was used.' unless port == '2001'
|
|
438
|
+
|
|
439
|
+
if macos?
|
|
440
|
+
mac_configure_system_proxy
|
|
441
|
+
elsif wsl?
|
|
442
|
+
wsl_configure_system_proxy
|
|
443
|
+
elsif ubuntu_like?
|
|
444
|
+
ubuntu_configure_system_proxy
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
def mac_configure_system_proxy
|
|
449
|
+
return true if mac_system_proxy_already_configured?
|
|
450
|
+
|
|
451
|
+
log 'Configuring system proxy to use SOCKS tunnel...' do
|
|
452
|
+
network_interfaces.map do |network_interface|
|
|
453
|
+
system %(networksetup -setautoproxyurl "#{network_interface}" "#{PROXY_URL}")
|
|
454
|
+
end.all?
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
def ubuntu_configure_system_proxy
|
|
459
|
+
return true if `gsettings get org.gnome.system.proxy mode` == "'auto'\n"
|
|
460
|
+
|
|
461
|
+
log 'Configuring system proxy to use SOCKS tunnel...' do
|
|
462
|
+
`gsettings set org.gnome.system.proxy mode 'auto'` &&
|
|
463
|
+
`gsettings set org.gnome.system.proxy autoconfig-url "#{PROXY_URL}"`
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
def wsl_configure_system_proxy
|
|
468
|
+
log 'Configuring system proxy to use SOCKS tunnel...' do
|
|
469
|
+
reg_key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings'
|
|
470
|
+
`powershell.exe Set-ItemProperty -path "'#{reg_key}'" AutoConfigURL -Value "'#{PROXY_URL}'"`
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
def mac_system_proxy_already_configured?
|
|
475
|
+
network_interfaces.map do |network_interface|
|
|
476
|
+
output = `networksetup -getautoproxyurl "#{network_interface}"`
|
|
477
|
+
output == "URL: #{PROXY_URL}\nEnabled: Yes\n"
|
|
478
|
+
end.all?
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
def network_interfaces
|
|
482
|
+
@network_interfaces ||= begin
|
|
483
|
+
`networksetup -listallnetworkservices`.split("\n").drop(1).select do |network_interface|
|
|
484
|
+
`networksetup -getautoproxyurl "#{network_interface}"`.start_with?('URL: (null)')
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
def macos?
|
|
490
|
+
RUBY_PLATFORM.include? 'darwin'
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
def wsl?
|
|
494
|
+
@wsl ||= File.exist?('/proc/version') && File.open('/proc/version').grep(/Microsoft/i).any?
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
def ubuntu_like?
|
|
498
|
+
return false if `which apt-get`.empty? && `which gsettings`.empty?
|
|
499
|
+
|
|
500
|
+
true
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
def pretty_ssh_config_path
|
|
504
|
+
pretty_path ssh_config_path
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
def pretty_ssh_key_path
|
|
508
|
+
pretty_path ssh_key_path
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
def pretty_path(path)
|
|
512
|
+
path.gsub ENV['HOME'], '~'
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
def log(message)
|
|
516
|
+
if block_given?
|
|
517
|
+
output.print "----> #{message}"
|
|
518
|
+
|
|
519
|
+
return_value = yield
|
|
520
|
+
|
|
521
|
+
output.puts return_value ? ' ✅ DONE' : ' ❌ FAIL'
|
|
522
|
+
|
|
523
|
+
return_value
|
|
524
|
+
else
|
|
525
|
+
output.puts "----> #{message}"
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
end
|
|
531
|
+
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
data/vtk.gemspec
CHANGED
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
spec.summary = 'A CLI for the platform'
|
|
13
13
|
spec.description = 'This is a platform CLI tool for VFS developer usage.'
|
|
14
14
|
spec.homepage = 'https://github.com/department-of-veterans-affairs/vtk'
|
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
|
|
16
16
|
|
|
17
17
|
spec.metadata['homepage_uri'] = spec.homepage
|
|
18
18
|
spec.metadata['documentation_uri'] = spec.homepage
|
|
@@ -29,12 +29,14 @@ 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'
|
|
35
37
|
spec.add_development_dependency 'rake', '~> 13.0.0'
|
|
36
38
|
spec.add_development_dependency 'rspec', '~> 3.10.0'
|
|
37
|
-
spec.add_development_dependency 'rubocop', '~> 1.
|
|
39
|
+
spec.add_development_dependency 'rubocop', '~> 1.8.0'
|
|
38
40
|
spec.add_development_dependency 'rubocop-rake', '~> 0.5.0'
|
|
39
41
|
spec.add_development_dependency 'rubocop-rspec', '~> 2.0.0'
|
|
40
42
|
|
metadata
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vtk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eric Boehs
|
|
8
8
|
- Lindsey Hattamer
|
|
9
9
|
- Travis Hilton
|
|
10
|
-
autorequire:
|
|
10
|
+
autorequire:
|
|
11
11
|
bindir: exe
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2021-
|
|
13
|
+
date: 2021-08-11 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
|
|
@@ -88,14 +116,14 @@ dependencies:
|
|
|
88
116
|
requirements:
|
|
89
117
|
- - "~>"
|
|
90
118
|
- !ruby/object:Gem::Version
|
|
91
|
-
version: 1.
|
|
119
|
+
version: 1.8.0
|
|
92
120
|
type: :development
|
|
93
121
|
prerelease: false
|
|
94
122
|
version_requirements: !ruby/object:Gem::Requirement
|
|
95
123
|
requirements:
|
|
96
124
|
- - "~>"
|
|
97
125
|
- !ruby/object:Gem::Version
|
|
98
|
-
version: 1.
|
|
126
|
+
version: 1.8.0
|
|
99
127
|
- !ruby/object:Gem::Dependency
|
|
100
128
|
name: rubocop-rake
|
|
101
129
|
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
|
|
@@ -150,6 +179,7 @@ files:
|
|
|
150
179
|
- docs/design-doc.md
|
|
151
180
|
- exe/vtk
|
|
152
181
|
- lib/vtk.rb
|
|
182
|
+
- lib/vtk/analytics.rb
|
|
153
183
|
- lib/vtk/cli.rb
|
|
154
184
|
- lib/vtk/command.rb
|
|
155
185
|
- lib/vtk/commands/.gitkeep
|
|
@@ -162,8 +192,12 @@ files:
|
|
|
162
192
|
- lib/vtk/commands/socks.rb
|
|
163
193
|
- lib/vtk/commands/socks/off.rb
|
|
164
194
|
- lib/vtk/commands/socks/on.rb
|
|
195
|
+
- lib/vtk/commands/socks/setup.rb
|
|
165
196
|
- lib/vtk/templates/.gitkeep
|
|
166
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
|
|
167
201
|
- lib/vtk/version.rb
|
|
168
202
|
- vtk.gemspec
|
|
169
203
|
homepage: https://github.com/department-of-veterans-affairs/vtk
|
|
@@ -174,7 +208,7 @@ metadata:
|
|
|
174
208
|
documentation_uri: https://github.com/department-of-veterans-affairs/vtk
|
|
175
209
|
source_code_uri: https://github.com/department-of-veterans-affairs/vtk
|
|
176
210
|
changelog_uri: https://github.com/department-of-veterans-affairs/vtk/blob/master/CHANGELOG.md
|
|
177
|
-
post_install_message:
|
|
211
|
+
post_install_message:
|
|
178
212
|
rdoc_options: []
|
|
179
213
|
require_paths:
|
|
180
214
|
- lib
|
|
@@ -182,15 +216,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
182
216
|
requirements:
|
|
183
217
|
- - ">="
|
|
184
218
|
- !ruby/object:Gem::Version
|
|
185
|
-
version: 2.
|
|
219
|
+
version: 2.5.0
|
|
186
220
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
221
|
requirements:
|
|
188
222
|
- - ">="
|
|
189
223
|
- !ruby/object:Gem::Version
|
|
190
224
|
version: '0'
|
|
191
225
|
requirements: []
|
|
192
|
-
rubygems_version: 3.
|
|
193
|
-
signing_key:
|
|
226
|
+
rubygems_version: 3.2.1
|
|
227
|
+
signing_key:
|
|
194
228
|
specification_version: 4
|
|
195
229
|
summary: A CLI for the platform
|
|
196
230
|
test_files: []
|