@@ -16,23 +16,79 @@ To simplify RESTCONF operations, create a `curl.sh` wrapper script:
1616
1717``` bash
1818#! /bin/sh
19+ # RESTCONF CLI wrapper for curl
1920
20- AUTH=${AUTH:- admin: admin}
21- HOST=${HOST:- infix.local}
21+ # Show usage and exit
22+ usage ()
23+ {
24+ cat << -EOF >&2
25+ Usage: $0 [-h HOST] [-d DATASTORE] [-u USER:PASS] METHOD PATH [CURL_ARGS...]
2226
23- method=$1
24- path=$2
27+ Options:
28+ -h HOST Target host (default: infix.local)
29+ -d DS Datastore: running, operational, startup (default: running)
30+ -u CREDS Credentials as user:pass (default: admin:admin)
31+
32+ Methods: GET, POST, PUT, PATCH, DELETE
33+ EOF
34+ exit " $1 "
35+ }
36+
37+ # Default values
38+ HOST=${HOST:- infix.local}
39+ DATASTORE=running
40+ AUTH=admin:admin
41+
42+ # Parse options
43+ while getopts " h:d:u:" opt; do
44+ case $opt in
45+ h) HOST=" $OPTARG " ;;
46+ d) DATASTORE=" $OPTARG " ;;
47+ u) AUTH=" $OPTARG " ;;
48+ * ) usage 1 ;;
49+ esac
50+ done
51+ shift $(( OPTIND - 1 ))
52+
53+ # Validate required arguments
54+ if [ $# -lt 2 ]; then
55+ echo " Error: METHOD and PATH are required" >&2
56+ usage 1
57+ fi
58+
59+ METHOD=$1
60+ PATH=$2
2561shift 2
2662
27- set -x
28- exec curl \
29- --insecure \
30- --user ${AUTH} \
31- --request ${method} \
32- --header " Content-Type: application/yang-data+json" \
33- --header " Accept: application/yang-data+json" \
34- " $@ " \
35- https://${HOST} /restconf/ds/ietf-datastores:${path}
63+ # Ensure PATH starts with /
64+ case " $PATH " in
65+ /* ) ;;
66+ * ) PATH=" /$PATH " ;;
67+ esac
68+
69+ # Build URL based on datastore
70+ case " $DATASTORE " in
71+ running|startup)
72+ URL=" https://${HOST} /restconf/data${PATH} "
73+ ;;
74+ operational)
75+ URL=" https://${HOST} /restconf/data${PATH} "
76+ ;;
77+ * )
78+ echo " Error: Invalid datastore '$DATASTORE '. Use: running, operational, or startup" >&2
79+ exit 1
80+ ;;
81+ esac
82+
83+ # Execute curl with all remaining arguments passed through
84+ exec /usr/bin/curl \
85+ --insecure \
86+ --user " ${AUTH} " \
87+ --request " ${METHOD} " \
88+ --header " Content-Type: application/yang-data+json" \
89+ --header " Accept: application/yang-data+json" \
90+ " $@ " \
91+ " ${URL} "
3692```
3793
3894Make it executable:
@@ -41,12 +97,16 @@ Make it executable:
4197~ $ chmod +x curl.sh
4298```
4399
44- This wrapper handles authentication, headers, and the base URL construction,
45- making commands much cleaner. You can override defaults with environment
46- variables:
100+ This wrapper handles authentication, headers, SSL certificates, and URL
101+ construction, making commands much cleaner. You can override defaults with
102+ command-line options or environment variables:
47103
48104``` bash
49- ~ $ HOST=192.168.1.10 AUTH=admin:secret ./curl.sh GET running/...
105+ # Using command-line options
106+ ~ $ ./curl.sh -h 192.168.1.10 -d operational -u admin:secret GET /ietf-interfaces:interfaces
107+
108+ # Using environment variables
109+ ~ $ HOST=192.168.1.10 ./curl.sh GET /ietf-system:system
50110```
51111
52112The examples below show both raw ` curl ` commands and the equivalent using
@@ -63,7 +123,7 @@ practical workflows.
63123** List all interface names:**
64124
65125``` bash
66- ~ $ ./curl.sh example.local GET operational/ietf-interfaces:interfaces 2> /dev/null | jq -r ' .["ietf-interfaces:interfaces"]["interface"][].name'
126+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-interfaces:interfaces 2> /dev/null | jq -r ' .["ietf-interfaces:interfaces"]["interface"][].name'
67127lo
68128e0
69129e1
@@ -89,7 +149,7 @@ This returns all supported YANG modules, revisions, and features.
89149Useful for exploration or backup:
90150
91151``` bash
92- ~ $ ./curl.sh example.local GET running -o backup.json
152+ ~ $ ./curl.sh -h example.local GET / -o backup.json
93153```
94154
95155### Common Workflow Patterns
@@ -99,21 +159,21 @@ Useful for exploration or backup:
99159Get all interfaces with IPs and search:
100160
101161``` bash
102- ~ $ ./curl.sh example.local GET operational/ietf-interfaces:interfaces 2> /dev/null \
162+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-interfaces:interfaces 2> /dev/null \
103163 | jq -r ' .["ietf-interfaces:interfaces"]["interface"][] | select(.["ietf-ip:ipv4"]["address"][]?.ip == "192.168.1.100") | .name'
104164```
105165
106166#### Pattern 2: List all interfaces that are down
107167
108168``` bash
109- ~ $ ./curl.sh example.local GET operational/ietf-interfaces:interfaces 2> /dev/null \
169+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-interfaces:interfaces 2> /dev/null \
110170 | jq -r ' .["ietf-interfaces:interfaces"]["interface"][] | select(.["oper-status"] == "down") | .name'
111171```
112172
113173#### Pattern 3: Get statistics for all interfaces
114174
115175``` bash
116- ~ $ ./curl.sh example.local GET operational/ietf-interfaces:interfaces 2> /dev/null \
176+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-interfaces:interfaces 2> /dev/null \
117177 | jq -r ' .["ietf-interfaces:interfaces"]["interface"][] | "\(.name): RX \(.statistics["in-octets"]) TX \(.statistics["out-octets"])"'
118178```
119179
@@ -128,7 +188,7 @@ e1: RX 0 TX 0
128188#### Pattern 4: Check if interface exists before configuring
129189
130190``` bash
131- ~ $ if ./curl.sh example.local GET running /ietf-interfaces:interfaces/interface=eth0 2> /dev/null | grep -q " ietf-interfaces:interface" ; then
191+ ~ $ if ./curl.sh -h example.local GET /ietf-interfaces:interfaces/interface=eth0 2> /dev/null | grep -q " ietf-interfaces:interface" ; then
132192 echo " Interface eth0 exists"
133193 else
134194 echo " Interface eth0 not found"
@@ -157,7 +217,7 @@ Example of fetching JSON configuration data:
157217** Using curl.sh:**
158218
159219``` bash
160- ~ $ ./curl.sh example.local GET running /ietf-system:system/hostname
220+ ~ $ ./curl.sh -h example.local GET /ietf-system:system/hostname
161221{
162222 " ietf-system:system" : {
163223 " hostname" : " foo"
@@ -181,7 +241,7 @@ Example of updating configuration with inline JSON data:
181241** Using curl.sh:**
182242
183243``` bash
184- ~ $ ./curl.sh example.local PATCH running /ietf-system:system \
244+ ~ $ ./curl.sh -h example.local PATCH /ietf-system:system \
185245 -d ' {"ietf-system:system":{"hostname":"bar"}}'
186246```
187247
@@ -190,8 +250,8 @@ Example of updating configuration with inline JSON data:
190250Add an IP address to the loopback interface:
191251
192252``` bash
193- ~ $ ./curl.sh example.local POST \
194- running /ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254 \
253+ ~ $ ./curl.sh -h example.local POST \
254+ /ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254 \
195255 -d ' { "prefix-length": 32 }'
196256```
197257
@@ -200,8 +260,8 @@ Add an IP address to the loopback interface:
200260Remove an IP address from the loopback interface:
201261
202262``` bash
203- ~ $ ./curl.sh example.local DELETE \
204- running /ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254
263+ ~ $ ./curl.sh -h example.local DELETE \
264+ /ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254
205265```
206266
207267### Copy Running to Startup
@@ -228,8 +288,8 @@ and then update startup with it:
228288** Using curl.sh:**
229289
230290``` bash
231- ~ $ ./curl.sh example.local GET running -o running-config.json
232- ~ $ ./curl.sh example.local PUT startup -d @running-config.json
291+ ~ $ ./curl.sh -h example.local GET / -o running-config.json
292+ ~ $ ./curl.sh -h example.local -d startup PUT / -d @running-config.json
233293```
234294
235295## Operational Data
@@ -239,15 +299,15 @@ and then update startup with it:
239299Get the running configuration for the loopback interface:
240300
241301``` bash
242- ~ $ ./curl.sh example.local GET running /ietf-interfaces:interfaces/interface=lo
302+ ~ $ ./curl.sh -h example.local GET /ietf-interfaces:interfaces/interface=lo
243303```
244304
245305### Read Interface Operational State
246306
247307Get operational data (state, statistics, etc.) for an interface:
248308
249309``` bash
250- ~ $ ./curl.sh example.local GET operational/ietf-interfaces:interfaces/interface=lo
310+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-interfaces:interfaces/interface=lo
251311```
252312
253313This includes administrative and operational state, MAC address, MTU, and
@@ -258,7 +318,7 @@ statistics counters.
258318Extract specific statistics using ` jq ` :
259319
260320``` bash
261- ~ $ ./curl.sh example.local GET operational/ietf-interfaces:interfaces/interface=eth0 2> /dev/null \
321+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-interfaces:interfaces/interface=eth0 2> /dev/null \
262322 | jq -r ' .["ietf-interfaces:interfaces"]["interface"][0]["statistics"]["in-octets"]'
263323```
264324
@@ -267,29 +327,29 @@ Extract specific statistics using `jq`:
267327Get operational data for all interfaces:
268328
269329``` bash
270- ~ $ ./curl.sh example.local GET operational/ietf-interfaces:interfaces
330+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-interfaces:interfaces
271331```
272332
273333### Read Routing Table
274334
275335Get the IPv4 routing table:
276336
277337``` bash
278- ~ $ ./curl.sh example.local GET operational/ietf-routing:routing/ribs/rib=ipv4-default
338+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-routing:routing/ribs/rib=ipv4-default
279339```
280340
281341### Read OSPF State
282342
283343Get OSPF operational data (neighbors, routes, etc.):
284344
285345``` bash
286- ~ $ ./curl.sh example.local GET operational/ietf-routing:routing/control-plane-protocols/control-plane-protocol=ietf-ospf:ospfv2,default
346+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-routing:routing/control-plane-protocols/control-plane-protocol=ietf-ospf:ospfv2,default
287347```
288348
289349Or get just the neighbor information:
290350
291351``` bash
292- ~ $ ./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
352+ ~ $ ./curl.sh -h example.local -d operational GET /ietf-routing:routing/control-plane-protocols/control-plane-protocol=ietf-ospf:ospfv2,default/ietf-ospf:ospf/areas/area=0.0.0.0/interfaces
293353```
294354
295355## System Operations (RPCs)
@@ -345,22 +405,22 @@ Create a `Makefile` to simplify common operations:
345405HOST ? = infix.local
346406
347407lo-running:
348- ./curl.sh $( HOST) GET running /ietf-interfaces:interfaces/interface=lo
408+ ./curl.sh -h $( HOST) GET /ietf-interfaces:interfaces/interface=lo
349409
350410lo-operational:
351- ./curl.sh $( HOST) GET operational/ietf-interfaces:interfaces/interface=lo
411+ ./curl.sh -h $( HOST) -d operational GET /ietf-interfaces:interfaces/interface=lo
352412
353413lo-add-ip:
354- ./curl.sh $( HOST) POST \
355- running /ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254 \
414+ ./curl.sh -h $( HOST) POST \
415+ /ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254 \
356416 -d ' { "prefix-length": 32 }'
357417
358418lo-del-ip:
359- ./curl.sh $( HOST) DELETE \
360- running /ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254
419+ ./curl.sh -h $( HOST) DELETE \
420+ /ietf-interfaces:interfaces/interface=lo/ietf-ip:ipv4/address=192.168.254.254
361421
362422%-stats:
363- @./curl.sh $( HOST) GET operational/ietf-interfaces:interfaces/interface=$* 2> /dev/null \
423+ @./curl.sh -h $( HOST) -d operational GET /ietf-interfaces:interfaces/interface=$* 2> /dev/null \
364424 | jq -r ' .["ietf-interfaces:interfaces"]["interface"][0]["statistics"]["in-octets"]'
365425
366426%-monitor:
0 commit comments