Skip to content

Instantly share code, notes, and snippets.

@hvnsweeting
Created December 3, 2012 07:02
Show Gist options
  • Save hvnsweeting/4193258 to your computer and use it in GitHub Desktop.
Save hvnsweeting/4193258 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
#NOTE must run with sudo
import logging
import subprocess as spr
from pprint import pprint, pformat
from ConfigParser import SafeConfigParser
import confparser, ifaces
from util import get_abs_path, print_and_log_maker
"""
functions help create neccessary network manipulating command and run it
"""
log = logging.getLogger(__name__)
print_and_log = print_and_log_maker(log)
BASENUMBER_FOR_TABLE = 50
def process_command(command):
execute_command(command)
def execute_command(command):
try:
command += " 2>&1"
resp = spr.check_output(command, shell=True)
except spr.CalledProcessError as e:
print_and_log("e", "CMD: %s \nRESP: %s " % (command, e.output))
return e.output
else:
print_and_log("d", "CMD: %s \nRESP: %s " % (command, resp))
return resp
def rule_command_factory(act, data, line=None):
#TODO we dont need line parameter, remove it, read pref number from rule
if line:
number_for_line = int(line[3:]) + BASENUMBER_FOR_TABLE
pref = data['id']
try:
rfrom = data['from']
except KeyError:
rfrom = "all"
finally:
cmdhead = "ip ru %s from %s " % (act, rfrom)
cmdmiddle = ""
cmdtail = "pref %s" % pref # pref is id in rule
try:
dest = data['to']
except KeyError:
pass
else:
cmdmiddle = "to %s " % dest
try:
tableid = data['lookup']
except KeyError:
# for failover, table_id is 50 + n (with n in WANn)
cmdmiddle += "lookup %s " % number_for_line
else:
# for loadbalancing, table_id is found in pr_by_dest
cmdmiddle += "lookup %s " % tableid
#TODO refactor this
if act == "del":
return "ip ru del " + cmdtail
else:
return cmdhead + cmdmiddle + cmdtail
def ip_rule(act, rule_data, line):
"""Return an ip rule command"""
return rule_command_factory(act, rule_data, line)
def generate_command(up, ruledata, line):
if up is True:
rule_para, iptable_para = "add", "A"
else:
rule_para, iptable_para = "del", "D"
if ruledata['type'] == "routing":
#print ip_rule(rule_para, ruledata, line)
return ip_rule(rule_para, ruledata, line)
elif ruledata['type'] == "nat":
#print iptable_command_factory(iptable_para, ruledata, line)
return iptable_command_factory(iptable_para, ruledata, line)
def iptable_command_factory(act, data, line):
try:
iface = ifaces.get_iface_of(line)
except KeyError, e:
print_and_log("e", e, line)
return ""
dport = data['port']
to_ip = data['to']
try:
comment = data['comment']
except KeyError as e:
comment = ""
return "iptables -t nat -%s DNAT_PATH -i %s -p tcp -m tcp --dport %s -m comment --comment '%s' -j DNAT --to %s" %\
(act, iface, dport, comment, to_ip)
def iptable_masq_factory(act, data):
# some address in config has port
to_ip = data['to'].split(":")[0]
return "iptables -t nat -A DNAT_MASQ -d %s -j MASQUERADE" % to_ip
def ip_ro_command_factory(table_id, lines_states, wans_weights=None):
# lines_states can be [wan1 wan2] or [1 2]
command = "ip ro replace default table %s " % table_id
if not wans_weights:
wans_weights = confparser.get_section_by_name(table_id)
alive_wanlines = [line for line in lines_states if lines_states[line]]
if len(alive_wanlines) > 0:
try:
int(alive_wanlines[0])
alive_wanlines = ["wan" + str(id_) for id_ in alive_wanlines]
except Exception, e:
print e
tail_of_command = ""
for line in wans_weights:
if 'wan' in line and line in alive_wanlines:
try:
tail_of_command += ("nexthop via %s dev %s weight %s " % (
ifaces.get_gw_of(line),
ifaces.get_iface_of(line),
wans_weights[line]))
except KeyError, e:
# bad iface
tail_of_command = ""
if tail_of_command:
return command + tail_of_command
else:
return ""
def get_all_ip_ro_command(lines_states, wandie):
"""
when wandie state is False, find all rt_tables contain it,
generate all ip route commands
Return list of ip route commands
"""
table_ids = confparser.tableids_contain(wandie)
ip_ro_cmds = [ip_ro_command_factory(id_, lines_states)
for id_ in table_ids if ip_ro_command_factory(id_, lines_states)]
return ip_ro_cmds
def delete_running_prefs(prefs):
for pref in prefs:
cmd = "ip ru | grep -e '^%s:'| wc -l" % pref
try:
counter = int(spr.check_output(cmd))
except OSError as e:
continue
else:
for i in range(counter):
command = "ip ru del pref %s" % pref
process_command(command)
def flush_dnat_iptables():
process_command("iptables -t nat -F DNAT_PATH")
process_command("iptables -t nat -F DNAT_MASQ")
def flush_route_cache():
process_command("sleep 5 && ip ro flush cache")
def delete_conntrack_with_ip_of(wan_down):
try:
for i in 'sdrq':
cmd = "conntrack -D -%s %s >/dev/null" % (
i, ifaces.get_ip_of(wan_down))
process_command(cmd)
except KeyError, e:
print_and_log('e', e)
def main():
pass
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment