YANG and OpenConfig Models: A Practical pyang Workflow - 夜莺博客

YANG and OpenConfig Models: A Practical pyang Workflow

YANG is the schema language behind every modern network API: NETCONF, RESTCONF and gNMI all encode data that a YANG model defines. The practical consequence is that you cannot reliably write a config payload without seeing the model, and guessing paths is why so many automation attempts fail with "unknown element" errors. This guide is the workflow an engineer needs before writing a single line of automation: get the models, render the tree, validate the payload, then send it.

What the pieces are

  • YANG — a data modelling language describing the configuration and state a device exposes as a tree of nodes.
  • Native models — vendor-specific (Cisco IOS XE native, Juniper Junos YANG). Faithful to the CLI, but not portable.
  • OpenConfig / IETF models — vendor-neutral models for common objects (interfaces, VLANs, BGP). The same path works on multiple vendors, which is the whole point of using them.
  • NETCONF/RESTCONF/gNMI — the transports. The model defines the payload structure; the transport defines how you exchange it.

Get the models and render the tree

pip install pyang
git clone https://github.com/openconfig/public.git
cd public/release/models

# Render an ASCII tree of the interfaces model
pyang -f tree -o if.tree openconfig-interfaces.yang
less if.tree
module: openconfig-interfaces
  +--rw interfaces
     +--rw interface* [name]
        +--rw name       -> ../config/name
        +--rw config
        |  +--rw name
        |  +--rw description?
        |  +--rw enabled?
        |  +--rw mtu?
        +--rw subinterfaces
           +--rw subinterface* [index]
              +--rw index    -> ../config/index
              +--rw config
              |  +--rw index?
              |  +--rw description?
              +--rw ipv4
                 +--rw addresses
                    +--rw address* [ip]

+--rw means read-write (configurable), ro means state only, * means a list, [name] is the list key and -> is a leafref pointing at where the value actually lives. That last detail explains a common confusion: you set config/name, not the top-level name.

Inspecting the model instead of the docs

# Full description of a path, with types and constraints
pyang -f tree --tree-path /interfaces/interface/subinterfaces/subinterface -o sub.tree openconfig-interfaces.yang

# Which types and defaults does a node have?
pyang -f jsonx openconfig-interfaces.yang | head
pyang -f yang --keep-comments openconfig-interfaces.yang > if.full.yang

# Dependencies and imports
pyang --lint -p . openconfig-interfaces.yang

--tree-path is the single most useful flag in day-to-day work: it prints only the branch you care about instead of the whole module, which on a large model such as OpenConfig BGP is the difference between a screen and a novel.

Validate before you send

# Config JSON must match the module exactly: leaf names, list keys, types
cat >if.json <<'EOF'
{
  "openconfig-interfaces:interfaces": {
    "interface": [
      {
        "name": "Ethernet1",
        "config": {
          "name": "Ethernet1",
          "description": "to-spine-1",
          "enabled": true,
          "mtu": 9000
        }
      }
    ]
  }
}
EOF

# XML payload for the same object (NETCONF)
cat >if.xml <<'EOF'
<interfaces xmlns="http://openconfig.net/yang/interfaces">
  <interface>
    <name>Ethernet1</name>
    <config>
      <name>Ethernet1</name>
      <description>to-spine-1</description>
      <enabled>true</enabled>
      <mtu>9000</mtu>
    </config>
  </interface>
</interfaces>
EOF

Then push it over the transport your device offers — for example RESTCONF on IOS XE:

curl -sk -u admin:password \
  -X PATCH -H "Content-Type: application/yang-data+json" \
  -d @if.json \
  "https://10.0.0.1/restconf/data/openconfig-interfaces:interfaces"

Why this workflow pays for itself

  1. Errors move left. A wrong leaf name caught by the tree never reaches the device.
  2. Native vs OpenConfig becomes a decision, not an accident — native models for deep platform features, OpenConfig for the portable 80%.
  3. Idempotency is easier. When you know the exact node path and its type, comparing intended and operational state is a dictionary diff.
  4. Vendor swap becomes survivable. Automation written against OpenConfig paths needs a regeneration pass, not a rewrite.

Twenty minutes with pyang saves days of payload guessing. Put the rendered trees in your automation repo next to the playbooks — they are documentation that cannot go stale, because they are generated from the same models the device implements.

Related Reading on This Site

原文链接:https://routebythescript.com/interpreting-yang-for-network-automation-with-netconf/ (Route By The Script - Interpreting YANG for network automation with NETCONF)