SP Scott Peterman
Network systems engineering

I turn opaque networks into something you can query, plan around, and build against.

When a network's real state isn't queryable, your designs become shapes automation can't consume, and the tools you bought are the ones you can't extend. That's the gap I work in. Thirty years operating networks; the last five building the software that makes their state something you can trust.

OPERATE 30 yrs · MPLS · BGP · EVPN BUILD validated on real Arista · Juniper · Cisco DOMAIN datacenter · peering · service provider BASE Littleton, CO
How it's built

Every tool below was validated against real multi-vendor network OSes in a functional lab — real routing tables, real failure scenarios, run through automated suites and re-run on every change, not a one-time pass. Never just mock data. The constructs have since made their way into production, but the lab is where they were proven.

Lab-validated
Built against real network OSes with real routing state and real failures. The primitives used in these projects are re-usable constructs. Change the language, framework or pipeline.
Multi-vendor
Arista, Juniper, Cisco — on a shared, vendor-agnostic core.
QA-driven
Robot Framework + pyATS out of GitLab CI. Four years of it.
Inheritable
Reusable primitives on carefully chosen libraries — FastAPI, SQLite. Nothing obscure; the next engineer can pick it up.
Selected work

Five systems, built end to end.

This is not a product catalog. What they show is the approach to my solutions: the problem, the decision it turned on, and the thing running. Each one is a capability I can rebuild for a network that needs it.

FIG.01
Discover
Go · Fyne 2
CDP · LLDP
SSH · serial
OS keyring

A terminal that already knows the topology

Every SSH client treats a network as a flat list of hostnames someone typed in by hand. Discovery lives in a second tool, capture in a third, and the map in a diagram nobody has opened since the last cutover — so the thing you connect with is the one thing that knows nothing about the network.

The decision

Make the client itself the discovery tool. Seed one address, crawl outward on CDP and LLDP, and let the resulting topology be the session tree — click a node and you're on it. The same crawl feeds inventory and config capture with deduplicated history, and exports to draw.io so the diagram is a build artifact instead of a chore. Credentials sit in an OS-backed vault; jump hosts, serial, and legacy KEX are first-class because real networks still have all three.

Crawl, map and capture running end to end in the topology-aware SSH client.
crawl → map → capture Go · Fyne 2 · Linux, macOS, Windows open ↗
FIG.02
Map
Go core · C ABI
C++ · Qt 6
SSH + SNMP
Qt WebEngine

Discovery and topology mapping as a native application

Discovery engines get written into whatever app needs them, so the crawl can't be driven from a job runner, a CLI, or a second UI without being rewritten. And the map is usually a picture — not a document another tool can read.

The decision

Build the crawl engine once in Go, expose it across a narrow C ABI, and let a C++/Qt application and a headless CLI be two front ends over the same core — so discovery is a library, not a feature of one binary. SSH and SNMP collect side by side, with OIDs already validated against Junos, IOS and EOS. The map JSON schema is treated as a contract, because other tools consume it; the viewer is a separate, loosely coupled executable, and export and merge are first-class.

Native Qt discovery and topology mapping application.
live crawl → topology → export Go · C · C++ · Qt 6 · Linux, macOS, Windows open ↗
FIG.03
Trace
Python · FastAPI
RIB · FIB
ECMP
directed graph

The forwarding path, read from the devices themselves

A traceroute probes from outside with ICMP and sees hop IPs. It's blind to RIB-versus-FIB divergence, an unresolved next-hop, and any ECMP path it didn't happen to hash into — which is exactly the state you need before and after a cut.

The decision

The device itself is the most accurate source of truth — so work it inside-out. SSH into each device, read its own forwarding tables, and ask four questions at every hop: is there a route, is it in the FIB, is the next-hop resolved, is the link healthy. Build a directed graph of every path a packet can actually take, then diff a before against an after and get path count, ECMP width, and edge churn as numbers you can gate a change on.

Forwarding path graph and a baseline-versus-comparison diff of paths, ECMP width and churn.
walk the FIB → graph → pre/post diff Python · FastAPI · Junos, EOS, IOS/NX-OS open ↗
FIG.04
Track
Python
SQLite
TextFSM
REST API

A searchable state-tracking machine for everything that isn't config

