Last active
December 13, 2020 23:39
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I copied split logic from bash script, but I think is better apply split from python string