-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtunnel.py
58 lines (48 loc) · 1.82 KB
/
tunnel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# https://sshtunnel.readthedocs.io/en/latest/
import configparser, getpass, logging, pathlib, sys
import sshtunnel
import toolbox as tb
ini_file = 'tunnel.ini'
defaults = {
'proxy_port': '22',
'proxy_user': getpass.getuser(),
'remote_host': 'localhost'
}
config = configparser.ConfigParser(defaults=defaults)
logger = sshtunnel.create_logger(loglevel='INFO')
logger.handlers[0].setFormatter(logging.Formatter('! %(message)s'))
class MockTunnel:
def __init__(self, local_bind_host, local_bind_port):
self.local_bind_host = local_bind_host
self.local_bind_port = local_bind_port
def __enter__(self): # for `with tunnel:`
return self
def __exit__(self, *args): # for `with tunnel:`
pass
def tunnel(remote_host, remote_port, local_port=0): # `0` means random port
if tb.is_pyinstaller():
# https://pyinstaller.readthedocs.io/en/stable/runtime-information.html
script_dir = sys.executable
else:
script_dir = __file__
# config file in same directory as this file
config_file = pathlib.Path(script_dir).with_name(ini_file)
config.read(config_file)
try:
section = config[remote_host]
except KeyError:
# remote host is not in ini file, so we don't need a real tunnel
tunnel = MockTunnel(
local_bind_host = remote_host,
local_bind_port = remote_port
)
else:
tunnel = sshtunnel.SSHTunnelForwarder(
ssh_address_or_host = section['proxy_host'],
ssh_config_file = None,
ssh_port = int(section['proxy_port']),
ssh_username = section['proxy_user'],
remote_bind_address = (section['remote_host'], int(remote_port)),
local_bind_address = ('localhost', local_port)
)
return tunnel