Files
sea/tcl/plugin/cc_rack
2022-08-18 15:04:28 +02:00

83 lines
2.4 KiB
Python
Executable File

#!/usr/bin/env python3
import socket
import sys
import re
from subprocess import check_output
from ast import literal_eval
rack_hosts = {k.lower(): v for k, v in
literal_eval(check_output('config/json_racklist').decode()).items()}
def get_ip(host):
"""given a host name, return ip as list of str(int) or None when not found"""
try:
for info in socket.getaddrinfo(host, 0, 0, socket.SOCK_STREAM):
ip = info[4][0].split('.')
if len(ip) == 4:
return ip
except socket.gaierror:
pass
return None
def get_host(ip):
"""given ip as list of str(int), return host or None when not found"""
try:
return socket.gethostbyaddr('.'.join(ip))[0]
except socket.herror:
return None
def subnet(ip_subnet):
"""try to find subnet"""
ip = list(ip_subnet)
if ip[0:2] != ['172', '28']:
return 'office'
ip[3] = '60' # assume instrument computer is at address 172.38.*.60
return get_host(ip).split('.')[0]
def get_rack(rack_name=None):
myip = get_ip(socket.gethostname())
if not myip:
return '! no own ip'
if rack_name:
rack_name = rack_name.lower()
rack_host = rack_hosts.get(rack_name)
if not rack_host:
return '%s is no known rack (see sea/tcl/config/rack.list)' % rack_name
rack_ip = get_ip(rack_host)
if not rack_ip:
return '! %s not found' % rack_name
if subnet(rack_ip) == 'office' or subnet(rack_ip) == subnet(myip):
return rack_name # given rack is accessible
return '! %s (%s) is in %s net' % (rack_name, '.'.join(rack_ip), subnet(rack_ip))
other_racks = []
found_racks = []
for rack, host in rack_hosts.items():
if rack == rack_name:
continue
ip = get_ip(host)
if ip:
if subnet(ip) == subnet(myip):
found_racks.append(rack)
else:
other_racks.append(rack)
if found_racks:
return ' '.join(found_racks)
if subnet(myip) == 'office':
other_racks = []
if other_racks:
return ' '.join(other_racks)
return "! no racks accessible"
if len(sys.argv) > 2:
print('Usage: cc_rack [<guessed rack>]')
else:
if len(sys.argv) == 2:
rack_name = sys.argv[1].lower()
else:
rack_name = None
print(get_rack(rack_name))