mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 23:43:20 +02:00
Merge pull request #1004 from kernelkit/new-show-command
Add new show command Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Executable → Regular
@@ -139,6 +139,7 @@ BR2_PACKAGE_CURIOS_HTTPD=y
|
||||
BR2_PACKAGE_CURIOS_NFTABLES=y
|
||||
BR2_PACKAGE_GENCERT=y
|
||||
BR2_PACKAGE_STATD=y
|
||||
BR2_PACKAGE_SHOW=y
|
||||
BR2_PACKAGE_FACTORY=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
|
||||
|
||||
@@ -119,6 +119,7 @@ BR2_PACKAGE_CONFD=y
|
||||
BR2_PACKAGE_CONFD_TEST_MODE=y
|
||||
BR2_PACKAGE_GENCERT=y
|
||||
BR2_PACKAGE_STATD=y
|
||||
BR2_PACKAGE_SHOW=y
|
||||
BR2_PACKAGE_FACTORY=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
|
||||
|
||||
@@ -176,6 +176,7 @@ INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_CONFD=y
|
||||
BR2_PACKAGE_GENCERT=y
|
||||
BR2_PACKAGE_STATD=y
|
||||
BR2_PACKAGE_SHOW=y
|
||||
BR2_PACKAGE_FACTORY=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
|
||||
|
||||
@@ -169,6 +169,7 @@ BR2_PACKAGE_CONFD=y
|
||||
# BR2_PACKAGE_CONFD_TEST_MODE is not set
|
||||
BR2_PACKAGE_GENCERT=y
|
||||
BR2_PACKAGE_STATD=y
|
||||
BR2_PACKAGE_SHOW=y
|
||||
BR2_PACKAGE_FACTORY=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
|
||||
|
||||
@@ -141,6 +141,7 @@ BR2_PACKAGE_CURIOS_HTTPD=y
|
||||
BR2_PACKAGE_CURIOS_NFTABLES=y
|
||||
BR2_PACKAGE_GENCERT=y
|
||||
BR2_PACKAGE_STATD=y
|
||||
BR2_PACKAGE_SHOW=y
|
||||
BR2_PACKAGE_FACTORY=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
|
||||
|
||||
@@ -123,6 +123,7 @@ BR2_PACKAGE_CONFD=y
|
||||
BR2_PACKAGE_CONFD_TEST_MODE=y
|
||||
BR2_PACKAGE_GENCERT=y
|
||||
BR2_PACKAGE_STATD=y
|
||||
BR2_PACKAGE_SHOW=y
|
||||
BR2_PACKAGE_FACTORY=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
|
||||
|
||||
@@ -34,6 +34,7 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/python-libyang/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/python-statd/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/python-yangdoc/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/skeleton-init-finit/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/show/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/tetris/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/libyang-cpp/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/sysrepo-cpp/Config.in"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
config BR2_PACKAGE_SHOW
|
||||
bool "show"
|
||||
help
|
||||
Tool to retrieve and present operational data from sysrepo.
|
||||
|
||||
https://github.com/kernelkit/infix
|
||||
@@ -0,0 +1,19 @@
|
||||
################################################################################
|
||||
#
|
||||
# show
|
||||
#
|
||||
################################################################################
|
||||
|
||||
SHOW_VERSION = 1.0
|
||||
SHOW_LICENSE = MIT
|
||||
SHOW_LICENSE_FILES = LICENSE
|
||||
SHOW_SITE_METHOD = local
|
||||
SHOW_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/show
|
||||
SHOW_REDISTRIBUTE = NO
|
||||
|
||||
define SHOW_INSTALL_TARGET_CMDS
|
||||
$(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) \
|
||||
DESTDIR="$(TARGET_DIR)" install
|
||||
endef
|
||||
|
||||
$(eval $(generic-package))
|
||||
@@ -239,35 +239,33 @@
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="fdb" help="Show unicast forwarding database">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
bridge -color fdb |pager
|
||||
</ACTION>
|
||||
bridge -color fdb |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
<COMMAND name="mdb" help="Show mulficast forwarding database">
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="detailed" help="Detailed (full) output">
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="detailed" help="Detailed (full) output">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
bridge -color -d mdb |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
bridge -color -d mdb |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
sysrepocfg -d operational -X -f json -x /ietf-interfaces:interfaces | \
|
||||
/usr/libexec/statd/cli-pretty show-bridge-mdb |pager
|
||||
</ACTION>
|
||||
show --raw interface | /usr/libexec/statd/cli-pretty show-bridge-mdb |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
<COMMAND name="stp" help="Show spanning tree status">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
sysrepocfg -d operational -X -f json -x /ietf-interfaces:interfaces | \
|
||||
/usr/libexec/statd/cli-pretty show-bridge-stp |pager
|
||||
</ACTION>
|
||||
show --raw interface | /usr/libexec/statd/cli-pretty show-bridge-stp |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
<COMMAND name="vlan" help="Show VLAN table">
|
||||
<ACTION sym="script">bridge -color vlan</ACTION>
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="detailed" help="Detailed (full) output">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
bridge -color -d vlan |pager
|
||||
</ACTION>
|
||||
bridge -color -d vlan |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
</COMMAND>
|
||||
@@ -292,8 +290,7 @@
|
||||
|
||||
<COMMAND name="ntp" help="Show NTP (client) status">
|
||||
<ACTION sym="script">
|
||||
sysrepocfg -d operational -X -f json -x /system-state/ntp | \
|
||||
/usr/libexec/statd/cli-pretty "show-ntp"
|
||||
show ntp
|
||||
</ACTION>
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="tracking" help="Show NTP tracking">
|
||||
@@ -307,11 +304,11 @@
|
||||
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="statistics" help="Show DHCP server statistics">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">show dhcp stat</ACTION>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">show dhcp stat</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="detailed" help="Detailed (full operational) output">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">show dhcp detail</ACTION>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">show dhcp detail</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
</SWITCH>
|
||||
@@ -325,51 +322,43 @@
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
<ACTION sym="script">
|
||||
tmp=$(mktemp)
|
||||
sysrepocfg -d operational -X -f json -x /ietf-system:system-state/infix-system:software | \
|
||||
jq -r '.[][].slot |= sort_by(.name)' > "$tmp"
|
||||
if [ -n "$KLISH_PARAM_name" ]; then
|
||||
cat "$tmp" | /usr/libexec/statd/cli-pretty "show-software" -n "$KLISH_PARAM_name"
|
||||
else
|
||||
cat "$tmp" | /usr/libexec/statd/cli-pretty "show-software"
|
||||
fi
|
||||
rm "$tmp"
|
||||
show software "$KLISH_PARAM_name"
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="ospf" help="Show OSPF status">
|
||||
<PARAM name="name" ptype="/STRING" help="neighbor, interfaces or bfd" min="0" max="1">
|
||||
<COMPL>
|
||||
<ACTION sym="printl">neighbor</ACTION>
|
||||
<ACTION sym="printl">interfaces</ACTION>
|
||||
<ACTION sym="printl">routes</ACTION>
|
||||
<ACTION sym="printl">database</ACTION>
|
||||
<ACTION sym="printl">bfd</ACTION>
|
||||
<ACTION sym="printl">neighbor</ACTION>
|
||||
<ACTION sym="printl">interfaces</ACTION>
|
||||
<ACTION sym="printl">routes</ACTION>
|
||||
<ACTION sym="printl">database</ACTION>
|
||||
<ACTION sym="printl">bfd</ACTION>
|
||||
</COMPL>
|
||||
</PARAM>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
if [ -z "$KLISH_PARAM_name" ]; then
|
||||
doas vtysh -c "show ip ospf" |pager
|
||||
doas vtysh -c "show-legacy ip ospf" |pager
|
||||
elif [ "$KLISH_PARAM_name" == "neighbor" ];then
|
||||
doas vtysh -c "show ip ospf neighbor" |pager
|
||||
doas vtysh -c "show-legacy ip ospf neighbor" |pager
|
||||
elif [ "$KLISH_PARAM_name" == "interfaces" ];then
|
||||
doas vtysh -c "show ip ospf interface" |pager
|
||||
doas vtysh -c "show-legacy ip ospf interface" |pager
|
||||
elif [ "$KLISH_PARAM_name" == "routes" ];then
|
||||
doas vtysh -c "show ip ospf route" |pager
|
||||
doas vtysh -c "show-legacy ip ospf route" |pager
|
||||
elif [ "$KLISH_PARAM_name" == "database" ];then
|
||||
doas vtysh -c "show ip ospf database" |pager
|
||||
doas vtysh -c "show-legacy ip ospf database" |pager
|
||||
elif [ "$KLISH_PARAM_name" == "bfd" ];then
|
||||
doas vtysh -c "show bfd peers" |pager
|
||||
doas vtysh -c "show-legacy bfd peers" |pager
|
||||
fi
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="routes" help="Show routing table">
|
||||
<PARAM name="ip" ptype="/STRING" help="ipv4 or ipv6" min="0" max="1">
|
||||
<COMPL>
|
||||
<ACTION sym="printl">ipv4</ACTION>
|
||||
<ACTION sym="printl">ipv6</ACTION>
|
||||
</COMPL>
|
||||
<COMPL>
|
||||
<ACTION sym="printl">ipv4</ACTION>
|
||||
<ACTION sym="printl">ipv6</ACTION>
|
||||
</COMPL>
|
||||
</PARAM>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
case $KLISH_PARAM_ip in
|
||||
@@ -380,14 +369,13 @@
|
||||
KLISH_PARAM_ip=ipv6
|
||||
;;
|
||||
esac
|
||||
show -p $KLISH_PARAM_ip route |pager
|
||||
show-legacy -p $KLISH_PARAM_ip route |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="hardware" help="Show hardware information">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
sysrepocfg -f json -X -d operational -x "/ietf-hardware:hardware" | \
|
||||
/usr/libexec/statd/cli-pretty "show-hardware" |pager
|
||||
show hardware |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
@@ -400,14 +388,7 @@
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
if [ -n "$KLISH_PARAM_name" ]; then
|
||||
doas sysrepocfg -f json -X -d operational -x \
|
||||
"/ietf-interfaces:interfaces/interface[name=\"$KLISH_PARAM_name\"]" | \
|
||||
/usr/libexec/statd/cli-pretty "show-interfaces" -n "$KLISH_PARAM_name" |pager
|
||||
else
|
||||
doas sysrepocfg -f json -X -d operational -m ietf-interfaces | \
|
||||
/usr/libexec/statd/cli-pretty "show-interfaces" |pager
|
||||
fi
|
||||
show interface "$KLISH_PARAM_name" |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
@@ -419,26 +400,26 @@
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="brief" help="Simplified (human-readable) output" mode="switch">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
ip -color -br addr | sort -V | sed 's/@dsa[0-9]/ /' |pager
|
||||
</ACTION>
|
||||
ip -color -br addr | sort -V | sed 's/@dsa[0-9]/ /' |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="detailed" help="Detailed (full) output" mode="switch">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
ip -color -d addr |pager
|
||||
</ACTION>
|
||||
ip -color -d addr |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="multicast" help="Show IGMP/MLD status" mode="switch">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
mctl |pager
|
||||
</ACTION>
|
||||
mctl |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="route" help="Show IPv4 routing table" mode="switch">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
show -p ip route |pager
|
||||
</ACTION>
|
||||
show-legacy -p ip route |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
</COMMAND>
|
||||
@@ -451,8 +432,8 @@
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="route" help="Show IPv6 routing table" mode="switch">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||
show -p ipv6 route |pager
|
||||
</ACTION>
|
||||
show-legacy -p ipv6 route |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
</COMMAND>
|
||||
@@ -530,11 +511,11 @@
|
||||
if [ -n "$KLISH_PARAM_split" ]; then
|
||||
if echo $KLISH_PARAM_addrlen |grep -q ':'; then
|
||||
split="-S $KLISH_PARAM_split"
|
||||
else
|
||||
else
|
||||
split="-s $KLISH_PARAM_split"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
split=""
|
||||
split=""
|
||||
fi
|
||||
netcalc $split $KLISH_PARAM_addrlen $KLISH_PARAM_netmask
|
||||
</ACTION>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Richard Alpe
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,11 @@
|
||||
.PHONY: all clean distclean install
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
|
||||
distclean: clean
|
||||
|
||||
install:
|
||||
install -D show.py $(DESTDIR)/bin/show
|
||||
install -D bash_completion.d/show $(DESTDIR)/etc/bash_completion.d/show
|
||||
@@ -0,0 +1,27 @@
|
||||
_show_completions() {
|
||||
local cur prev commands interface_subs routes_subs
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
|
||||
commands="dhcp interface ntp routes software stp"
|
||||
|
||||
if [[ $COMP_CWORD -eq 1 ]]; then
|
||||
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
|
||||
return 0
|
||||
fi
|
||||
|
||||
case "$prev" in
|
||||
interface)
|
||||
COMPREPLY=( $(compgen -W "$(ls /sys/class/net/)" -- "$cur") )
|
||||
;;
|
||||
routes)
|
||||
COMPREPLY=( $(compgen -W "ipv4 ipv6" -- "$cur") )
|
||||
;;
|
||||
software)
|
||||
COMPREPLY=( $(compgen -W "primary secondary" -- "$cur") )
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
complete -F _show_completions show
|
||||
Executable
+190
@@ -0,0 +1,190 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import json
|
||||
from typing import List
|
||||
import os
|
||||
import shlex
|
||||
import argparse
|
||||
|
||||
RAW_OUTPUT = False
|
||||
|
||||
def run_sysrepocfg(xpath: str) -> dict:
|
||||
if not isinstance(xpath, str) or not xpath.startswith("/"):
|
||||
print("Invalid XPATH. It must be a valid string starting with '/'.")
|
||||
return {}
|
||||
|
||||
safe_xpath = shlex.quote(xpath)
|
||||
|
||||
try:
|
||||
result = subprocess.run([
|
||||
"sysrepocfg", "-f", "json", "-X", "-d", "operational", "-x", safe_xpath
|
||||
], capture_output=True, text=True, check=True)
|
||||
json_data = json.loads(result.stdout)
|
||||
return json_data
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running sysrepocfg: {e}")
|
||||
return {}
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Error parsing JSON output: {e}")
|
||||
return {}
|
||||
|
||||
def cli_pretty(json_data: dict, command: str, *args: str):
|
||||
if not command or not all(isinstance(arg, str) for arg in args):
|
||||
print("Invalid command or arguments. All arguments must be strings.")
|
||||
return
|
||||
|
||||
safe_args = [shlex.quote(arg) for arg in args]
|
||||
|
||||
try:
|
||||
json_input = json.dumps(json_data) # Keep as string, not bytes
|
||||
result = subprocess.run([
|
||||
"/usr/libexec/statd/cli-pretty", command, *safe_args
|
||||
], input=json_input, capture_output=True, text=True, check=True)
|
||||
print(result.stdout, end="")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running cli-pretty: {e}")
|
||||
|
||||
def dhcp(args: List[str]) -> None:
|
||||
data = run_sysrepocfg("/infix-dhcp-server:dhcp-server")
|
||||
if not data:
|
||||
print("No interface data retrieved.")
|
||||
return
|
||||
|
||||
if RAW_OUTPUT:
|
||||
print(json.dumps(data, indent=2))
|
||||
return
|
||||
cli_pretty(data, "show-dhcp-server")
|
||||
|
||||
def hardware(args: List[str]) -> None:
|
||||
data = run_sysrepocfg("/ietf-hardware:hardware")
|
||||
if not data:
|
||||
print("No hardware data retrieved.")
|
||||
return
|
||||
|
||||
if RAW_OUTPUT:
|
||||
print(json.dumps(data, indent=2))
|
||||
return
|
||||
cli_pretty(data, "show-hardware")
|
||||
|
||||
def ntp(args: List[str]) -> None:
|
||||
data = run_sysrepocfg("/system-state/ntp")
|
||||
if not data:
|
||||
print("No ntp data retrieved.")
|
||||
return
|
||||
|
||||
if RAW_OUTPUT:
|
||||
print(json.dumps(data, indent=2))
|
||||
return
|
||||
cli_pretty(data, "show-ntp")
|
||||
|
||||
def is_valid_interface_name(interface_name: str) -> bool:
|
||||
"""
|
||||
Validates a Linux network interface name.
|
||||
"""
|
||||
if len(interface_name) > 15:
|
||||
return False
|
||||
|
||||
pattern = r'^[a-zA-Z0-9._-]+$'
|
||||
return bool(re.match(pattern, interface_name))
|
||||
|
||||
def interface(args: List[str]) -> None:
|
||||
data = run_sysrepocfg("/ietf-interfaces:interfaces")
|
||||
if not data:
|
||||
print("No interface data retrieved.")
|
||||
return
|
||||
|
||||
if RAW_OUTPUT:
|
||||
print(json.dumps(data, indent=2))
|
||||
return
|
||||
|
||||
if len(args) == 0 or not args[0]: # Treat "" as no arg.
|
||||
cli_pretty(data, "show-interfaces")
|
||||
elif len(args) == 1:
|
||||
iface = args[0]
|
||||
if is_valid_interface_name(iface):
|
||||
cli_pretty(data, f"show-interfaces", "-n", iface)
|
||||
else:
|
||||
print(f"Invalid interface name: {iface}")
|
||||
else:
|
||||
print("Too many arguments provided. Only one interface name is expected.")
|
||||
|
||||
def stp(args: List[str]) -> None:
|
||||
data = run_sysrepocfg("/ietf-interfaces:interfaces")
|
||||
if not data:
|
||||
print("No interface data retrieved.")
|
||||
return
|
||||
|
||||
if RAW_OUTPUT:
|
||||
print(json.dumps(data, indent=2))
|
||||
return
|
||||
cli_pretty(data, "show-bridge-stp")
|
||||
|
||||
def software(args: List[str]) -> None:
|
||||
data = run_sysrepocfg("/ietf-system:system-state/infix-system:software")
|
||||
if not data:
|
||||
print("No software data retrieved.")
|
||||
return
|
||||
|
||||
if RAW_OUTPUT:
|
||||
print(json.dumps(data, indent=2))
|
||||
return
|
||||
if len(args) == 0 or not args[0]: # Treat "" as no arg.
|
||||
cli_pretty(data, "show-software")
|
||||
elif len(args) == 1:
|
||||
name = args[0]
|
||||
if name not in ("primary", "secondary"):
|
||||
print(f"Invalid software name: {name}")
|
||||
return
|
||||
|
||||
cli_pretty(data, f"show-software", "-n", name)
|
||||
else:
|
||||
print("Too many arguments provided. Only one name is expected.")
|
||||
|
||||
def routes(args: List[str]):
|
||||
ip_version = args[0] if args and args[0] in ["ipv4", "ipv6"] else "ipv4"
|
||||
|
||||
data = run_sysrepocfg("/ietf-routing:routing/ribs")
|
||||
if not data:
|
||||
print("No route data retrieved.")
|
||||
return
|
||||
if RAW_OUTPUT:
|
||||
print(json.dumps(data, indent=2))
|
||||
return
|
||||
cli_pretty(data, "show-routing-table", "-i", ip_version)
|
||||
|
||||
|
||||
def execute_command(command: str, args: List[str]):
|
||||
command_mapping = {
|
||||
'dhcp': dhcp,
|
||||
'hardware': hardware,
|
||||
'interface': interface,
|
||||
'ntp': ntp,
|
||||
'routes': routes,
|
||||
'software' : software,
|
||||
'stp': stp,
|
||||
}
|
||||
|
||||
if command in command_mapping:
|
||||
command_mapping[command](args)
|
||||
else:
|
||||
print(f"Unknown command: {command}")
|
||||
|
||||
|
||||
def main():
|
||||
global RAW_OUTPUT
|
||||
|
||||
parser = argparse.ArgumentParser(description="Show operational data")
|
||||
parser.add_argument('command', help="Command to execute")
|
||||
parser.add_argument('args', nargs=argparse.REMAINDER, help="Additional arguments for the command")
|
||||
parser.add_argument('-r', '--raw', action='store_true', help="Print raw JSON output from Sysrepo")
|
||||
|
||||
args = parser.parse_args()
|
||||
RAW_OUTPUT = args.raw
|
||||
|
||||
execute_command(args.command, args.args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1193,7 +1193,7 @@ def show_software(json, name):
|
||||
f"{'VERSION':<{PadSoftware.version}}"
|
||||
f"{'DATE':<{PadSoftware.date}}")
|
||||
print(Decore.invert(hdr))
|
||||
for _s in slots:
|
||||
for _s in reversed(slots):
|
||||
slot = Software(_s)
|
||||
if slot.is_rootfs():
|
||||
slot.print()
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
primary secondary net
|
||||
|
||||
[7mNAME STATE VERSION DATE [0m
|
||||
secondary inactive 94cd526 2025-01-15T10:00:56Z
|
||||
primary booted 94cd526 2025-01-15T10:00:56Z
|
||||
secondary inactive 94cd526 2025-01-15T10:00:56Z
|
||||
|
||||
Reference in New Issue
Block a user