import json import subprocess from jinja2 import Template from flask import Flask, render_template_string, jsonify, url_for app = Flask(__name__) def run_bgp_curl_command(): curl_command = [ "curl", "-k", "--location", "--request", "POST", "https://ip:port/show", "--form", "data={\"op\": \"show\", \"path\": [\"bgp\", \"summ\"]}", "--form", "key=key" ] response = subprocess.check_output(curl_command, text=True) return json.loads(response) def run_arp_curl_command(): curl_command = [ "curl", "-k", "--location", "--request", "POST", "https://ip:port/show", "--form", "data={\"op\": \"show\", \"path\": [\"arp\"]}", "--form", "key=key" ] response = subprocess.check_output(curl_command, text=True) return json.loads(response) def run_interfaces_curl_command(): curl_command = [ "curl", "-k", "--location", "--request", "POST", "https://ip:port/show", "--form", "data={\"op\": \"show\", \"path\": [\"interfaces\"]}", "--form", "key=key" ] response = subprocess.check_output(curl_command, text=True) return json.loads(response) def parse_bgp_data(data): ipv4_section = "" ipv6_section = "" ipv4_info = {} ipv6_info = {} if "data" in data: raw_data = data["data"] if "IPv4 Unicast Summary" in raw_data: ipv4_raw = raw_data.split("IPv4 Unicast Summary (VRF default):")[1] ipv4_section = ipv4_raw.split("IPv6 Unicast Summary (VRF default):")[0].strip() ipv4_info = extract_bgp_info(ipv4_raw) if "IPv6 Unicast Summary" in raw_data: ipv6_raw = raw_data.split("IPv6 Unicast Summary (VRF default):")[1].strip() ipv6_section = ipv6_raw ipv6_info = extract_bgp_info(ipv6_raw) def process_peers(peer_data): peers = [] for line in peer_data.split("\n"): if line.strip().startswith("Neighbor"): continue if line.strip(): peer_info = line.split() if len(peer_info) >= 12: peers.append({ "neighbor": peer_info[0], "version": peer_info[1], "as_number": peer_info[2], "msg_received": peer_info[3], "msg_sent": peer_info[4], "table_version": peer_info[5], "in_queue": peer_info[6], "out_queue": peer_info[7], "up_down": peer_info[8], "state_pfx_rcd": peer_info[9], "prefix_sent": peer_info[10], "description": " ".join(peer_info[11:]) }) return peers ipv4_peers = process_peers(ipv4_section) ipv6_peers = process_peers(ipv6_section) return ipv4_info, ipv4_peers, ipv6_info, ipv6_peers def extract_bgp_info(raw_data): lines = raw_data.split("\n") info = {} for line in lines: if "BGP router identifier" in line: parts = line.split(",") info["router_id"] = parts[0].split("identifier")[1].strip() info["local_as"] = parts[1].split("number")[1].strip().split(" ")[0] if "vrf-id" in parts[-1]: info["vrf_id"] = parts[-1].split("vrf-id")[1].strip() if "BGP table version" in line: info["table_version"] = line.split("version")[1].strip() if "RIB entries" in line: parts = line.split(",") info["rib_entries"] = parts[0].split("entries")[1].strip() info["rib_memory"] = parts[1].split("using")[1].strip() if "Peers" in line: parts = line.split(",") info["peers"] = parts[0].split("Peers")[1].strip() info["peers_memory"] = parts[1].split("using")[1].strip() return info def parse_arp_data(data): arp_table = [] if "data" in data: raw_data = data["data"] for line in raw_data.split("\n"): if line.strip() and not line.startswith("Address") and "---" not in line: arp_info = line.split() if len(arp_info) >= 4: arp_table.append({ "address": arp_info[0], "interface": arp_info[1], "link_layer_address": arp_info[2], "state": arp_info[3] }) return arp_table def parse_interface_data(data): interface_table = [] if "data" in data: raw_data = data["data"] for line in raw_data.split("\n"): if line.startswith("Interface") and "IP Address" in line: continue if line.startswith("Codes:"): continue if line.strip().startswith('-'): continue if line.strip(): interface_info = line.split() if len(interface_info) >= 6: interface_table.append({ "interface": interface_info[0], "ip_address": interface_info[1] if interface_info[1] != '-' else 'N/A', "mac_address": interface_info[2], "vrf": interface_info[3], "mtu": interface_info[4], "status": interface_info[5], "description": " ".join(interface_info[6:]) }) return interface_table def generate_bgp_html_table(ipv4_info, ipv4_peers, ipv6_info, ipv6_peers): html_template = """ BGP Table

Core1.Doet.pixelHosting.nl

BGP Table

IPv4 Unicast Summary

BGP Router ID: {{ ipv4_info.router_id }}, Local AS Number: {{ ipv4_info.local_as }} VRF ID: {{ ipv4_info.vrf_id }}

BGP Table Version: {{ ipv4_info.table_version }}

RIB Entries: {{ ipv4_info.rib_entries }}, using {{ ipv4_info.rib_memory }}

Peers: {{ ipv4_info.peers }}, using {{ ipv4_info.peers_memory }}

{% for peer in ipv4_peers %} {% endfor %}
Neighbor Version (V) AS Number Messages Received Messages Sent Table Version Inbound Queue (InQ) Outbound Queue (OutQ) Up/Down State/PfxRcd Prefix Sent (PfxSnt) Description
{{ peer.neighbor }} {{ peer.version }} {{ peer.as_number }} {{ peer.msg_received }} {{ peer.msg_sent }} {{ peer.table_version }} {{ peer.in_queue }} {{ peer.out_queue }} {{ peer.up_down }} {{ peer.state_pfx_rcd }} {{ peer.prefix_sent }} {{ peer.description }}

JSON version

IPv6 Unicast Summary

BGP Router ID: {{ ipv6_info.router_id }}, Local AS Number: {{ ipv6_info.local_as }} VRF ID: {{ ipv6_info.vrf_id }}

BGP Table Version: {{ ipv6_info.table_version }}

RIB Entries: {{ ipv6_info.rib_entries }}, using {{ ipv6_info.rib_memory }}

Peers: {{ ipv6_info.peers }}, using {{ ipv6_info.peers_memory }}

{% for peer in ipv6_peers %} {% endfor %}
Neighbor Version (V) AS Number Messages Received Messages Sent Table Version Inbound Queue (InQ) Outbound Queue (OutQ) Up/Down State/PfxRcd Prefix Sent (PfxSnt) Description
{{ peer.neighbor }} {{ peer.version }} {{ peer.as_number }} {{ peer.msg_received }} {{ peer.msg_sent }} {{ peer.table_version }} {{ peer.in_queue }} {{ peer.out_queue }} {{ peer.up_down }} {{ peer.state_pfx_rcd }} {{ peer.prefix_sent }} {{ peer.description }}

JSON version

""" template = Template(html_template) html_output = template.render(ipv4_info=ipv4_info, ipv4_peers=ipv4_peers, ipv6_info=ipv6_info, ipv6_peers=ipv6_peers) return html_output def generate_arp_html_table(arp_table): html_template = """ ARP Table

Core1.Doet.pixelHosting.nl

ARP Table

{% for entry in arp_table %} {% endfor %}
Address Interface Link Layer Address State
{{ entry.address }} {{ entry.interface }} {{ entry.link_layer_address }} {{ entry.state }}

JSON version

""" template = Template(html_template) html_output = template.render(arp_table=arp_table) return html_output def generate_interfaces_html_table(interface_table): html_template = """ Interface Table

Core1.Doet.pixelHosting.nl

Interface Table

Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down

{% for entry in interface_table %} {% endfor %}
Interface IP Address MAC Address VRF MTU Status Description
{{ entry.interface }} {{ entry.ip_address }} {{ entry.mac_address }} {{ entry.vrf }} {{ entry.mtu }} {{ entry.status }} {{ entry.description }}

JSON version

""" template = Template(html_template) html_output = template.render(interface_table=interface_table) return html_output def generate_bgp_json(ipv4_info, ipv4_peers, ipv6_info, ipv6_peers): return { "ipv4_info": ipv4_info, "ipv4_peers": ipv4_peers, "ipv6_info": ipv6_info, "ipv6_peers": ipv6_peers } def generate_arp_json(arp_table): return {"arp_table": arp_table} @app.route("/bgp") def bgp(): bgp_data = run_bgp_curl_command() ipv4_info, ipv4_peers, ipv6_info, ipv6_peers = parse_bgp_data(bgp_data) bgp_html = generate_bgp_html_table(ipv4_info, ipv4_peers, ipv6_info, ipv6_peers) return render_template_string(bgp_html) @app.route("/bgp/json") def bgp_json(): bgp_data = run_bgp_curl_command() ipv4_info, ipv4_peers, ipv6_info, ipv6_peers = parse_bgp_data(bgp_data) return jsonify(generate_bgp_json(ipv4_info, ipv4_peers, ipv6_info, ipv6_peers)) @app.route("/arp") def arp(): arp_data = run_arp_curl_command() arp_table = parse_arp_data(arp_data) arp_html = generate_arp_html_table(arp_table) return render_template_string(arp_html) @app.route("/arp/json") def arp_json(): arp_data = run_arp_curl_command() arp_table = parse_arp_data(arp_data) return jsonify(generate_arp_json(arp_table)) @app.route('/interfaces') def interface_table_page(): data = run_interfaces_curl_command() interface_table = parse_interface_data(data) interfaces_html = generate_interfaces_html_table(interface_table) # Correct variable name return render_template_string(interfaces_html) # Render the correct variable @app.route('/interfaces/json') def interface_table_summary_json(): data = run_interfaces_curl_command() interface_table = parse_interface_data(data) return jsonify({"interface_table": interface_table}) if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=5000)