Read and change an IOS-XE interface with RESTCONF and curl
Cisco IOSWorking
Tasks
- Enable RESTCONF with local AAA and the HTTPS server.
- Find the RESTCONF root with the well-known URI.
- GET GigabitEthernet2 from the
ietf-interfacesmodel. - PATCH its description to
to SW1 Gi1/0/48 via RESTCONF. - Read the leaf back through RESTCONF, read the hostname from the native model, and check the CLI.
Solution
1Enable RESTCONF on R1R1
R1 on Cisco IOS username netops privilege 15 secret 0 Lab.Pass.2026 aaa new-model aaa authentication login default local aaa authorization exec default local ip http secure-server ip http authentication local restconfRESTCONF needs the HTTPS server and a user that AAA authorizes at privilege 15. The programmability processes take a minute to start;
show platform software yang-management processshows their state.2Discover the API rootSRV1
SRV1 on Linux curl -s -k -u netops:Lab.Pass.2026 https://10.0.0.1/.well-known/host-meta3Read one interfaceSRV1
SRV1 on Linux curl -s -k -u netops:Lab.Pass.2026 \ -H "Accept: application/yang-data+json" \ https://10.0.0.1/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet24Change the description with PATCHSRV1
SRV1 on Linux curl -s -k -u netops:Lab.Pass.2026 -X PATCH \ -H "Content-Type: application/yang-data+json" \ -H "Accept: application/yang-data+json" \ -d '{"ietf-interfaces:interface": {"name": "GigabitEthernet2", "description": "to SW1 Gi1/0/48 via RESTCONF"}}' \ -o /dev/null -w "%{http_code}\n" \ https://10.0.0.1/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet2PATCH merges, so the IP address stays. A PUT with this body would replace the whole interface entry and remove the address. IOS-XE accepts a single list entry as a JSON object; some servers want it wrapped in a one-element array, as in the RFC 8040 examples.
5Read back the leaf and the hostnameSRV1
SRV1 on Linux curl -s -k -u netops:Lab.Pass.2026 -H "Accept: application/yang-data+json" \ https://10.0.0.1/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet2/description curl -s -k -u netops:Lab.Pass.2026 -H "Accept: application/yang-data+json" \ https://10.0.0.1/restconf/data/Cisco-IOS-XE-native:native/hostname
Verify
SRV1# curl -s -k -u netops:Lab.Pass.2026 https://10.0.0.1/.well-known/host-meta
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
<Link rel='restconf' href='/restconf'/>
</XRD>The root is /restconf, so data lives under /restconf/data.
SRV1# curl -s -k -u netops:Lab.Pass.2026 -H "Accept: application/yang-data+json" https://10.0.0.1/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet2
{
"ietf-interfaces:interface": {
"name": "GigabitEthernet2",
"description": "to SW1",
"type": "iana-if-type:ethernetCsmacd",
"enabled": true,
"ietf-ip:ipv4": {
"address": [
{
"ip": "10.1.12.1",
"netmask": "255.255.255.0"
}
]
},
"ietf-ip:ipv6": {
}
}
}Module-qualified names on the top node and on nodes from other modules (ietf-ip:ipv4). IOS-XE reports
IPv4 masks as netmask.
SRV1# curl ... -X PATCH ... -w "%{http_code}"
204204 No Content is success for PATCH. There is no body to read.
SRV1# curl ... /interface=GigabitEthernet2/description and .../Cisco-IOS-XE-native:native/hostname
{
"ietf-interfaces:description": "to SW1 Gi1/0/48 via RESTCONF"
}
{
"Cisco-IOS-XE-native:hostname": "R1"
}The leaf has the new value, and the same API also serves Cisco's native model.
R1# show running-config interface GigabitEthernet2
Building configuration...
Current configuration : 129 bytes
!
interface GigabitEthernet2
description to SW1 Gi1/0/48 via RESTCONF
ip address 10.1.12.1 255.255.255.0
negotiation auto
endThe CLI shows the change made through the API, and the IP address is still there.
Mistakes people make
- Forgetting
ip http secure-server. Without it nothing listens on 443 and curl gets connection refused. - Using a user that AAA does not authorize at privilege 15. RESTCONF rejects the requests.
- Sending a slash in a key unencoded.
GigabitEthernet1/0/1must be writtenGigabitEthernet1%2F0%2F1. - Using PUT for a one-field change and wiping the rest of the interface.
- Keeping
-k(no certificate check) outside a lab. Install a proper certificate and point curl at the CA with--cacert.
On other platforms
The same PATCH from Python with requests.
import requests
URL = ("https://10.0.0.1/restconf/data/"
"ietf-interfaces:interfaces/interface=GigabitEthernet2")
HEADERS = {
"Content-Type": "application/yang-data+json",
"Accept": "application/yang-data+json",
}
body = {"ietf-interfaces:interface": {
"name": "GigabitEthernet2",
"description": "to SW1 Gi1/0/48 via RESTCONF",
}}
r = requests.patch(URL, json=body, headers=HEADERS,
auth=("netops", "Lab.Pass.2026"), verify=False, timeout=15)
print(r.status_code)Say it in the interview
"I enable ip http secure-server and restconf with a privilege 15 AAA user, find the root at
/.well-known/host-meta, and build the URI from the model: module and container, then the list with its
key, then the leaf. GET returns JSON with module-qualified names. For a one-field change I use PATCH, which
returns 204, and I confirm in the CLI that nothing else on the interface changed."