forked from mirrors/thatmattlove-hyperglass
overhaul of construct.py
This commit is contained in:
parent
370916662d
commit
b489874928
2 changed files with 251 additions and 336 deletions
|
|
@ -20,317 +20,210 @@ commands = configuration.commands()
|
||||||
routers_list = devices["router"]
|
routers_list = devices["router"]
|
||||||
|
|
||||||
|
|
||||||
def frr(router, cmd, ipprefix):
|
class codes:
|
||||||
logger.info(f"Constructing {cmd} command for FRR router {router} to {ipprefix}...")
|
"""Class for easy calling & recalling of http success/error codes"""
|
||||||
try:
|
|
||||||
# Loop through routers config file, match input router with configured routers, set variables
|
def __init__(self):
|
||||||
for r in routers_list:
|
# 200 OK: renders standard display text
|
||||||
if router == r["address"]:
|
self.success = 200
|
||||||
type = r["type"]
|
# 405 Method Not Allowed: Renders Bulma "warning" class notification message with message text
|
||||||
src_addr_ipv4 = r["src_addr_ipv4"]
|
self.warning = 405
|
||||||
src_addr_ipv6 = r["src_addr_ipv6"]
|
# 415 Unsupported Media Type: Renders Bulma "danger" class notification message with message text
|
||||||
try:
|
self.danger = 415
|
||||||
# Loop through commands config file, set variables for matched commands
|
|
||||||
if cmd == "Query Type":
|
|
||||||
msg = "You must select a query type."
|
code = codes()
|
||||||
code = 415
|
|
||||||
logger.error(f"{msg}, {code}, {router}, {cmd}, {ipprefix}")
|
|
||||||
return (msg, code, router, cmd, ipprefix)
|
def frr(cmd, ipprefix, device):
|
||||||
# BGP Community Query
|
d_address = device["address"]
|
||||||
elif cmd in ["bgp_community"]:
|
d_src_addr_ipv4 = device["src_addr_ipv4"]
|
||||||
# Extended Communities, new-format
|
d_src_addr_ipv6 = device["src_addr_ipv6"]
|
||||||
if re.match("^([0-9]{0,5})\:([0-9]{1,5})$", ipprefix):
|
d_location = device["location"]
|
||||||
query = json.dumps(
|
d_name = device["name"]
|
||||||
{"cmd": cmd, "afi": "dual", "target": ipprefix}
|
d_port = device["port"]
|
||||||
)
|
d_type = device["type"]
|
||||||
msg = f"{ipprefix} matched new-format community."
|
|
||||||
code = 200
|
logger.info(f"Constructing {cmd} command for FRR router {d_name} to {ipprefix}...")
|
||||||
return (msg, code, router, query)
|
# BGP Community Query
|
||||||
# Extended Communities, 32 bit format
|
if cmd in ["bgp_community"]:
|
||||||
elif re.match("^[0-9]{1,10}$", ipprefix):
|
# Extended Communities, new-format
|
||||||
query = json.dumps(
|
query = json.dumps({"cmd": cmd, "afi": "dual", "target": ipprefix})
|
||||||
{"cmd": cmd, "afi": "dual", "target": ipprefix}
|
if re.match("^([0-9]{0,5})\:([0-9]{1,5})$", ipprefix):
|
||||||
)
|
msg = f"{ipprefix} matched new-format community."
|
||||||
msg = f"{ipprefix} matched 32 bit community."
|
return (msg, code.success, d_address, query)
|
||||||
code = 200
|
# Extended Communities, 32 bit format
|
||||||
return (msg, code, router, query)
|
elif re.match("^[0-9]{1,10}$", ipprefix):
|
||||||
# RFC 8092 Large Community Support
|
msg = f"{ipprefix} matched 32 bit community."
|
||||||
elif re.match(
|
return (msg, code.success, d_address, query)
|
||||||
"^([0-9]{1,10})\:([0-9]{1,10})\:[0-9]{1,10}$", ipprefix
|
# RFC 8092 Large Community Support
|
||||||
):
|
elif re.match("^([0-9]{1,10})\:([0-9]{1,10})\:[0-9]{1,10}$", ipprefix):
|
||||||
query = json.dumps(
|
msg = f"{ipprefix} matched large community."
|
||||||
{"cmd": cmd, "afi": "dual", "target": ipprefix}
|
return (msg, code.success, d_address, query)
|
||||||
)
|
else:
|
||||||
msg = f"{ipprefix} matched large community."
|
msg = f"{ipprefix} is an invalid BGP Community Format."
|
||||||
code = 200
|
logger.error(f"{msg}, {code.danger}, {d_name}, {query}")
|
||||||
return (msg, code, router, query)
|
return (msg, code.danger, d_address, query)
|
||||||
else:
|
# BGP AS_PATH Query
|
||||||
msg = f"{ipprefix} is an invalid BGP Community Format."
|
elif cmd in ["bgp_aspath"]:
|
||||||
code = 415
|
if re.match(".*", ipprefix):
|
||||||
logger.error(f"{msg}, {code}, {router}, {cmd}, {ipprefix}")
|
query = json.dumps({"cmd": cmd, "afi": "dual", "target": ipprefix})
|
||||||
return (msg, code, router, cmd, ipprefix)
|
msg = f"{ipprefix} matched AS_PATH regex."
|
||||||
# BGP AS_PATH Query
|
return (msg, code.success, d_address, query)
|
||||||
elif cmd in ["bgp_aspath"]:
|
else:
|
||||||
if re.match(".*", ipprefix):
|
msg = f"{ipprefix} is an invalid AS_PATH regex."
|
||||||
query = json.dumps(
|
logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}")
|
||||||
{"cmd": cmd, "afi": "dual", "target": ipprefix}
|
return (msg, code.danger, d_address, query)
|
||||||
)
|
# BGP Route Query
|
||||||
msg = f"{ipprefix} matched AS_PATH regex."
|
elif cmd in ["bgp_route"]:
|
||||||
code = 200
|
try:
|
||||||
return (msg, code, router, query)
|
# Use netaddr library to verify if input is a valid IPv4 address or prefix
|
||||||
else:
|
if IPNetwork(ipprefix).ip.version == 4:
|
||||||
msg = f"{ipprefix} is an invalid AS_PATH regex."
|
query = json.dumps({"cmd": cmd, "afi": "ipv4", "target": ipprefix})
|
||||||
code = 415
|
msg = f"{ipprefix} is a valid IPv4 Adddress."
|
||||||
logger.error(f"{msg}, {code}, {router}, {cmd}, {ipprefix}")
|
return (msg, code.success, d_address, query)
|
||||||
return (msg, code, router, query)
|
# Use netaddr library to verify if input is a valid IPv6 address or prefix
|
||||||
# BGP Route Query
|
elif IPNetwork(ipprefix).ip.version == 6:
|
||||||
elif cmd in ["bgp_route"]:
|
query = json.dumps({"cmd": cmd, "afi": "ipv6", "target": ipprefix})
|
||||||
try:
|
msg = f"{ipprefix} is a valid IPv6 Adddress."
|
||||||
# Use netaddr library to verify if input is a valid IPv4 address or prefix
|
return (msg, code.success, d_address, query)
|
||||||
if IPNetwork(ipprefix).ip.version == 4:
|
# Exception from netaddr library will return a user-facing error
|
||||||
query = json.dumps(
|
except:
|
||||||
{"cmd": cmd, "afi": "ipv4", "target": ipprefix}
|
msg = f"{ipprefix} is an invalid IP Address."
|
||||||
)
|
logger.error(f"{msg}, {code.danger}, {d_name}, {query}")
|
||||||
msg = f"{ipprefix} is a valid IPv4 Adddress."
|
return (msg, code.danger, d_address, query)
|
||||||
code = 200
|
# Ping/Traceroute
|
||||||
return (msg, code, router, query)
|
elif cmd in ["ping", "traceroute"]:
|
||||||
# Use netaddr library to verify if input is a valid IPv6 address or prefix
|
try:
|
||||||
elif IPNetwork(ipprefix).ip.version == 6:
|
if IPNetwork(ipprefix).ip.version == 4:
|
||||||
query = json.dumps(
|
query = json.dumps(
|
||||||
{"cmd": cmd, "afi": "ipv6", "target": ipprefix}
|
{
|
||||||
)
|
"cmd": cmd,
|
||||||
msg = f"{ipprefix} is a valid IPv6 Adddress."
|
"afi": "ipv4",
|
||||||
code = 200
|
"source": d_src_addr_ipv4,
|
||||||
return (msg, code, router, query)
|
"target": ipprefix,
|
||||||
# Exception from netaddr library will return a user-facing error
|
}
|
||||||
except:
|
|
||||||
msg = f"{ipprefix} is an invalid IP Address."
|
|
||||||
code = 415
|
|
||||||
logger.error(f"{msg}, {code}, {router}, {cmd}, {ipprefix}")
|
|
||||||
return (msg, code, router, cmd, ipprefix)
|
|
||||||
# Ping/Traceroute
|
|
||||||
elif cmd in ["ping", "traceroute"]:
|
|
||||||
try:
|
|
||||||
if IPNetwork(ipprefix).ip.version == 4:
|
|
||||||
query = json.dumps(
|
|
||||||
{
|
|
||||||
"cmd": cmd,
|
|
||||||
"afi": "ipv4",
|
|
||||||
"source": src_addr_ipv4,
|
|
||||||
"target": ipprefix,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
msg = f"{ipprefix} is a valid IPv4 Adddress."
|
|
||||||
code = 200
|
|
||||||
return (msg, code, router, query)
|
|
||||||
elif IPNetwork(ipprefix).ip.version == 6:
|
|
||||||
query = json.dumps(
|
|
||||||
{
|
|
||||||
"cmd": cmd,
|
|
||||||
"afi": "ipv6",
|
|
||||||
"source": src_addr_ipv6,
|
|
||||||
"target": ipprefix,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
msg = f"{ipprefix} is a valid IPv6 Adddress."
|
|
||||||
code = 200
|
|
||||||
return (msg, code, router, query)
|
|
||||||
except:
|
|
||||||
msg = f"{ipprefix} is an invalid IP Address."
|
|
||||||
code = 415
|
|
||||||
logger.error(f"{msg}, {code}, {router}, {cmd}, {ipprefix}")
|
|
||||||
return (msg, code, router, cmd, ipprefix)
|
|
||||||
else:
|
|
||||||
msg = f"Command {cmd} not found."
|
|
||||||
code = 415
|
|
||||||
logger.error(f"{msg}, {code}, {router}, {cmd}, {ipprefix}")
|
|
||||||
return (msg, code, router, cmd, ipprefix)
|
|
||||||
except:
|
|
||||||
router_ip = r["address"]
|
|
||||||
error_msg = logger.error(
|
|
||||||
f"Input router IP {router} does not match the configured router IP of {router_ip}"
|
|
||||||
)
|
)
|
||||||
raise ValueError(error_msg)
|
msg = f"{ipprefix} is a valid IPv4 Adddress."
|
||||||
except:
|
return (msg, code.success, d_address, query)
|
||||||
raise
|
elif IPNetwork(ipprefix).ip.version == 6:
|
||||||
|
query = json.dumps(
|
||||||
|
{
|
||||||
|
"cmd": cmd,
|
||||||
|
"afi": "ipv6",
|
||||||
|
"source": d_src_addr_ipv6,
|
||||||
|
"target": ipprefix,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
msg = f"{ipprefix} is a valid IPv6 Adddress."
|
||||||
|
return (msg, code.success, d_address, query)
|
||||||
|
except:
|
||||||
|
msg = f"{ipprefix} is an invalid IP Address."
|
||||||
|
logger.error(f"{msg}, {code.danger}, {d_name}, {query}")
|
||||||
|
return (msg, code.danger, d_name, query)
|
||||||
|
else:
|
||||||
|
msg = f"Command {cmd} not found."
|
||||||
|
logger.error(f"{msg}, {code.danger}, {d_name}, {query}")
|
||||||
|
return (msg, code.danger, d_name, query)
|
||||||
|
|
||||||
|
|
||||||
def netmiko(router, cmd, ipprefix):
|
def ssh(cmd, ipprefix, device):
|
||||||
"""Receives JSON from Flask, constucts the command that will be passed to the router. Also handles input validation & error handling."""
|
"""Receives JSON from Flask, constucts the command that will be passed to the router. Also handles input validation & error handling."""
|
||||||
logger.info(f"Constructing {cmd} command for {router} to {ipprefix}...")
|
d_address = device["address"]
|
||||||
try:
|
d_src_addr_ipv4 = device["src_addr_ipv4"]
|
||||||
# Loop through routers config file, match input router with configured routers, set variables
|
d_src_addr_ipv6 = device["src_addr_ipv6"]
|
||||||
for r in routers_list:
|
d_location = device["location"]
|
||||||
try:
|
d_name = device["name"]
|
||||||
if router == r["address"]:
|
d_port = device["port"]
|
||||||
type = r["type"]
|
d_type = device["type"]
|
||||||
src_addr_ipv4 = r["src_addr_ipv4"]
|
|
||||||
src_addr_ipv6 = r["src_addr_ipv6"]
|
logger.info(f"Constructing {cmd} command for {d_name} to {ipprefix}...")
|
||||||
# Loop through commands config file, set variables for matched commands
|
# Loop through commands config file, set variables for matched commands
|
||||||
for nos in commands:
|
class command:
|
||||||
if type == nos:
|
def __init__(self, type):
|
||||||
nos = commands[type]
|
if type in commands:
|
||||||
nos_commands = nos[0]
|
self.dual = commands[type][0]["dual"]
|
||||||
# Dual stack commands (agnostic of IPv4/IPv6)
|
self.ipv4 = commands[type][0]["ipv4"]
|
||||||
dual_commands = nos_commands["dual"]
|
self.ipv6 = commands[type][0]["ipv6"]
|
||||||
# IPv4 Specific Commands
|
else:
|
||||||
ipv4_commands = nos_commands["ipv4"]
|
msg = f"{d_type} is an unsupported network operating system."
|
||||||
# IPv6 Specific Commands
|
logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}")
|
||||||
ipv6_commands = nos_commands["ipv6"]
|
return (msg, code.danger, d_name, cmd, ipprefix)
|
||||||
if cmd == "Query Type":
|
|
||||||
msg = "You must select a query type."
|
c = command(d_type)
|
||||||
code = 415
|
# BGP Community Query
|
||||||
logger.error(
|
if cmd == "bgp_community":
|
||||||
f"{msg}, {code}, {router}, {cmd}, {ipprefix}"
|
# Extended Communities, new-format
|
||||||
)
|
if re.match("^([0-9]{0,5})\:([0-9]{1,5})$", ipprefix):
|
||||||
return (msg, code, router, cmd, ipprefix)
|
mc = c.dual[cmd]
|
||||||
# BGP Community Query
|
command = mc.format(target=ipprefix)
|
||||||
elif cmd in ["bgp_community"]:
|
msg = f"{ipprefix} matched new-format community."
|
||||||
# Extended Communities, new-format
|
return (msg, code.success, d_address, d_type, command)
|
||||||
if re.match("^([0-9]{0,5})\:([0-9]{1,5})$", ipprefix):
|
# Extended Communities, 32 bit format
|
||||||
for a, c in dual_commands.items():
|
elif re.match("^[0-9]{1,10}$", ipprefix):
|
||||||
if a == cmd:
|
mc = c.dual[cmd]
|
||||||
command = c.format(target=ipprefix)
|
command = mc.format(target=ipprefix)
|
||||||
msg = f"{ipprefix} matched new-format community."
|
msg = f"{ipprefix} matched 32 bit community."
|
||||||
code = 200
|
return (msg, code.success, d_address, d_type, command)
|
||||||
return (msg, code, router, type, command)
|
# RFC 8092 Large Community Support
|
||||||
# Extended Communities, 32 bit format
|
elif re.match("^([0-9]{1,10})\:([0-9]{1,10})\:[0-9]{1,10}$", ipprefix):
|
||||||
elif re.match("^[0-9]{1,10}$", ipprefix):
|
mc = c.dual[cmd]
|
||||||
for a, c in dual_commands.items():
|
command = mc.format(target=ipprefix)
|
||||||
if a == cmd:
|
msg = f"{ipprefix} matched large community."
|
||||||
command = c.format(target=ipprefix)
|
return (msg, code.success, d_address, d_type, command)
|
||||||
msg = (
|
else:
|
||||||
f"{ipprefix} matched 32 bit community."
|
msg = f"{ipprefix} is an invalid BGP Community Format."
|
||||||
)
|
logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}")
|
||||||
code = 200
|
return (msg, code.danger, d_name, cmd, ipprefix)
|
||||||
return (msg, code, router, type, command)
|
# BGP AS_PATH Query
|
||||||
# RFC 8092 Large Community Support
|
elif cmd == "bgp_aspath":
|
||||||
elif re.match(
|
if re.match(".*", ipprefix):
|
||||||
"^([0-9]{1,10})\:([0-9]{1,10})\:[0-9]{1,10}$",
|
mc = c.dual[cmd]
|
||||||
ipprefix,
|
command = mc.format(target=ipprefix)
|
||||||
):
|
msg = f"{ipprefix} matched AS_PATH regex."
|
||||||
for a, c in dual_commands.items():
|
return (msg, code.success, d_address, d_type, command)
|
||||||
if a == cmd:
|
else:
|
||||||
command = c.format(target=ipprefix)
|
msg = f"{ipprefix} is an invalid AS_PATH regex."
|
||||||
msg = f"{ipprefix} matched large community."
|
logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}")
|
||||||
code = 200
|
return (msg, code.danger, d_name, cmd, ipprefix)
|
||||||
return (msg, code, router, type, command)
|
# BGP Route Query
|
||||||
else:
|
elif cmd == "bgp_route":
|
||||||
msg = f"{ipprefix} is an invalid BGP Community Format."
|
try:
|
||||||
code = 415
|
# Use netaddr library to verify if input is a valid IPv4 address or prefix
|
||||||
logger.error(
|
if IPNetwork(ipprefix).ip.version == 4:
|
||||||
f"{msg}, {code}, {router}, {cmd}, {ipprefix}"
|
mc = c.ipv4[cmd]
|
||||||
)
|
command = mc.format(target=ipprefix)
|
||||||
return (msg, code, router, cmd, ipprefix)
|
msg = f"{ipprefix} is a valid IPv4 Adddress."
|
||||||
# BGP AS_PATH Query
|
return (msg, code.success, d_address, d_type, command)
|
||||||
elif cmd in ["bgp_aspath"]:
|
# Use netaddr library to verify if input is a valid IPv6 address or prefix
|
||||||
if re.match(".*", ipprefix):
|
elif IPNetwork(ipprefix).ip.version == 6:
|
||||||
for a, c in dual_commands.items():
|
mc = c.ipv6[cmd]
|
||||||
if a == cmd:
|
command = mc.format(target=ipprefix)
|
||||||
command = c.format(target=ipprefix)
|
msg = f"{ipprefix} is a valid IPv6 Adddress."
|
||||||
msg = f"{ipprefix} matched AS_PATH regex."
|
return (msg, code.success, d_address, d_type, command)
|
||||||
code = 200
|
# Exception from netaddr library will return a user-facing error
|
||||||
return (msg, code, router, type, command)
|
except:
|
||||||
else:
|
msg = f"{ipprefix} is an invalid IP Address."
|
||||||
msg = f"{ipprefix} is an invalid AS_PATH regex."
|
logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}")
|
||||||
code = 415
|
return (msg, code.danger, d_name, cmd, ipprefix)
|
||||||
logger.error(
|
# Ping/Traceroute
|
||||||
f"{msg}, {code}, {router}, {cmd}, {ipprefix}"
|
elif cmd in ["ping", "traceroute"]:
|
||||||
)
|
try:
|
||||||
return (msg, code, router, cmd, ipprefix)
|
if IPNetwork(ipprefix).ip.version == 4:
|
||||||
# BGP Route Query
|
mc = c.ipv4[cmd]
|
||||||
elif cmd in ["bgp_route"]:
|
command = mc.format(target=ipprefix, src_addr_ipv4=d_src_addr_ipv4)
|
||||||
try:
|
msg = f"{ipprefix} is a valid IPv4 Adddress."
|
||||||
# Use netaddr library to verify if input is a valid IPv4 address or prefix
|
return (msg, code.success, d_address, d_type, command)
|
||||||
if IPNetwork(ipprefix).ip.version == 4:
|
elif IPNetwork(ipprefix).ip.version == 6:
|
||||||
for a, c in ipv4_commands.items():
|
mc = c.ipv6[cmd]
|
||||||
if a == cmd:
|
command = mc.format(target=ipprefix, src_addr_ipv6=d_src_addr_ipv6)
|
||||||
command = c.format(target=ipprefix)
|
msg = f"{ipprefix} is a valid IPv6 Adddress."
|
||||||
msg = f"{ipprefix} is a valid IPv4 Adddress."
|
return (msg, code.success, d_address, d_type, command)
|
||||||
code = 200
|
except:
|
||||||
return (
|
msg = f"{ipprefix} is an invalid IP Address."
|
||||||
msg,
|
logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}")
|
||||||
code,
|
return (msg, code.danger, d_name, cmd, ipprefix)
|
||||||
router,
|
else:
|
||||||
type,
|
msg = f"Command {cmd} not found."
|
||||||
command,
|
logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}")
|
||||||
)
|
return (msg, code.danger, d_name, cmd, ipprefix)
|
||||||
# Use netaddr library to verify if input is a valid IPv6 address or prefix
|
|
||||||
elif IPNetwork(ipprefix).ip.version == 6:
|
|
||||||
for a, c in ipv6_commands.items():
|
|
||||||
if a == cmd:
|
|
||||||
command = c.format(target=ipprefix)
|
|
||||||
msg = f"{ipprefix} is a valid IPv6 Adddress."
|
|
||||||
code = 200
|
|
||||||
return (
|
|
||||||
msg,
|
|
||||||
code,
|
|
||||||
router,
|
|
||||||
type,
|
|
||||||
command,
|
|
||||||
)
|
|
||||||
# Exception from netaddr library will return a user-facing error
|
|
||||||
except:
|
|
||||||
msg = f"{ipprefix} is an invalid IP Address."
|
|
||||||
code = 415
|
|
||||||
logger.error(
|
|
||||||
f"{msg}, {code}, {router}, {cmd}, {ipprefix}"
|
|
||||||
)
|
|
||||||
return (msg, code, router, cmd, ipprefix)
|
|
||||||
# Ping/Traceroute
|
|
||||||
elif cmd in ["ping", "traceroute"]:
|
|
||||||
try:
|
|
||||||
if IPNetwork(ipprefix).ip.version == 4:
|
|
||||||
for a, c in ipv4_commands.items():
|
|
||||||
if a == cmd:
|
|
||||||
command = c.format(
|
|
||||||
target=ipprefix,
|
|
||||||
src_addr_ipv4=src_addr_ipv4,
|
|
||||||
)
|
|
||||||
msg = f"{ipprefix} is a valid IPv4 Adddress."
|
|
||||||
code = 200
|
|
||||||
return (
|
|
||||||
msg,
|
|
||||||
code,
|
|
||||||
router,
|
|
||||||
type,
|
|
||||||
command,
|
|
||||||
)
|
|
||||||
elif IPNetwork(ipprefix).ip.version == 6:
|
|
||||||
for a, c in ipv6_commands.items():
|
|
||||||
if a == cmd:
|
|
||||||
command = c.format(
|
|
||||||
target=ipprefix,
|
|
||||||
src_addr_ipv6=src_addr_ipv6,
|
|
||||||
)
|
|
||||||
msg = f"{ipprefix} is a valid IPv6 Adddress."
|
|
||||||
code = 200
|
|
||||||
return (
|
|
||||||
msg,
|
|
||||||
code,
|
|
||||||
router,
|
|
||||||
type,
|
|
||||||
command,
|
|
||||||
)
|
|
||||||
except:
|
|
||||||
msg = f"{ipprefix} is an invalid IP Address."
|
|
||||||
code = 415
|
|
||||||
logger.error(
|
|
||||||
f"{msg}, {code}, {router}, {cmd}, {ipprefix}"
|
|
||||||
)
|
|
||||||
return (msg, code, router, cmd, ipprefix)
|
|
||||||
else:
|
|
||||||
msg = f"Command {cmd} not found."
|
|
||||||
code = 415
|
|
||||||
logger.error(
|
|
||||||
f"{msg}, {code}, {router}, {cmd}, {ipprefix}"
|
|
||||||
)
|
|
||||||
return (msg, code, router, cmd, ipprefix)
|
|
||||||
except:
|
|
||||||
router_ip = r["address"]
|
|
||||||
error_msg = logger.error(
|
|
||||||
f"Input router IP {router} does not match the configured router IP of {router_ip}"
|
|
||||||
)
|
|
||||||
raise ValueError(error_msg)
|
|
||||||
except:
|
|
||||||
raise
|
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,19 @@ class device:
|
||||||
for r in routers_list:
|
for r in routers_list:
|
||||||
if r["location"] == lg_router:
|
if r["location"] == lg_router:
|
||||||
self.address = r["address"]
|
self.address = r["address"]
|
||||||
self.port = r["port"]
|
self.asn = r["asn"]
|
||||||
self.type = r["type"]
|
self.src_addr_ipv4 = r["src_addr_ipv4"]
|
||||||
|
self.src_addr_ipv6 = r["src_addr_ipv6"]
|
||||||
self.credential = r["credential"]
|
self.credential = r["credential"]
|
||||||
self.location = r["location"]
|
self.location = r["location"]
|
||||||
|
self.name = r["name"]
|
||||||
|
self.port = r["port"]
|
||||||
|
self.type = r["type"]
|
||||||
self.proxy = r["proxy"]
|
self.proxy = r["proxy"]
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
return vars(self)
|
||||||
|
|
||||||
|
|
||||||
class credential:
|
class credential:
|
||||||
def __init__(self, cred):
|
def __init__(self, cred):
|
||||||
|
|
@ -60,20 +67,20 @@ class params:
|
||||||
class http:
|
class http:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.msg, self.status, self.router, self.query = construct.frr(
|
self.msg, self.status, self.router, self.query = construct.frr(
|
||||||
d.address, lg_cmd, lg_ipprefix
|
lg_cmd, lg_ipprefix, d()
|
||||||
)
|
)
|
||||||
|
|
||||||
def all(self):
|
def __call__(self):
|
||||||
return self.msg, self.status, self.router, self.query
|
return vars(self)
|
||||||
|
|
||||||
class ssh:
|
class ssh:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.msg, self.status, self.router, self.type, self.command = construct.netmiko(
|
self.msg, self.status, self.router, self.type, self.command = construct.ssh(
|
||||||
d.address, lg_cmd, lg_ipprefix
|
lg_cmd, lg_ipprefix, d()
|
||||||
)
|
)
|
||||||
|
|
||||||
def all(self):
|
def __call__(self):
|
||||||
return self.msg, self.status, self.router, self.type, self.command
|
return vars(self)
|
||||||
|
|
||||||
def nm_host(self):
|
def nm_host(self):
|
||||||
c = credential(d.credential)
|
c = credential(d.credential)
|
||||||
|
|
@ -104,15 +111,14 @@ class connect:
|
||||||
"""Sends HTTP POST to router running the hyperglass-frr API"""
|
"""Sends HTTP POST to router running the hyperglass-frr API"""
|
||||||
http = params().http()
|
http = params().http()
|
||||||
c = credential(d.credential)
|
c = credential(d.credential)
|
||||||
logger.error(f"API Key: {c.password}")
|
|
||||||
try:
|
try:
|
||||||
headers = {"Content-Type": "application/json", "X-API-Key": c.password}
|
headers = {"Content-Type": "application/json", "X-API-Key": c.password}
|
||||||
json_query = json.dumps(http.query)
|
json_query = json.dumps(http.query)
|
||||||
frr_endpoint = f"http://{d.address}:{d.port}/frr"
|
frr_endpoint = f"http://{d.address}:{d.port}/frr"
|
||||||
frr_output = requests.post(
|
frr_response = requests.post(
|
||||||
frr_endpoint, headers=headers, data=json_query
|
frr_endpoint, headers=headers, data=json_query
|
||||||
)
|
)
|
||||||
return frr_output
|
return frr_response.text, frr_response.status_code
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
@ -130,6 +136,7 @@ class connect:
|
||||||
ssh = params().ssh()
|
ssh = params().ssh()
|
||||||
nm_proxy = ssh.nm_proxy()
|
nm_proxy = ssh.nm_proxy()
|
||||||
nm_host = ssh.nm_host()
|
nm_host = ssh.nm_host()
|
||||||
|
dp = proxy(d.proxy)
|
||||||
|
|
||||||
nm_connect_proxied = ConnectHandler(**nm_proxy)
|
nm_connect_proxied = ConnectHandler(**nm_proxy)
|
||||||
nm_ssh_command = dp.ssh_command.format(**nm_host) + "\n"
|
nm_ssh_command = dp.ssh_command.format(**nm_host) + "\n"
|
||||||
|
|
@ -188,9 +195,14 @@ def execute(lg_data):
|
||||||
# If netaddr library throws an exception, return a user-facing error.
|
# If netaddr library throws an exception, return a user-facing error.
|
||||||
except:
|
except:
|
||||||
msg = f"{lg_ipprefix} is not a valid IP Address."
|
msg = f"{lg_ipprefix} is not a valid IP Address."
|
||||||
code = 415
|
code = 405
|
||||||
logger.error(f"{msg}, {code}, {lg_data}")
|
logger.error(f"{msg}, {code}, {lg_data}")
|
||||||
return (msg, code, lg_data)
|
return (msg, code, lg_data)
|
||||||
|
elif lg_cmd == "Query Type":
|
||||||
|
msg = "You must select a query type."
|
||||||
|
code = 405
|
||||||
|
logger.error(f"{msg}, {code}, {lg_data}")
|
||||||
|
return (msg, code, lg_data)
|
||||||
|
|
||||||
global d
|
global d
|
||||||
d = device(lg_router)
|
d = device(lg_router)
|
||||||
|
|
@ -198,23 +210,33 @@ def execute(lg_data):
|
||||||
if d.type == "frr":
|
if d.type == "frr":
|
||||||
http = params().http()
|
http = params().http()
|
||||||
try:
|
try:
|
||||||
output = connect.restapi.frr()
|
if http.status in range(200, 300):
|
||||||
parsed_output = parse.parse(output, d.type, lg_cmd)
|
output, frr_status = connect.restapi.frr()
|
||||||
return parsed_output, http.status, params().http().all()
|
parsed_output = parse.parse(output, d.type, lg_cmd)
|
||||||
|
return parsed_output, frr_status, http()
|
||||||
|
elif http.status in range(400, 500):
|
||||||
|
return http.msg, http.status, http()
|
||||||
|
else:
|
||||||
|
logger.error(general_error, 500, http())
|
||||||
|
return general_error, 500, http()
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
ssh = params().ssh()
|
ssh = params().ssh()
|
||||||
if d.proxy:
|
if ssh.status in range(200, 300):
|
||||||
global dp
|
if d.proxy:
|
||||||
dp = proxy(d.proxy)
|
output = connect.nm.proxied(d.proxy)
|
||||||
output = connect.nm.proxied(d.proxy)
|
parsed_output = parse.parse(output, d.type, lg_cmd)
|
||||||
parsed_output = parse.parse(output, d.type, lg_cmd)
|
return parsed_output, ssh.status, ssh.router, ssh.command
|
||||||
return parsed_output, ssh.status, ssh.router, ssh.command
|
elif not d.proxy:
|
||||||
elif not d.proxy:
|
output = connect.nm.direct()
|
||||||
output = connect.nm.direct()
|
parsed_output = parse.parse(output, d.type, lg_cmd)
|
||||||
parsed_output = parse.parse(output, d.type, lg_cmd)
|
return parsed_output, ssh.status, ssh.router, ssh.command
|
||||||
return parsed_output, ssh.status, ssh.router, ssh.command
|
elif ssh.status in range(400, 500):
|
||||||
|
return ssh.msg, ssh.status, ssh()
|
||||||
|
else:
|
||||||
|
logger.error(general_error, 500, ssh())
|
||||||
|
return general_error, 500, ssh()
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue