blob: f1fc3da097831a9900b671a84da57372654a1b47 [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])) + '.' + \
gstepanov4861d712015-04-09 13:28:02 +030031 str(ord(addr[1])) + '.' + \
32 str(ord(addr[2])) + '.' + \
33 str(ord(addr[3]))
gstepanovf1ff52d2015-04-07 15:54:33 +030034
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 " +
gstepanov4861d712015-04-09 13:28:02 +030060 "-p tcp -i " + iface + " --dport "
61 + str(base_port) +
gstepanove3481cd2015-04-03 21:45:52 +030062 " -j DNAT --to " + str(ip) + ":22"],
63 stdin=subprocess.PIPE,
64 stdout=subprocess.PIPE,
65 stderr=subprocess.STDOUT,
66 shell=True)
67
68 out, err = p.communicate()
69
koder aka kdanilovda45e882015-04-06 02:24:42 +030070 if out is not None:
gstepanove3481cd2015-04-03 21:45:52 +030071 print out
72
koder aka kdanilovda45e882015-04-06 02:24:42 +030073 if err is not None:
gstepanove3481cd2015-04-03 21:45:52 +030074 print err
75
76 node_port[ip] = base_port
77 base_port += 1
78
79 return node_port
80
81
82def parse_command_line(argv):
gstepanovf1ff52d2015-04-07 15:54:33 +030083 parser = argparse.ArgumentParser(description=
84 "Connect to fuel master "
gstepanove3481cd2015-04-03 21:45:52 +030085 "and setup ssh agent")
gstepanovf1ff52d2015-04-07 15:54:33 +030086 parser.add_argument(
87 "--base_port", type=int, required=True)
88
89 parser.add_argument(
90 "--ext_ip", type=str, required=True)
91
92 parser.add_argument(
93 "--clean", type=bool, default=False)
94
95 parser.add_argument(
96 "--ports", type=str, nargs='+')
gstepanove3481cd2015-04-03 21:45:52 +030097
98 return parser.parse_args(argv)
99
100
101def main(argv):
102 arg_object = parse_command_line(argv)
103 mapping = make_tunnels(arg_object.ports,
gstepanovf1ff52d2015-04-07 15:54:33 +0300104 ext_ip=arg_object.ext_ip,
gstepanove3481cd2015-04-03 21:45:52 +0300105 base_port=arg_object.base_port,
106 delete=arg_object.clean)
107
108 if arg_object.clean is False:
109 for k in mapping:
110 print k + " " + str(mapping[k])
111
112
113if __name__ == "__main__":
114 main(sys.argv[1:])