Scripting with RESTCONF¶
RESTCONF provides a programmatic interface to both configuration and
operational data over HTTPS. This guide shows practical examples using
curl to interact with the RESTCONF API.
All examples use the following conventions:
- Host:
example.local(replace with your device hostname/IP) - Credentials:
admin:admin(default username:password) - HTTPS: Self-signed certificates require
-kflag in curl
Helper Script¶
To simplify RESTCONF operations, create a curl.sh wrapper script:
#!/bin/sh
AUTH=${AUTH:-admin:admin}
HOST=${HOST:-infix.local}
method=$1
path=$2
shift 2
set -x
exec curl \
--insecure \
--user ${AUTH} \
--request ${method} \
--header "Content-Type: application/yang-data+json" \
--header "Accept: application/yang-data+json" \
"$@" \
https://${HOST}/restconf/ds/ietf-datastores:${path}
Make it executable:
This wrapper handles authentication, headers, and the base URL construction, making commands much cleaner. You can override defaults with environment variables:
The examples below show both raw curl commands and the equivalent using
curl.sh where applicable.
Discovery & Common Patterns¶
Before working with specific configuration items, you often need to discover what exists on the system. This section shows common discovery patterns and practical workflows.
Discovering Available Interfaces¶
List all interface names:
~$ ./curl.sh example.local GET operational/ietf-interfaces:interfaces 2>/dev/null | jq -r '.["ietf-interfaces:interfaces"]["interface"][].name'
lo
e0
e1
This is essential for automation - interface names vary by platform (eth0, e1, enp0s3, etc.), so scripts should discover them rather than hardcode.
Get API Capabilities¶
Discover what YANG modules are available:
~$ curl -kX GET -u admin:admin \
-H 'Accept: application/yang-data+json' \
https://example.local/restconf/data/ietf-yang-library:yang-library
This returns all supported YANG modules, revisions, and features.
Get Entire Running Configuration¶
Useful for exploration or backup:
Common Workflow Patterns¶
Pattern 1: Find interface by IP address¶
Get all interfaces with IPs and search:
~$ ./curl.sh example.local GET operational/ietf-interfaces:interfaces 2>/dev/null \
| jq -r '.["ietf-interfaces:interfaces"]["interface"][] | select(.["ietf-ip:ipv4"]["address"][]?.ip == "192.168.1.100") | .name'
Pattern 2: List all interfaces that are down¶
~$ ./curl.sh example.local GET operational/ietf-interfaces:interfaces 2>/dev/null \
| jq -r '.["ietf-interfaces:interfaces"]["interface"][] | select(.["oper-status"] == "down") | .name'
Pattern 3: Get statistics for all interfaces¶
~$ ./curl.sh example.local GET operational/ietf-interfaces:interfaces 2>/dev/null \
| jq -r '.["ietf-interfaces:interfaces"]["interface"][] | "\(.name): RX \(.statistics["in-octets"]) TX \(.statistics["out-octets"])"'
Output:
Pattern 4: Check if interface exists before configuring¶
~$ if ./curl.sh example.local GET running/ietf-interfaces:interfaces/interface=eth0 2>/dev/null | grep -q "ietf-interfaces:interface"; then
echo "Interface eth0 exists"
else
echo "Interface eth0 not found"
fi
Configuration Operations¶
Read Hostname¶
Example of fetching JSON configuration data:
Using curl directly:
~$ curl -kX GET -u admin:admin \
-H 'Accept: application/yang-data+json' \
https://example.local/restconf/data/ietf-system:system/hostname
{
"ietf-system:system": {
"hostname": "foo"
}
}
Using curl.sh:
~$ ./curl.sh example.local GET running/ietf-system:system/hostname
{
"ietf-system:system": {
"hostname": "foo"
}
}
Set Hostname¶
Example of updating configuration with inline JSON data:
Using curl directly:
~$ curl -kX PATCH -u admin:admin \
-H 'Content-Type: application/yang-data+json' \
-d '{"ietf-system:system":{"hostname":"bar"}}' \
https://example.local/restconf/data/ietf-system:system
Using curl.sh:
~$ ./curl.sh example.local PATCH running/ietf-system:system \
-d '{"ietf-system:system":{"hostname":"bar"}}'
Add IP Address to Interface¶
Add an IP address to the loopback interface:
~$ ./curl.sh example.local POST \
running/ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254 \
-d '{ "prefix-length": 32 }'
Delete IP Address from Interface¶
Remove an IP address from the loopback interface:
~$ ./curl.sh example.local DELETE \
running/ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254
Copy Running to Startup¶
No copy command available yet to copy between datastores, and the Rousette back-end also does not support "write-through" to the startup datastore.
To save running-config to startup-config, fetch running to a local file and then update startup with it:
Using curl directly:
~$ curl -kX GET -u admin:admin -o running-config.json \
-H 'Accept: application/yang-data+json' \
https://example.local/restconf/ds/ietf-datastores:running
~$ curl -kX PUT -u admin:admin -d @running-config.json \
-H 'Content-Type: application/yang-data+json' \
https://example.local/restconf/ds/ietf-datastores:startup
Using curl.sh:
~$ ./curl.sh example.local GET running -o running-config.json
~$ ./curl.sh example.local PUT startup -d @running-config.json
Operational Data¶
Read Interface Configuration¶
Get the running configuration for the loopback interface:
Read Interface Operational State¶
Get operational data (state, statistics, etc.) for an interface:
This includes administrative and operational state, MAC address, MTU, and statistics counters.
Read Interface Statistics¶
Extract specific statistics using jq:
~$ ./curl.sh example.local GET operational/ietf-interfaces:interfaces/interface=eth0 2>/dev/null \
| jq -r '.["ietf-interfaces:interfaces"]["interface"][0]["statistics"]["in-octets"]'
List All Interfaces¶
Get operational data for all interfaces:
Read Routing Table¶
Get the IPv4 routing table:
Read OSPF State¶
Get OSPF operational data (neighbors, routes, etc.):
~$ ./curl.sh example.local GET operational/ietf-routing:routing/control-plane-protocols/control-plane-protocol=ietf-ospf:ospfv2,default
Or get just the neighbor information:
~$ ./curl.sh example.local GET operational/ietf-routing:routing/control-plane-protocols/control-plane-protocol=ietf-ospf:ospfv2,default/ietf-ospf:ospf/areas/area=0.0.0.0/interfaces
System Operations (RPCs)¶
Factory Reset¶
Reset the system to factory defaults:
~$ curl -kX POST -u admin:admin \
-H "Content-Type: application/yang-data+json" \
https://example.local/restconf/operations/ietf-factory-default:factory-reset
curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
Note: The connection error is expected - the device resets immediately.
System Reboot¶
Reboot the system:
~$ curl -kX POST -u admin:admin \
-H "Content-Type: application/yang-data+json" \
https://example.local/restconf/operations/ietf-system:system-restart
Set Date and Time¶
Example of an RPC that takes input/arguments:
~$ curl -kX POST -u admin:admin \
-H "Content-Type: application/yang-data+json" \
-d '{"ietf-system:input": {"current-datetime": "2024-04-17T13:48:02-01:00"}}' \
https://example.local/restconf/operations/ietf-system:set-current-datetime
Verify the change with SSH:
Advanced Examples¶
Makefile for Common Operations¶
Create a Makefile to simplify common operations:
HOST ?= infix.local
lo-running:
./curl.sh $(HOST) GET running/ietf-interfaces:interfaces/interface=lo
lo-operational:
./curl.sh $(HOST) GET operational/ietf-interfaces:interfaces/interface=lo
lo-add-ip:
./curl.sh $(HOST) POST \
running/ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254 \
-d '{ "prefix-length": 32 }'
lo-del-ip:
./curl.sh $(HOST) DELETE \
running/ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254
%-stats:
@./curl.sh $(HOST) GET operational/ietf-interfaces:interfaces/interface=$* 2>/dev/null \
| jq -r '.["ietf-interfaces:interfaces"]["interface"][0]["statistics"]["in-octets"]'
%-monitor:
while sleep 0.2; do make -s HOST=$(HOST) $*-stats; done \
| ttyplot -t "$(HOST):$* in-octets" -r
Usage examples:
# Get loopback operational state
~$ make lo-operational
# Add IP to loopback
~$ make lo-add-ip
# Get eth0 statistics
~$ make eth0-stats
# Monitor eth0 traffic in real-time (requires ttyplot)
~$ make eth0-monitor
You can override the host:
Monitoring Interface Traffic¶
The %-monitor target demonstrates real-time monitoring by polling
interface statistics and piping to ttyplot for visualization. Install
ttyplot with:
Then monitor any interface:
This creates a live ASCII graph of incoming octets on eth0.