83 lines
2.4 KiB
Python
Executable File
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))
|
|
|