Bugfixes, cleanup and improvements
[re6stnet.git] / re6st / utils.py
1 import argparse, errno, logging, os, signal, struct, socket, time
2 from OpenSSL import crypto
3
4 logging_levels = logging.WARNING, logging.INFO, logging.DEBUG, 5
5
6 class FileHandler(logging.FileHandler):
7
8 _reopen = False
9
10 def release(self):
11 try:
12 if self._reopen:
13 self._reopen = False
14 self.close()
15 self._open()
16 finally:
17 self.lock.release()
18 # In the rare case _reopen is set just before the lock was released
19 if self._reopen and self.lock.acquire(0):
20 self.release()
21
22 def async_reopen(self, *_):
23 self._reopen = True
24 if self.lock.acquire(0):
25 self.release()
26
27 def setupLog(log_level, filename=None, **kw):
28 if log_level and filename:
29 makedirs(os.path.dirname(filename))
30 handler = FileHandler(filename)
31 sig = handler.async_reopen
32 else:
33 handler = logging.StreamHandler()
34 sig = signal.SIG_IGN
35 handler.setFormatter(logging.Formatter(
36 '%(asctime)s %(levelname)-9s %(message)s', '%d-%m-%Y %H:%M:%S'))
37 root = logging.getLogger()
38 root.addHandler(handler)
39 signal.signal(signal.SIGUSR1, sig)
40 if log_level:
41 root.setLevel(logging_levels[log_level-1])
42 else:
43 logging.disable(logging.CRITICAL)
44 logging.addLevelName(5, 'TRACE')
45 logging.trace = lambda *args, **kw: logging.log(5, *args, **kw)
46
47 class ArgParser(argparse.ArgumentParser):
48
49 def convert_arg_line_to_args(self, arg_line):
50 arg_line = arg_line.split('#')[0].rstrip()
51 if arg_line:
52 if arg_line.startswith('@'):
53 yield arg_line
54 return
55 for arg in ('--' + arg_line.lstrip('--')).split():
56 if arg.strip():
57 yield arg
58
59 def makedirs(path):
60 try:
61 os.makedirs(path)
62 except OSError, e:
63 if e.errno != errno.EEXIST:
64 raise
65
66 def binFromIp(ip):
67 ip1, ip2 = struct.unpack('>QQ', socket.inet_pton(socket.AF_INET6, ip))
68 return bin(ip1)[2:].rjust(64, '0') + bin(ip2)[2:].rjust(64, '0')
69
70
71 def ipFromBin(prefix, suffix=''):
72 ip = prefix + suffix.rjust(128 - len(prefix), '0')
73 return socket.inet_ntop(socket.AF_INET6,
74 struct.pack('>QQ', int(ip[:64], 2), int(ip[64:], 2)))
75
76 def networkFromCa(ca_path):
77 # Get network prefix from ca.crt
78 with open(ca_path, 'r') as f:
79 ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
80 return bin(ca.get_serial_number())[3:]
81
82 def subnetFromCert(cert_path):
83 # Get ip from cert.crt
84 with open(cert_path, 'r') as f:
85 cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
86 return cert.get_subject().CN
87
88 def address_str(address):
89 return ';'.join(map(','.join, address))
90
91
92 def address_list(address_list):
93 return list(tuple(address.split(','))
94 for address in address_list.split(';'))
95
96
97 def binFromSubnet(subnet):
98 p, l = subnet.split('/')
99 return bin(int(p))[2:].rjust(int(l), '0')