Config backup answers "what changed?" with a text diff, and only for config. Everything else the network knows — ARP, BGP, routes, LLDP, interfaces — is state you can't query, can't version, and can't trust.

The decision

Make any CLI output a first-class record. Define a template and it's collected, parsed, versioned, and semantically diffed — a peer dropping to Idle, not a timer ticking. Every parse is scored on records, fields, population and consistency, so the platform tells you whether its own data is even true, with a template lab for fixing the ones that aren't. All of it API-addressable, so it becomes the source of truth other automation reads.

Template lab scoring a parse against raw CLI output, with the parsed records beside it.
collect → parse → score → semantic diff Python · SQLite · TextFSM · self-hosted open ↗
FIG.05
Serve
Python
SQLite · dnslib
split horizon
two-process

DNS and DHCP you can actually build against

DHCP hands out an address; DNS has to carry the name; and in most shops a human stitches the two together while the automation can touch neither. The network's own foundational services are the part nobody designs to be built against.

The decision

Build both to be automated from the first packet. Authored intent lives in git, but the decisions get made on state — machine state in SQLite, and DNS derived directly from live lease state. Split-horizon views, forwarders and cache are all config surfaces, not file edits. Two processes joined by one narrow, well-defined interface that degrades gracefully instead of ever failing a lease. Validated end to end on real Cisco gear, across a relay.

DNS console showing split-horizon views, upstream forwarders and cache controls.
lease state → zones → split horizon Python · SQLite · dnslib · lab-validated on Cisco relay open ↗
One foundation

These aren't five tools — they're one set of reusable primitives applied five times. I'd rather everything spoke RESTCONF; operational reality is SSH-first, so parsing is the first-class citizen — the output selects the template, not the engineer. Underneath sits a hardened, vendor-agnostic SSH client and a structured artifact that carries the contract between stages. Each one is built to be a platform, not a script: something automation can consume reliably, and the next engineer can pick up and extend.

The real test of a primitive is whether it survives being pulled out and handed to someone else. The terminal core from the SSH client is now a standalone Qt widget that owns no pty, with PySide6 wrappers, so a Python developer with no compiler and no Qt installed gets a native terminal in one pip install — I built it because I started out on Windows with no terminal options at all while writing automation tooling. The same Go core → C ABI → C++/Qt model then carried straight over to the mapping application above: engine once, front ends many, shipping on Linux, macOS and Windows.

Track record

Where it came from.

2024 — now
Principal Infrastructure Engineer
Datacenter and peering infrastructure on Arista and Juniper — circuit turn-ups, PNI implementations, and BGP peer migrations with pre-flight validation, state auditing, and cutover execution.
2022 — 2024
Principal Infrastructure Engineer · Columbia Sportswear
Enterprise network across 600+ retail locations, datacenters, and corporate sites (Cisco, Aruba, Palo Alto). Built a device-state collection platform for auditing and compliance.
2019 — 2022
Principal Engineer · Charter the QA instinct
Built datacenter QA network automation from the ground up — Robot Framework and pyATS suites against real hardware, out of GitLab CI on every config and image change. EVPN/VXLAN fabric and control/data-plane convergence validation. This is where "is the data even true?" became a habit.
2012 — 2019
Architect, IP Edge · Level3 / TW Telecom the gap seat
IP services architecture across a tier-1 backbone — MPLS L3VPN, VPLS, anycast DNS, NetFlow at carrier scale. Sat between engineering and automation, making sure the design constructs were built to be consumed by automation, a decade before that was the norm.
2006 — 2012
Architect III · Cricket / AT&T
Mobile carrier core — MPLS with OSPF-TE, VPLS, MVNO peering, datacenter fabrics up to ~300 switches.
Reference
Protocols
BGP · MPLS L3VPN
VPLS · EVPN/VXLAN
OSPF / IS-IS · SD-WAN
Platforms
Cisco IOS/XE/NX-OS
Arista EOS · Junos
Palo Alto · Aruba · F5
Languages
Python · Go · C/C++
C#/.NET · JS/TS
Qt 6 · PyQt6/PySide6
FastAPI · Fyne
Automation
pyATS · Robot Framework
Nornir · NAPALM · TextFSM
MCP · LLM tool calling
Paramiko · GitLab CI