Files
nando/nando
2015-07-14 20:33:39 +03:00

137 lines
4.7 KiB
Python
Executable File

#!/usr/bin/env python
import socket,sys,time,os,configobj
RC="/etc/nandorc"
BLOCK_SIZE=10240
def setup_options():
''' Setup the command line options '''
from argparse import ArgumentParser
parser=ArgumentParser(description="Alive notifier. Options first read from /etc/nandorc, and overriden by switches.")
parser.add_argument("--host",action='store', dest='HOST',type=str,default=None,
help="Host name/IP of the server")
parser.add_argument("--port", action='store', dest='PORT', default=None,type=int,
help="Port number of the server")
parser.add_argument("-t",action='store', dest='TIMEOUT',default=5, type=int,
help="Connection timeout")
parser.add_argument("-i",action='store', dest='INTERVAL',default=0, type=int,
help="Send signal every i seconds. If 0, send only once and exit.")
parser.add_argument("-m",action='store', dest='MSGFILE',type=str,default=None,
help="Read a text file as description. Max length 512 chars")
parser.add_argument("--query-ip",action='store', dest='QUERY_HOSTNAME',default=None,type=str,
help="Query the IP of a host name")
parser.add_argument("--query-host",action='store', dest='QUERY_IP',default=None,type=str,
help="Query the hostname of an IP")
parser.add_argument("command",type=str,action="store",default="",nargs="?",
choices=['','list','alive','lost'],
help="Command to send. If empty, send standard alive-notice. Commands: list, alive")
options=parser.parse_args()
if os.path.exists(RC):
rc=configobj.ConfigObj(RC)
if options.HOST is None:
if "HOST" in rc.keys():
options.HOST=rc['HOST']
if options.PORT is None:
if "PORT" in rc.keys():
options.PORT=int(rc['PORT'])
if options.MSGFILE is None:
if "MSGFILE" in rc.keys():
options.MSGFILE=rc['MSGFILE']
if options.HOST is None:
parser.error("Host name required")
if options.PORT is None:
parser.error("Port number required")
return options
def print_table(data):
lengths=[0,0,0,0]
for row in data.split("\n"):
cols=row.split("|",4)
if len(cols)!=4:
continue
for c in range(4):
lengths[c]=max(lengths[c], len(cols[c]))
lengths=[str(x) for x in lengths]
for row in data.split("\n"):
cols=row.split("|",4)
if len(cols)!=4:
continue
print(("{0:<"+lengths[0]+"} | {1:<"+lengths[1]+"} | {2:>"+lengths[2]+"} | {3}").format(*cols))
def query_ip(sock,opts):
sock.sendto("list", (opts.HOST, opts.PORT))
received = sock.recv(BLOCK_SIZE)
for row in received.split("\n"):
cols=row.split("|",4)
if cols[0]==opts.QUERY_HOSTNAME:
sys.stdout.write(cols[1])
sys.exit(0)
sys.exit(1)
def query_host(sock,opts):
sock.sendto("list", (opts.HOST, opts.PORT))
received = sock.recv(BLOCK_SIZE)
for row in received.split("\n"):
cols=row.split("|",4)
if cols[1]==opts.QUERY_IP:
sys.stdout.write(cols[0])
sys.exit(0)
sys.exit(1)
def read_desc(opts):
if not opts.MSGFILE:
return ""
if not os.path.isfile(opts.MSGFILE):
return ""
DESC=open(opts.MSGFILE,"rb").read(1024)
DESC=''.join([ c for c in DESC if c not in ['\n','\r','|'] ])
return DESC
opts=setup_options()
errors=0
while True:
try:
MYNAME = socket.gethostname()
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(opts.TIMEOUT)
sock.connect((opts.HOST,opts.PORT))
MYIP=sock.getsockname()[0]
if opts.QUERY_HOSTNAME:
query_ip(sock,opts)
if opts.QUERY_IP:
query_host(sock,opts)
if opts.command=="":
DESC=read_desc(opts)
MSG="{0}|{1}|{2}\n".format(MYNAME,MYIP,DESC)
else:
MSG=opts.command
sock.sendto(MSG, (opts.HOST, opts.PORT))
received = sock.recv(BLOCK_SIZE)
if opts.command!="":
print_table(received)
if opts.INTERVAL==0 and opts.command=="":
sock.sendto("list", (opts.HOST, opts.PORT))
received = sock.recv(BLOCK_SIZE)
print_table(received)
errors=0
except socket.error:
print("Didn't get reply from {0}:{1}".format(opts.HOST,opts.PORT))
errors=1
except IndexError:
print(received)
if opts.INTERVAL==0:
break
time.sleep(opts.INTERVAL)
sys.exit(errors)