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>
This commit is contained in:
Joachim Wiberg
2026-05-27 20:53:31 +02:00
parent 6958c9bb1a
commit 925a43dead
4 changed files with 45 additions and 14 deletions
+2
View File
@@ -38,6 +38,8 @@ All notable changes to the project are documented in this file.
exposing the set of PMD types currently supported. Useful for SFP/SFP+
diagnosis: an LR-only optic narrows the list to a single entry, confirming
the transceiver without `ethtool -m`
- New CLI command `show operational`, and XPath filtering for this and any of
the other datastores, using `[path /path/to/subtree]`
### Fixes
+5 -1
View File
@@ -283,6 +283,7 @@ static void rmtmp(const char *path)
static void sysrepo_print_error(sr_session_ctx_t *sess)
{
const sr_error_info_t *erri = NULL;
const char *msg;
int err;
if (!sess)
@@ -292,7 +293,10 @@ static void sysrepo_print_error(sr_session_ctx_t *sess)
if (err || !erri || !erri->err_count)
return;
warnx("%s (%d)", erri->err->message, erri->err->err_code);
msg = erri->err->message;
if (!msg)
msg = sr_strerror(erri->err->err_code);
warnx("%s (%d)", msg, erri->err->err_code);
}
/* Connect to sysrepo and create NACM-aware session on running datastore */
+11 -10
View File
@@ -17,17 +17,18 @@ def get_json(xpath: str, datastore: str = "operational", quiet: bool = False) ->
print("Invalid XPATH. It must be a valid string starting with '/'.")
return {}
try:
result = subprocess.run(["copy", datastore, "-x", shlex.quote(xpath)],
capture_output=True, text=True, check=True)
if not result.stdout.strip():
return {}
json_data = json.loads(result.stdout)
return json_data
except subprocess.CalledProcessError as e:
if not quiet:
print(f"Error running copy: {e}")
result = subprocess.run(["copy", datastore, "-x", shlex.quote(xpath)],
capture_output=True, text=True)
if result.returncode != 0:
# copy already wrote a 'failed retrieving …' message (and a
# sysrepo error line) to stderr; relay it verbatim.
if not quiet and result.stderr:
print(result.stderr.rstrip())
return {}
if not result.stdout.strip():
return {}
try:
return json.loads(result.stdout)
except json.JSONDecodeError as e:
if not quiet:
print(f"Error parsing JSON output: {e}")
+27 -3
View File
@@ -737,15 +737,39 @@ echo "Public: $pub"
</COMMAND>
<COMMAND name="factory-config" help="Show factory-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy factory | jq -C . |pager</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
</COMMAND>
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy factory ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
</COMMAND>
<COMMAND name="running-config" help="Show running-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy running | jq -C . |pager</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
</COMMAND>
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy running ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
</COMMAND>
<COMMAND name="startup-config" help="Show startup-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy startup | jq -C . |pager</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
</COMMAND>
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy startup ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
</COMMAND>
<COMMAND name="operational" help="Show operational data (running config + system state)">
<SWITCH name="optional" min="0">
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
</COMMAND>
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy operational ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
</COMMAND>
<COMMAND name="firewall" help="Show firewall status and configuration">