Verifying device configuration and state

The yang::NetconfVerify and yang::RestconfVerify resources check that a device matches a set of conditions on every deploy. Each condition is a yang::VerificationEntry: an xpath, an operator and (for binary operators) an expected value. Use them to assert config, to wait for operational state to settle (e.g. a session to come up), or to expose a verified value to the rest of the model.

A verify resource does two things on every deploy:

  1. it reads the device and checks each entry — failing (or skipping) the resource when a condition is not met;

  2. for each entry that opts in with a fact_name, it publishes the result as a fact, which can then be turned into a deploy-time reference (see Referencing a verified result).

Quick start

Assert that the Base router interface to-core is operationally up on a Nokia SR OS device:

import yang

verify = yang::NetconfVerify(
    name="to-core-up",
    device="router-east",
    host="10.20.30.40",
    port=830,
    credentials=yang::Credentials(
        username_env_var="ROUTER_EAST_USERNAME",
        password_env_var="ROUTER_EAST_PASSWORD",
    ),
)
verify.entries += yang::VerificationEntry(
    xpath="./state/router[router-name='Base']/interface[interface-name='to-core']/oper-state",
    operator="eq",
    value="up",
    condition_failed_message="Interface to-core is not up",
    namespaces={"": "urn:nokia.com:sros:ns:yang:sr:state"},
)

On every deploy the handler sends a get rpc (the subtree filter is built automatically from the entry xpaths), reads the matched nodes and compares them. If oper-state is not up, the deploy fails with Interface to-core is not up, and the failing condition shows up in the diagnose view of the web console.

Attributes

The resource carries the connection details, the entries carry the conditions.

Resource — yang::NetconfVerify / yang::RestconfVerify

Attribute

Description

name

Name of the verify resource, unique per device

device

Device name, used as agent name

host, port

Management address and port of the device

credentials / credentials_v2

Credentials used to connect, as for the other yang resources

retry_count, retry_interval

Retry behaviour of the device requests (transport errors)

condition_retry_count, condition_retry_interval

Re-read and re-check the conditions while they are not met (see Waiting for a condition) — default 0 (no wait)

skip_on_condition_failure

Skip the resource instead of failing it when conditions are not met (default false)

protocol_operation

(NetconfVerify) get (default) or get-config

datastore

(NetconfVerify) datastore for get-config (default running)

scheme, verify

(RestconfVerify) http scheme (default https) and TLS certificate verification (default true)

Entry — yang::VerificationEntry / yang::RestconfVerificationEntry

Attribute

Description

xpath

The xpath of the node(s) to check (see below for the supported subset)

operator

The comparison operator (see Operators and quantifiers)

value

The expected value, required for the binary operators (eq, gt, ge, le, lt)

quantifier

How to handle multiple matches (default one-result)

condition_failed_message

Human-readable message shown in the diagnose view when the condition is not met

namespaces

Mapping of prefix to namespace uri used in the xpath ("" is the default namespace)

fact_name

When set, publish the result as a fact under this name (see Publishing the result as a fact) — default null

url

(RestconfVerificationEntry) the RESTCONF path to query

content

(RestconfVerificationEntry) the content query parameter: all, config or nonconfig

Operators and quantifiers

Operators

Operator

Meaning

eq

the value equals value

gt, ge, lt, le

numeric comparison against value (values cast to int)

exists

a node matching the xpath is present

missing

no node matches the xpath

Quantifiers — how multiple matched nodes are handled

Quantifier

Meaning

one-result

(default) exactly one node must match; the resource fails immediately otherwise

all

every matched node must satisfy the operator

any

at least one matched node must satisfy the operator

count

compare the number of matched nodes against value (use with eq/gt/…)

The xpath supports the same restricted subset as the netconf filters: it must start at the root (./), and predicates ([...]) can only pin children to exact values ([router-name='Base']). Namespaces can be given as a {uri}tag prefix or through the namespaces mapping.

RESTCONF

yang::RestconfVerify works the same way, with yang::RestconfVerificationEntry entries that add the RESTCONF url to query (and an optional content filter):

import yang

verify = yang::RestconfVerify(
    name="policy-allowall",
    device="router-east",
    host="10.20.30.40",
    port=443,
    credentials=yang::Credentials(username="admin", password="admin"),
)
verify.entries += yang::RestconfVerificationEntry(
    url="/conf:configure/",
    content="config",
    xpath="./configure/policy-options/policy-statement[name='allowall']/default-action",
    operator="eq",
    value="allow",
    namespaces={"": "urn:nokia.com:sros:ns:yang:sr:conf"},
)

