YANG, NETCONF, RESTCONF and gNMI Walkthrough¶
Model-driven programmability replaces screen scraping with structured APIs. YANG defines what the data looks like, and NETCONF, RESTCONF and gNMI are three ways to read and change it. This walkthrough shows how to find a model, pull and change configuration with ncclient and with curl, and subscribe to telemetry with gNMI using gnmic, including the difference between periodic and on-change subscriptions.
The examples use a Cisco IOS XE device, but the ideas carry to any platform that supports these interfaces.
How the pieces fit¶
graph TB
Y["YANG models<br/>define the data (RFC 7950)"] --> N["NETCONF<br/>XML over SSH, port 830"]
Y --> R["RESTCONF<br/>HTTPS, JSON or XML, port 443"]
Y --> G["gNMI<br/>gRPC, Protobuf or JSON"]
N --> D["Device datastores<br/>running config and state"]
R --> D
G --> D
- YANG (RFC 7950) is a modelling language. A YANG module describes containers, lists and leaves, their types, and whether they are configuration or operational state.
- NETCONF (RFC 6241) is an RPC protocol. It runs over SSH (default port 830), exchanges XML, and has operations such as
get,get-config,edit-config,commitandlock. - RESTCONF (RFC 8040) maps the same models onto HTTP methods (GET, PUT, POST, PATCH, DELETE) with JSON or XML bodies.
- gNMI is the gRPC Network Management Interface from the OpenConfig project. It has
Get,Set,CapabilitiesandSubscribeRPCs and is the main choice for streaming telemetry.
NETCONF and RESTCONF are good for configuration. gNMI is the leading choice for telemetry at scale because the device pushes data and the collector does not have to poll.
Enable the interfaces on IOS XE¶
netconf-yang starts the NETCONF server on port 830. RESTCONF needs the HTTPS server, and the account you use must have privilege 15 or an appropriate AAA authorisation. Check the programmability configuration guide for your release for gNMI, since the enable commands and the port (commonly 9339 for secure gNMI) depend on the software version. Verify what is running with:
Warning
Do not leave these interfaces open to your whole network. Restrict the management plane with ACLs or a management VRF, and use certificates instead of disabling verification once you are past the lab stage.
Finding the right model¶
You need three things: which models the device supports, what they look like, and the path to the data you want.
- Ask the device. NETCONF advertises its capabilities in the hello message, and gNMI returns them from
Capabilities. Both list the supported modules and versions. - Browse the source. The community YangModels/yang repository holds the vendor and standards modules. Cisco's IOS XE models live under
vendor/cisco/xe/<release>/. - Render a tree. Install
pyangand print the structure:
pip install pyang
pyang -f tree -p . ietf-interfaces.yang
pyang -f tree --tree-path /interfaces/interface Cisco-IOS-XE-native.yang | head -50
The tree shows each node, with rw for configuration and ro for operational state. Three families of models matter:
| Family | Example module | Notes |
|---|---|---|
| IETF | ietf-interfaces, ietf-ip |
Standard but limited coverage |
| OpenConfig | openconfig-interfaces, openconfig-bgp |
Vendor-neutral; support level varies |
| Native | Cisco-IOS-XE-native, Cisco-IOS-XE-interfaces-oper |
Full coverage of the platform, vendor-specific |
If you only need to manage Cisco gear, native models cover the most. If you manage several vendors, prefer OpenConfig or IETF where the device implements what you need.
NETCONF with ncclient¶
Pull configuration¶
from ncclient import manager
with manager.connect(
host="192.0.2.10",
port=830,
username="automation",
password="change-me",
hostkey_verify=False, # lab only
device_params={"name": "iosxe"},
) as m:
flt = """
<filter>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>GigabitEthernet1</name>
</interface>
</interfaces>
</filter>
"""
reply = m.get_config(source="running", filter=flt)
print(reply.xml)
The filter is a subtree filter. You name the nodes you want, using the module's XML namespace, and the device returns only those. A request without a filter returns the entire config, which can be large.
To see what the device supports:
Change configuration¶
config = """
<config>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>GigabitEthernet2</name>
<description>uplink to dist-1</description>
<enabled>true</enabled>
</interface>
</interfaces>
</config>
"""
reply = m.edit_config(target="running", config=config)
print(reply.ok)
edit_config merges by default, so only the leaves you send change. Per-element operation attributes (replace, delete, remove, create) override that. IOS XE writes to the running datastore directly, and a candidate datastore is only available when enabled separately. Changes made this way live in the running config, so save them as you would after any other change (copy running-config startup-config, or the Cisco save-config RPC).
A good habit is to read back the same filter after edit_config and confirm the new value.
RESTCONF with curl¶
The same data is available over HTTPS. The root is /restconf/data/, the module name prefixes the top container, and list keys follow an equals sign.
curl -k -u automation:change-me \
-H "Accept: application/yang-data+json" \
https://192.0.2.10/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet1
-k skips certificate verification and is for the lab only. The Accept header selects JSON; use application/yang-data+xml for XML. Interface names with slashes must be URL-encoded, so GigabitEthernet1/0/1 becomes GigabitEthernet1%2F0%2F1.
Change a description with PATCH, which merges:
curl -k -u automation:change-me -X PATCH \
-H "Content-Type: application/yang-data+json" \
-H "Accept: application/yang-data+json" \
-d '{"ietf-interfaces:interface": {"name": "GigabitEthernet2", "description": "uplink to dist-1"}}' \
https://192.0.2.10/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet2
A successful PATCH returns 204 No Content. The methods behave differently:
| Method | Effect |
|---|---|
| GET | Read a resource |
| POST | Create a child resource (fails if it exists) |
| PUT | Create or replace the target resource entirely |
| PATCH | Merge the supplied data into the target |
| DELETE | Remove the target |
PUT replaces everything at that path, so PUT on a whole interface removes attributes you did not include. Use PATCH unless you mean to replace. Error responses are JSON documents with an errors list, and the HTTP status (400, 401, 404, 409) tells you the category.
RESTCONF is easy to use from anywhere HTTP works, including Python requests, Postman and shell scripts, which makes it a good first model-driven interface to try.
gNMI and telemetry with gnmic¶
gnmic is an open-source gNMI client (see its documentation for installation options). Start by confirming the connection and listing supported models:
--skip-verify ignores certificate validation and is for the lab. Use --tls-ca with your CA file in production.
Read a value once with get:
gnmic -a 192.0.2.10:9339 -u automation -p change-me --skip-verify \
get --path "/interfaces/interface[name=GigabitEthernet1]/state/oper-status"
gNMI paths use the schema's path format with list keys in square brackets. The paths you can use depend on which models the device supports, so take them from capabilities and from the YANG tree.
Change a value with set:
gnmic -a 192.0.2.10:9339 -u automation -p change-me --skip-verify \
set --update-path "/interfaces/interface[name=GigabitEthernet2]/config/description" \
--update-value "uplink to dist-1"
Subscribing¶
A subscription asks the device to send data on its own. The key choice is the mode.
Periodic (sample). The device sends the current value at a fixed interval, whether or not it changed.
gnmic -a 192.0.2.10:9339 -u automation -p change-me --skip-verify \
subscribe --path "/interfaces/interface/state/counters" \
--mode stream --stream-mode sample --sample-interval 10s
On-change. The device sends an update only when the value changes, plus an initial snapshot.
gnmic -a 192.0.2.10:9339 -u automation -p change-me --skip-verify \
subscribe --path "/interfaces/interface/state/oper-status" \
--mode stream --stream-mode on-change
graph LR
subgraph Periodic
A1["t=0 value 100"] --> A2["t=10 value 140"] --> A3["t=20 value 140"] --> A4["t=30 value 190"]
end
subgraph OnChange
B1["initial value up"] --> B2["change: down"] --> B3["change: up"]
end
Use periodic for counters and gauges such as byte counts, CPU and memory, because they change constantly and you want a regular time series for graphs. Use on-change for state and events: interface status, BGP neighbour state, configuration changes. On-change gives faster detection and far less traffic, but not every path supports it. A device may reject the subscription or fall back to sampling for paths that cannot be tracked as events, so test each path.
Other modes exist: --mode once sends one snapshot and closes, and --mode poll lets the client trigger each update. A third stream mode, target-defined, lets the device pick per path.
To store the data, gnmic can write to Prometheus, InfluxDB, Kafka and other outputs from a config file, which turns a one-off command into a collector. Check its documentation for the output options.
Choosing between them¶
| Task | Good choice |
|---|---|
| One-off config read or write from a script | RESTCONF or NETCONF |
| Transactional multi-part config change | NETCONF (candidate, lock, commit where supported) |
| Quick checks from the shell | RESTCONF with curl |
| Streaming interface counters and events | gNMI subscriptions |
| Multi-vendor, vendor-neutral models | gNMI or NETCONF with OpenConfig where supported |
These interfaces do not replace the CLI knowledge you need to read the result. The model for a BGP neighbour still maps to the same protocol behaviour you study in the CCNP course. To try the examples without production gear, build a virtual IOS XE device as described in the lab setup guide.
For tooling that wraps these protocols, Netmiko is still the fallback when a feature has no model, and Ansible has netconf and httpapi connection types that use the same models.
References¶
- RFC 7950: The YANG 1.1 Data Modeling Language
- RFC 6241: NETCONF
- RFC 8040: RESTCONF
- YangModels/yang on GitHub
- ncclient on GitHub
- gnmic documentation
- gNMI specification and OpenConfig on GitHub
- pyang on GitHub
Unlock the full question banks and cram sheets
A free account opens every question bank, the timed practice exams, the printable cram sheets, all the simulations and the lab files. Without one you see a 5-question sample of each.
No card needed. Study tips by email are optional and off unless you tick the box. Your address is never sold or shared. Privacy policy ยท Terms
Signed in as . Your account
You're on the free account, so lessons after the first module, question banks, exams and cram sheets show a sample. See Track Pass and All-Access
Also from NetManager Systems: NetManager, network monitoring for multi-vendor networks. Try the NetManager, NetDiag, PCAP Analyzer and OpsDash demos: every new account gets a free 7-day read-only login to each.