Skip to content

Instantly share code, notes, and snippets.

@iuridiniz
Last active December 13, 2020 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save iuridiniz/ef33c9a9b7497ae5fb155496d35a4454 to your computer and use it in GitHub Desktop.
Save iuridiniz/ef33c9a9b7497ae5fb155496d35a4454 to your computer and use it in GitHub Desktop.
This script manages routes by adding or removing them. (For usage with haresources: http://www.linux-ha.org/wiki/Haresources)
#!/usr/bin/env python
#
# Description: This script manages routes by adding or removing them.
#
# Author: Iuri Diniz <iuri @ evolux dooot net dot br>
# License: GNU General Public License (GPL)
# Support: suporte at evolux dooot net dot br
# Copyright: (C) 2019 Evolux Sistemas LTDA.
#
# This script manages Routes
#
# It can add a route, or remove one.
#
# usage: $0 <net-address>/<net-mask>/<gw>/<iface> {start|stop|status}
#
# The "start" arg adds a route.
#
# Surprisingly, the "stop" arg removes one. :-)
#
import sys
import os
import re
import socket
import subprocess
def usage():
print("Usage: %s <net-address>/<net-mask>/<gw>/<iface> {start|stop|status}" %(sys.argv[0], ))
print("")
print(" ex: %s 189.23.0.0/16/187.28.242.197/eth1:1 start" %(sys.argv[0]))
print(" net-address: 189.23.0.0")
print(" mask: 16")
print(" gw: 187.28.242.197")
print(" iface: eth1:1")
print("")
sys.exit(1)
# https://stackoverflow.com/a/4017219
def is_valid_ipv4_address(address):
try:
socket.inet_pton(socket.AF_INET, address)
except AttributeError: # no inet_pton here, sorry
try:
socket.inet_aton(address)
except socket.error:
return False
return address.count('.') == 3
except socket.error: # not a valid address
return False
return True
def is_valid_net_mask(mask):
try:
return 0 <= int(mask) <= 32
except ValueError:
return False
def _ip_route_cmd(cmd, baseip, mask, gw, iface):
try:
output = subprocess.check_output(['ip',
'route',
'{}'.format(cmd),
'{}/{}'.format(baseip, mask),
'via',
'{}'.format(gw),
'dev',
'{}'.format(iface)])
return output, 0
except subprocess.CalledProcessError as e:
return "", e.returncode
def ip_route_add(baseip, mask, gw, iface):
_, exitcode = _ip_route_cmd("add", baseip, mask, gw, iface)
sys.exit(exitcode)
def ip_route_del(baseip, mask, gw, iface):
_, exitcode = _ip_route_cmd("del", baseip, mask, gw, iface)
sys.exit(exitcode)
def ip_route_exists(baseip, mask, gw, iface):
output, exitcode = _ip_route_cmd("show", baseip, mask, gw, iface)
if exitcode:
sys.exit(exitcode)
output = output.strip()
exitcode = output != "{}/{}".format(baseip, mask)
sys.exit(exitcode)
def main():
if len(sys.argv) != 3:
usage()
args = sys.argv[1]
action = sys.argv[2]
args = args.strip()
action = action.strip().lower()
# ignore slash and anything after it
baseip = re.sub(r"/.*", "", args)
# remove baseip from args
args = re.sub(r"^{}/?".format(baseip), "", args)
# ignore slash and anything after it
mask = re.sub(r"/.*", "", args)
# remove mask from args
args = re.sub(r"^{}/?".format(mask), "", args)
# ignore slash and anything after it
gw = re.sub(r"/.*", "", args)
# remove gw from args
args = re.sub(r"^{}/?".format(gw), "", args)
# ignore slash and anything after it
iface = re.sub(r"/.*", "", args)
# remove iface from args
args = re.sub(r"^{}/?".format(iface), "", args)
# validate all
if not all([is_valid_ipv4_address(baseip),
is_valid_net_mask(mask),
is_valid_ipv4_address(gw),
len(iface) > 0,
len(args) == 0]):
#print([baseip, mask, gw, iface, args])
usage()
if not action in ("start", "stop", "status"):
usage()
if action == "start":
ip_route_add(baseip, mask, gw, iface)
elif action == "stop":
ip_route_del(baseip, mask, gw, iface)
elif action == "status":
ip_route_exists(baseip, mask, gw, iface)
else:
assert "Cannot reach here for action %s" %(action,)
if __name__ == "__main__":
main()
@iuridiniz
Copy link
Author

I copied split logic from bash script, but I think is better apply split from python string

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment