139 lines
3.6 KiB
Python
Executable File
139 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import sys
|
|
from pathlib import Path
|
|
from configparser import ConfigParser
|
|
from socket import gethostbyname, create_connection
|
|
|
|
cfgdir = Path(__file__).resolve().parent / 'cfg'
|
|
|
|
|
|
def check_connection(host, port=22):
|
|
try:
|
|
addr = gethostbyname(host)
|
|
test_socket = create_connection((addr, port), timeout=0.1)
|
|
except Exception as e:
|
|
if isinstance(e, TimeoutError):
|
|
return '', addr
|
|
return '', ''
|
|
else:
|
|
test_socket.close()
|
|
return '*', addr
|
|
|
|
|
|
def print_row(row, sizes):
|
|
print(' '.join(v.ljust(l) for v, l in zip(row, sizes)))
|
|
|
|
|
|
def print_line(sizes):
|
|
print(' '.join('-' * l for l in sizes))
|
|
|
|
|
|
legend = ['', '', '', '* running', '* online']
|
|
opt = sys.argv[-1]
|
|
if opt.startswith('-'):
|
|
opt = opt[1:]
|
|
header = ['box name', 'box type', 'V', 'frappy']
|
|
if opt == 's':
|
|
header.append('')
|
|
legend = []
|
|
else:
|
|
header.append('ip ')
|
|
if opt == 'a':
|
|
header.extend(['router', 'MAC addr'])
|
|
else:
|
|
header.append('')
|
|
legend = legend[:5]
|
|
table = [header]
|
|
all_ports = {}
|
|
|
|
for file in sorted(cfgdir.glob('*.cfg')):
|
|
name = file.stem
|
|
all_ports[name] = box_ports = {}
|
|
parser = ConfigParser()
|
|
parser.read(file)
|
|
info = {k: dict(parser[k]) for k in parser.sections()}
|
|
router = info.get('ROUTER', {})
|
|
if opt == 'a':
|
|
ports = sorted(router)
|
|
router = []
|
|
following = None
|
|
firstport = None
|
|
for p in ports:
|
|
try:
|
|
pnum = int(p)
|
|
if 'router' not in box_ports:
|
|
box_ports['router'] = pnum
|
|
if pnum == following:
|
|
first = router[-1].split('-')[0]
|
|
router[-1] = f'{first}-{following}'
|
|
following += 1
|
|
continue
|
|
following = pnum + 1
|
|
except ValueError:
|
|
pnum = -1
|
|
router.append(p)
|
|
router = ' '.join(router)
|
|
else:
|
|
router = 'router' if router else ''
|
|
frappy_info = info.get('FRAPPY', {})
|
|
frappy = frappy_info.get('cfg', '')
|
|
if frappy:
|
|
box_ports['frappy'] = int(frappy_info.get('port', 10767))
|
|
box = info.get('BOX', {})
|
|
row = [name, box.get('type', 'unknown'), box.get('version', '0'), frappy]
|
|
if opt == 's':
|
|
row.append(router)
|
|
else:
|
|
row.extend(['', router])
|
|
if opt == 'a':
|
|
row.append(box.get('mac', ''))
|
|
table.append(row)
|
|
|
|
sizes = [max([len(row[i]) for row in table]) for i in range(len(header))]
|
|
if opt != 's':
|
|
# make space for '*'
|
|
sizes[3] += 1
|
|
sizes[4] += 1
|
|
|
|
firstrow = True
|
|
print_line(sizes)
|
|
for row in table:
|
|
if firstrow:
|
|
firstrow = False
|
|
print_row(header, sizes)
|
|
print_line(sizes)
|
|
continue
|
|
if row[0]:
|
|
name = row[0]
|
|
online = ''
|
|
if opt != 's':
|
|
online, addr = check_connection(row[0], 22)
|
|
addr += online
|
|
if opt != 'a' and online != '*':
|
|
continue
|
|
row[4] = addr
|
|
if opt != 's':
|
|
port = all_ports[name].get('frappy')
|
|
if port and online == '*':
|
|
flag = check_connection(name, port)[0]
|
|
else:
|
|
flag = ' '
|
|
row[3] += flag
|
|
print(' '.join(v.ljust(l) for v, l in zip(row, sizes)))
|
|
print_line(sizes)
|
|
|
|
if legend:
|
|
print_row(legend, sizes)
|
|
|
|
print('V 0: not yet migrated to gitea')
|
|
print('V 1: 2025-05')
|
|
|
|
USAGE = f"""
|
|
Usage:
|
|
listboxes o # only boxes online (default)
|
|
listboxes a # all boxes, all info
|
|
listboxes s # without ip and online check
|
|
"""
|
|
if opt not in 'sao':
|
|
print(USAGE)
|