A Flask web application for managing Cisco and Huawei routers over NETCONF. It lets you register devices, pull live interface state, and push interface configuration changes (description, IP address, admin state) through a browser UI no manual CLI/SSH needed.
- Router inventory add, edit, and delete routers (name, IP address, vendor/technology, NETCONF connection profile), stored in SQLite.
- Interface reporting connect to every registered router over NETCONF, pull interface state (admin/oper status, description, MAC address, speed, IP/mask) and cache it in the database for fast browsing.
- Interface editing edit an interface's description, IP/mask, and admin state from the UI; the change is rendered into a vendor-specific NETCONF
edit-configpayload (via Jinja2 templates) and pushed to the device, then the local cache is refreshed with the device's confirmed state. - Multi-vendor support Cisco IOS-XE (
ietf-interfaces/ native YANG models) and Huawei VRP (huawei-ifm/huawei-systemYANG models), each with its own NETCONF query filter and config template. - Reactive UI without a JS framework server-rendered partials swapped in with htmx, so tables/forms update without full page reloads.
| Layer | Technology |
|---|---|
| Backend | Python, Flask, Flask-WTF |
| NETCONF client | ncclient, xmltodict |
| Config templating | Jinja2 (utils/gen_conf_template) |
| Database | SQLite (database/database.db) |
| Frontend | Jinja2 templates, htmx, jQuery / jQuery UI |
app.py # Flask routes / application entry point
database/
database-schema.sql # routers_info + interfaces table definitions
database.db # SQLite database file
db_functions.py # raw SQL helpers (select/insert/update/delete)
utils/
forms.py # Flask-WTF "add router" form
get_interfaces.py # NETCONF <get> calls + XML parsing per vendor
configure_interface.py # NETCONF <edit-config> call
cirde_to_mask.py # CIDR <-> dotted-decimal netmask conversion
bandwidth.py # bandwidth unit conversion helpers
ping_devices.py # TCP reachability check helper
gen_conf_template/
template_generator.py # renders vendor-specific edit-config XML
templates/
interface_config_csr100v.jinja # Cisco CSR1000v interface template
interface_config_cx600.jinja # Huawei CX600 interface template
router_config/ # sample full-device configs used in the lab (CSR1000v, CX600)
templates/ # Jinja2 pages + htmx partials (hx-*.html)
static/ # CSS, JS (htmx/jQuery), diagram, demo videos
routers_info:id,router_name,router_ipaddress,router_technology,netconf_connectioninterfaces:router_name,interface_name,description,admin_state,operation_state,mac_address,speed,ipaddress,mask,router_technology
- Python 3.11+
- One or more Cisco IOS-XE / Huawei VRP devices (physical or virtual, e.g. CSR1000v / CX600) with NETCONF enabled and reachable from where you run the app
- Vendor NETCONF ports: Cisco typically
830, Huawei typically22
pip install flask flask-wtf wtforms ncclient xmltodict jinja2No
requirements.txtis currently checked in install the packages above, or generate one withpip freeze > requirements.txtonce your environment is set up.
python app.pyFlask will start in debug mode on the default port. Open the app in your browser and:
- Go to Routers info and add your routers (name, IP, vendor, NETCONF connection type).
- Go to Interfaces and click get interfaces info to pull live state from every router via NETCONF.
- Click a row's edit action to change an interface's description/IP/admin state the app builds the vendor-specific NETCONF payload and applies it to the device.
- NETCONF credentials and per-vendor ports/connection names are currently hardcoded in
app.py/utils/get_interfaces.py/utils/configure_interface.py(e.g.username="lahcen",password="Netconf@2021"). Before using this against real infrastructure, move these into environment variables or a config file instead of source code. - SQL queries in
app.py/database/db_functions.pyare built with plain string interpolation. If you expose this app beyond a trusted lab environment, switch to parameterized queries to avoid SQL injection. Flask-SECRET_KEYis also hardcoded inapp.pyreplace it with a value from the environment in any non-lab deployment.
An editable draw.io diagram of the app flow is available at static/diagram.drawio.