diff --git a/docs/netlab/status.md b/docs/netlab/status.md index bae167d77c..8569fab80e 100644 --- a/docs/netlab/status.md +++ b/docs/netlab/status.md @@ -47,7 +47,7 @@ Lab default in /home/user/net101/tools/X provider(s): clab ┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓ -┃ node ┃ device ┃ image ┃ mgmt IPv4 ┃ connection ┃ provider ┃ VM/container ┃ status ┃ +┃ node ┃ device ┃ image ┃ mgmt IP ┃ connection ┃ provider ┃ VM/container ┃ status ┃ ┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩ │ host-1 │ linux │ python:3.9-alpine │ 192.168.121.107 │ docker │ clab │ clab-X-host-1 │ Up 4 minutes │ ├─────────┼────────┼─────────────────────────────┼─────────────────┼────────────┼──────────┼────────────────┼──────────────┤ diff --git a/netsim/cli/status.py b/netsim/cli/status.py index 1711a0769b..c2a7792ed8 100644 --- a/netsim/cli/status.py +++ b/netsim/cli/status.py @@ -164,11 +164,15 @@ def fetch_node_status(ls: Box, topology: Box) -> None: p_module = providers.get_provider_module(topology,n_provider) load_provider_status(p_status,n_provider,topology) - ls.nodes[n_name] = { - 'device': n_data.device, - 'mgmt': n_data.mgmt.ipv4 - } - node_stat = ls.nodes[n_name] + node_stat = get_empty_box() + for source_attr,status_attr in { + 'device': 'device', + 'mgmt.ipv4': 'mgmt', + 'mgmt.ipv6': 'mgmt6' }.items(): + attr_value = n_data.get(source_attr,None) + if attr_value: + node_stat[status_attr] = attr_value + node_stat.connection = n_ext.ansible_connection if n_data.get('unmanaged',False): node_stat.image = 'unmanaged' @@ -182,6 +186,8 @@ def fetch_node_status(ls: Box, topology: Box) -> None: wk_state = p_status[n_provider].get(wk_name,None) or p_status[n_provider].get(n_name,None) or get_empty_box() node_stat.status = wk_state.get('status','Unknown') + ls.nodes[n_name] = node_stat + for t_name,t_data in topology.tools.items(): n_provider = 'clab' load_provider_status(p_status,n_provider,topology) @@ -199,10 +205,12 @@ def fetch_node_status(ls: Box, topology: Box) -> None: def show_lab_nodes(ls: Box, topology: Box) -> None: rows = [] - heading = [ 'node', 'device', 'image', 'mgmt IPv4', 'connection', 'provider', 'VM/container', 'status'] + heading = [ 'node', 'device', 'image', 'mgmt IP', 'connection', 'provider', 'VM/container', 'status'] for n_name,n_data in ls.nodes.items(): - row = [ n_name, n_data.device, n_data.image, n_data.get('mgmt',''), + mgmt = "\n".join([ addr for addr in (n_data.get('mgmt'),n_data.get('mgmt6')) if addr ]) + + row = [ n_name, n_data.device, n_data.image, mgmt, n_data.connection, n_data.get('provider',''), n_data.get('provider_name',''), n_data.status ] rows.append(row) diff --git a/tests/check-integration-tests.sh b/tests/check-integration-tests.sh index f45c56b402..585a0af9f4 100755 --- a/tests/check-integration-tests.sh +++ b/tests/check-integration-tests.sh @@ -3,11 +3,13 @@ # Run transformation code on integration tests for an additional # verification before merging pull requests # +err_cnt=0 + for file in integration/**/[0-9]*.yml platform-integration/**/[0-9]*.yml; do - ../netlab create -o none -d none $file 2>/dev/null || ( + ../netlab create -o none -d none "$file" 2>/dev/null || ( echo "Errors found in $file" echo "=========================================" - ../netlab create -o none -d none $file + ../netlab create -o none -d none "$file" echo "" exit 1 ) || err_cnt=$((err_cnt + 1)) diff --git a/tests/platform-integration/cli/12-status-mgmt-v4-only.yml b/tests/platform-integration/cli/12-status-mgmt-v4-only.yml new file mode 100644 index 0000000000..8ee2491ee3 --- /dev/null +++ b/tests/platform-integration/cli/12-status-mgmt-v4-only.yml @@ -0,0 +1,49 @@ +--- +message: | + This test checks that netlab status displays IPv4 management + addresses for libvirt and clab nodes while keeping tool status + JSON intact. + +plugin: [ files ] +provider: libvirt +defaults.device: linux + +tools: + graphite: + +defaults.netlab.integration: + skip: [ initial ] + validate: bash validate.sh + +nodes: + vm: + mgmt.ipv4: 192.168.121.21 + ctr: + provider: clab + mgmt.ipv4: 192.168.121.22 + +links: [ vm-ctr ] + +files: + validate.sh: | + #!/bin/bash + set -e + netlab status >status.out + grep "mgmt IP" status.out >/dev/null + grep "192.168.121.21" status.out >/dev/null + grep "192.168.121.22" status.out >/dev/null + grep "graphite" status.out >/dev/null + netlab status --format json >status.json + python3 - <<'PY' + import json + + with open("status.json", encoding="utf-8") as status_file: + nodes = json.load(status_file)["nodes"] + + assert nodes["vm"]["mgmt"] == "192.168.121.21" + assert nodes["ctr"]["mgmt"] == "192.168.121.22" + assert nodes["graphite"]["device"] == "(tool)" + assert "mgmt" not in nodes["graphite"] + assert "mgmt6" not in nodes["graphite"] + PY + echo "netlab status displays IPv4 management addresses for nodes and keeps tool JSON unchanged" diff --git a/tests/platform-integration/cli/13-status-mgmt-dual-stack.yml b/tests/platform-integration/cli/13-status-mgmt-dual-stack.yml new file mode 100644 index 0000000000..568207b3eb --- /dev/null +++ b/tests/platform-integration/cli/13-status-mgmt-dual-stack.yml @@ -0,0 +1,53 @@ +--- +message: | + This test checks that netlab status displays both IPv4 and IPv6 + management addresses in a mixed libvirt, clab, and tool topology. + +plugin: [ files ] +provider: libvirt +defaults.device: linux + +tools: + graphite: + +defaults.addressing.mgmt.ipv6: 2001:db8:121::/64 + +defaults.netlab.integration: + skip: [ initial ] + validate: bash validate.sh + +nodes: + vm: + mgmt.ipv4: 192.168.121.31 + mgmt.ipv6: 2001:db8:121::31 + ctr: + provider: clab + mgmt.ipv4: 192.168.121.32 + +links: [ vm-ctr ] + +files: + validate.sh: | + #!/bin/bash + set -e + netlab status >status.out + grep "mgmt IP" status.out >/dev/null + grep "192.168.121.31" status.out >/dev/null + grep "2001:db8:121::31" status.out >/dev/null + grep "192.168.121.32" status.out >/dev/null + grep "graphite" status.out >/dev/null + netlab status --format json >status.json + python3 - <<'PY' + import json + + with open("status.json", encoding="utf-8") as status_file: + nodes = json.load(status_file)["nodes"] + + assert nodes["vm"]["mgmt"] == "192.168.121.31" + assert nodes["vm"]["mgmt6"] == "2001:db8:121::31" + assert nodes["ctr"]["mgmt"] == "192.168.121.32" + assert nodes["graphite"]["device"] == "(tool)" + assert "mgmt" not in nodes["graphite"] + assert "mgmt6" not in nodes["graphite"] + PY + echo "netlab status displays dual-stack management addresses in a mixed topology"