blob: ec7373663b894a1ee75a855dfce2ec7dd5f43e97 [file] [log] [blame]
gstepanove3481cd2015-04-03 21:45:52 +03001import argparse
2import subprocess
3import sys
gstepanovf1ff52d2015-04-07 15:54:33 +03004import socket
5import fcntl
6import struct
7import array
gstepanove3481cd2015-04-03 21:45:52 +03008
9
gstepanovf1ff52d2015-04-07 15:54:33 +030010def all_interfaces():
11 max_possible = 128 # arbitrary. raise if needed.
12 bytes = max_possible * 32
13 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
14 names = array.array('B', '\0' * bytes)
15 outbytes = struct.unpack('iL', fcntl.ioctl(
16 s.fileno(),
17 0x8912, # SIOCGIFCONF
18 struct.pack('iL', bytes, names.buffer_info()[0])
19 ))[0]
20 namestr = names.tostring()
21 lst = []
22 for i in range(0, outbytes, 40):
23 name = namestr[i:i+16].split('\0', 1)[0]
24 ip = namestr[i+20:i+24]
25 lst.append((name, ip))
26 return lst
27
28
29def format_ip(addr):
30 return str(ord(addr[0])) + '.' + \
31 str(ord(addr[1])) + '.' + \
32 str(ord(addr[2])) + '.' + \
33 str(ord(addr[3]))
34
35
36def find_interface_by_ip(ext_ip):
37 ifs = all_interfaces()
38 for i in ifs:
39 ip = format_ip(i[1])
40
41 if ip == ext_ip:
42 return str(i[0])
43
44 print "External ip doesnt corresponds to any of available interfaces"
45 return None
46
47
48def make_tunnels(ips, ext_ip, base_port=12345, delete=False):
gstepanove3481cd2015-04-03 21:45:52 +030049 node_port = {}
50
51 if delete is True:
52 mode = "-D"
53 else:
54 mode = "-A"
55
gstepanovf1ff52d2015-04-07 15:54:33 +030056 iface = find_interface_by_ip(ext_ip)
57
gstepanove3481cd2015-04-03 21:45:52 +030058 for ip in ips:
59 p = subprocess.Popen(["iptables -t nat " + mode + " PREROUTING " +
gstepanovf1ff52d2015-04-07 15:54:33 +030060 "-p tcp -i " + iface + " --dport " + str(base_port) +
gstepanove3481cd2015-04-03 21:45:52 +030061 " -j DNAT --to " + str(ip) + ":22"],
62 stdin=subprocess.PIPE,
63 stdout=subprocess.PIPE,
64 stderr=subprocess.STDOUT,
65 shell=True)
66
67 out, err = p.communicate()
68
koder aka kdanilovda45e882015-04-06 02:24:42 +030069 if out is not None:
gstepanove3481cd2015-04-03 21:45:52 +030070 print out
71
koder aka kdanilovda45e882015-04-06 02:24:42 +030072 if err is not None:
gstepanove3481cd2015-04-03 21:45:52 +030073 print err
74
75 node_port[ip] = base_port
76 base_port += 1
77
78 return node_port
79
80
81def parse_command_line(argv):
gstepanovf1ff52d2015-04-07 15:54:33 +030082 parser = argparse.ArgumentParser(description=
83 "Connect to fuel master "
gstepanove3481cd2015-04-03 21:45:52 +030084 "and setup ssh agent")
gstepanovf1ff52d2015-04-07 15:54:33 +030085 parser.add_argument(
86 "--base_port", type=int, required=True)
87
88 parser.add_argument(
89 "--ext_ip", type=str, required=True)
90
91 parser.add_argument(
92 "--clean", type=bool, default=False)
93
94 parser.add_argument(
95 "--ports", type=str, nargs='+')
gstepanove3481cd2015-04-03 21:45:52 +030096
97 return parser.parse_args(argv)
98
99
100def main(argv):
101 arg_object = parse_command_line(argv)
102 mapping = make_tunnels(arg_object.ports,
gstepanovf1ff52d2015-04-07 15:54:33 +0300103 ext_ip=arg_object.ext_ip,
gstepanove3481cd2015-04-03 21:45:52 +0300104 base_port=arg_object.base_port,
105 delete=arg_object.clean)
106
107 if arg_object.clean is False:
108 for k in mapping:
109 print k + " " + str(mapping[k])
110
111
112if __name__ == "__main__":
113 main(sys.argv[1:])