From 944274f792ddc0deb567cd9aa5281beeb790d353 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 17 Jul 2026 15:17:31 +0200 Subject: [PATCH 1/9] Make the SONiC port_config path configurable The directory holding the per-HWSKU port_config .ini files was hardcoded to /etc/sonic/port_config, which only exists inside the container image (the Dockerfile copies files/sonic/port_config there). Running the config generator outside a container -- for local development or an E2E test harness that points it at the in-repo files -- required root to plant files under /etc/sonic. Introduce a SONIC_PORT_CONFIG_PATH setting in osism.settings, following the existing SONIC_* environment variable convention, and wire constants.PORT_CONFIG_PATH to it. The default is unchanged, and the value is read at import time like every other setting, so the container behavior is identical. Tests cover the default, the environment override, and the settings-to-constants wiring. Assisted-by: Claude:claude-fable-5 Signed-off-by: Roger Luethi --- osism/settings.py | 4 ++++ osism/tasks/conductor/sonic/constants.py | 4 +++- .../tasks/conductor/sonic/test_constants.py | 20 +++++++++++++++++++ tests/unit/test_settings.py | 14 +++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/osism/settings.py b/osism/settings.py index f6e81cff..b9ac8111 100644 --- a/osism/settings.py +++ b/osism/settings.py @@ -70,6 +70,10 @@ def read_secret(secret_name): SONIC_EXPORT_SUFFIX = os.getenv("SONIC_EXPORT_SUFFIX", "_config_db.json") SONIC_EXPORT_IDENTIFIER = os.getenv("SONIC_EXPORT_IDENTIFIER", "serial-number") +# Directory holding the per-HWSKU port_config .ini files (bundled in the +# repo under files/sonic/port_config and installed by the Dockerfile) +SONIC_PORT_CONFIG_PATH = os.getenv("SONIC_PORT_CONFIG_PATH", "/etc/sonic/port_config") + # SONiC ZTP firmware configuration # # The ZTP firmware install uses a dynamic-url built from diff --git a/osism/tasks/conductor/sonic/constants.py b/osism/tasks/conductor/sonic/constants.py index 4f34b8a1..31ea2d61 100644 --- a/osism/tasks/conductor/sonic/constants.py +++ b/osism/tasks/conductor/sonic/constants.py @@ -2,6 +2,8 @@ """Constants and mappings for SONiC configuration.""" +from osism import settings + # Tag to add AF L2VPN EVPN to BGP neighbor BGP_AF_L2VPN_EVPN_TAG = "bgp-af-l2vpn-evpn" @@ -74,7 +76,7 @@ HIGH_SPEED_PORTS = {100000, 200000, 400000, 800000} # 100G, 200G, 400G, 800G in Mbps # Path to SONiC port configuration files -PORT_CONFIG_PATH = "/etc/sonic/port_config" +PORT_CONFIG_PATH = settings.SONIC_PORT_CONFIG_PATH # List of supported vendors SUPPORTED_VENDORS = [ diff --git a/tests/unit/tasks/conductor/sonic/test_constants.py b/tests/unit/tasks/conductor/sonic/test_constants.py index f65e8cc8..3c4c72bf 100644 --- a/tests/unit/tasks/conductor/sonic/test_constants.py +++ b/tests/unit/tasks/conductor/sonic/test_constants.py @@ -1,7 +1,11 @@ # SPDX-License-Identifier: Apache-2.0 +import importlib + import pytest +from osism import settings as settings_module +from osism.tasks.conductor.sonic import constants as constants_module from osism.tasks.conductor.sonic.constants import ( BGP_AF_L2VPN_EVPN_TAG, DEFAULT_LOCAL_AS_PREFIX, @@ -151,3 +155,19 @@ def test_supported_hwskus_entry_invariants(hwsku): assert "-" in hwsku vendor = hwsku.split("-")[0] assert vendor in SUPPORTED_VENDORS + + +# --------------------------------------------------------------------------- +# PORT_CONFIG_PATH settings wiring +# --------------------------------------------------------------------------- + + +def test_port_config_path_follows_settings(): + original = settings_module.SONIC_PORT_CONFIG_PATH + try: + settings_module.SONIC_PORT_CONFIG_PATH = "/custom/port_config" + reloaded = importlib.reload(constants_module) + assert reloaded.PORT_CONFIG_PATH == "/custom/port_config" + finally: + settings_module.SONIC_PORT_CONFIG_PATH = original + importlib.reload(constants_module) diff --git a/tests/unit/test_settings.py b/tests/unit/test_settings.py index 4f1df8ca..5d5907c0 100644 --- a/tests/unit/test_settings.py +++ b/tests/unit/test_settings.py @@ -583,6 +583,20 @@ def test_sonic_export_identifier_override(reload_settings, monkeypatch): assert settings_module.SONIC_EXPORT_IDENTIFIER == "asset-tag" +def test_sonic_port_config_path_default(reload_settings, monkeypatch): + monkeypatch.delenv("SONIC_PORT_CONFIG_PATH", raising=False) + reload_settings() + + assert settings_module.SONIC_PORT_CONFIG_PATH == "/etc/sonic/port_config" + + +def test_sonic_port_config_path_override(reload_settings, monkeypatch): + monkeypatch.setenv("SONIC_PORT_CONFIG_PATH", "/tmp/port_config") + reload_settings() + + assert settings_module.SONIC_PORT_CONFIG_PATH == "/tmp/port_config" + + # --------------------------------------------------------------------------- # NETBOX_SECONDARIES # --------------------------------------------------------------------------- From 5adc61ce159feea7ae6f10205e40ec682337e308 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 17 Jul 2026 15:19:44 +0200 Subject: [PATCH 2/9] Add E2E golden-test harness for SONiC configs Unit tests verify the SONiC config generator against fixture values that encode the author's assumptions, so a class of regressions -- such as mixed kbps/Mbps interface speeds -- can pass the unit suite while producing broken switch configurations. Nothing exercised the full pipeline: real NetBox data in, complete config_db.json out. Add a golden-file E2E harness that provisions NetBox on a local kind cluster (reusing the deploy script from a netbox-manager checkout), seeds it with the bundled example data, runs sync_sonic(), and compares every exported config_db file against goldens committed under tests/e2e/golden/. Any generator behavior change then surfaces as a reviewable golden diff instead of shipping silently. tests/e2e/generate.py drives the generation. sync_sonic() returns only a device-to-config dict and logs-and-swallows per-device failures, so the driver asserts success itself: the returned device set must match the expectation derived from the golden file names, empty configs fail, and a loguru sink turns any ERROR-level record into a failure. --no-expect skips the device-set check for the initial golden bootstrap. tests/e2e/compare.py enforces exact file-set equality (missing, extra, and mismatched exports are reported as distinct categories) and reports mismatches both as structural paths such as PORT|Ethernet4.speed and as a unified diff of the canonicalized JSON. Canonicalization sorts dictionary keys only; array order is part of the compared contract. --regenerate rewrites the goldens canonically for review. Both modules are pure logic and covered by the regular unit suite under tests/unit/e2e/. tests/e2e/run.sh and the Makefile targets sonic-e2e, sonic-e2e-regen, sonic-e2e-up and sonic-e2e-down tie the phases together. The exports use hostname identifiers (the seed devices carry no serial numbers) and the generator reads the in-repo port_config files via SONIC_PORT_CONFIG_PATH. netbox-manager is installed from the checkout rather than PyPI so a coordinated cross-repository change is tested against the changed code and data. Golden files are not yet committed; the initial set is bootstrapped with make sonic-e2e-regen and reviewed by hand. A Zuul job and seed data for known regression scenarios are follow-up work. Assisted-by: Claude:claude-fable-5 Signed-off-by: Roger Luethi --- Makefile | 25 ++++ tests/e2e/__init__.py | 0 tests/e2e/compare.py | 184 +++++++++++++++++++++++ tests/e2e/generate.py | 114 +++++++++++++++ tests/e2e/run.sh | 163 +++++++++++++++++++++ tests/unit/e2e/__init__.py | 0 tests/unit/e2e/test_compare.py | 251 ++++++++++++++++++++++++++++++++ tests/unit/e2e/test_generate.py | 108 ++++++++++++++ 8 files changed, 845 insertions(+) create mode 100644 Makefile create mode 100644 tests/e2e/__init__.py create mode 100644 tests/e2e/compare.py create mode 100644 tests/e2e/generate.py create mode 100755 tests/e2e/run.sh create mode 100644 tests/unit/e2e/__init__.py create mode 100644 tests/unit/e2e/test_compare.py create mode 100644 tests/unit/e2e/test_generate.py diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..ef7dd56d --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +CLUSTER_NAME ?= sonic-e2e +NETBOX_MANAGER_DIR ?= $(abspath ../netbox-manager) + +# SONiC config-generation E2E golden test (see tests/e2e/run.sh). + +# Full cycle: provision kind + NetBox (an existing cluster is reused and +# left in place), seed, generate, compare against tests/e2e/golden/. +sonic-e2e: + NETBOX_MANAGER_DIR=$(NETBOX_MANAGER_DIR) CLUSTER_NAME=$(CLUSTER_NAME) tests/e2e/run.sh + +# Regenerate the golden files after an intentional generator change, +# then review and commit the diff. +sonic-e2e-regen: + NETBOX_MANAGER_DIR=$(NETBOX_MANAGER_DIR) CLUSTER_NAME=$(CLUSTER_NAME) tests/e2e/run.sh --regenerate + +# Provision kind + NetBox and leave it running for debugging. Export a +# NETBOX_TOKEN beforehand to get a known API token minted. +sonic-e2e-up: + CLUSTER_NAME=$(CLUSTER_NAME) $(NETBOX_MANAGER_DIR)/tests/e2e/deploy_netbox.sh + +# Delete the kind cluster created for the E2E test. +sonic-e2e-down: + kind delete cluster --name $(CLUSTER_NAME) + +.PHONY: sonic-e2e sonic-e2e-regen sonic-e2e-up sonic-e2e-down diff --git a/tests/e2e/__init__.py b/tests/e2e/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/e2e/compare.py b/tests/e2e/compare.py new file mode 100644 index 00000000..3ae27e34 --- /dev/null +++ b/tests/e2e/compare.py @@ -0,0 +1,184 @@ +# SPDX-License-Identifier: Apache-2.0 + +"""Golden-file comparator for the SONiC config-generation E2E test. + +Compares exported SONiC ``config_db.json`` files against committed golden +files. config_db is a shallow TABLE -> entry -> attribute tree, so +structural difference paths are rendered as ``TABLE|entry.attribute``. + +Canonicalization sorts dictionary keys only; array order is preserved and +compared, since list order can be part of the generated contract. +""" + +import argparse +import difflib +import json +import sys +from dataclasses import dataclass, field +from pathlib import Path + + +def _walk(golden, actual, path, depth, out): + """Collect difference paths between two parsed JSON values. + + ``depth`` counts dict levels already entered: children of the top level + (tables) attach with ``|``, everything deeper with ``.``. List indices + attach as ``[i]`` and stay at their parent's depth. + """ + if isinstance(golden, dict) and isinstance(actual, dict): + for key in sorted(golden.keys() | actual.keys()): + sep = "|" if depth == 1 else "." + child = f"{path}{sep}{key}" if path else str(key) + if key not in actual: + out.append(f"{child}: only in golden") + elif key not in golden: + out.append(f"{child}: only in actual") + else: + _walk(golden[key], actual[key], child, depth + 1, out) + elif isinstance(golden, list) and isinstance(actual, list): + for i in range(max(len(golden), len(actual))): + child = f"{path}[{i}]" + if i >= len(actual): + out.append(f"{child}: only in golden") + elif i >= len(golden): + out.append(f"{child}: only in actual") + else: + _walk(golden[i], actual[i], child, depth, out) + elif golden != actual: + out.append(f"{path}: golden {golden!r}, actual {actual!r}") + + +def diff_paths(golden, actual): + """Return sorted structural paths of the differences between two configs.""" + out = [] + _walk(golden, actual, "", 0, out) + return sorted(out) + + +def _canonical(config): + """Canonical JSON text: dict keys sorted, arrays untouched.""" + return json.dumps(config, indent=2, sort_keys=True) + "\n" + + +def unified_diff(golden, actual, name): + """Unified diff of the canonicalized golden and actual configs.""" + return "".join( + difflib.unified_diff( + _canonical(golden).splitlines(keepends=True), + _canonical(actual).splitlines(keepends=True), + fromfile=f"golden/{name}", + tofile=f"export/{name}", + ) + ) + + +@dataclass +class Mismatch: + """Content difference of one exported file against its golden file.""" + + paths: list + diff: str + + +@dataclass +class CompareResult: + """Outcome of comparing an export directory against the golden directory.""" + + missing: list = field(default_factory=list) + extra: list = field(default_factory=list) + mismatched: dict = field(default_factory=dict) + + @property + def ok(self): + return not (self.missing or self.extra or self.mismatched) + + def report(self): + lines = [] + for name in self.missing: + lines.append( + f"MISSING {name}: not exported " + "(generation or export failed - see generate log)" + ) + for name in self.extra: + lines.append(f"EXTRA {name}: unexpected extra export (no golden file)") + for name, mismatch in self.mismatched.items(): + lines.append(f"MISMATCH {name}:") + lines.extend(f" {path}" for path in mismatch.paths) + lines.append(mismatch.diff) + if not lines: + lines.append("OK: exports match the golden files") + return "\n".join(lines) + + +def compare_dirs(golden_dir, export_dir): + """Compare all golden ``*.json`` files against the exported ones. + + Requires exact file-set equality: a golden file without an export is + ``missing`` (generation or export failed), an export without a golden + file is ``extra``, and differing content is ``mismatched``. Non-JSON + files (e.g. firmware symlinks in the export directory) are ignored. + """ + golden_dir = Path(golden_dir) + export_dir = Path(export_dir) + golden_names = {p.name for p in golden_dir.glob("*.json")} + export_names = {p.name for p in export_dir.glob("*.json")} + + result = CompareResult( + missing=sorted(golden_names - export_names), + extra=sorted(export_names - golden_names), + ) + for name in sorted(golden_names & export_names): + golden = json.loads((golden_dir / name).read_text()) + actual = json.loads((export_dir / name).read_text()) + paths = diff_paths(golden, actual) + if paths: + result.mismatched[name] = Mismatch( + paths=paths, diff=unified_diff(golden, actual, name) + ) + return result + + +def regenerate(golden_dir, export_dir): + """Rewrite the golden directory from the export directory. + + Every exported ``*.json`` file is stored in canonical form (sorted dict + keys) so regenerated goldens produce minimal, reviewable git diffs; + stale golden files without a matching export are removed. Never run in + CI - regeneration is a deliberate local step after an intentional + generator change. + """ + golden_dir = Path(golden_dir) + export_dir = Path(export_dir) + golden_dir.mkdir(parents=True, exist_ok=True) + + export_names = {p.name for p in export_dir.glob("*.json")} + for stale in golden_dir.glob("*.json"): + if stale.name not in export_names: + stale.unlink() + for name in sorted(export_names): + config = json.loads((export_dir / name).read_text()) + (golden_dir / name).write_text(_canonical(config)) + + +def main(argv=None): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--golden", required=True, help="golden file directory") + parser.add_argument("--export", required=True, help="export directory to check") + parser.add_argument( + "--regenerate", + action="store_true", + help="rewrite the golden files from the export directory", + ) + args = parser.parse_args(argv) + + if args.regenerate: + regenerate(args.golden, args.export) + return 0 + + result = compare_dirs(args.golden, args.export) + print(result.report()) + return 0 if result.ok else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/e2e/generate.py b/tests/e2e/generate.py new file mode 100644 index 00000000..0c29e3e2 --- /dev/null +++ b/tests/e2e/generate.py @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: Apache-2.0 + +"""Generation driver for the SONiC config E2E test. + +Runs ``sync_sonic()`` against the seeded NetBox and asserts that generation +itself succeeded. ``sync_sonic`` returns only a ``{device: config}`` dict: +its internal rc is reported solely through the task layer when a ``task_id`` +is set, and per-device failures are logged and swallowed. Success is +therefore asserted here by + +- comparing the returned device set against the expectation derived from + the golden files (``--golden``), and +- failing on any ERROR-level loguru record captured during the run, which + covers every swallowed-exception path in ``sync.py``. + +All environment (NETBOX_API/NETBOX_TOKEN, SONIC_EXPORT_DIR, +SONIC_PORT_CONFIG_PATH, SONIC_EXPORT_IDENTIFIER=hostname) must be set +before this module is imported, since ``osism.settings`` reads it at import +time. The exported files are checked against the goldens by ``compare.py``. +""" + +import argparse +import os +import sys +from pathlib import Path + +from loguru import logger + + +def expected_devices(golden_dir, prefix, suffix): + """Derive the expected device names from the golden file names.""" + devices = set() + for path in Path(golden_dir).glob("*.json"): + if path.name.startswith(prefix) and path.name.endswith(suffix): + devices.add(path.name[len(prefix) : -len(suffix)]) + return devices + + +def run_generation(sync): + """Call the sync function, capturing ERROR-level loguru records. + + Returns ``(device_configs, errors)`` where ``errors`` is the list of + error messages logged during the run. + """ + errors = [] + sink_id = logger.add( + lambda message: errors.append(str(message).strip()), + level="ERROR", + format="{message}", + ) + try: + configs = sync() + finally: + logger.remove(sink_id) + return configs, errors + + +def main(argv=None, sync=None): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--golden", + help="golden file directory the expected device set is derived from", + ) + parser.add_argument( + "--no-expect", + action="store_true", + help="skip the device-set check (golden bootstrap / regeneration)", + ) + args = parser.parse_args(argv) + if not args.no_expect and not args.golden: + parser.error("either --golden or --no-expect is required") + + if sync is None: + missing_env = [ + name for name in ("NETBOX_API", "NETBOX_TOKEN") if not os.environ.get(name) + ] + if missing_env: + print(f"Missing required environment variables: {', '.join(missing_env)}") + return 2 + from osism.tasks.conductor.sonic.sync import sync_sonic + + sync = sync_sonic + + configs, errors = run_generation(sync) + + failed = False + for error in errors: + print(f"ERROR during generation: {error}") + failed = True + + empty = sorted(name for name, config in configs.items() if not config) + for name in empty: + print(f"EMPTY config generated for device: {name}") + failed = True + + if args.golden: + from osism import settings + + expected = expected_devices( + args.golden, settings.SONIC_EXPORT_PREFIX, settings.SONIC_EXPORT_SUFFIX + ) + for name in sorted(expected - set(configs)): + print(f"MISSING device (expected from goldens, not generated): {name}") + failed = True + for name in sorted(set(configs) - expected): + print(f"UNEXPECTED device (generated, no golden file): {name}") + failed = True + + print(f"Generated {len(configs)} SONiC configurations") + return 1 if failed else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/e2e/run.sh b/tests/e2e/run.sh new file mode 100755 index 00000000..9192e30b --- /dev/null +++ b/tests/e2e/run.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env bash +# +# SONiC config-generation E2E golden test: +# +# 1. provision NetBox on a local kind cluster (reuses netbox-manager's +# tests/e2e/deploy_netbox.sh; an existing cluster of the same name +# is reused and left in place) +# 2. seed it with netbox-manager and the bundled example/ data +# 3. run sync_sonic() via tests/e2e/generate.py +# 4. compare the exported config_db files against tests/e2e/golden/ +# (or rewrite the goldens with --regenerate) +# +# Requirements: docker, kind, kubectl, helm, openssl, a netbox-manager +# checkout (sibling directory or NETBOX_MANAGER_DIR), and this repo's +# pipenv environment (pipenv install --dev). +# +# Environment overrides: +# NETBOX_MANAGER_DIR netbox-manager checkout (default: ../netbox-manager) +# CLUSTER_NAME kind cluster name (default: sonic-e2e) +# NAMESPACE NetBox namespace (default: netbox) +# NETBOX_TOKEN API token (default: random; also minted in NetBox) +# NETBOX_PORT local port-forward port (default: 8080) +# KEEP_CLUSTER=1 leave a cluster created by this run in place + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +cd "${REPO_ROOT}" + +REGENERATE=0 +for arg in "$@"; do + case "${arg}" in + --regenerate) REGENERATE=1 ;; + *) + echo "usage: $0 [--regenerate]" >&2 + exit 2 + ;; + esac +done + +NETBOX_MANAGER_DIR="${NETBOX_MANAGER_DIR:-${REPO_ROOT}/../netbox-manager}" +NETBOX_MANAGER_DIR="$(cd "${NETBOX_MANAGER_DIR}" 2>/dev/null && pwd)" || { + echo "error: netbox-manager checkout not found; set NETBOX_MANAGER_DIR" >&2 + exit 2 +} + +CLUSTER_NAME="${CLUSTER_NAME:-sonic-e2e}" +NAMESPACE="${NAMESPACE:-netbox}" +NETBOX_TOKEN="${NETBOX_TOKEN:-$(openssl rand -hex 20)}" +NETBOX_PORT="${NETBOX_PORT:-8080}" +GOLDEN_DIR="${REPO_ROOT}/tests/e2e/golden" +export CLUSTER_NAME NAMESPACE NETBOX_TOKEN + +# Only tear down a cluster this run actually created -- never a reused +# debug cluster (make sonic-e2e-up) that happens to share the name. +CREATED_CLUSTER=0 +if ! kind get clusters 2>/dev/null | grep -qx "${CLUSTER_NAME}"; then + CREATED_CLUSTER=1 +fi + +PF_PID="" +EXPORT_DIR="" +dump_diagnostics() { + echo "==================== kind / NetBox diagnostics ====================" + kubectl get nodes -o wide 2>&1 || true + kubectl get pods -A -o wide 2>&1 || true + kubectl -n "${NAMESPACE}" get events --sort-by=.lastTimestamp 2>&1 | tail -n 40 || true + echo "==================================================================" +} +cleanup() { + rc=$? + if [[ -n "${PF_PID}" ]]; then + kill "${PF_PID}" 2>/dev/null || true + fi + if [[ "${rc}" -ne 0 ]]; then + echo ">>> E2E run failed (exit ${rc}); dumping cluster diagnostics" + dump_diagnostics || true + fi + if [[ -n "${EXPORT_DIR}" ]]; then + rm -rf "${EXPORT_DIR}" + fi + if [[ "${CREATED_CLUSTER}" == "1" && "${KEEP_CLUSTER:-0}" != "1" ]]; then + echo ">>> Deleting kind cluster '${CLUSTER_NAME}'" + kind delete cluster --name "${CLUSTER_NAME}" || true + else + echo ">>> Leaving kind cluster '${CLUSTER_NAME}' in place" + fi +} +trap cleanup EXIT + +# --- Phase 1: provision NetBox on kind ------------------------------------- +PRINT_NETBOX_TOKEN=0 "${NETBOX_MANAGER_DIR}/tests/e2e/deploy_netbox.sh" + +echo ">>> Port-forwarding svc/netbox -> 127.0.0.1:${NETBOX_PORT}" +kubectl -n "${NAMESPACE}" port-forward "svc/netbox" "${NETBOX_PORT}:80" & +PF_PID=$! + +ready=0 +for _ in $(seq 1 30); do + if curl -fsS -o /dev/null "http://127.0.0.1:${NETBOX_PORT}/api/" 2>/dev/null; then + ready=1 + break + fi + sleep 1 +done +if [[ "${ready}" != "1" ]]; then + echo "error: NetBox API not reachable on 127.0.0.1:${NETBOX_PORT} after 30s" >&2 + exit 1 +fi +if ! kill -0 "${PF_PID}" 2>/dev/null; then + echo "error: port-forward exited early (is 127.0.0.1:${NETBOX_PORT} already in use?)" >&2 + exit 1 +fi + +# --- Phase 2: seed with netbox-manager ------------------------------------- +# The CLI is installed from the checkout so a Zuul Depends-On on a +# netbox-manager change is honored for code and data alike. +echo ">>> Installing netbox-manager from ${NETBOX_MANAGER_DIR}" +pipenv run pip install --quiet "${NETBOX_MANAGER_DIR}" + +echo ">>> Installing the netbox.netbox Ansible collection" +pipenv run ansible-galaxy collection install -r "${NETBOX_MANAGER_DIR}/requirements.yml" + +export NETBOX_MANAGER_URL="http://127.0.0.1:${NETBOX_PORT}" +export NETBOX_MANAGER_TOKEN="${NETBOX_TOKEN}" +export NETBOX_MANAGER_DEVICETYPE_LIBRARY="${NETBOX_MANAGER_DIR}/example/devicetypes" +export NETBOX_MANAGER_MODULETYPE_LIBRARY="${NETBOX_MANAGER_DIR}/example/moduletypes" +export NETBOX_MANAGER_RESOURCES="${NETBOX_MANAGER_DIR}/example/resources" +export NETBOX_MANAGER_IGNORE_SSL_ERRORS=true + +echo ">>> Seeding NetBox with the netbox-manager example data" +pipenv run netbox-manager run --fail-fast + +# Scenario overlay (spec phase 4): a second run with +# NETBOX_MANAGER_RESOURCES=${REPO_ROOT}/tests/e2e/resources goes here once +# the regression-scenario seed data exists. + +# --- Phase 3: generate SONiC configurations --------------------------------- +EXPORT_DIR="$(mktemp -d)" +export NETBOX_API="http://127.0.0.1:${NETBOX_PORT}" +export SONIC_EXPORT_DIR="${EXPORT_DIR}" +export SONIC_EXPORT_IDENTIFIER="hostname" +export SONIC_PORT_CONFIG_PATH="${REPO_ROOT}/files/sonic/port_config" + +echo ">>> Generating SONiC configurations (tests/e2e/generate.py)" +if [[ "${REGENERATE}" == "1" ]]; then + pipenv run python -m tests.e2e.generate --no-expect +else + pipenv run python -m tests.e2e.generate --golden "${GOLDEN_DIR}" +fi + +# --- Phase 4: compare against (or regenerate) the golden files ------------- +if [[ "${REGENERATE}" == "1" ]]; then + echo ">>> Regenerating golden files in ${GOLDEN_DIR}" + pipenv run python -m tests.e2e.compare \ + --golden "${GOLDEN_DIR}" --export "${EXPORT_DIR}" --regenerate + echo ">>> Golden files regenerated; review and commit the diff." +else + echo ">>> Comparing exports against ${GOLDEN_DIR}" + pipenv run python -m tests.e2e.compare \ + --golden "${GOLDEN_DIR}" --export "${EXPORT_DIR}" + echo ">>> SONiC E2E golden test passed." +fi diff --git a/tests/unit/e2e/__init__.py b/tests/unit/e2e/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/e2e/test_compare.py b/tests/unit/e2e/test_compare.py new file mode 100644 index 00000000..36351a46 --- /dev/null +++ b/tests/unit/e2e/test_compare.py @@ -0,0 +1,251 @@ +# SPDX-License-Identifier: Apache-2.0 + +"""Unit tests for the E2E golden-file comparator. + +The comparator itself (tests/e2e/compare.py) is pure logic and independent +of any infrastructure, so it is tested here as part of the regular unit +suite. +""" + +import json + +from tests.e2e.compare import compare_dirs, diff_paths, main, regenerate + + +class TestDiffPaths: + def test_equal_configs_yield_no_paths(self): + config = {"PORT": {"Ethernet0": {"speed": "100000"}}} + + assert diff_paths(config, config) == [] + + def test_value_mismatch_reports_table_entry_attribute_path(self): + golden = {"PORT": {"Ethernet4": {"speed": "100000"}}} + actual = {"PORT": {"Ethernet4": {"speed": "100"}}} + + assert diff_paths(golden, actual) == [ + "PORT|Ethernet4.speed: golden '100000', actual '100'" + ] + + def test_entry_only_in_golden(self): + golden = {"PORT": {"Ethernet4": {"speed": "100000"}}} + actual = {"PORT": {}} + + assert diff_paths(golden, actual) == ["PORT|Ethernet4: only in golden"] + + def test_entry_only_in_actual(self): + golden = {"PORT": {}} + actual = {"PORT": {"Ethernet4": {"speed": "100000"}}} + + assert diff_paths(golden, actual) == ["PORT|Ethernet4: only in actual"] + + def test_table_only_in_golden(self): + golden = {"VLAN": {"Vlan100": {}}} + actual = {} + + assert diff_paths(golden, actual) == ["VLAN: only in golden"] + + def test_array_order_is_significant(self): + golden = {"PORT": {"Ethernet0": {"valid_speeds": ["100000", "50000"]}}} + actual = {"PORT": {"Ethernet0": {"valid_speeds": ["50000", "100000"]}}} + + paths = diff_paths(golden, actual) + + assert paths == [ + "PORT|Ethernet0.valid_speeds[0]: golden '100000', actual '50000'", + "PORT|Ethernet0.valid_speeds[1]: golden '50000', actual '100000'", + ] + + def test_array_length_difference_reported(self): + golden = {"PORT": {"Ethernet0": {"valid_speeds": ["100000"]}}} + actual = {"PORT": {"Ethernet0": {"valid_speeds": ["100000", "50000"]}}} + + assert diff_paths(golden, actual) == [ + "PORT|Ethernet0.valid_speeds[1]: only in actual" + ] + + def test_type_mismatch_reported_as_value_difference(self): + golden = {"PORT": {"Ethernet0": {"mtu": "9100"}}} + actual = {"PORT": {"Ethernet0": {"mtu": 9100}}} + + assert diff_paths(golden, actual) == [ + "PORT|Ethernet0.mtu: golden '9100', actual 9100" + ] + + def test_multiple_differences_are_sorted_by_path(self): + golden = { + "PORT": {"Ethernet0": {"speed": "100000"}}, + "VLAN": {"Vlan100": {"vlanid": "100"}}, + } + actual = { + "PORT": {"Ethernet0": {"speed": "100"}}, + "VLAN": {"Vlan100": {"vlanid": "200"}}, + } + + paths = diff_paths(golden, actual) + + assert paths == sorted(paths) + assert len(paths) == 2 + + def test_deeply_nested_values_use_dot_separators(self): + golden = {"BGP_NEIGHBOR": {"10.0.0.1": {"af": {"ipv4": "on"}}}} + actual = {"BGP_NEIGHBOR": {"10.0.0.1": {"af": {"ipv4": "off"}}}} + + assert diff_paths(golden, actual) == [ + "BGP_NEIGHBOR|10.0.0.1.af.ipv4: golden 'on', actual 'off'" + ] + + +class TestCompareDirs: + @staticmethod + def _write(directory, name, config): + directory.mkdir(parents=True, exist_ok=True) + (directory / name).write_text(json.dumps(config)) + + def test_identical_dirs_are_ok(self, tmp_path): + config = {"PORT": {"Ethernet0": {"speed": "100000"}}} + self._write(tmp_path / "golden", "osism_sw1_config_db.json", config) + self._write(tmp_path / "export", "osism_sw1_config_db.json", config) + + result = compare_dirs(tmp_path / "golden", tmp_path / "export") + + assert result.ok + assert result.missing == [] + assert result.extra == [] + assert result.mismatched == {} + + def test_missing_export_is_reported(self, tmp_path): + self._write(tmp_path / "golden", "osism_sw1_config_db.json", {}) + (tmp_path / "export").mkdir() + + result = compare_dirs(tmp_path / "golden", tmp_path / "export") + + assert not result.ok + assert result.missing == ["osism_sw1_config_db.json"] + + def test_extra_export_is_reported(self, tmp_path): + (tmp_path / "golden").mkdir() + self._write(tmp_path / "export", "osism_sw2_config_db.json", {}) + + result = compare_dirs(tmp_path / "golden", tmp_path / "export") + + assert not result.ok + assert result.extra == ["osism_sw2_config_db.json"] + + def test_mismatch_collects_paths_and_unified_diff(self, tmp_path): + name = "osism_sw1_config_db.json" + self._write( + tmp_path / "golden", name, {"PORT": {"Ethernet4": {"speed": "100000"}}} + ) + self._write( + tmp_path / "export", name, {"PORT": {"Ethernet4": {"speed": "100"}}} + ) + + result = compare_dirs(tmp_path / "golden", tmp_path / "export") + + assert not result.ok + mismatch = result.mismatched[name] + assert mismatch.paths == ["PORT|Ethernet4.speed: golden '100000', actual '100'"] + assert '- "speed": "100000"' in mismatch.diff + assert '+ "speed": "100"' in mismatch.diff + + def test_non_json_files_are_ignored(self, tmp_path): + config = {"PORT": {}} + self._write(tmp_path / "golden", "osism_sw1_config_db.json", config) + self._write(tmp_path / "export", "osism_sw1_config_db.json", config) + (tmp_path / "export" / "firmware_sw1.bin").write_text("not json") + + result = compare_dirs(tmp_path / "golden", tmp_path / "export") + + assert result.ok + + def test_report_distinguishes_failure_categories(self, tmp_path): + self._write(tmp_path / "golden", "osism_sw1_config_db.json", {"A": {}}) + self._write(tmp_path / "golden", "osism_sw2_config_db.json", {}) + self._write(tmp_path / "export", "osism_sw1_config_db.json", {"B": {}}) + self._write(tmp_path / "export", "osism_sw3_config_db.json", {}) + + result = compare_dirs(tmp_path / "golden", tmp_path / "export") + report = result.report() + + assert "osism_sw2_config_db.json" in report + assert "generation or export failed" in report + assert "osism_sw3_config_db.json" in report + assert "unexpected extra" in report + assert "osism_sw1_config_db.json" in report + assert "A: only in golden" in report + + +class TestRegenerate: + def test_copies_exports_to_golden_canonically(self, tmp_path): + export = tmp_path / "export" + golden = tmp_path / "golden" + export.mkdir() + (export / "osism_sw1_config_db.json").write_text('{"B": {}, "A": {}}') + + regenerate(golden, export) + + content = (golden / "osism_sw1_config_db.json").read_text() + assert content == '{\n "A": {},\n "B": {}\n}\n' + + def test_removes_stale_golden_files(self, tmp_path): + export = tmp_path / "export" + golden = tmp_path / "golden" + export.mkdir() + golden.mkdir() + (export / "osism_sw1_config_db.json").write_text("{}") + (golden / "osism_gone_config_db.json").write_text("{}") + + regenerate(golden, export) + + assert not (golden / "osism_gone_config_db.json").exists() + assert (golden / "osism_sw1_config_db.json").exists() + + def test_ignores_non_json_exports(self, tmp_path): + export = tmp_path / "export" + golden = tmp_path / "golden" + export.mkdir() + (export / "firmware_sw1.bin").write_text("binary") + (export / "osism_sw1_config_db.json").write_text("{}") + + regenerate(golden, export) + + assert not (golden / "firmware_sw1.bin").exists() + + +class TestMain: + @staticmethod + def _dirs(tmp_path, golden_config, export_config): + golden = tmp_path / "golden" + export = tmp_path / "export" + golden.mkdir() + export.mkdir() + name = "osism_sw1_config_db.json" + (golden / name).write_text(json.dumps(golden_config)) + (export / name).write_text(json.dumps(export_config)) + return golden, export + + def test_matching_dirs_exit_zero(self, tmp_path, capsys): + golden, export = self._dirs(tmp_path, {"A": {}}, {"A": {}}) + + rc = main(["--golden", str(golden), "--export", str(export)]) + + assert rc == 0 + assert "OK" in capsys.readouterr().out + + def test_mismatch_exits_nonzero_and_prints_report(self, tmp_path, capsys): + golden, export = self._dirs(tmp_path, {"A": {}}, {"B": {}}) + + rc = main(["--golden", str(golden), "--export", str(export)]) + + assert rc == 1 + out = capsys.readouterr().out + assert "A: only in golden" in out + + def test_regenerate_rewrites_goldens_and_exits_zero(self, tmp_path): + golden, export = self._dirs(tmp_path, {"A": {}}, {"B": {}}) + + rc = main(["--golden", str(golden), "--export", str(export), "--regenerate"]) + + assert rc == 0 + name = "osism_sw1_config_db.json" + assert json.loads((golden / name).read_text()) == {"B": {}} diff --git a/tests/unit/e2e/test_generate.py b/tests/unit/e2e/test_generate.py new file mode 100644 index 00000000..2e3a831d --- /dev/null +++ b/tests/unit/e2e/test_generate.py @@ -0,0 +1,108 @@ +# SPDX-License-Identifier: Apache-2.0 + +"""Unit tests for the E2E generation driver. + +The driver's assertion logic (expected device set, loguru error capture) +is pure and tested here with an injected sync callable; only the real +``sync_sonic`` import is exercised in the actual E2E run. +""" + +from loguru import logger + +from tests.e2e.generate import expected_devices, main, run_generation + + +class TestExpectedDevices: + def test_strips_prefix_and_suffix(self, tmp_path): + (tmp_path / "osism_testbed-switch-0_config_db.json").write_text("{}") + (tmp_path / "osism_testbed-switch-1_config_db.json").write_text("{}") + + assert expected_devices(tmp_path, "osism_", "_config_db.json") == { + "testbed-switch-0", + "testbed-switch-1", + } + + def test_ignores_non_json_and_foreign_names(self, tmp_path): + (tmp_path / "osism_sw1_config_db.json").write_text("{}") + (tmp_path / "README.md").write_text("") + (tmp_path / "other_sw2.json").write_text("{}") + + assert expected_devices(tmp_path, "osism_", "_config_db.json") == {"sw1"} + + +class TestRunGeneration: + def test_returns_configs_and_no_errors_for_clean_sync(self): + configs, errors = run_generation(lambda: {"sw1": {"PORT": {}}}) + + assert configs == {"sw1": {"PORT": {}}} + assert errors == [] + + def test_captures_loguru_errors_during_sync(self): + def failing_sync(): + logger.error("Failed to sync SONiC configuration for device sw1: boom") + return {} + + configs, errors = run_generation(failing_sync) + + assert configs == {} + assert len(errors) == 1 + assert "boom" in errors[0] + + def test_does_not_capture_non_error_levels(self): + def chatty_sync(): + logger.info("processing") + logger.warning("odd but fine") + return {"sw1": {}} + + _, errors = run_generation(chatty_sync) + + assert errors == [] + + def test_sink_is_removed_after_run(self): + _, errors = run_generation(lambda: {}) + logger.error("logged after the run") + + assert errors == [] + + +class TestMain: + def test_success_returns_zero(self, tmp_path, capsys): + (tmp_path / "osism_sw1_config_db.json").write_text("{}") + + rc = main(["--golden", str(tmp_path)], sync=lambda: {"sw1": {"PORT": {}}}) + + assert rc == 0 + + def test_captured_errors_fail_the_run(self, tmp_path, capsys): + (tmp_path / "osism_sw1_config_db.json").write_text("{}") + + def failing_sync(): + logger.error("device sw1 exploded") + return {"sw1": {}} + + rc = main(["--golden", str(tmp_path)], sync=failing_sync) + + assert rc == 1 + assert "device sw1 exploded" in capsys.readouterr().out + + def test_device_set_mismatch_fails_and_names_devices(self, tmp_path, capsys): + (tmp_path / "osism_sw1_config_db.json").write_text("{}") + (tmp_path / "osism_sw2_config_db.json").write_text("{}") + + rc = main(["--golden", str(tmp_path)], sync=lambda: {"sw1": {"PORT": {}}}) + + assert rc == 1 + assert "sw2" in capsys.readouterr().out + + def test_empty_config_counts_as_failure(self, tmp_path, capsys): + (tmp_path / "osism_sw1_config_db.json").write_text("{}") + + rc = main(["--golden", str(tmp_path)], sync=lambda: {"sw1": {}}) + + assert rc == 1 + assert "sw1" in capsys.readouterr().out + + def test_no_expect_skips_device_set_check(self, capsys): + rc = main(["--no-expect"], sync=lambda: {"sw1": {"PORT": {}}}) + + assert rc == 0 From 8cdb793b35ecf7c05b80d7645ee31dbb00b430aa Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 17 Jul 2026 16:23:57 +0200 Subject: [PATCH 3/9] Build the SNMP vault only when secrets exist _add_snmp_configuration created a VaultLib instance for every device before looking at the secrets custom field. get_vault() reads the key file at /share/ansible_vault_password.key and fetches the encrypted vault password from Redis, so outside a worker container -- local development, or an E2E run against a plain NetBox -- it fails and logs three ERROR-level messages per synced device, even though there was nothing to decrypt in the first place. Defer vault construction until the device actually carries a non-empty secrets custom field. Devices with encrypted secrets are decrypted exactly as before; devices without secrets no longer touch the key file or Redis at all. Found by the E2E harness error guard, which treats any ERROR-level log record during config generation as a failure. Assisted-by: Claude:claude-fable-5 Signed-off-by: Roger Luethi --- .../tasks/conductor/sonic/config_generator.py | 10 ++--- .../sonic/test_config_generator_snmp.py | 39 +++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/osism/tasks/conductor/sonic/config_generator.py b/osism/tasks/conductor/sonic/config_generator.py index bc2d92db..4b9c2dcc 100644 --- a/osism/tasks/conductor/sonic/config_generator.py +++ b/osism/tasks/conductor/sonic/config_generator.py @@ -2268,14 +2268,14 @@ def _add_snmp_configuration(config, device, oob_ip): in the config_context of the device. """ - # Create vault instance for Custom Field decryption - vault = get_vault() - - # Decrypt secrets Custom Field + # Decrypt the secrets Custom Field. The vault needs the key file and + # Redis, and get_vault() logs ERRORs where those are absent, so it is + # only built when there are secrets to decrypt. node_secrets = device.custom_fields.get("secrets", {}) if node_secrets is None: node_secrets = {} - deep_decrypt(node_secrets, vault) + if node_secrets: + deep_decrypt(node_secrets, get_vault()) # Configure SNMP location and contact location = device.config_context.get("_segment_snmp_server_location", "Data Center") diff --git a/tests/unit/tasks/conductor/sonic/test_config_generator_snmp.py b/tests/unit/tasks/conductor/sonic/test_config_generator_snmp.py index d11844b8..f04d1600 100644 --- a/tests/unit/tasks/conductor/sonic/test_config_generator_snmp.py +++ b/tests/unit/tasks/conductor/sonic/test_config_generator_snmp.py @@ -169,3 +169,42 @@ def test_add_snmp_configuration_secrets_none_treated_as_empty(patch_snmp_secrets "shaKey": "OBFUSCATEDAUTHSECRET", "aesKey": "OBFUSCATEDPRIVSECRET", } + + +def test_add_snmp_configuration_no_secrets_skips_vault(mocker): + """Without encrypted secrets there is nothing to decrypt, so the vault + (which needs the container key file and Redis) must not be built at + all -- ``get_vault`` logs ERRORs in environments without a vault.""" + get_vault_mock = mocker.patch( + "osism.tasks.conductor.sonic.config_generator.get_vault" + ) + deep_decrypt_mock = mocker.patch( + "osism.tasks.conductor.sonic.config_generator.deep_decrypt" + ) + config = {} + + _add_snmp_configuration(config, _snmp_device(), oob_ip=None) + _add_snmp_configuration( + config, _snmp_device(custom_fields={"secrets": None}), oob_ip=None + ) + + get_vault_mock.assert_not_called() + deep_decrypt_mock.assert_not_called() + assert "SNMP_SERVER" in config + + +def test_add_snmp_configuration_with_secrets_uses_vault(mocker): + get_vault_mock = mocker.patch( + "osism.tasks.conductor.sonic.config_generator.get_vault" + ) + deep_decrypt_mock = mocker.patch( + "osism.tasks.conductor.sonic.config_generator.deep_decrypt", + side_effect=lambda data, vault: None, + ) + config = {} + device = _snmp_device(custom_fields={"secrets": {"snmp_auth": "$ANSIBLE_VAULT..."}}) + + _add_snmp_configuration(config, device, oob_ip=None) + + get_vault_mock.assert_called_once() + deep_decrypt_mock.assert_called_once() From e01acad8bdcf5d22a92053669f0935ef78bb3c3f Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 17 Jul 2026 16:39:46 +0200 Subject: [PATCH 4/9] Isolate the E2E seeding tool in its own venv The harness previously installed netbox-manager into the project venv. netbox-manager pins its own versions of packages that python-osism pins exactly -- the install mutated five of them, including pynetbox -- so a local E2E run silently left the developer venv diverged from Pipfile.lock. Install netbox-manager into a dedicated venv (.venv-sonic-e2e, gitignored, reused across runs, overridable via SEED_VENV) instead. The venv's bin directory is prepended to PATH because netbox-manager drives Ansible through ansible-runner, which resolves ansible-playbook via PATH rather than relative to its own interpreter. Assisted-by: Claude:claude-fable-5 Signed-off-by: Roger Luethi --- .gitignore | 1 + tests/e2e/run.sh | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 046f8b11..7d088d6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.egg-info +.venv-sonic-e2e/ *.pyc *.swp __pycache__ diff --git a/tests/e2e/run.sh b/tests/e2e/run.sh index 9192e30b..c8b32a13 100755 --- a/tests/e2e/run.sh +++ b/tests/e2e/run.sh @@ -114,12 +114,24 @@ fi # --- Phase 2: seed with netbox-manager ------------------------------------- # The CLI is installed from the checkout so a Zuul Depends-On on a -# netbox-manager change is honored for code and data alike. +# netbox-manager change is honored for code and data alike. It goes into a +# dedicated venv: netbox-manager pins different versions of packages that +# python-osism also pins (e.g. pynetbox), and installing it into the +# project venv would silently mutate those pins. +SEED_VENV="${SEED_VENV:-${REPO_ROOT}/.venv-sonic-e2e}" +if [[ ! -x "${SEED_VENV}/bin/pip" ]]; then + echo ">>> Creating seeding venv ${SEED_VENV}" + python3 -m venv "${SEED_VENV}" +fi +# netbox-manager drives Ansible through ansible-runner, which resolves +# ansible-playbook via PATH -- the venv's bin must therefore be on PATH, +# not merely used for the netbox-manager entry point itself. +export PATH="${SEED_VENV}/bin:${PATH}" echo ">>> Installing netbox-manager from ${NETBOX_MANAGER_DIR}" -pipenv run pip install --quiet "${NETBOX_MANAGER_DIR}" +"${SEED_VENV}/bin/pip" install --quiet "${NETBOX_MANAGER_DIR}" echo ">>> Installing the netbox.netbox Ansible collection" -pipenv run ansible-galaxy collection install -r "${NETBOX_MANAGER_DIR}/requirements.yml" +"${SEED_VENV}/bin/ansible-galaxy" collection install -r "${NETBOX_MANAGER_DIR}/requirements.yml" export NETBOX_MANAGER_URL="http://127.0.0.1:${NETBOX_PORT}" export NETBOX_MANAGER_TOKEN="${NETBOX_TOKEN}" @@ -129,7 +141,7 @@ export NETBOX_MANAGER_RESOURCES="${NETBOX_MANAGER_DIR}/example/resources" export NETBOX_MANAGER_IGNORE_SSL_ERRORS=true echo ">>> Seeding NetBox with the netbox-manager example data" -pipenv run netbox-manager run --fail-fast +"${SEED_VENV}/bin/netbox-manager" run --fail-fast # Scenario overlay (spec phase 4): a second run with # NETBOX_MANAGER_RESOURCES=${REPO_ROOT}/tests/e2e/resources goes here once From 406c5f9ef41921b92ef302bde7d0be5c566d3f8c Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 17 Jul 2026 17:04:45 +0200 Subject: [PATCH 5/9] Add golden files for the SONiC E2E test Bootstrap the golden set from the netbox-manager example data via make sonic-e2e-regen: the four testbed switches plus the OOB switch, generated by sync_sonic() against a seeded NetBox 4.5.10. The files pin current generator behavior as a change detector; they were cross-checked against their independent sources rather than reviewed line by line: - hostname, hwsku, management IP, loopback addresses (v4/v6) and the eth0 MAC match the seed resources for each device - all 34 PORT entries of the AS7726-32X devices carry exactly the speeds of files/sonic/port_config/Accton-AS7726-32X.ini (the seed sets no NetBox speed overrides) - BGP ASNs follow the documented rule (4200 prefix + loopback-derived suffix, e.g. 192.168.16.27 -> 4200016027) and the interconnected spine pair shares the group minimum 4200016029 - a second seed-and-generate cycle against a fresh NetBox deployment reproduced all five files byte-for-byte (determinism) The VLAN tables are empty on every device: the example data assigns VLANs only to the switches' own management interfaces, never to data ports, so the generator's VLAN paths are not yet exercised. Coverage for those (and for the breakout regression scenarios) comes with the planned scenario seed data. Assisted-by: Claude:claude-fable-5 Signed-off-by: Roger Luethi --- .../osism_testbed-switch-0_config_db.json | 743 ++++++++++++ .../osism_testbed-switch-1_config_db.json | 743 ++++++++++++ .../osism_testbed-switch-2_config_db.json | 632 ++++++++++ .../osism_testbed-switch-3_config_db.json | 632 ++++++++++ .../osism_testbed-switch-oob_config_db.json | 1035 +++++++++++++++++ 5 files changed, 3785 insertions(+) create mode 100644 tests/e2e/golden/osism_testbed-switch-0_config_db.json create mode 100644 tests/e2e/golden/osism_testbed-switch-1_config_db.json create mode 100644 tests/e2e/golden/osism_testbed-switch-2_config_db.json create mode 100644 tests/e2e/golden/osism_testbed-switch-3_config_db.json create mode 100644 tests/e2e/golden/osism_testbed-switch-oob_config_db.json diff --git a/tests/e2e/golden/osism_testbed-switch-0_config_db.json b/tests/e2e/golden/osism_testbed-switch-0_config_db.json new file mode 100644 index 00000000..6d8889c3 --- /dev/null +++ b/tests/e2e/golden/osism_testbed-switch-0_config_db.json @@ -0,0 +1,743 @@ +{ + "ACL_RULE": { + "GNMI_ONLY|RULE_1": { + "IP_TYPE": "IP", + "L4_DST_PORT": "8080", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SNMP_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SSH_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + } + }, + "ACL_TABLE": { + "GNMI_ONLY": { + "policy_desc": "GNMI_ONLY", + "services": [ + "EXTERNAL_CLIENT" + ], + "type": "CTRLPLANE" + }, + "SNMP_ONLY": { + "policy_desc": "SNMP_ONLY", + "services": [ + "SNMP" + ], + "type": "CTRLPLANE" + }, + "SSH_ONLY": { + "policy_desc": "SSH_ONLY", + "services": [ + "SSH" + ], + "type": "CTRLPLANE" + } + }, + "BGP_GLOBALS": { + "default": { + "local_asn": "4200016027", + "router_id": "192.168.16.27" + } + }, + "BGP_GLOBALS_AF": {}, + "BGP_GLOBALS_AF_NETWORK": { + "default|ipv4_unicast|192.168.16.27/32": {}, + "default|ipv6_unicast|fda6:f659:8c2b:0:192:168:16:27/128": {} + }, + "BGP_GLOBALS_ROUTE_ADVERTISE": {}, + "BGP_NEIGHBOR": { + "default|Ethernet0": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet120": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet124": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet20": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet24": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet28": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet32": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet36": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet40": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet44": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet48": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet52": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet56": { + "peer_type": "external", + "v6only": "true" + } + }, + "BGP_NEIGHBOR_AF": { + "default|Ethernet0|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet0|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet124|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet124|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet124|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet20|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet20|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet24|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet24|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet28|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet28|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet32|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet32|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet36|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet36|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet40|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet40|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet44|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet44|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet48|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet48|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet52|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet52|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet56|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet56|ipv6_unicast": { + "admin_status": "true" + } + }, + "BREAKOUT_CFG": {}, + "BREAKOUT_PORTS": {}, + "DEVICE_METADATA": { + "localhost": { + "hostname": "testbed-switch-0", + "hwsku": "Accton-AS7726-32X", + "mac": "4E:A2:D7:B8:F3:C6", + "platform": "x86_64-accton_as7726_32x-r0" + } + }, + "DNS_NAMESERVER": {}, + "INTERFACE": { + "Ethernet0": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet120": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet124": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet20": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet24": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet28": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet32": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet36": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet40": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet44": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet48": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet52": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet56": { + "ipv6_use_link_local_only": "enable" + } + }, + "LOOPBACK": { + "Loopback0": { + "admin_status": "up" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|192.168.16.27/32": {}, + "Loopback0|fda6:f659:8c2b:0:192:168:16:27/128": {} + }, + "MGMT_INTERFACE": { + "eth0": { + "admin_status": "up" + }, + "eth0|172.16.0.27/20": {} + }, + "NTP_SERVER": {}, + "PORT": { + "Ethernet0": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/1", + "autoneg": "off", + "index": "1", + "lanes": "1,2,3,4", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet100": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/26", + "autoneg": "off", + "index": "26", + "lanes": "101,102,103,104", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet104": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/27", + "autoneg": "off", + "index": "27", + "lanes": "105,106,107,108", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet108": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/28", + "autoneg": "off", + "index": "28", + "lanes": "109,110,111,112", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet112": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/29", + "autoneg": "off", + "index": "29", + "lanes": "113,114,115,116", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet116": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/30", + "autoneg": "off", + "index": "30", + "lanes": "117,118,119,120", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet12": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/4", + "autoneg": "off", + "index": "4", + "lanes": "13,14,15,16", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet120": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/31", + "autoneg": "off", + "index": "31", + "lanes": "121,122,123,124", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet124": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/32", + "autoneg": "off", + "index": "32", + "lanes": "125,126,127,128", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet125": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/33", + "autoneg": "off", + "index": "33", + "lanes": "129", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet126": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/34", + "autoneg": "off", + "index": "34", + "lanes": "128", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet16": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/5", + "autoneg": "off", + "index": "5", + "lanes": "17,18,19,20", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet20": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/6", + "autoneg": "off", + "index": "6", + "lanes": "21,22,23,24", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet24": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/7", + "autoneg": "off", + "index": "7", + "lanes": "25,26,27,28", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet28": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/8", + "autoneg": "off", + "index": "8", + "lanes": "29,30,31,32", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet32": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/9", + "autoneg": "off", + "index": "9", + "lanes": "33,34,35,36", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet36": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/10", + "autoneg": "off", + "index": "10", + "lanes": "37,38,39,40", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet4": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/2", + "autoneg": "off", + "index": "2", + "lanes": "5,6,7,8", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet40": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/11", + "autoneg": "off", + "index": "11", + "lanes": "41,42,43,44", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet44": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/12", + "autoneg": "off", + "index": "12", + "lanes": "45,46,47,48", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet48": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/13", + "autoneg": "off", + "index": "13", + "lanes": "49,50,51,52", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet52": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/14", + "autoneg": "off", + "index": "14", + "lanes": "53,54,55,56", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet56": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/15", + "autoneg": "off", + "index": "15", + "lanes": "57,58,59,60", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet60": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/16", + "autoneg": "off", + "index": "16", + "lanes": "61,62,63,64", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet64": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/17", + "autoneg": "off", + "index": "17", + "lanes": "65,66,67,68", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet68": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/18", + "autoneg": "off", + "index": "18", + "lanes": "69,70,71,72", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet72": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/19", + "autoneg": "off", + "index": "19", + "lanes": "73,74,75,76", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet76": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/20", + "autoneg": "off", + "index": "20", + "lanes": "77,78,79,80", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet8": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/3", + "autoneg": "off", + "index": "3", + "lanes": "9,10,11,12", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet80": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/21", + "autoneg": "off", + "index": "21", + "lanes": "81,82,83,84", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet84": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/22", + "autoneg": "off", + "index": "22", + "lanes": "85,86,87,88", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet88": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/23", + "autoneg": "off", + "index": "23", + "lanes": "89,90,91,92", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet92": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/24", + "autoneg": "off", + "index": "24", + "lanes": "93,94,95,96", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet96": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/25", + "autoneg": "off", + "index": "25", + "lanes": "97,98,99,100", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + } + }, + "PORTCHANNEL": {}, + "PORTCHANNEL_INTERFACE": {}, + "PORTCHANNEL_MEMBER": {}, + "SNMP_AGENT_ADDRESS_CONFIG": { + "172.16.0.27|161|mgmt": { + "name": "agentEntry1" + } + }, + "SNMP_SERVER": { + "SYSTEM": { + "sysContact": "info@example.com", + "sysLocation": "Data Center", + "traps": "enable" + } + }, + "STATIC_ROUTE": { + "mgmt|0.0.0.0/0": { + "nexthop": null + } + }, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_4_0_1" + } + }, + "VLAN": {}, + "VLAN_INTERFACE": {}, + "VLAN_MEMBER": {}, + "VRF": {}, + "VXLAN_EVPN_NVO": {}, + "VXLAN_TUNNEL": {}, + "VXLAN_TUNNEL_MAP": {} +} diff --git a/tests/e2e/golden/osism_testbed-switch-1_config_db.json b/tests/e2e/golden/osism_testbed-switch-1_config_db.json new file mode 100644 index 00000000..1a8a0bec --- /dev/null +++ b/tests/e2e/golden/osism_testbed-switch-1_config_db.json @@ -0,0 +1,743 @@ +{ + "ACL_RULE": { + "GNMI_ONLY|RULE_1": { + "IP_TYPE": "IP", + "L4_DST_PORT": "8080", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SNMP_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SSH_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + } + }, + "ACL_TABLE": { + "GNMI_ONLY": { + "policy_desc": "GNMI_ONLY", + "services": [ + "EXTERNAL_CLIENT" + ], + "type": "CTRLPLANE" + }, + "SNMP_ONLY": { + "policy_desc": "SNMP_ONLY", + "services": [ + "SNMP" + ], + "type": "CTRLPLANE" + }, + "SSH_ONLY": { + "policy_desc": "SSH_ONLY", + "services": [ + "SSH" + ], + "type": "CTRLPLANE" + } + }, + "BGP_GLOBALS": { + "default": { + "local_asn": "4200016028", + "router_id": "192.168.16.28" + } + }, + "BGP_GLOBALS_AF": {}, + "BGP_GLOBALS_AF_NETWORK": { + "default|ipv4_unicast|192.168.16.28/32": {}, + "default|ipv6_unicast|fda6:f659:8c2b:0:192:168:16:28/128": {} + }, + "BGP_GLOBALS_ROUTE_ADVERTISE": {}, + "BGP_NEIGHBOR": { + "default|Ethernet0": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet120": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet124": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet20": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet24": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet28": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet32": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet36": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet40": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet44": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet48": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet52": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet56": { + "peer_type": "external", + "v6only": "true" + } + }, + "BGP_NEIGHBOR_AF": { + "default|Ethernet0|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet0|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet124|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet124|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet124|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet20|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet20|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet24|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet24|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet28|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet28|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet32|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet32|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet36|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet36|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet40|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet40|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet44|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet44|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet48|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet48|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet52|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet52|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet56|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet56|ipv6_unicast": { + "admin_status": "true" + } + }, + "BREAKOUT_CFG": {}, + "BREAKOUT_PORTS": {}, + "DEVICE_METADATA": { + "localhost": { + "hostname": "testbed-switch-1", + "hwsku": "Accton-AS7726-32X", + "mac": "73:9F:C1:E5:B2:8D", + "platform": "x86_64-accton_as7726_32x-r0" + } + }, + "DNS_NAMESERVER": {}, + "INTERFACE": { + "Ethernet0": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet120": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet124": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet20": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet24": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet28": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet32": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet36": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet40": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet44": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet48": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet52": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet56": { + "ipv6_use_link_local_only": "enable" + } + }, + "LOOPBACK": { + "Loopback0": { + "admin_status": "up" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|192.168.16.28/32": {}, + "Loopback0|fda6:f659:8c2b:0:192:168:16:28/128": {} + }, + "MGMT_INTERFACE": { + "eth0": { + "admin_status": "up" + }, + "eth0|172.16.0.28/20": {} + }, + "NTP_SERVER": {}, + "PORT": { + "Ethernet0": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/1", + "autoneg": "off", + "index": "1", + "lanes": "1,2,3,4", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet100": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/26", + "autoneg": "off", + "index": "26", + "lanes": "101,102,103,104", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet104": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/27", + "autoneg": "off", + "index": "27", + "lanes": "105,106,107,108", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet108": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/28", + "autoneg": "off", + "index": "28", + "lanes": "109,110,111,112", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet112": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/29", + "autoneg": "off", + "index": "29", + "lanes": "113,114,115,116", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet116": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/30", + "autoneg": "off", + "index": "30", + "lanes": "117,118,119,120", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet12": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/4", + "autoneg": "off", + "index": "4", + "lanes": "13,14,15,16", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet120": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/31", + "autoneg": "off", + "index": "31", + "lanes": "121,122,123,124", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet124": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/32", + "autoneg": "off", + "index": "32", + "lanes": "125,126,127,128", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet125": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/33", + "autoneg": "off", + "index": "33", + "lanes": "129", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet126": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/34", + "autoneg": "off", + "index": "34", + "lanes": "128", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet16": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/5", + "autoneg": "off", + "index": "5", + "lanes": "17,18,19,20", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet20": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/6", + "autoneg": "off", + "index": "6", + "lanes": "21,22,23,24", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet24": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/7", + "autoneg": "off", + "index": "7", + "lanes": "25,26,27,28", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet28": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/8", + "autoneg": "off", + "index": "8", + "lanes": "29,30,31,32", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet32": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/9", + "autoneg": "off", + "index": "9", + "lanes": "33,34,35,36", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet36": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/10", + "autoneg": "off", + "index": "10", + "lanes": "37,38,39,40", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet4": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/2", + "autoneg": "off", + "index": "2", + "lanes": "5,6,7,8", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet40": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/11", + "autoneg": "off", + "index": "11", + "lanes": "41,42,43,44", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet44": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/12", + "autoneg": "off", + "index": "12", + "lanes": "45,46,47,48", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet48": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/13", + "autoneg": "off", + "index": "13", + "lanes": "49,50,51,52", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet52": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/14", + "autoneg": "off", + "index": "14", + "lanes": "53,54,55,56", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet56": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/15", + "autoneg": "off", + "index": "15", + "lanes": "57,58,59,60", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet60": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/16", + "autoneg": "off", + "index": "16", + "lanes": "61,62,63,64", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet64": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/17", + "autoneg": "off", + "index": "17", + "lanes": "65,66,67,68", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet68": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/18", + "autoneg": "off", + "index": "18", + "lanes": "69,70,71,72", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet72": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/19", + "autoneg": "off", + "index": "19", + "lanes": "73,74,75,76", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet76": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/20", + "autoneg": "off", + "index": "20", + "lanes": "77,78,79,80", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet8": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/3", + "autoneg": "off", + "index": "3", + "lanes": "9,10,11,12", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet80": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/21", + "autoneg": "off", + "index": "21", + "lanes": "81,82,83,84", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet84": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/22", + "autoneg": "off", + "index": "22", + "lanes": "85,86,87,88", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet88": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/23", + "autoneg": "off", + "index": "23", + "lanes": "89,90,91,92", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet92": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/24", + "autoneg": "off", + "index": "24", + "lanes": "93,94,95,96", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet96": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/25", + "autoneg": "off", + "index": "25", + "lanes": "97,98,99,100", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + } + }, + "PORTCHANNEL": {}, + "PORTCHANNEL_INTERFACE": {}, + "PORTCHANNEL_MEMBER": {}, + "SNMP_AGENT_ADDRESS_CONFIG": { + "172.16.0.28|161|mgmt": { + "name": "agentEntry1" + } + }, + "SNMP_SERVER": { + "SYSTEM": { + "sysContact": "info@example.com", + "sysLocation": "Data Center", + "traps": "enable" + } + }, + "STATIC_ROUTE": { + "mgmt|0.0.0.0/0": { + "nexthop": null + } + }, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_4_0_1" + } + }, + "VLAN": {}, + "VLAN_INTERFACE": {}, + "VLAN_MEMBER": {}, + "VRF": {}, + "VXLAN_EVPN_NVO": {}, + "VXLAN_TUNNEL": {}, + "VXLAN_TUNNEL_MAP": {} +} diff --git a/tests/e2e/golden/osism_testbed-switch-2_config_db.json b/tests/e2e/golden/osism_testbed-switch-2_config_db.json new file mode 100644 index 00000000..d22f1192 --- /dev/null +++ b/tests/e2e/golden/osism_testbed-switch-2_config_db.json @@ -0,0 +1,632 @@ +{ + "ACL_RULE": { + "GNMI_ONLY|RULE_1": { + "IP_TYPE": "IP", + "L4_DST_PORT": "8080", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SNMP_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SSH_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + } + }, + "ACL_TABLE": { + "GNMI_ONLY": { + "policy_desc": "GNMI_ONLY", + "services": [ + "EXTERNAL_CLIENT" + ], + "type": "CTRLPLANE" + }, + "SNMP_ONLY": { + "policy_desc": "SNMP_ONLY", + "services": [ + "SNMP" + ], + "type": "CTRLPLANE" + }, + "SSH_ONLY": { + "policy_desc": "SSH_ONLY", + "services": [ + "SSH" + ], + "type": "CTRLPLANE" + } + }, + "BGP_GLOBALS": { + "default": { + "local_asn": "4200016029", + "router_id": "192.168.16.29" + } + }, + "BGP_GLOBALS_AF": {}, + "BGP_GLOBALS_AF_NETWORK": { + "default|ipv4_unicast|192.168.16.29/32": {}, + "default|ipv6_unicast|fda6:f659:8c2b:0:192:168:16:29/128": {} + }, + "BGP_GLOBALS_ROUTE_ADVERTISE": {}, + "BGP_NEIGHBOR": { + "default|Ethernet0": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet120": { + "peer_type": "internal", + "v6only": "true" + }, + "default|Ethernet124": { + "peer_type": "internal", + "v6only": "true" + }, + "default|Ethernet4": { + "peer_type": "external", + "v6only": "true" + } + }, + "BGP_NEIGHBOR_AF": { + "default|Ethernet0|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet0|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet0|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet120|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet124|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet124|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet124|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet4|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet4|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet4|l2vpn_evpn": { + "admin_status": "true" + } + }, + "BREAKOUT_CFG": {}, + "BREAKOUT_PORTS": {}, + "DEVICE_METADATA": { + "localhost": { + "hostname": "testbed-switch-2", + "hwsku": "Accton-AS7726-32X", + "mac": "B5:2E:8A:F7:D1:C9", + "platform": "x86_64-accton_as7726_32x-r0" + } + }, + "DNS_NAMESERVER": {}, + "INTERFACE": { + "Ethernet0": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet120": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet124": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet4": { + "ipv6_use_link_local_only": "enable" + } + }, + "LOOPBACK": { + "Loopback0": { + "admin_status": "up" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|192.168.16.29/32": {}, + "Loopback0|fda6:f659:8c2b:0:192:168:16:29/128": {} + }, + "MGMT_INTERFACE": { + "eth0": { + "admin_status": "up" + }, + "eth0|172.16.0.29/20": {} + }, + "NTP_SERVER": {}, + "PORT": { + "Ethernet0": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/1", + "autoneg": "off", + "index": "1", + "lanes": "1,2,3,4", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet100": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/26", + "autoneg": "off", + "index": "26", + "lanes": "101,102,103,104", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet104": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/27", + "autoneg": "off", + "index": "27", + "lanes": "105,106,107,108", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet108": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/28", + "autoneg": "off", + "index": "28", + "lanes": "109,110,111,112", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet112": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/29", + "autoneg": "off", + "index": "29", + "lanes": "113,114,115,116", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet116": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/30", + "autoneg": "off", + "index": "30", + "lanes": "117,118,119,120", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet12": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/4", + "autoneg": "off", + "index": "4", + "lanes": "13,14,15,16", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet120": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/31", + "autoneg": "off", + "index": "31", + "lanes": "121,122,123,124", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet124": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/32", + "autoneg": "off", + "index": "32", + "lanes": "125,126,127,128", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet125": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/33", + "autoneg": "off", + "index": "33", + "lanes": "129", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet126": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/34", + "autoneg": "off", + "index": "34", + "lanes": "128", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet16": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/5", + "autoneg": "off", + "index": "5", + "lanes": "17,18,19,20", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet20": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/6", + "autoneg": "off", + "index": "6", + "lanes": "21,22,23,24", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet24": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/7", + "autoneg": "off", + "index": "7", + "lanes": "25,26,27,28", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet28": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/8", + "autoneg": "off", + "index": "8", + "lanes": "29,30,31,32", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet32": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/9", + "autoneg": "off", + "index": "9", + "lanes": "33,34,35,36", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet36": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/10", + "autoneg": "off", + "index": "10", + "lanes": "37,38,39,40", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet4": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/2", + "autoneg": "off", + "index": "2", + "lanes": "5,6,7,8", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet40": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/11", + "autoneg": "off", + "index": "11", + "lanes": "41,42,43,44", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet44": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/12", + "autoneg": "off", + "index": "12", + "lanes": "45,46,47,48", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet48": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/13", + "autoneg": "off", + "index": "13", + "lanes": "49,50,51,52", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet52": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/14", + "autoneg": "off", + "index": "14", + "lanes": "53,54,55,56", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet56": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/15", + "autoneg": "off", + "index": "15", + "lanes": "57,58,59,60", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet60": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/16", + "autoneg": "off", + "index": "16", + "lanes": "61,62,63,64", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet64": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/17", + "autoneg": "off", + "index": "17", + "lanes": "65,66,67,68", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet68": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/18", + "autoneg": "off", + "index": "18", + "lanes": "69,70,71,72", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet72": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/19", + "autoneg": "off", + "index": "19", + "lanes": "73,74,75,76", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet76": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/20", + "autoneg": "off", + "index": "20", + "lanes": "77,78,79,80", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet8": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/3", + "autoneg": "off", + "index": "3", + "lanes": "9,10,11,12", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet80": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/21", + "autoneg": "off", + "index": "21", + "lanes": "81,82,83,84", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet84": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/22", + "autoneg": "off", + "index": "22", + "lanes": "85,86,87,88", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet88": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/23", + "autoneg": "off", + "index": "23", + "lanes": "89,90,91,92", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet92": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/24", + "autoneg": "off", + "index": "24", + "lanes": "93,94,95,96", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet96": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/25", + "autoneg": "off", + "index": "25", + "lanes": "97,98,99,100", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + } + }, + "PORTCHANNEL": {}, + "PORTCHANNEL_INTERFACE": {}, + "PORTCHANNEL_MEMBER": {}, + "SNMP_AGENT_ADDRESS_CONFIG": { + "172.16.0.29|161|mgmt": { + "name": "agentEntry1" + } + }, + "SNMP_SERVER": { + "SYSTEM": { + "sysContact": "info@example.com", + "sysLocation": "Data Center", + "traps": "enable" + } + }, + "STATIC_ROUTE": { + "mgmt|0.0.0.0/0": { + "nexthop": null + } + }, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_4_0_1" + } + }, + "VLAN": {}, + "VLAN_INTERFACE": {}, + "VLAN_MEMBER": {}, + "VRF": {}, + "VXLAN_EVPN_NVO": {}, + "VXLAN_TUNNEL": {}, + "VXLAN_TUNNEL_MAP": {} +} diff --git a/tests/e2e/golden/osism_testbed-switch-3_config_db.json b/tests/e2e/golden/osism_testbed-switch-3_config_db.json new file mode 100644 index 00000000..79a44986 --- /dev/null +++ b/tests/e2e/golden/osism_testbed-switch-3_config_db.json @@ -0,0 +1,632 @@ +{ + "ACL_RULE": { + "GNMI_ONLY|RULE_1": { + "IP_TYPE": "IP", + "L4_DST_PORT": "8080", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SNMP_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SSH_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + } + }, + "ACL_TABLE": { + "GNMI_ONLY": { + "policy_desc": "GNMI_ONLY", + "services": [ + "EXTERNAL_CLIENT" + ], + "type": "CTRLPLANE" + }, + "SNMP_ONLY": { + "policy_desc": "SNMP_ONLY", + "services": [ + "SNMP" + ], + "type": "CTRLPLANE" + }, + "SSH_ONLY": { + "policy_desc": "SSH_ONLY", + "services": [ + "SSH" + ], + "type": "CTRLPLANE" + } + }, + "BGP_GLOBALS": { + "default": { + "local_asn": "4200016029", + "router_id": "192.168.16.30" + } + }, + "BGP_GLOBALS_AF": {}, + "BGP_GLOBALS_AF_NETWORK": { + "default|ipv4_unicast|192.168.16.30/32": {}, + "default|ipv6_unicast|fda6:f659:8c2b:0:192:168:16:30/128": {} + }, + "BGP_GLOBALS_ROUTE_ADVERTISE": {}, + "BGP_NEIGHBOR": { + "default|Ethernet0": { + "peer_type": "external", + "v6only": "true" + }, + "default|Ethernet120": { + "peer_type": "internal", + "v6only": "true" + }, + "default|Ethernet124": { + "peer_type": "internal", + "v6only": "true" + }, + "default|Ethernet4": { + "peer_type": "external", + "v6only": "true" + } + }, + "BGP_NEIGHBOR_AF": { + "default|Ethernet0|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet0|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet0|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet120|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet120|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet124|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet124|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet124|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet4|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet4|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet4|l2vpn_evpn": { + "admin_status": "true" + } + }, + "BREAKOUT_CFG": {}, + "BREAKOUT_PORTS": {}, + "DEVICE_METADATA": { + "localhost": { + "hostname": "testbed-switch-3", + "hwsku": "Accton-AS7726-32X", + "mac": "C3:4F:A2:B8:E5:D7", + "platform": "x86_64-accton_as7726_32x-r0" + } + }, + "DNS_NAMESERVER": {}, + "INTERFACE": { + "Ethernet0": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet120": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet124": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet4": { + "ipv6_use_link_local_only": "enable" + } + }, + "LOOPBACK": { + "Loopback0": { + "admin_status": "up" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|192.168.16.30/32": {}, + "Loopback0|fda6:f659:8c2b:0:192:168:16:30/128": {} + }, + "MGMT_INTERFACE": { + "eth0": { + "admin_status": "up" + }, + "eth0|172.16.0.30/20": {} + }, + "NTP_SERVER": {}, + "PORT": { + "Ethernet0": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/1", + "autoneg": "off", + "index": "1", + "lanes": "1,2,3,4", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet100": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/26", + "autoneg": "off", + "index": "26", + "lanes": "101,102,103,104", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet104": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/27", + "autoneg": "off", + "index": "27", + "lanes": "105,106,107,108", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet108": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/28", + "autoneg": "off", + "index": "28", + "lanes": "109,110,111,112", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet112": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/29", + "autoneg": "off", + "index": "29", + "lanes": "113,114,115,116", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet116": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/30", + "autoneg": "off", + "index": "30", + "lanes": "117,118,119,120", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet12": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/4", + "autoneg": "off", + "index": "4", + "lanes": "13,14,15,16", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet120": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/31", + "autoneg": "off", + "index": "31", + "lanes": "121,122,123,124", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet124": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/32", + "autoneg": "off", + "index": "32", + "lanes": "125,126,127,128", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet125": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/33", + "autoneg": "off", + "index": "33", + "lanes": "129", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet126": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/34", + "autoneg": "off", + "index": "34", + "lanes": "128", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet16": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/5", + "autoneg": "off", + "index": "5", + "lanes": "17,18,19,20", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet20": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/6", + "autoneg": "off", + "index": "6", + "lanes": "21,22,23,24", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet24": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/7", + "autoneg": "off", + "index": "7", + "lanes": "25,26,27,28", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet28": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/8", + "autoneg": "off", + "index": "8", + "lanes": "29,30,31,32", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet32": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/9", + "autoneg": "off", + "index": "9", + "lanes": "33,34,35,36", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet36": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/10", + "autoneg": "off", + "index": "10", + "lanes": "37,38,39,40", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet4": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/2", + "autoneg": "off", + "index": "2", + "lanes": "5,6,7,8", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet40": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/11", + "autoneg": "off", + "index": "11", + "lanes": "41,42,43,44", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet44": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/12", + "autoneg": "off", + "index": "12", + "lanes": "45,46,47,48", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet48": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/13", + "autoneg": "off", + "index": "13", + "lanes": "49,50,51,52", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet52": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/14", + "autoneg": "off", + "index": "14", + "lanes": "53,54,55,56", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet56": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/15", + "autoneg": "off", + "index": "15", + "lanes": "57,58,59,60", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet60": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/16", + "autoneg": "off", + "index": "16", + "lanes": "61,62,63,64", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet64": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/17", + "autoneg": "off", + "index": "17", + "lanes": "65,66,67,68", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet68": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/18", + "autoneg": "off", + "index": "18", + "lanes": "69,70,71,72", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet72": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/19", + "autoneg": "off", + "index": "19", + "lanes": "73,74,75,76", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet76": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/20", + "autoneg": "off", + "index": "20", + "lanes": "77,78,79,80", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet8": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/3", + "autoneg": "off", + "index": "3", + "lanes": "9,10,11,12", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet80": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/21", + "autoneg": "off", + "index": "21", + "lanes": "81,82,83,84", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet84": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/22", + "autoneg": "off", + "index": "22", + "lanes": "85,86,87,88", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet88": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/23", + "autoneg": "off", + "index": "23", + "lanes": "89,90,91,92", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet92": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/24", + "autoneg": "off", + "index": "24", + "lanes": "93,94,95,96", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet96": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/25", + "autoneg": "off", + "index": "25", + "lanes": "97,98,99,100", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + } + }, + "PORTCHANNEL": {}, + "PORTCHANNEL_INTERFACE": {}, + "PORTCHANNEL_MEMBER": {}, + "SNMP_AGENT_ADDRESS_CONFIG": { + "172.16.0.30|161|mgmt": { + "name": "agentEntry1" + } + }, + "SNMP_SERVER": { + "SYSTEM": { + "sysContact": "info@example.com", + "sysLocation": "Data Center", + "traps": "enable" + } + }, + "STATIC_ROUTE": { + "mgmt|0.0.0.0/0": { + "nexthop": null + } + }, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_4_0_1" + } + }, + "VLAN": {}, + "VLAN_INTERFACE": {}, + "VLAN_MEMBER": {}, + "VRF": {}, + "VXLAN_EVPN_NVO": {}, + "VXLAN_TUNNEL": {}, + "VXLAN_TUNNEL_MAP": {} +} diff --git a/tests/e2e/golden/osism_testbed-switch-oob_config_db.json b/tests/e2e/golden/osism_testbed-switch-oob_config_db.json new file mode 100644 index 00000000..60a70f3d --- /dev/null +++ b/tests/e2e/golden/osism_testbed-switch-oob_config_db.json @@ -0,0 +1,1035 @@ +{ + "ACL_RULE": { + "GNMI_ONLY|RULE_1": { + "IP_TYPE": "IP", + "L4_DST_PORT": "8080", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SNMP_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + }, + "SSH_ONLY|RULE_1": { + "IP_TYPE": "IP", + "PACKET_ACTION": "ACCEPT", + "PRIORITY": "9999", + "SRC_IP": "172.16.0.0/20" + } + }, + "ACL_TABLE": { + "GNMI_ONLY": { + "policy_desc": "GNMI_ONLY", + "services": [ + "EXTERNAL_CLIENT" + ], + "type": "CTRLPLANE" + }, + "SNMP_ONLY": { + "policy_desc": "SNMP_ONLY", + "services": [ + "SNMP" + ], + "type": "CTRLPLANE" + }, + "SSH_ONLY": { + "policy_desc": "SSH_ONLY", + "services": [ + "SSH" + ], + "type": "CTRLPLANE" + } + }, + "BGP_GLOBALS": { + "default": { + "local_asn": "4200016031", + "router_id": "192.168.16.31" + } + }, + "BGP_GLOBALS_AF": {}, + "BGP_GLOBALS_AF_NETWORK": { + "default|ipv4_unicast|192.168.16.31/32": {}, + "default|ipv6_unicast|fda6:f659:8c2b:0:192:168:16:31/128": {} + }, + "BGP_GLOBALS_ROUTE_ADVERTISE": {}, + "BGP_NEIGHBOR": { + "default|172.16.0.10": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.11": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.12": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.13": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.14": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.15": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.16": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.17": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.18": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.19": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.27": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.28": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.29": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.30": { + "peer_type": "external", + "v6only": "true" + }, + "default|172.16.0.5": { + "peer_type": "external", + "v6only": "true" + } + }, + "BGP_NEIGHBOR_AF": { + "default|Ethernet10|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet10|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet11|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet11|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet12|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet12|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet13|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet13|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet14|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet14|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet15|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet15|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet16|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet16|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet17|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet17|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet18|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet18|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet19|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet19|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet1|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet1|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet1|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet29|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet29|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet29|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet2|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet2|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet2|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet30|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet30|ipv6_unicast": { + "admin_status": "true" + }, + "default|Ethernet30|l2vpn_evpn": { + "admin_status": "true" + }, + "default|Ethernet5|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet5|ipv6_unicast": { + "admin_status": "true" + } + }, + "BREAKOUT_CFG": {}, + "BREAKOUT_PORTS": {}, + "DEVICE_METADATA": { + "localhost": { + "hostname": "testbed-switch-oob", + "hwsku": "Accton-AS5835-54T", + "mac": "F8:1D:7C:93:A6:2B", + "platform": "x86_64-accton_as5835_54t-r0" + } + }, + "DNS_NAMESERVER": {}, + "INTERFACE": { + "Ethernet1": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet10": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet11": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet12": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet13": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet14": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet15": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet16": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet17": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet18": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet19": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet2": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet29": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet30": { + "ipv6_use_link_local_only": "enable" + }, + "Ethernet5": { + "ipv6_use_link_local_only": "enable" + } + }, + "LOOPBACK": { + "Loopback0": { + "admin_status": "up" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|192.168.16.31/32": {}, + "Loopback0|fda6:f659:8c2b:0:192:168:16:31/128": {} + }, + "MGMT_INTERFACE": { + "eth0": { + "admin_status": "up" + }, + "eth0|172.16.0.31/20": {} + }, + "NTP_SERVER": {}, + "PORT": { + "Ethernet0": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/1", + "autoneg": "off", + "index": "1", + "lanes": "2", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet1": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/2", + "autoneg": "off", + "index": "2", + "lanes": "1", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet10": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/11", + "autoneg": "off", + "index": "11", + "lanes": "12", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet11": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/12", + "autoneg": "off", + "index": "12", + "lanes": "11", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet12": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/13", + "autoneg": "off", + "index": "13", + "lanes": "14", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet13": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/14", + "autoneg": "off", + "index": "14", + "lanes": "13", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet14": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/15", + "autoneg": "off", + "index": "15", + "lanes": "16", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet15": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/16", + "autoneg": "off", + "index": "16", + "lanes": "15", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet16": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/17", + "autoneg": "off", + "index": "17", + "lanes": "18", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet17": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/18", + "autoneg": "off", + "index": "18", + "lanes": "17", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet18": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/19", + "autoneg": "off", + "index": "19", + "lanes": "20", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet19": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/20", + "autoneg": "off", + "index": "20", + "lanes": "19", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet2": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/3", + "autoneg": "off", + "index": "3", + "lanes": "4", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet20": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/21", + "autoneg": "off", + "index": "21", + "lanes": "22", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet21": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/22", + "autoneg": "off", + "index": "22", + "lanes": "21", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet22": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/23", + "autoneg": "off", + "index": "23", + "lanes": "24", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet23": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/24", + "autoneg": "off", + "index": "24", + "lanes": "23", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet24": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/25", + "autoneg": "off", + "index": "25", + "lanes": "54", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet25": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/26", + "autoneg": "off", + "index": "26", + "lanes": "53", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet26": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/27", + "autoneg": "off", + "index": "27", + "lanes": "56", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet27": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/28", + "autoneg": "off", + "index": "28", + "lanes": "55", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet28": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/29", + "autoneg": "off", + "index": "29", + "lanes": "58", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet29": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/30", + "autoneg": "off", + "index": "30", + "lanes": "57", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet3": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/4", + "autoneg": "off", + "index": "4", + "lanes": "3", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet30": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/31", + "autoneg": "off", + "index": "31", + "lanes": "60", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet31": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/32", + "autoneg": "off", + "index": "32", + "lanes": "59", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet32": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/33", + "autoneg": "off", + "index": "33", + "lanes": "62", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet33": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/34", + "autoneg": "off", + "index": "34", + "lanes": "61", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet34": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/35", + "autoneg": "off", + "index": "35", + "lanes": "64", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet35": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/36", + "autoneg": "off", + "index": "36", + "lanes": "63", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet36": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/37", + "autoneg": "off", + "index": "37", + "lanes": "66", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet37": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/38", + "autoneg": "off", + "index": "38", + "lanes": "65", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet38": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/39", + "autoneg": "off", + "index": "39", + "lanes": "68", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet39": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/40", + "autoneg": "off", + "index": "40", + "lanes": "67", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet4": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/5", + "autoneg": "off", + "index": "5", + "lanes": "6", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet40": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/41", + "autoneg": "off", + "index": "41", + "lanes": "70", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet41": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/42", + "autoneg": "off", + "index": "42", + "lanes": "69", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet42": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/43", + "autoneg": "off", + "index": "43", + "lanes": "72", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet43": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/44", + "autoneg": "off", + "index": "44", + "lanes": "71", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet44": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/45", + "autoneg": "off", + "index": "45", + "lanes": "74", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet45": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/46", + "autoneg": "off", + "index": "46", + "lanes": "73", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet46": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/47", + "autoneg": "off", + "index": "47", + "lanes": "76", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet47": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/48", + "autoneg": "off", + "index": "48", + "lanes": "75", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet48": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/49", + "autoneg": "off", + "index": "49", + "lanes": "37,38,39,40", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet5": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/6", + "autoneg": "off", + "index": "6", + "lanes": "5", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet52": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/50", + "autoneg": "off", + "index": "50", + "lanes": "29,30,31,32", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet56": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/51", + "autoneg": "off", + "index": "51", + "lanes": "33,34,35,36", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet6": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/7", + "autoneg": "off", + "index": "7", + "lanes": "8", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet60": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/52", + "autoneg": "off", + "index": "52", + "lanes": "49,50,51,52", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet64": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/53", + "autoneg": "off", + "index": "53", + "lanes": "45,46,47,48", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet68": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/54", + "autoneg": "off", + "index": "54", + "lanes": "41,42,43,44", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet7": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/8", + "autoneg": "off", + "index": "8", + "lanes": "7", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet8": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/9", + "autoneg": "off", + "index": "9", + "lanes": "10", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet9": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/10", + "autoneg": "off", + "index": "10", + "lanes": "9", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + } + }, + "PORTCHANNEL": {}, + "PORTCHANNEL_INTERFACE": {}, + "PORTCHANNEL_MEMBER": {}, + "SNMP_AGENT_ADDRESS_CONFIG": { + "172.16.0.31|161|mgmt": { + "name": "agentEntry1" + } + }, + "SNMP_SERVER": { + "SYSTEM": { + "sysContact": "info@example.com", + "sysLocation": "Data Center", + "traps": "enable" + } + }, + "STATIC_ROUTE": { + "mgmt|0.0.0.0/0": { + "nexthop": null + } + }, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_4_0_1" + } + }, + "VLAN": {}, + "VLAN_INTERFACE": {}, + "VLAN_MEMBER": {}, + "VRF": {}, + "VXLAN_EVPN_NVO": {}, + "VXLAN_TUNNEL": {}, + "VXLAN_TUNNEL_MAP": {} +} From 015c0c19f35cef9978481b55ddf7ce7afb944f3a Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 17 Jul 2026 18:00:34 +0200 Subject: [PATCH 6/9] Add the SONiC E2E golden test to Zuul Wire the E2E golden test into CI as python-osism-sonic-e2e: provision NetBox on a kind cluster, seed it with the netbox-manager example data, run sync_sonic() and compare the exported config_db files against tests/e2e/golden/ via tests/e2e/run.sh. The netbox-manager checkout comes from required-projects, so the job consumes its seed data and CLI at tip-of-main and a Depends-On change is tested against the changed code and data. The pre-run playbook is adapted from netbox-manager's pre-e2e.yml (same pinned kind, kubectl and Helm versions with SHA256-verified downloads, same IPv6 accept_ra workaround for SLAAC-only CI nodes) and must stay in sync with it until the setup is factored into a shared zuul-jobs role. On top of that it installs curl, openssl and python3-venv for the harness script and its seeding venv. In check the job carries a files matcher so it only runs for changes that can alter the generated output: conductor code, settings, the port_config files, the harness itself, the CI playbooks, and the dependency pins. periodic-daily runs it unconditionally, bounding silent drift of the netbox-manager seed data to a day. Assisted-by: Claude:claude-fable-5 Signed-off-by: Roger Luethi --- .zuul.yaml | 30 +++++++++ playbooks/pre-sonic-e2e.yml | 119 +++++++++++++++++++++++++++++++++++ playbooks/test-sonic-e2e.yml | 35 +++++++++++ 3 files changed, 184 insertions(+) create mode 100644 playbooks/pre-sonic-e2e.yml create mode 100644 playbooks/test-sonic-e2e.yml diff --git a/.zuul.yaml b/.zuul.yaml index 6e3fcd70..127ba595 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -140,6 +140,34 @@ pre-run: playbooks/pre.yml run: playbooks/test-integration.yml +# End-to-end golden test for the SONiC config generator: provisions +# NetBox on kind, seeds it with the netbox-manager example data, runs +# sync_sonic() and compares the exported config_db files against +# tests/e2e/golden/. In check the job only runs when files that can +# change the generated output (or the harness itself) are touched; +# periodic-daily runs it unconditionally and catches drift of the +# netbox-manager seed data, which is consumed at tip-of-main via +# required-projects (honoring Depends-On). +- job: + name: python-osism-sonic-e2e + nodeset: ubuntu-noble + pre-run: playbooks/pre-sonic-e2e.yml + run: playbooks/test-sonic-e2e.yml + required-projects: + - osism/netbox-manager + timeout: 2400 + files: + - ^\.zuul\.yaml$ + - ^Makefile$ + - ^Pipfile\.lock$ + - ^files/sonic/.* + - ^osism/settings\.py$ + - ^osism/tasks/conductor/.* + - ^osism/utils/.* + - ^playbooks/(pre-|test-)sonic-e2e\.yml$ + - ^requirements\.txt$ + - ^tests/e2e/.* + - project: merge-mode: squash-merge default-branch: main @@ -154,6 +182,7 @@ - python-osism-test-setup - python-osism-unit-tests - python-osism-integration-tests + - python-osism-sonic-e2e periodic-daily: jobs: - flake8 @@ -163,6 +192,7 @@ - python-osism-test-setup - python-osism-unit-tests - python-osism-integration-tests + - python-osism-sonic-e2e periodic-midnight: jobs: - container-image-python-osism-push diff --git a/playbooks/pre-sonic-e2e.yml b/playbooks/pre-sonic-e2e.yml new file mode 100644 index 00000000..0f4b7175 --- /dev/null +++ b/playbooks/pre-sonic-e2e.yml @@ -0,0 +1,119 @@ +--- +# Node preparation for the SONiC config-generation E2E golden test. +# +# Adapted from netbox-manager's playbooks/pre-e2e.yml (which prepares the +# same kind + NetBox stack for its own E2E job); the tool pins and the +# IPv6 workaround must stay in sync with that playbook until the setup is +# factored into a shared zuul-jobs role. +- name: Prepare the SONiC E2E node + hosts: all + + vars: + # SHA256 digests of the linux/amd64 artifacts for the pinned tool + # versions below. They guard against a tampered download (CDN/DNS + # hijack, TLS-intercepting proxy) installing an attacker-controlled + # binary as root. Re-pin each digest whenever its *_version is bumped. + kind_version: v0.32.0 + kind_sha256: 50030de23cf40a18505f20426f6a8506bedf13c6e509244bd1fa9463721b0f54 + kubectl_version: v1.35.5 + kubectl_sha256: 90f75ea6ecc9ea5633262e1c0b83a40560003b30fc94a04cb099404fcef0c224 + helm_version: v3.16.4 + helm_sha256: fc307327959aa38ed8f9f7e66d45492bb022a66c3e5da6063958254b9767d179 + + pre_tasks: + # This CI node is IPv6-only and learns its address and default route via + # SLAAC / Router Advertisements. Later, `kind create cluster` makes Docker + # create a dual-stack network, which sets net.ipv6.conf.all.forwarding=1; + # with the default accept_ra=1 the kernel then stops honouring RAs, so the + # SLAAC default route expires and the node drops off the network a few + # minutes into the run. accept_ra=2 keeps RAs honoured even while + # forwarding is on, preserving the default route. Set it here -- before + # Docker/kind enable forwarding -- so the route never lapses. See + # https://docs.docker.com/engine/daemon/ipv6/ and + # https://forums.docker.com/t/docker-removes-host-ipv6-default-route/83238 + - name: Keep accepting IPv6 RAs after Docker enables forwarding (preserve default route) + become: true + ansible.builtin.copy: + dest: /etc/sysctl.d/99-sonic-e2e-accept-ra.conf + owner: root + group: root + mode: "0644" + content: | + net.ipv6.conf.all.accept_ra = 2 + net.ipv6.conf.default.accept_ra = 2 + {% if ansible_default_ipv6.interface is defined %} + net.ipv6.conf.{{ ansible_default_ipv6.interface }}.accept_ra = 2 + {% endif %} + + - name: Apply the accept_ra sysctl settings now + become: true + ansible.builtin.command: + cmd: sysctl -p /etc/sysctl.d/99-sonic-e2e-accept-ra.conf + changed_when: true + + roles: + - ensure-pip + - ensure-pipenv + - ensure-docker + + tasks: + - name: Ensure the Docker service is running + become: true + ansible.builtin.service: + name: docker + state: started + enabled: true + + # curl and openssl are used by tests/e2e/run.sh directly; python3-venv + # provides the venv module the script uses for the seeding venv. + - name: Install required packages + become: true + ansible.builtin.apt: + name: + - curl + - openssl + - python3-venv + + - name: Install kubectl + become: true + ansible.builtin.get_url: + url: "https://dl.k8s.io/release/{{ kubectl_version }}/bin/linux/amd64/kubectl" + dest: /usr/local/bin/kubectl + mode: "0755" + checksum: "sha256:{{ kubectl_sha256 }}" + + - name: Install kind + become: true + ansible.builtin.get_url: + url: "https://kind.sigs.k8s.io/dl/{{ kind_version }}/kind-linux-amd64" + dest: /usr/local/bin/kind + mode: "0755" + checksum: "sha256:{{ kind_sha256 }}" + + - name: Create a private temporary directory for the Helm archive + ansible.builtin.tempfile: + state: directory + suffix: helm + register: helm_tmp + + - name: Download the Helm archive + ansible.builtin.get_url: + url: "https://get.helm.sh/helm-{{ helm_version }}-linux-amd64.tar.gz" + dest: "{{ helm_tmp.path }}/helm.tar.gz" + mode: "0644" + checksum: "sha256:{{ helm_sha256 }}" + + - name: Install Helm + become: true + ansible.builtin.unarchive: + src: "{{ helm_tmp.path }}/helm.tar.gz" + dest: /usr/local/bin + remote_src: true + extra_opts: + - --strip-components=1 + - linux-amd64/helm + + - name: Remove the temporary Helm directory + ansible.builtin.file: + path: "{{ helm_tmp.path }}" + state: absent diff --git a/playbooks/test-sonic-e2e.yml b/playbooks/test-sonic-e2e.yml new file mode 100644 index 00000000..5abcc34b --- /dev/null +++ b/playbooks/test-sonic-e2e.yml @@ -0,0 +1,35 @@ +--- +- name: Run the SONiC config-generation E2E golden test + hosts: all + + vars: + python_venv_dir: /tmp/venv + + tasks: + - name: Install dependencies + ansible.builtin.shell: + executable: /bin/bash + chdir: "{{ zuul.project.src_dir }}" + cmd: | + set -e + set -o pipefail + set -x + + {{ python_venv_dir }}/bin/pipenv install --dev --deploy + {{ python_venv_dir }}/bin/pipenv run pip install . + + - name: Run the E2E golden test + ansible.builtin.shell: + executable: /bin/bash + chdir: "{{ zuul.project.src_dir }}" + cmd: | + set -e + set -o pipefail + set -x + + # run.sh invokes bare `pipenv`; the netbox-manager checkout comes + # from Zuul's required-projects, so a Depends-On change to it is + # tested against the changed code and seed data. + export PATH="{{ python_venv_dir }}/bin:${PATH}" + export NETBOX_MANAGER_DIR="{{ ansible_user_dir }}/{{ zuul.projects['github.com/osism/netbox-manager'].src_dir }}" + tests/e2e/run.sh From 10d947c87fc4d540ed854511421a710dcf1d8622 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 17 Jul 2026 19:24:37 +0200 Subject: [PATCH 7/9] Install the ansible extra before E2E generation The CI run of python-osism-sonic-e2e failed at the generation step: importing sync_sonic pulls in the whole conductor package, whose utils module does `from ansible import constants` at import time, and ansible-core was not present in the job's venv. The gap is easy to miss because every other environment masks it: the unit tests stub the ansible modules in tests/unit/conftest.py (so the unit job and a local pytest run stay green without ansible-core), and the container image installs requirements.ansible.txt explicitly. The E2E driver is the first consumer of the real import chain in a plain pipenv environment. Have run.sh install the project's own [ansible] extra (which resolves to requirements.ansible.txt, the same pin the container uses) into the project venv before generating. The step is idempotent and covers local runs from a fresh venv as well as CI. Assisted-by: Claude:claude-fable-5 Signed-off-by: Roger Luethi --- tests/e2e/run.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/e2e/run.sh b/tests/e2e/run.sh index c8b32a13..eb8562eb 100755 --- a/tests/e2e/run.sh +++ b/tests/e2e/run.sh @@ -148,6 +148,13 @@ echo ">>> Seeding NetBox with the netbox-manager example data" # the regression-scenario seed data exists. # --- Phase 3: generate SONiC configurations --------------------------------- +# The conductor import chain needs ansible-core, which lives in the +# project's optional [ansible] extra (the container image installs it via +# requirements.ansible.txt). The unit tests stub it out in conftest.py, so +# a venv that runs the unit suite does not necessarily satisfy this import. +echo ">>> Ensuring the osism[ansible] extra is installed" +pipenv run pip install --quiet ".[ansible]" + EXPORT_DIR="$(mktemp -d)" export NETBOX_API="http://127.0.0.1:${NETBOX_PORT}" export SONIC_EXPORT_DIR="${EXPORT_DIR}" From ee730e4fc35797abdff652273d989573b9e8d182 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 17 Jul 2026 21:28:13 +0200 Subject: [PATCH 8/9] Add a breakout scenario to the SONiC E2E test The bundled netbox-manager example models no breakout ports and sets no explicit interface speeds, so breakout detection and the kbps-to-Mbps speed normalisation are never exercised by the base golden test -- exactly the generation logic behind the recent customer-visible breakout speed regression. Add a scenario overlay applied as a second seeding pass. It defines a minimal synthetic device type (hwsku Accton-AS9726-32D) and two devices that each break the 8-lane 400G master Eth1/1 into a 4x100G group. The three non-master sub-ports are absent from the port_config .ini and so are generated by _add_missing_breakout_ports. The two devices differ only in where the sub-port speed comes from: e2e-breakout-derived speed derived from the interface type; no explicit NetBox speed. This is how real deployments model breakouts. e2e-breakout-explicit the same sub-ports with an explicit NetBox speed in kbps -- the other unit the collection step must normalise. Both must yield sub-port speed 100000. A tagged-VLAN port is added on the derived device for VLAN/VLAN_MEMBER coverage the base example lacks. The seed data is synthetic; real customer NetBox configs were used only as a modelling reference for interface naming and speed conventions, with no customer identifiers copied. Assisted-by: Claude:claude-fable-5 Signed-off-by: Roger Luethi --- tests/e2e/run.sh | 10 +- .../devicetypes/Edgecore/9726-32D-E2E.yaml | 37 ++++++ .../resources/500-breakout-scenarios.yml | 112 ++++++++++++++++++ 3 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 tests/e2e/scenario/devicetypes/Edgecore/9726-32D-E2E.yaml create mode 100644 tests/e2e/scenario/resources/500-breakout-scenarios.yml diff --git a/tests/e2e/run.sh b/tests/e2e/run.sh index eb8562eb..9901af4b 100755 --- a/tests/e2e/run.sh +++ b/tests/e2e/run.sh @@ -143,9 +143,13 @@ export NETBOX_MANAGER_IGNORE_SSL_ERRORS=true echo ">>> Seeding NetBox with the netbox-manager example data" "${SEED_VENV}/bin/netbox-manager" run --fail-fast -# Scenario overlay (spec phase 4): a second run with -# NETBOX_MANAGER_RESOURCES=${REPO_ROOT}/tests/e2e/resources goes here once -# the regression-scenario seed data exists. +# Scenario overlay: a second seeding pass adds the breakout / speed-unit +# regression devices that the base example does not cover. It reuses the +# site / tenant / roles created above and brings its own device type. +echo ">>> Seeding NetBox with the E2E scenario overlay" +export NETBOX_MANAGER_DEVICETYPE_LIBRARY="${REPO_ROOT}/tests/e2e/scenario/devicetypes" +export NETBOX_MANAGER_RESOURCES="${REPO_ROOT}/tests/e2e/scenario/resources" +"${SEED_VENV}/bin/netbox-manager" run --fail-fast --skipmtl # --- Phase 3: generate SONiC configurations --------------------------------- # The conductor import chain needs ansible-core, which lives in the diff --git a/tests/e2e/scenario/devicetypes/Edgecore/9726-32D-E2E.yaml b/tests/e2e/scenario/devicetypes/Edgecore/9726-32D-E2E.yaml new file mode 100644 index 00000000..c161befd --- /dev/null +++ b/tests/e2e/scenario/devicetypes/Edgecore/9726-32D-E2E.yaml @@ -0,0 +1,37 @@ +--- +# Minimal device type for the SONiC E2E breakout regression scenarios. +# +# This is not a faithful model of the real 9726-32D; it defines only the +# interfaces the scenarios need. Config generation is driven by the hwsku +# custom field (Accton-AS9726-32D on the scenario devices), not by this +# device type -- the device type only controls which NetBox interfaces +# exist. +# +# The interface layout mirrors how real deployments model breakouts (the +# NetBox EthX/Y/Z sub-port notation, speed derived from the interface +# type rather than set explicitly). On the 8-lane 400G master Ethernet0 +# (Accton-AS9726-32D.ini), the four sub-ports Eth1/1/1..4 map to +# Ethernet0/2/4/6 as a 4x100G breakout; the three non-master sub-ports are +# absent from the .ini and so are generated by _add_missing_breakout_ports, +# where the sub-port speed is read back from the collected NetBox data. +# +# Eth1/5 is a plain (non-breakout) 100G port used for VLAN coverage. +manufacturer: Edgecore +model: 9726-32D-E2E +slug: edgecore-9726-32d-e2e +u_height: 1.0 +is_full_depth: true +interfaces: + - name: eth0 + type: 1000base-t + mgmt_only: true + - name: Eth1/1/1 + type: 100gbase-x-qsfp28 + - name: Eth1/1/2 + type: 100gbase-x-qsfp28 + - name: Eth1/1/3 + type: 100gbase-x-qsfp28 + - name: Eth1/1/4 + type: 100gbase-x-qsfp28 + - name: Eth1/5 + type: 100gbase-x-qsfp28 diff --git a/tests/e2e/scenario/resources/500-breakout-scenarios.yml b/tests/e2e/scenario/resources/500-breakout-scenarios.yml new file mode 100644 index 00000000..3a42481e --- /dev/null +++ b/tests/e2e/scenario/resources/500-breakout-scenarios.yml @@ -0,0 +1,112 @@ +--- +# Scenario overlay for the SONiC E2E golden test. +# +# The bundled netbox-manager example models no breakout ports and sets no +# explicit interface speeds, so the breakout code paths and the kbps->Mbps +# speed handling are never exercised by it. These devices add that +# coverage. They reuse the site / location / tenant / roles / tags / custom +# fields created by the base example run, and live in their own rack so +# they never collide with base devices. +# +# Both devices use the edgecore-9726-32d-e2e device type (hwsku +# Accton-AS9726-32D) and break Eth1/1 into a 4x100G group. They differ +# only in how the sub-port speed reaches NetBox: +# +# e2e-breakout-derived speed derived from the interface type +# (100gbase-x-qsfp28 -> 100000 Mbps); no explicit +# speed. This is how real deployments model +# breakouts. +# e2e-breakout-explicit the same sub-ports with an explicit NetBox speed +# set in kbps (100000000), the other unit the +# collection step must normalise. +# +# Both must yield sub-port speed 100000 in the generated config. + +- vars: + site: Discworld + location: Ankh-Morpork + tenant: Testbed + +- rack: + name: E2E + tenant: "{{ tenant }}" + site: "{{ site }}" + location: "{{ location }}" + u_height: 47 + +- vlan: + name: E2E Data + tenant: "{{ tenant }}" + vid: 200 + site: "{{ site }}" + vlan_role: OOB + +# --- Derived-speed breakout (the real-deployment shape) -------------------- + +- device: + name: e2e-breakout-derived + tenant: "{{ tenant }}" + site: "{{ site }}" + location: "{{ location }}" + rack: E2E + device_type: edgecore-9726-32d-e2e + device_role: leaf + face: front + position: 1 + tags: + - managed-by-metalbox + - managed-by-osism + custom_fields: + sonic_parameters: + hwsku: Accton-AS9726-32D + version: 4.5.0 + +# Tagged VLAN on the plain (non-breakout) port, exercising the VLAN and +# tagged-VLAN-to-port paths the base example leaves uncovered. +- device_interface: + device: e2e-breakout-derived + name: Eth1/5 + mode: tagged + tagged_vlans: + - name: E2E Data + site: "{{ site }}" + +# --- Explicit-speed breakout (the other speed unit) ----------------------- + +- device: + name: e2e-breakout-explicit + tenant: "{{ tenant }}" + site: "{{ site }}" + location: "{{ location }}" + rack: E2E + device_type: edgecore-9726-32d-e2e + device_role: leaf + face: front + position: 2 + tags: + - managed-by-metalbox + - managed-by-osism + custom_fields: + sonic_parameters: + hwsku: Accton-AS9726-32D + version: 4.5.0 + +- device_interface: + device: e2e-breakout-explicit + name: Eth1/1/1 + speed: 100000000 + +- device_interface: + device: e2e-breakout-explicit + name: Eth1/1/2 + speed: 100000000 + +- device_interface: + device: e2e-breakout-explicit + name: Eth1/1/3 + speed: 100000000 + +- device_interface: + device: e2e-breakout-explicit + name: Eth1/1/4 + speed: 100000000 From ffdb7a2bcb4034a188c5a1e3042bf9c3ad8b0822 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 17 Jul 2026 21:28:23 +0200 Subject: [PATCH 9/9] Add golden files for the breakout scenario Goldens for the two breakout scenario devices, generated against a seeded NetBox. Both devices produce sub-port speed 100000 for the 4x100G group -- the same value whether the speed is derived from the interface type or set explicitly in kbps. Verified the guard by reverting the fix locally against these goldens: - Restoring the mixed-unit collection (explicit speed left in kbps) together with the downstream division turns the derived golden red (Ethernet0/2/4/6 speed 100000 -> 100, the customer-visible symptom) while the explicit golden stays green. - Dropping the division instead turns the explicit golden red (speed 100000 -> 100000000, raw kbps) while the derived golden stays green. The current code keeps both green, so either regression would now fail the E2E test with a speed diff on the affected device. Assisted-by: Claude:claude-fable-5 Signed-off-by: Roger Luethi --- .../osism_e2e-breakout-derived_config_db.json | 565 ++++++++++++++++++ ...osism_e2e-breakout-explicit_config_db.json | 549 +++++++++++++++++ 2 files changed, 1114 insertions(+) create mode 100644 tests/e2e/golden/osism_e2e-breakout-derived_config_db.json create mode 100644 tests/e2e/golden/osism_e2e-breakout-explicit_config_db.json diff --git a/tests/e2e/golden/osism_e2e-breakout-derived_config_db.json b/tests/e2e/golden/osism_e2e-breakout-derived_config_db.json new file mode 100644 index 00000000..304ab307 --- /dev/null +++ b/tests/e2e/golden/osism_e2e-breakout-derived_config_db.json @@ -0,0 +1,565 @@ +{ + "BGP_GLOBALS": {}, + "BGP_GLOBALS_AF": {}, + "BGP_GLOBALS_AF_NETWORK": {}, + "BGP_GLOBALS_ROUTE_ADVERTISE": {}, + "BGP_NEIGHBOR": {}, + "BGP_NEIGHBOR_AF": {}, + "BREAKOUT_CFG": { + "Ethernet0": { + "breakout_owner": "MANUAL", + "brkout_mode": "4x100G", + "port": "1/1" + } + }, + "BREAKOUT_PORTS": { + "Ethernet0": { + "master": "Ethernet0" + }, + "Ethernet2": { + "master": "Ethernet0" + }, + "Ethernet4": { + "master": "Ethernet0" + }, + "Ethernet6": { + "master": "Ethernet0" + } + }, + "DEVICE_METADATA": { + "localhost": { + "hostname": "e2e-breakout-derived", + "hwsku": "Accton-AS9726-32D", + "mac": "00:00:00:00:00:00", + "platform": "x86_64-accton_as9726_32d-r0" + } + }, + "DNS_NAMESERVER": {}, + "INTERFACE": {}, + "LOOPBACK": {}, + "LOOPBACK_INTERFACE": {}, + "MGMT_INTERFACE": {}, + "NTP_SERVER": {}, + "PORT": { + "Ethernet0": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/1/1", + "autoneg": "off", + "index": "1", + "lanes": "73,74", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,50000,25000,10000,1000" + }, + "Ethernet104": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/14", + "autoneg": "off", + "index": "14", + "lanes": "137,138,139,140,141,142,143,144", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet112": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/15", + "autoneg": "off", + "index": "15", + "lanes": "145,146,147,148,149,150,151,152", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet120": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/16", + "autoneg": "off", + "index": "16", + "lanes": "153,154,155,156,157,158,159,160", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet128": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/17", + "autoneg": "off", + "index": "17", + "lanes": "169,170,171,172,173,174,175,176", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet136": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/18", + "autoneg": "off", + "index": "18", + "lanes": "161,162,163,164,165,166,167,168", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet144": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/19", + "autoneg": "off", + "index": "19", + "lanes": "177,178,179,180,181,182,183,184", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet152": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/20", + "autoneg": "off", + "index": "20", + "lanes": "185,186,187,188,189,190,191,192", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet16": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/3", + "autoneg": "off", + "index": "3", + "lanes": "81,82,83,84,85,86,87,88", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet160": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/21", + "autoneg": "off", + "index": "21", + "lanes": "1,2,3,4,5,6,7,8", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet168": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/22", + "autoneg": "off", + "index": "22", + "lanes": "9,10,11,12,13,14,15,16", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet176": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/23", + "autoneg": "off", + "index": "23", + "lanes": "17,18,19,20,21,22,23,24", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet184": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/24", + "autoneg": "off", + "index": "24", + "lanes": "25,26,27,28,29,30,31,32", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet192": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/25", + "autoneg": "off", + "index": "25", + "lanes": "201,202,203,204,205,206,207,208", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet2": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/1/3", + "autoneg": "off", + "index": "1", + "lanes": "75,76", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,50000,25000,10000,1000" + }, + "Ethernet200": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/26", + "autoneg": "off", + "index": "26", + "lanes": "193,194,195,196,197,198,199,200", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet208": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/27", + "autoneg": "off", + "index": "27", + "lanes": "217,218,219,220,221,222,223,224", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet216": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/28", + "autoneg": "off", + "index": "28", + "lanes": "209,210,211,212,213,214,215,216", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet224": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/29", + "autoneg": "off", + "index": "29", + "lanes": "233,234,235,236,237,238,239,240", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet232": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/30", + "autoneg": "off", + "index": "30", + "lanes": "225,226,227,228,229,230,231,232", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet24": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/4", + "autoneg": "off", + "index": "4", + "lanes": "89,90,91,92,93,94,95,96", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet240": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/31", + "autoneg": "off", + "index": "31", + "lanes": "249,250,251,252,253,254,255,256", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet248": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/32", + "autoneg": "off", + "index": "32", + "lanes": "241,242,243,244,245,246,247,248", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet256": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/33", + "autoneg": "off", + "index": "33", + "lanes": "259", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000" + }, + "Ethernet257": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/34", + "autoneg": "off", + "index": "34", + "lanes": "260", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000" + }, + "Ethernet32": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/5", + "autoneg": "off", + "index": "5", + "lanes": "97,98,99,100,101,102,103,104", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "tagged_vlans": [ + "200" + ], + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet4": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/1/5", + "autoneg": "off", + "index": "1", + "lanes": "77,78", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,50000,25000,10000,1000" + }, + "Ethernet40": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/6", + "autoneg": "off", + "index": "6", + "lanes": "105,106,107,108,109,110,111,112", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet48": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/7", + "autoneg": "off", + "index": "7", + "lanes": "113,114,115,116,117,118,119,120", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet56": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/8", + "autoneg": "off", + "index": "8", + "lanes": "121,122,123,124,125,126,127,128", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet6": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/1/7", + "autoneg": "off", + "index": "1", + "lanes": "79,80", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,50000,25000,10000,1000" + }, + "Ethernet64": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/9", + "autoneg": "off", + "index": "9", + "lanes": "41,42,43,44,45,46,47,48", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet72": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/10", + "autoneg": "off", + "index": "10", + "lanes": "33,34,35,36,37,38,39,40", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet8": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/2", + "autoneg": "off", + "index": "2", + "lanes": "65,66,67,68,69,70,71,72", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet80": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/11", + "autoneg": "off", + "index": "11", + "lanes": "49,50,51,52,53,54,55,56", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet88": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/12", + "autoneg": "off", + "index": "12", + "lanes": "57,58,59,60,61,62,63,64", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet96": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/13", + "autoneg": "off", + "index": "13", + "lanes": "129,130,131,132,133,134,135,136", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + } + }, + "PORTCHANNEL": {}, + "PORTCHANNEL_INTERFACE": {}, + "PORTCHANNEL_MEMBER": {}, + "SNMP_SERVER": { + "SYSTEM": { + "sysContact": "info@example.com", + "sysLocation": "Data Center", + "traps": "enable" + } + }, + "STATIC_ROUTE": {}, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_4_0_1" + } + }, + "VLAN": { + "Vlan200": { + "admin_status": "up", + "autostate": "enable", + "members": [ + "Ethernet32" + ], + "vlanid": "200" + } + }, + "VLAN_INTERFACE": {}, + "VLAN_MEMBER": { + "Vlan200|Ethernet32": { + "tagging_mode": "tagged" + } + }, + "VRF": {}, + "VXLAN_EVPN_NVO": {}, + "VXLAN_TUNNEL": {}, + "VXLAN_TUNNEL_MAP": {} +} diff --git a/tests/e2e/golden/osism_e2e-breakout-explicit_config_db.json b/tests/e2e/golden/osism_e2e-breakout-explicit_config_db.json new file mode 100644 index 00000000..2581dfdc --- /dev/null +++ b/tests/e2e/golden/osism_e2e-breakout-explicit_config_db.json @@ -0,0 +1,549 @@ +{ + "BGP_GLOBALS": {}, + "BGP_GLOBALS_AF": {}, + "BGP_GLOBALS_AF_NETWORK": {}, + "BGP_GLOBALS_ROUTE_ADVERTISE": {}, + "BGP_NEIGHBOR": {}, + "BGP_NEIGHBOR_AF": {}, + "BREAKOUT_CFG": { + "Ethernet0": { + "breakout_owner": "MANUAL", + "brkout_mode": "4x100G", + "port": "1/1" + } + }, + "BREAKOUT_PORTS": { + "Ethernet0": { + "master": "Ethernet0" + }, + "Ethernet2": { + "master": "Ethernet0" + }, + "Ethernet4": { + "master": "Ethernet0" + }, + "Ethernet6": { + "master": "Ethernet0" + } + }, + "DEVICE_METADATA": { + "localhost": { + "hostname": "e2e-breakout-explicit", + "hwsku": "Accton-AS9726-32D", + "mac": "00:00:00:00:00:00", + "platform": "x86_64-accton_as9726_32d-r0" + } + }, + "DNS_NAMESERVER": {}, + "INTERFACE": {}, + "LOOPBACK": {}, + "LOOPBACK_INTERFACE": {}, + "MGMT_INTERFACE": {}, + "NTP_SERVER": {}, + "PORT": { + "Ethernet0": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/1/1", + "autoneg": "off", + "index": "1", + "lanes": "73,74", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,50000,25000,10000,1000" + }, + "Ethernet104": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/14", + "autoneg": "off", + "index": "14", + "lanes": "137,138,139,140,141,142,143,144", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet112": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/15", + "autoneg": "off", + "index": "15", + "lanes": "145,146,147,148,149,150,151,152", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet120": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/16", + "autoneg": "off", + "index": "16", + "lanes": "153,154,155,156,157,158,159,160", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet128": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/17", + "autoneg": "off", + "index": "17", + "lanes": "169,170,171,172,173,174,175,176", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet136": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/18", + "autoneg": "off", + "index": "18", + "lanes": "161,162,163,164,165,166,167,168", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet144": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/19", + "autoneg": "off", + "index": "19", + "lanes": "177,178,179,180,181,182,183,184", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet152": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/20", + "autoneg": "off", + "index": "20", + "lanes": "185,186,187,188,189,190,191,192", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet16": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/3", + "autoneg": "off", + "index": "3", + "lanes": "81,82,83,84,85,86,87,88", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet160": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/21", + "autoneg": "off", + "index": "21", + "lanes": "1,2,3,4,5,6,7,8", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet168": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/22", + "autoneg": "off", + "index": "22", + "lanes": "9,10,11,12,13,14,15,16", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet176": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/23", + "autoneg": "off", + "index": "23", + "lanes": "17,18,19,20,21,22,23,24", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet184": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/24", + "autoneg": "off", + "index": "24", + "lanes": "25,26,27,28,29,30,31,32", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet192": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/25", + "autoneg": "off", + "index": "25", + "lanes": "201,202,203,204,205,206,207,208", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet2": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/1/3", + "autoneg": "off", + "index": "1", + "lanes": "75,76", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,50000,25000,10000,1000" + }, + "Ethernet200": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/26", + "autoneg": "off", + "index": "26", + "lanes": "193,194,195,196,197,198,199,200", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet208": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/27", + "autoneg": "off", + "index": "27", + "lanes": "217,218,219,220,221,222,223,224", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet216": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/28", + "autoneg": "off", + "index": "28", + "lanes": "209,210,211,212,213,214,215,216", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet224": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/29", + "autoneg": "off", + "index": "29", + "lanes": "233,234,235,236,237,238,239,240", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet232": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/30", + "autoneg": "off", + "index": "30", + "lanes": "225,226,227,228,229,230,231,232", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet24": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/4", + "autoneg": "off", + "index": "4", + "lanes": "89,90,91,92,93,94,95,96", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet240": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/31", + "autoneg": "off", + "index": "31", + "lanes": "249,250,251,252,253,254,255,256", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet248": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/32", + "autoneg": "off", + "index": "32", + "lanes": "241,242,243,244,245,246,247,248", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet256": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/33", + "autoneg": "off", + "index": "33", + "lanes": "259", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000" + }, + "Ethernet257": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/34", + "autoneg": "off", + "index": "34", + "lanes": "260", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000" + }, + "Ethernet32": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/5", + "autoneg": "off", + "index": "5", + "lanes": "97,98,99,100,101,102,103,104", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet4": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/1/5", + "autoneg": "off", + "index": "1", + "lanes": "77,78", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,50000,25000,10000,1000" + }, + "Ethernet40": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/6", + "autoneg": "off", + "index": "6", + "lanes": "105,106,107,108,109,110,111,112", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet48": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/7", + "autoneg": "off", + "index": "7", + "lanes": "113,114,115,116,117,118,119,120", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet56": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/8", + "autoneg": "off", + "index": "8", + "lanes": "121,122,123,124,125,126,127,128", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet6": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/1/7", + "autoneg": "off", + "index": "1", + "lanes": "79,80", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,50000,25000,10000,1000" + }, + "Ethernet64": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/9", + "autoneg": "off", + "index": "9", + "lanes": "41,42,43,44,45,46,47,48", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet72": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/10", + "autoneg": "off", + "index": "10", + "lanes": "33,34,35,36,37,38,39,40", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet8": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/2", + "autoneg": "off", + "index": "2", + "lanes": "65,66,67,68,69,70,71,72", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet80": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/11", + "autoneg": "off", + "index": "11", + "lanes": "49,50,51,52,53,54,55,56", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet88": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/12", + "autoneg": "off", + "index": "12", + "lanes": "57,58,59,60,61,62,63,64", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + }, + "Ethernet96": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/13", + "autoneg": "off", + "index": "13", + "lanes": "129,130,131,132,133,134,135,136", + "link_training": "off", + "mtu": "9100", + "speed": "400000", + "unreliable_los": "auto", + "valid_speeds": "400000" + } + }, + "PORTCHANNEL": {}, + "PORTCHANNEL_INTERFACE": {}, + "PORTCHANNEL_MEMBER": {}, + "SNMP_SERVER": { + "SYSTEM": { + "sysContact": "info@example.com", + "sysLocation": "Data Center", + "traps": "enable" + } + }, + "STATIC_ROUTE": {}, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_4_0_1" + } + }, + "VLAN": {}, + "VLAN_INTERFACE": {}, + "VLAN_MEMBER": {}, + "VRF": {}, + "VXLAN_EVPN_NVO": {}, + "VXLAN_TUNNEL": {}, + "VXLAN_TUNNEL_MAP": {} +}