feat: colors by types

- hide cursor
- same headers in CLI and TUI
This commit is contained in:
Johann Dreo 2022-08-09 11:20:48 +02:00
commit 23d83914f8

View file

@ -155,7 +155,7 @@ class TunnelsParser:
self.re_forwarding = re.compile(r"-\w*([LRD])\w*\s*(\d+):(.*):(\d+)") self.re_forwarding = re.compile(r"-\w*([LRD])\w*\s*(\d+):(.*):(\d+)")
self.header = 'TYPE\tFORWARD\tSSH_PID\tIN_PORT\tVIA_HOST\tTARGET_HOST\tOUT_PORT' self.header = 'TYPE\tFORWARD\tSSHPID\tINPORT\tVIA\tTARGET\tOUTPORT'
def get_tunnel(self, pos): def get_tunnel(self, pos):
pid = list(self.tunnels.keys())[pos] pid = list(self.tunnels.keys())[pos]
@ -258,6 +258,9 @@ class CursesMonitor:
"""Textual user interface to display up-to-date informations about current tunnels""" """Textual user interface to display up-to-date informations about current tunnels"""
def __init__(self, scr): def __init__(self, scr):
# hide cursor
curses.curs_set(0)
# curses screen # curses screen
self.scr = scr self.scr = scr
@ -278,31 +281,61 @@ class CursesMonitor:
self.ui_delay = 0.05 # seconds between two screen update self.ui_delay = 0.05 # seconds between two screen update
# colors # colors
# FIXME different colors for different types of tunnels (auto or raw) # 0:black, 1:red, 2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white.
# 0: Black, self.colors_tunnel = {
# 1: Blue, 'kind_auto' : curses.COLOR_CYAN,
# 2: Green, 'kind_raw' : curses.COLOR_BLUE,
# 3: Cyan, 'ssh_pid' : curses.COLOR_WHITE,
# 4: Red, 'in_port' : curses.COLOR_YELLOW,
# 5: Magenta, 'out_port' : curses.COLOR_YELLOW,
# 6: Brown, 'in_port_priv' : curses.COLOR_RED,
# 7: White ("Light Gray"), 'out_port_priv' : curses.COLOR_RED,
# 8: Bright Black ("Gray"), 'via_host' : curses.COLOR_GREEN,
# 9: Bright Blue, 'target_host' : curses.COLOR_GREEN,
# 10: Bright Green, 'via_local' : curses.COLOR_BLUE,
# 11: Bright Cyan, 'target_local' : curses.COLOR_BLUE,
# 12: Bright Red, 'via_priv' : curses.COLOR_CYAN,
# 13: Bright Magenta, 'target_priv' : curses.COLOR_CYAN,
# 14: Yellow, 'tunnels_nb' : curses.COLOR_RED,
# 15: Bright White 'tunnels_nb_none': curses.COLOR_RED,
self.colors_tunnel = {'kind_auto': 4, 'kind_raw': 5, 'ssh_pid': 0, 'in_port': 3, 'forward_local' : curses.COLOR_BLUE,
'via_host': 2, 'target_host': 2, 'out_port': 3, 'tunnels_nb': 4, 'tunnels_nb_none': 1, 'forward_remote' : curses.COLOR_CYAN,
'forward': 6} 'forward_dynamic': curses.COLOR_YELLOW,
self.colors_highlight = {'kind_auto': 9, 'kind_raw': 9, 'ssh_pid': 9, 'in_port': 9, 'forward_unknown': curses.COLOR_WHITE,
'via_host': 9, 'target_host': 9, 'out_port': 9, 'tunnels_nb': 9, 'tunnels_nb_none': 9, }
'forward': 9} self.colors_highlight = {
self.colors_connection = {'ssh_pid': 0, 'autossh_pid': 0, 'status': 4, 'status_out': 1, 'kind_auto' : 9,
'local_address': 2, 'in_port': 3, 'foreign_address': 2, 'out_port': 3} 'kind_raw' : 9,
'ssh_pid' : 9,
'in_port' : 9,
'out_port' : 9,
'in_port_priv' : 9,
'out_port_priv' : 9,
'via_host' : 9,
'target_host' : 9,
'via_local' : 9,
'target_local' : 9,
'via_priv' : 9,
'target_priv' : 9,
'tunnels_nb' : 9,
'tunnels_nb_none': 9,
'forward_local' : 9,
'forward_remote' : 9,
'forward_dynamic': 9,
'forward_unknown': 9,
}
self.colors_connection = {
'ssh_pid' : curses.COLOR_WHITE,
'autossh_pid' : curses.COLOR_WHITE,
'status' : curses.COLOR_CYAN,
'status_out' : curses.COLOR_RED,
'local_address' : curses.COLOR_BLUE,
'foreign_address': curses.COLOR_GREEN,
'in_port' : curses.COLOR_YELLOW,
'out_port' : curses.COLOR_YELLOW,
'in_port_priv' : curses.COLOR_RED,
'out_port_priv' : curses.COLOR_RED,
}
self.header = ("TYPE", "FORWARD", "SSHPID", "INPORT", "VIA", "TARGET", "OUTPORT") self.header = ("TYPE", "FORWARD", "SSHPID", "INPORT", "VIA", "TARGET", "OUTPORT")
@ -459,6 +492,7 @@ class CursesMonitor:
# end of the loop # end of the loop
def format(self): def format(self):
"""Prepare formating strings to pad with spaces up to the tolumn header width."""
reps = [self.tp.tunnels[t].repr_tunnel() for t in self.tp.tunnels] reps = [self.tp.tunnels[t].repr_tunnel() for t in self.tp.tunnels]
tuns = [t.split() for t in reps] tuns = [t.split() for t in reps]
tuns.append(self.header) tuns.append(self.header)
@ -556,25 +590,67 @@ class CursesMonitor:
"""Add line corresponding to the line-th autossh process""" """Add line corresponding to the line-th autossh process"""
self.scr.addstr('\n') self.scr.addstr('\n')
# Handle on the current tunnel object.
t = self.tp.get_tunnel(line)
# Highlight selected line.
colors = self.colors_tunnel colors = self.colors_tunnel
if self.cur_line == line: if self.cur_line == line:
colors = self.colors_highlight colors = self.colors_highlight
# TYPE
if type(self.tp.get_tunnel(line)) == AutoTunnel: if type(self.tp.get_tunnel(line)) == AutoTunnel:
# Format 'auto' using the 0th column format string and the related color..
self.scr.addstr(self.format()[0].format('auto'), curses.color_pair(colors['kind_auto'])) self.scr.addstr(self.format()[0].format('auto'), curses.color_pair(colors['kind_auto']))
# Trailing space.
self.scr.addstr(' ', curses.color_pair(colors['kind_auto'])) self.scr.addstr(' ', curses.color_pair(colors['kind_auto']))
else: else:
self.scr.addstr(self.format()[0].format('ssh'), curses.color_pair(colors['kind_raw'])) self.scr.addstr(self.format()[0].format('ssh'), curses.color_pair(colors['kind_raw']))
self.scr.addstr(' ', curses.color_pair(colors['kind_raw'])) self.scr.addstr(' ', curses.color_pair(colors['kind_raw']))
# self.add_tunnel_info('ssh_pid', line) # FORWARD
self.add_tunnel_info('forward' , line, 1) fwd = t.forward
self.scr.addstr(self.format()[1].format(fwd), curses.color_pair(colors['forward_'+fwd]))
self.scr.addstr(' ', curses.color_pair(colors['forward_'+fwd]))
# SSHPID
self.add_tunnel_info('ssh_pid' , line, 2) self.add_tunnel_info('ssh_pid' , line, 2)
# INPORT
if t.in_port <= 1024:
self.scr.addstr(self.format()[3].format(t.in_port), curses.color_pair(colors['in_port_priv']))
self.scr.addstr(' ', curses.color_pair(colors['in_port_priv']))
else:
self.add_tunnel_info('in_port' , line, 3) self.add_tunnel_info('in_port' , line, 3)
# VIA
if any(re.match(p,t.via_host) for p in ["^127\..*", "::1", "localhost"]): # loopback
self.scr.addstr(self.format()[4].format(t.via_host), curses.color_pair(colors['via_local']))
self.scr.addstr(' ', curses.color_pair(colors['via_local']))
elif any(re.match(p,t.via_host) for p in ["^10\..*", "^172\.[123][0-9]*\..*", "^192\.0\.0\.[0-9]+", "^192\.168\..*", "64:ff9b:1:.*", "fc00::.*"]): # private network
self.scr.addstr(self.format()[4].format(t.via_host), curses.color_pair(colors['via_priv']))
self.scr.addstr(' ', curses.color_pair(colors['via_priv']))
else:
self.add_tunnel_info('via_host' , line, 4) self.add_tunnel_info('via_host' , line, 4)
self.add_tunnel_info('target_host', line, 5)
# TARGET
if any(re.match(p,t.target_host) for p in ["^127\..*", "::1", "localhost"]): # loopback
self.scr.addstr(self.format()[5].format(t.target_host), curses.color_pair(colors['target_local']))
self.scr.addstr(' ', curses.color_pair(colors['target_local']))
elif any(re.match(p,t.target_host) for p in ["^10\..*", "^172\.[123][0-9]*\..*", "^192\.0\.0\.[0-9]+", "^192\.168\..*", "64:ff9b:1:.*", "fc00::.*"]): # private network
self.scr.addstr(self.format()[5].format(t.target_host), curses.color_pair(colors['target_priv']))
self.scr.addstr(' ', curses.color_pair(colors['target_priv']))
else:
self.add_tunnel_info('target_host' , line, 5)
# OUTPORT
if t.out_port <= 1024:
self.scr.addstr(self.format()[6].format(t.out_port), curses.color_pair(colors['out_port_priv']))
self.scr.addstr(' ', curses.color_pair(colors['out_port_priv']))
else:
self.add_tunnel_info('out_port' , line, 6) self.add_tunnel_info('out_port' , line, 6)
# CONNECTIONS
nb = len(self.tp.get_tunnel(line).connections) nb = len(self.tp.get_tunnel(line).connections)
if nb > 0: if nb > 0:
# for each connection related to this process # for each connection related to this process