forward 0.3.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +0 -2
- data/README.md +24 -0
- data/Rakefile +3 -1
- data/bin/forward +1 -1
- data/forward.gemspec +17 -11
- data/lib/forward/api/resource.rb +51 -83
- data/lib/forward/api/tunnel.rb +41 -68
- data/lib/forward/api/user.rb +14 -11
- data/lib/forward/api.rb +7 -26
- data/lib/forward/cli.rb +55 -253
- data/lib/forward/command/account.rb +69 -0
- data/lib/forward/command/base.rb +62 -0
- data/lib/forward/command/config.rb +64 -0
- data/lib/forward/command/tunnel.rb +178 -0
- data/lib/forward/common.rb +44 -0
- data/lib/forward/config.rb +75 -118
- data/lib/forward/request.rb +72 -0
- data/lib/forward/socket.rb +125 -0
- data/lib/forward/static/app.rb +157 -0
- data/lib/forward/static/directory.erb +142 -0
- data/lib/forward/tunnel.rb +102 -40
- data/lib/forward/version.rb +1 -1
- data/lib/forward.rb +80 -63
- data/test/api/resource_test.rb +70 -54
- data/test/api/tunnel_test.rb +50 -51
- data/test/api/user_test.rb +33 -20
- data/test/cli_test.rb +0 -126
- data/test/command/account_test.rb +26 -0
- data/test/command/tunnel_test.rb +133 -0
- data/test/config_test.rb +103 -54
- data/test/forward_test.rb +47 -0
- data/test/test_helper.rb +35 -26
- data/test/tunnel_test.rb +50 -22
- metadata +210 -169
- data/forwardhq.crt +0 -112
- data/lib/forward/api/client_log.rb +0 -20
- data/lib/forward/api/tunnel_key.rb +0 -18
- data/lib/forward/client.rb +0 -110
- data/lib/forward/error.rb +0 -12
- data/test/api/tunnel_key_test.rb +0 -28
- data/test/api_test.rb +0 -0
- data/test/client_test.rb +0 -8
data/lib/forward/client.rb
DELETED
@@ -1,110 +0,0 @@
|
|
1
|
-
module Forward
|
2
|
-
class Client
|
3
|
-
attr_reader :config
|
4
|
-
attr_reader :options
|
5
|
-
attr_accessor :tunnel
|
6
|
-
|
7
|
-
def initialize(options = {})
|
8
|
-
@options = options
|
9
|
-
@config = Config.create_or_load
|
10
|
-
end
|
11
|
-
|
12
|
-
def basic_auth?
|
13
|
-
@options[:username] && @options[:password]
|
14
|
-
end
|
15
|
-
|
16
|
-
# Sets up a Tunnel instance and adds it to the Client.
|
17
|
-
def setup_tunnel
|
18
|
-
Forward.log.debug('Setting up tunnel')
|
19
|
-
@tunnel = Forward::Tunnel.new(self.options)
|
20
|
-
if @tunnel.id
|
21
|
-
@tunnel.poll_status
|
22
|
-
else
|
23
|
-
Forward::Client.cleanup_and_exit!('Unable to create a tunnel. If this continues contact support@forwardhq.com')
|
24
|
-
end
|
25
|
-
Forward.log.debug("Tunnel setup: #{@tunnel.inspect}")
|
26
|
-
|
27
|
-
@tunnel
|
28
|
-
end
|
29
|
-
|
30
|
-
# The options Hash used by Net::SSH.
|
31
|
-
#
|
32
|
-
# Returns a Hash of options.
|
33
|
-
def ssh_options
|
34
|
-
{
|
35
|
-
:config => false,
|
36
|
-
:port => Forward.ssh_port,
|
37
|
-
:keys_only => true,
|
38
|
-
:keys => [],
|
39
|
-
:key_data => [ @config.private_key ],
|
40
|
-
:encryption => 'blowfish-cbc',
|
41
|
-
:logger => Forward.logger,
|
42
|
-
:verbose => Forward.debug? ? :debug : :warn
|
43
|
-
}
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.current
|
47
|
-
@client
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.watch_session(session)
|
51
|
-
@client.tunnel.inactive_for = 0 if session.busy?(true)
|
52
|
-
true
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.forwarding_message(tunnel)
|
56
|
-
remote = HighLine.color("https://#{@tunnel.subdomain}.fwd.wf", :underline)
|
57
|
-
|
58
|
-
unless tunnel.cname.nil? || tunnel.cname.empty?
|
59
|
-
remote << ' and '<< HighLine.color("http://#{@tunnel.cname}", :underline)
|
60
|
-
end
|
61
|
-
|
62
|
-
if !tunnel.vhost.nil? && tunnel.vhost !~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
|
63
|
-
local = tunnel.vhost
|
64
|
-
local << " port #{tunnel.hostport}" unless tunnel.hostport.to_i == 80
|
65
|
-
else
|
66
|
-
local = "port #{tunnel.hostport}"
|
67
|
-
end
|
68
|
-
|
69
|
-
"Forwarding #{local} to #{remote}\nCtrl-C to stop forwarding"
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.start(options = {})
|
73
|
-
Forward.log.debug('Starting client')
|
74
|
-
trap(:INT) { cleanup_and_exit!('closing tunnel and exiting...') }
|
75
|
-
|
76
|
-
Forward.client = @client = Client.new(options)
|
77
|
-
@tunnel = @client.setup_tunnel
|
78
|
-
@session = Net::SSH.start(@tunnel.tunneler, Forward.ssh_user, @client.ssh_options)
|
79
|
-
|
80
|
-
Forward.log.debug("Starting remote forward at #{@tunnel.subdomain}.fwd.wf")
|
81
|
-
puts forwarding_message(@tunnel)
|
82
|
-
|
83
|
-
@session.forward.remote(@tunnel.hostport, @tunnel.host, @tunnel.port)
|
84
|
-
@session.loop { watch_session(@session) }
|
85
|
-
|
86
|
-
rescue Net::SSH::AuthenticationFailed => e
|
87
|
-
Forward.log.fatal("SSH Auth failed `#{e}'")
|
88
|
-
cleanup_and_exit!("Authentication failed, try deleting `#{Forward::Config.config_path}' and giving it another go. If the problem continues, contact support@forwardhq.com")
|
89
|
-
rescue => e
|
90
|
-
Forward.log.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
91
|
-
cleanup_and_exit!("You've been disconnected...")
|
92
|
-
end
|
93
|
-
|
94
|
-
def self.cleanup_and_exit!(message = 'exiting...')
|
95
|
-
puts message.chomp
|
96
|
-
|
97
|
-
@session.close if @session && !@session.closed?
|
98
|
-
|
99
|
-
Forward.log.debug('Exiting')
|
100
|
-
send_debug_log if Forward.debug_remotely?
|
101
|
-
ensure
|
102
|
-
Thread.main.exit
|
103
|
-
end
|
104
|
-
|
105
|
-
def self.send_debug_log
|
106
|
-
log = Forward.stringio_log.string
|
107
|
-
Forward::Api::ClientLog.create(log)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
data/lib/forward/error.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
module Forward
|
2
|
-
# An error occurred with the API
|
3
|
-
class ApiError < StandardError; end
|
4
|
-
# An error occurred with the CLI
|
5
|
-
class CLIError < StandardError; end
|
6
|
-
# An error occurred with the Client
|
7
|
-
class ClientError < StandardError; end
|
8
|
-
# An error occurred with the Config
|
9
|
-
class ConfigError < StandardError; end
|
10
|
-
# An error occurred with the Tunnel
|
11
|
-
class TunnelError < StandardError; end
|
12
|
-
end
|
data/test/api/tunnel_key_test.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Forward::Api::TunnelKey do
|
4
|
-
|
5
|
-
before :each do
|
6
|
-
FakeWeb.allow_net_connect = false
|
7
|
-
end
|
8
|
-
|
9
|
-
it "retrieves the public_key and returns it" do
|
10
|
-
fake_body = { :private_key => 'ssh-key 1234567890' }
|
11
|
-
|
12
|
-
stub_api_request(:post, '/api/v2/tunnel_keys', :body => fake_body.to_json)
|
13
|
-
|
14
|
-
response = Api::TunnelKey.create
|
15
|
-
response.must_equal fake_body[:private_key]
|
16
|
-
end
|
17
|
-
|
18
|
-
it "exits with message if response has errors" do
|
19
|
-
fake_body = { :type => 'api_error' }
|
20
|
-
|
21
|
-
stub_api_request(:post, '/api/v2/tunnel_keys', :body => fake_body.to_json, :status => [ 422, 'Unprocessable Entity' ])
|
22
|
-
|
23
|
-
lambda {
|
24
|
-
dev_null { Api::TunnelKey.create }
|
25
|
-
}.must_raise SystemExit
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
data/test/api_test.rb
DELETED
File without changes
|