Cisco IOS XE • Python • RESTCONF • NETCONF/YANG • pyATS/Genie

Cisco IOS XE Network Automation

A Python network-automation project for collecting live Cisco IOS XE state, validating expected behavior, comparing management protocols, making a narrowly scoped configuration change, and proving rollback to the original baseline.

The implementation was exercised against Cisco DevNet Catalyst 8000V sandboxes. Read-only collection uses RESTCONF, NETCONF/YANG, and pyATS/Genie; configuration writes are disabled by default and constrained to a single demo loopback on a private/reservable lab.

Cisco IOS XELive Catalyst 8000V device state
↓
RESTCONF
YANG / JSON
NETCONF
YANG / XML
pyATS / Genie
SSH / CLI
↓
Normalized network stateInterfaces · routes · policy checks · semantic diff
↓
Evidence and rollbackPASS/FAIL results · read-after-write · baseline restoration
Three independent management paths are normalized before comparison and validation.

Observed live results

The project records expected success and failure behavior rather than only showing that an API call returned data.

ValidationObserved result
Stable live policyPASS
Intentional bad default-route next hopFAIL as expected
Two independent live baseline captures0 semantic differences
Guarded Loopback250 creationCreated and read-back verified
Semantic post-change diffExactly 2 intended changes: interface + connected route
Post-change policy validation18/18 checks passed
Guarded rollbackDelete verified
Original baseline vs rollback state0 semantic differences
RESTCONF vs NETCONF hostnameMATCH
RESTCONF vs NETCONF interface stateMATCH
RESTCONF vs NETCONF vs pyATS/Genie interface stateMATCH
pyATS AEtest validation100% section success

What I built

Each management interface is treated as a collector feeding the same internal state model. That separates protocol-specific parsing from validation logic and makes disagreement between sources visible.

RESTCONF

Structured operational state

Collects hostname, IOS XE version, interface state, IPv4 addressing, and routing data through YANG-backed JSON APIs.

NETCONF

Independent YANG path

Uses ncclient with the IOS XE device handler to retrieve hostname and operational interface state over NETCONF/XML.

pyATS / Genie

Cisco-native validation

Connects through Unicon, parses CLI state with Genie, and runs reusable AEtest sections with native PASS/FAIL behavior.

Normalized model

One comparison layer

Transforms protocol-specific responses into common interface and routing objects before policy checks or semantic comparison.

Cross-protocol verification

The same live interface is observed through three separate paths. The comparison uses only fields all three sources expose consistently: interface name, administrative state, operational state, and IPv4 address.

RESTCONF / YANG --------------------┐
NETCONF / YANG ---------------------+--> normalized interface state --> MATCH / FAIL
SSH + Genie parser + pyATS ---------┘
Why this matters: a single successful API response does not prove the automation interpreted the device correctly. Independent sources give the validation layer something meaningful to compare.

Guarded change and rollback

The write path is deliberately narrow. It is not a generic configuration shell and is intended only for a private/reservable lab device.

01
Writes start disabled.
CISCO_ALLOW_WRITES=true must be explicitly set.
02
Scope is fixed.
Only Loopback250, 192.0.2.250/32, with a fixed ownership description.
03
Existing state is protected.
Creation refuses to overwrite an existing Loopback250.
04
Every write is read back.
Create and delete operations verify resulting device state.
05
Post-change policy runs.
Management interface, intended loopback, and required route checks must still pass.
06
Rollback is proven.
The final snapshot is semantically compared with the original baseline.
baseline
  -> guarded create
  -> read-after-write verification
  -> semantic diff: 2 intended changes
  -> policy validation: 18/18 PASS
  -> guarded delete
  -> read-after-delete verification
  -> compare with original baseline: 0 changes

Validation and failure behavior

Declarative policy

YAML policies describe expected interfaces, routing behavior, addresses, and other network state independently of the collectors.

Semantic diffing

Pre/post snapshots compare meaningful network state instead of producing noise from counters or protocol-specific response shapes.

Negative testing

An intentionally incorrect default-route expectation is expected to fail, proving that the validator catches a real policy violation.

Fail-closed configuration

Credentials and write permission come from environment variables; missing required configuration does not silently fall back to unsafe behavior.

Software engineering around the network

The repository is structured as a Python package rather than a collection of one-off scripts.

Python package

Separated responsibilities

Collectors, normalized models, policy validation, semantic diffing, reporting, RESTCONF, NETCONF, and pyATS integration live in separate modules.

CLI

Repeatable commands

The cisco-validate command exposes collection, validation, diffing, cross-check, and guarded demo-change workflows.

Tests

Offline verification

Deterministic fixtures let policy and diff behavior run without Cisco credentials or network connectivity.

CI

Python 3.11 and 3.12

GitHub Actions installs the package, runs Ruff, executes pytest, and verifies Python files are not accidentally committed executable.

Security design

The project treats the live lab and the public repository as separate trust boundaries.

Credentials

Environment-backed secrets

Device credentials remain outside Git. The checked-in pyATS testbed resolves credentials from environment variables.

Transport checks

Secure defaults

TLS verification and NETCONF SSH host-key verification are enabled by default. Disposable DevNet exceptions must be explicitly enabled for that session.

Source and verification

The public repository contains the Python package, policies, fixtures, public-safe pyATS testbed, AEtest job, automated tests, and CI configuration.

Back to top All projects