Waiting for a condition

When a condition reflects state that takes time to settle (a session establishing, an interface coming up), set condition_retry_count / condition_retry_interval so the handler re-reads the device and re-checks the conditions before giving up:

verify = yang::NetconfVerify(
    name="bgp-established",
    device="router-east",
    host="10.20.30.40",
    port=830,
    credentials=yang::Credentials(username="admin", password="admin"),
    condition_retry_count=12,
    condition_retry_interval=5,   # re-check every 5s, up to 12 times (~1 min)
    skip_on_condition_failure=true,
)
verify.entries += yang::VerificationEntry(
    xpath="./state/router[router-name='Base']/bgp/neighbor[ip-address='192.0.2.1']/statistics/session-state",
    operator="eq",
    value="Established",
    namespaces={"": "urn:nokia.com:sros:ns:yang:sr:state"},
)

With skip_on_condition_failure=true the resource is skipped (not failed) when the condition is still not met after the retries — useful to gate downstream resources without erroring the deploy.

Publishing the result as a fact

Set fact_name on an entry to publish its verification result as a fact on every deploy. The fact value is a serialized yang::VerificationResult:

{
  "xpath": "./state/router[router-name='Base']/interface[interface-name='to-core']/oper-state",
  "operator": "eq",
  "value": "up",
  "quantifier": "one-result",
  "values": ["up"],
  "errors": [],
  "success": true
}
  • values are the value(s) read from the device, errors the failure messages (empty on success) and success the overall outcome.

  • The fact is keyed by fact_name, so the fact_names of a single resource must be unique (this is validated at export — a duplicate fails the compile).

  • The fact is published on every successful read, including when the verification fails (so the result is always observable), but not during a dry run.

Facts can be browsed in the web console and queried through the orchestrator api. Because the result holds the raw values, a consumer can re-run the verification on the fact value without re-reading the device.

Referencing a verified result

A fact, on its own, is read at compile time — so a model that consumes it must be recompiled to pick up a new value. To consume a verified value at deploy time instead (no recompile when the device value changes), wrap the fact in a reference with yang::create_verification_reference(entry):

import yang

verify = yang::NetconfVerify(
    name="mgmt-address",
    device="router-east",
    host="10.20.30.40",
    port=830,
    credentials=yang::Credentials(username="admin", password="admin"),
)
entry = yang::VerificationEntry(
    xpath="./state/router[router-name='management']/interface[interface-name='system']/ipv4/primary/address",
    operator="exists",
    fact_name="mgmt_address",          # required: the reference resolves the published fact
    namespaces={"": "urn:nokia.com:sros:ns:yang:sr:state"},
)
verify.entries += entry

# A reference that resolves, on the agent at deploy time, to the yang::VerificationResult
# published by `verify` for `entry`.
result_ref = yang::create_verification_reference(entry)

result_ref is a reference to a yang::VerificationResult. Assign it wherever a yang::VerificationResult is expected; the orchestrator resolves it during deployment by fetching the fact verify publishes, and deserializing it into the dataclass (the verified xpath, operator, expected value, quantifier, the discovered values, the errors and the success flag).

The entry must set fact_name — without it no fact is published and the reference could never resolve, so create_verification_reference raises at compile. The entry must also be attached to exactly one verify resource, otherwise the resource publishing the fact would be ambiguous and the plugin raises as well. This mirrors std::FactReference / std::create_fact_reference (the reference is in fact built on top of it), but resolves to a structured yang::VerificationResult rather than a plain string.

With vs without a reference

Without a reference

With a reference

Set fact_name?

optional

required

What you get

a fact (browsable, queryable) and a pass/skip/fail verdict on the resource

the above, plus a yang::VerificationResult usable elsewhere in the model

When the value is read

at compile time (re-reading needs a recompile)

on the agent, at deploy time (no recompile)

Typical use

assert config, gate a deploy, expose operational data

feed a verified/operational value into another resource without recompiling

Limitations

  • The xpath supports only the restricted subset described above (root-anchored, exact-value predicates) — the same one the netconf subtree filters accept.

  • gt/ge/lt/le cast both operands to integers; non-numeric values raise at deploy.

  • One reference points at one entry’s result; build one reference per entry you want to consume.