Skip to content

Commit 785b227

Browse files
committed
cli: add 'show operational [path /X]' and path filter to config views
Extend the existing 'show <running|startup|factory>-config' family with an optional 'path /XPATH' argument that maps straight to the underlying 'copy -x' flag, and add 'show operational [path /XPATH]' for symmetry with the configuration datastores. admin@example:/> show running-config path /ietf-interfaces:interfaces admin@example:/> show operational path /ietf-system:system-state Also, improve error feedback from the copy command slightly. Before: admin@example:~$ copy running -x /foo Error: (null) (5) Error: failed retrieving running-config data After: admin@example:~$ copy running -x /foo Error: Couldn't parse path "/foo": Prefix "foo" not defined. (5) Error: failed retrieving running-config data Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
1 parent 0a2566f commit 785b227

4 files changed

Lines changed: 45 additions & 14 deletions

File tree

doc/ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ All notable changes to the project are documented in this file.
3232
exposing the set of PMD types currently supported. Useful for SFP/SFP+
3333
diagnosis: an LR-only optic narrows the list to a single entry, confirming
3434
the transceiver without `ethtool -m`
35+
- New CLI command `show operational`, and XPath filtering for this and any of
36+
the other datastores, using `[path /path/to/subtree]`
3537

3638
### Fixes
3739

src/bin/copy.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ static void rmtmp(const char *path)
283283
static void sysrepo_print_error(sr_session_ctx_t *sess)
284284
{
285285
const sr_error_info_t *erri = NULL;
286+
const char *msg;
286287
int err;
287288

288289
if (!sess)
@@ -292,7 +293,10 @@ static void sysrepo_print_error(sr_session_ctx_t *sess)
292293
if (err || !erri || !erri->err_count)
293294
return;
294295

295-
warnx("%s (%d)", erri->err->message, erri->err->err_code);
296+
msg = erri->err->message;
297+
if (!msg)
298+
msg = sr_strerror(erri->err->err_code);
299+
warnx("%s (%d)", msg, erri->err->err_code);
296300
}
297301

298302
/* Connect to sysrepo and create NACM-aware session on running datastore */

src/bin/show/__init__.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@ def get_json(xpath: str, datastore: str = "operational", quiet: bool = False) ->
1717
print("Invalid XPATH. It must be a valid string starting with '/'.")
1818
return {}
1919

20-
try:
21-
result = subprocess.run(["copy", datastore, "-x", shlex.quote(xpath)],
22-
capture_output=True, text=True, check=True)
23-
if not result.stdout.strip():
24-
return {}
25-
json_data = json.loads(result.stdout)
26-
return json_data
27-
except subprocess.CalledProcessError as e:
28-
if not quiet:
29-
print(f"Error running copy: {e}")
20+
result = subprocess.run(["copy", datastore, "-x", shlex.quote(xpath)],
21+
capture_output=True, text=True)
22+
if result.returncode != 0:
23+
# copy already wrote a 'failed retrieving …' message (and a
24+
# sysrepo error line) to stderr; relay it verbatim.
25+
if not quiet and result.stderr:
26+
print(result.stderr.rstrip())
3027
return {}
28+
if not result.stdout.strip():
29+
return {}
30+
try:
31+
return json.loads(result.stdout)
3132
except json.JSONDecodeError as e:
3233
if not quiet:
3334
print(f"Error parsing JSON output: {e}")

src/klish-plugin-infix/xml/infix.xml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -737,15 +737,39 @@ echo "Public: $pub"
737737
</COMMAND>
738738

739739
<COMMAND name="factory-config" help="Show factory-config">
740-
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy factory | jq -C . |pager</ACTION>
740+
<SWITCH name="optional" min="0">
741+
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
742+
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
743+
</COMMAND>
744+
</SWITCH>
745+
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy factory ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
741746
</COMMAND>
742747

743748
<COMMAND name="running-config" help="Show running-config">
744-
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy running | jq -C . |pager</ACTION>
749+
<SWITCH name="optional" min="0">
750+
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
751+
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
752+
</COMMAND>
753+
</SWITCH>
754+
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy running ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
745755
</COMMAND>
746756

747757
<COMMAND name="startup-config" help="Show startup-config">
748-
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy startup | jq -C . |pager</ACTION>
758+
<SWITCH name="optional" min="0">
759+
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
760+
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
761+
</COMMAND>
762+
</SWITCH>
763+
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy startup ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
764+
</COMMAND>
765+
766+
<COMMAND name="operational" help="Show operational data (running config + system state)">
767+
<SWITCH name="optional" min="0">
768+
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
769+
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
770+
</COMMAND>
771+
</SWITCH>
772+
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy operational ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
749773
</COMMAND>
750774

751775
<COMMAND name="firewall" help="Show firewall status and configuration">

0 commit comments

Comments
 (0)