The IETF model-driven management stack: YANG data modeling (containers/lists/leaves, types, config vs state, augment/deviation), NETCONF protocol (XML/SSH RPCs, get/edit-config, capabilities), datastores (running/candidate/startup, commit & confirmed-commit, NMDA), and RESTCONF.
Screen-scraping the CLI is fragile: unstructured text, per-vendor syntax, no transactions. Model-driven management fixes that — a machine-readable data model (YANG) defines the schema, and a protocol (NETCONF/RESTCONF) moves structured data in and out with real datastores and commits. This is the IETF half of the story; the gRPC/OpenConfig half is gNMI & OpenConfig.
YANG is the schema (what data exists and its types). NETCONF is the protocol that carries that data as XML over SSH, with candidate/running datastores and a commit model. Don't confuse the model with the protocol — YANG is used by NETCONF, RESTCONF and gNMI.
YANG (RFC 7950) is a language for modeling configuration and state as a tree. A model is a module with a namespace; the tree is built from containers, lists (keyed), leaves, and leaf-lists, with strong types.
container interfaces {
list interface {
key "name";
leaf name { type string; }
leaf enabled { type boolean; default true; }
leaf mtu { type uint16 { range "68..9216"; } }
container state { // operational, read-only
config false;
leaf oper-status { type enumeration { enum up; enum down; } }
}
}
}
config true vs config false — the key split: configurable intent
vs read-only operational state. This drives get-config (config only) vs get (config +
state).typedef, grouping/uses,
augment (add nodes to another model), deviation (declare what a device doesn't
support), and constraints (must, when).pyang / yanglint.NETCONF (RFC 6241) installs, manipulates, and deletes config using XML-encoded RPCs over SSH (port 830). Four conceptual layers:
| Layer | What |
|---|---|
| Content | YANG data, encoded as XML |
| Operations | get, get-config, edit-config, copy-config, delete-config, lock/unlock, commit, validate |
| Messages | rpc / rpc-reply / notification |
| Transport | SSH (TLS also defined); a hello exchanges capabilities (which models/features the device supports) |
An edit-config into the candidate datastore looks like:
<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<edit-config>
<target><candidate/></target>
<config>
<interfaces xmlns="...">
<interface>
<name>eth0</name>
<enabled>true</enabled>
<mtu>9000</mtu>
</interface>
</interfaces>
</config>
</edit-config>
</rpc>
edit-config operations per node: merge (default),
replace, create, delete, remove; plus
default-operation, test-option (validate first), and
error-option (rollback-on-error).The feature CLI can't match: transactional config.
commit atomically. startup — persisted boot config.lock → edit-config (candidate) →
validate → commit. confirmed-commit auto-rolls-back if you don't
confirm — safe remote changes without locking yourself out.RESTCONF (RFC 8040) exposes the same YANG models over HTTP (port 443) with
JSON or XML: GET/POST/PUT/PATCH/DELETE
map to the datastore operations. Stateless and firewall-friendly, but no candidate/commit semantics or locking like
full NETCONF — good for simple, scriptable access.
netconf connection + netconf_config / *_config modules (see
Ansible).config false mean, and how does it change get vs get-config?