From ee57a54af0e9f2bc143f5ef96237c8a401815cca Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Fri, 6 Feb 2026 23:45:31 +0000 Subject: [PATCH 01/11] refactor: Phase 0 - Framework refactoring & code quality - Create src/constants.py: centralized magic strings, defaults, templates, BMC_HARDCODED_VLANS (VLANs 2/99 per DC4) - Create src/utils.py: infer_firmware(), classify_vlan_group() shared utils - Rewrite src/loader.py: remove dead pretty_print_json, raise exceptions instead of returning None, add type hints, use logging - Rewrite src/generator.py: relative imports only, logging, propagate template errors (no more warnings.warn) - Rewrite src/main.py: add --debug CLI flag (DC3), decompose monolithic main(), _configure_logging(), relative imports (DC1) - Refactor src/convertors/convertors_lab_switch_json.py: import from constants/utils, remove dead code, gate debug behind parameter, logging - Rewrite src/convertors/convertors_bmc_switch_json.py: use get_real_path(), infer_firmware(), BMC_HARDCODED_VLANS from constants, logging - Create tests/conftest.py: shared fixtures, path setup, diff helpers - Create tests/test_unit.py: 25 unit tests for constants, utils, loader - Rewrite tests/test_convertors.py: use tmp_path, strip debug key (DC6) - Fix tests/test_generator.py: proper parametrize IDs (was embedding entire _ALL_PAIRS list into each test name) - Update Dell BMC expected output: remove VLAN 7, update VLAN 99 name All 56 tests pass (25 unit + 8 converter + 23 generator). --- src/constants.py | 104 +++++ src/convertors/__init__.py | 19 +- src/convertors/convertors_bmc_switch_json.py | 362 ++++++---------- src/convertors/convertors_lab_switch_json.py | 232 ++++------ src/generator.py | 115 ++--- src/loader.py | 94 +++-- src/main.py | 396 ++++++++---------- src/utils.py | 43 ++ tests/conftest.py | 82 ++++ .../expected_outputs/s46-r06-3248bmc-6-1.json | 6 +- tests/test_convertors.py | 322 +++----------- tests/test_generator.py | 327 +++------------ tests/test_unit.py | 127 ++++++ 13 files changed, 996 insertions(+), 1233 deletions(-) create mode 100644 src/constants.py create mode 100644 src/utils.py create mode 100644 tests/conftest.py create mode 100644 tests/test_unit.py diff --git a/src/constants.py b/src/constants.py new file mode 100644 index 0000000..03ea21e --- /dev/null +++ b/src/constants.py @@ -0,0 +1,104 @@ +""" +Centralized constants for the AzureStack Network Switch Config Generator. + +All magic strings, default values, and lookup tables live here so that +every module imports from one source of truth. +""" + +# ── Switch vendors & firmware ────────────────────────────────────────────── +CISCO = "cisco" +DELL = "dellemc" + +NXOS = "nxos" +OS10 = "os10" + +# Vendor → firmware mapping (used by infer_firmware) +VENDOR_FIRMWARE_MAP: dict[str, str] = { + CISCO: NXOS, + DELL: OS10, +} + +# ── Switch types / roles ────────────────────────────────────────────────── +TOR1 = "TOR1" +TOR2 = "TOR2" +BMC = "BMC" + +# Switch types that go through the standard TOR converter pipeline +TOR_SWITCH_TYPES: list[str] = [TOR1, TOR2] + +# ── Deployment patterns ─────────────────────────────────────────────────── +PATTERN_HYPERCONVERGED = "hyperconverged" +PATTERN_FULLY_CONVERGED = "fully_converged" +PATTERN_FULLY_CONVERGED1 = "fully_converged1" # trunk mode +PATTERN_FULLY_CONVERGED2 = "fully_converged2" # access mode + +# ── Output defaults ────────────────────────────────────────────────────── +DEFAULT_OUTPUT_DIR = "output" +OUTPUT_FILE_EXTENSION = ".json" + +# ── Network defaults ───────────────────────────────────────────────────── +JUMBO_MTU = 9216 + +# ── Redundancy ──────────────────────────────────────────────────────────── +HSRP = "hsrp" +VRRP = "vrrp" +REDUNDANCY_PRIORITY_ACTIVE = 150 +REDUNDANCY_PRIORITY_STANDBY = 140 + +# ── VLAN group prefixes (used to classify supernet GroupName → symbol) ──── +# Maps a GroupName prefix to the symbolic VLAN-set key used in templates. +VLAN_GROUP_MAP: dict[str, str] = { + "HNVPA": "C", + "INFRA": "M", + "TENANT": "C", + "L3FORWARD": "C", + "STORAGE": "S", + "UNUSED": "UNUSED", + "NATIVE": "NATIVE", +} + +# ── BMC VLAN definitions (hardcoded for POC — DC4) ─────────────────────── +# These are the VLANs that every BMC switch gets, regardless of vendor. +# Consistent for all vendors since BMC is lab-internal. +BMC_HARDCODED_VLANS: list[dict] = [ + {"vlan_id": 2, "name": "UNUSED_VLAN", "shutdown": True}, + {"vlan_id": 99, "name": "NATIVE_VLAN"}, +] +# BMC-relevant supernet group prefixes (additional VLANs pulled from input) +BMC_RELEVANT_GROUPS: list[str] = ["BMC", "UNUSED", "NATIVE"] + +# ── IP map key prefixes (used by _build_ip_mapping) ────────────────────── +# These are assembled at runtime as e.g. "P2P_BORDER1_TOR1", "LOOPBACK0_TOR2" +IP_PREFIX_P2P_BORDER1 = "P2P_BORDER1" +IP_PREFIX_P2P_BORDER2 = "P2P_BORDER2" +IP_PREFIX_LOOPBACK0 = "LOOPBACK0" +IP_PREFIX_P2P_IBGP = "P2P_IBGP" + +# ── In-code JSON templates (never mutate — always deepcopy) ────────────── + +SWITCH_TEMPLATE: dict = { + "make": "", + "model": "", + "type": "", + "hostname": "", + "version": "", + "firmware": "", + "site": "", +} + +SVI_TEMPLATE: dict = { + "ip": "", + "cidr": 0, + "mtu": JUMBO_MTU, + "redundancy": { + "type": "", + "group": 0, + "priority": 0, + "virtual_ip": "", + }, +} + +VLAN_TEMPLATE: dict = { + "vlan_id": 0, + "name": "", +} diff --git a/src/convertors/__init__.py b/src/convertors/__init__.py index 806f1d9..21bf1d5 100644 --- a/src/convertors/__init__.py +++ b/src/convertors/__init__.py @@ -1,34 +1,23 @@ """ -Convertors Package - Static Registry Pattern +Convertors Package — Static Registry Pattern -This package contains convertor modules that transform various input formats -into the standardized JSON format used by the network config generator. - -All convertors are statically imported here so PyInstaller can detect them +All convertors are statically imported so PyInstaller can detect them without needing hooks or hidden imports. - -Available convertors: -- convertors_lab_switch_json: Converts lab-style input JSON to standard format -- convertors_bmc_switch_json: Converts BMC switch definitions to standard format """ -# Static imports - PyInstaller can detect these automatically from .convertors_lab_switch_json import convert_switch_input_json as convert_lab_switches from .convertors_bmc_switch_json import convert_bmc_switches # Registry mapping convertor names to functions -# This allows main.py to use registry lookup instead of dynamic imports CONVERTORS = { - # Primary convertor names (for backward compatibility) + # Primary convertor names (backward compatible) 'convertors.convertors_lab_switch_json': convert_lab_switches, 'convertors.convertors_bmc_switch_json': convert_bmc_switches, - - # Short aliases for convenience + # Short aliases 'lab': convert_lab_switches, 'bmc': convert_bmc_switches, } -# Export public API __all__ = [ 'CONVERTORS', 'convert_lab_switches', diff --git a/src/convertors/convertors_bmc_switch_json.py b/src/convertors/convertors_bmc_switch_json.py index 5a33878..4b74afb 100644 --- a/src/convertors/convertors_bmc_switch_json.py +++ b/src/convertors/convertors_bmc_switch_json.py @@ -1,313 +1,185 @@ """ BMC Switch JSON Converter -This module handles the conversion of BMC switch definitions from lab input JSON -to standardized JSON format. It's designed to be called from the main converter -but kept separate for modularity and easy maintenance. +Converts BMC switch definitions from lab input JSON to standardised JSON format. +Called from the main TOR converter but kept separate for modularity. Since BMC switches are for internal lab use only, some configurations are hardcoded -for simplicity and can be refined as needed. +for simplicity (see DC4 decision) and can be refined later. """ +from __future__ import annotations + import json +import logging +from copy import deepcopy from pathlib import Path from typing import Dict, List -from copy import deepcopy -# Import constants from main converter -try: - from .convertors_lab_switch_json import ( - DEFAULT_OUTPUT_DIR, OUTPUT_FILE_EXTENSION, BMC, CISCO, DELL, NXOS, OS10, JUMBO_MTU - ) - from ..loader import get_real_path -except ImportError: - # Fallback constants if main converter is not available - DEFAULT_OUTPUT_DIR = "_output" - OUTPUT_FILE_EXTENSION = ".json" - BMC = "BMC" - CISCO = "cisco" - DELL = "dellemc" - NXOS = "nxos" - OS10 = "os10" - JUMBO_MTU = 9216 - - def get_real_path(path): - return Path(path) +from ..loader import get_real_path +from ..constants import ( + DEFAULT_OUTPUT_DIR, OUTPUT_FILE_EXTENSION, + BMC, JUMBO_MTU, + BMC_HARDCODED_VLANS, BMC_RELEVANT_GROUPS, +) +from ..utils import infer_firmware + +logger = logging.getLogger(__name__) class BMCSwitchConverter: - """ - Dedicated converter for BMC switches. - Handles the generation of standardized JSON configuration for BMC switches. - """ - + """Dedicated converter for BMC switches.""" + def __init__(self, input_data: Dict, output_dir: str = DEFAULT_OUTPUT_DIR): - """ - Initialize BMC converter with input data and output directory. - - Args: - input_data: Dictionary containing the lab definition JSON - output_dir: Directory where output files will be written - """ self.input_data = input_data self.output_dir = Path(output_dir) self.output_dir.mkdir(exist_ok=True, parents=True) - + + # ── public API ──────────────────────────────────────────────────────── + def convert_all_bmc_switches(self) -> None: - """ - Convert all BMC switches found in the input data to standard JSON format. - """ + """Convert every BMC switch found in the input data.""" switches_json = self.input_data.get("InputData", {}).get("Switches", []) bmc_switches = [sw for sw in switches_json if sw.get("Type") == BMC] - + if not bmc_switches: - print("[i] No BMC switches found in input data") + logger.info("No BMC switches found in input data") return - - print(f"[*] Found {len(bmc_switches)} BMC switch(es) to convert") - + + logger.info("Found %d BMC switch(es) to convert", len(bmc_switches)) + for bmc_switch in bmc_switches: self._convert_single_bmc(bmc_switch) - - print(f"[✓] BMC conversion completed - {len(bmc_switches)} switch(es) processed") - + + logger.info("BMC conversion completed — %d switch(es) processed", len(bmc_switches)) + + # ── private helpers ─────────────────────────────────────────────────── + def _convert_single_bmc(self, switch_data: Dict) -> None: - """ - Convert a single BMC switch to standard JSON format. - - Args: - switch_data: Dictionary containing BMC switch information - """ - # Build switch metadata switch_info = self._build_switch_info(switch_data) - - # Build configuration sections vlans = self._build_vlans() interfaces = self._build_interfaces(switch_data) - - # Assemble final JSON structure (BMC only needs switch, vlans, interfaces) - bmc_json = { + + bmc_json: dict = { "switch": switch_info, "vlans": vlans, - "interfaces": interfaces + "interfaces": interfaces, } - - # Write output file + hostname = switch_info.get("hostname", "bmc") output_file = self.output_dir / f"{hostname}{OUTPUT_FILE_EXTENSION}" - - with output_file.open("w", encoding="utf-8") as f: - json.dump(bmc_json, f, indent=2) - - print(f"[✓] Generated BMC config: {output_file}") - - def _build_switch_info(self, switch_data: Dict) -> Dict: - """ - Build the switch metadata section. - - Args: - switch_data: Dictionary containing switch information - - Returns: - Dictionary with switch metadata - """ + output_file.write_text(json.dumps(bmc_json, indent=2), encoding="utf-8") + logger.info("Generated BMC config: %s", output_file) + + # -- switch metadata --------------------------------------------------- + + @staticmethod + def _build_switch_info(switch_data: Dict) -> Dict: sw_make = switch_data.get("Make", "").lower() - - # Determine firmware based on make - firmware = ( - NXOS if sw_make == CISCO else - OS10 if sw_make == DELL else - switch_data.get("Firmware", "").lower() - ) - return { "make": sw_make, "model": switch_data.get("Model", "").lower(), "type": switch_data.get("Type"), "hostname": switch_data.get("Hostname", "").lower(), "version": switch_data.get("Firmware", "").lower(), - "firmware": firmware + "firmware": infer_firmware(sw_make), } - + + # -- VLANs ------------------------------------------------------------- + def _build_vlans(self) -> List[Dict]: + """Build VLAN list. + + Starts with the hardcoded BMC VLANs (DC4), then appends any extra + BMC-relevant VLANs found in the Supernets section. """ - Build VLAN configuration for BMC switch. - Extracts BMC-relevant VLANs from the supernets definition. - - Returns: - List of VLAN dictionaries - """ - vlans_out = [] - - # Always add VLAN 2 (UNUSED_VLAN) for BMC switches - hardcoded requirement (shutdown) - vlans_out.append({ - "vlan_id": 2, - "name": "UNUSED_VLAN", - "shutdown": True - }) - - # Always add VLAN 7 (Infra_7) for BMC switches - hardcoded requirement - vlans_out.append({ - "vlan_id": 7, - "name": "Infra_7" - }) - + # Start with hardcoded VLANs (deep-copied to avoid mutation) + vlans_out: list[dict] = [deepcopy(v) for v in BMC_HARDCODED_VLANS] + hardcoded_ids = {v["vlan_id"] for v in BMC_HARDCODED_VLANS} + supernets = self.input_data.get("InputData", {}).get("Supernets", []) - + for net in supernets: group_name = net.get("GroupName", "").upper() ipv4 = net.get("IPv4", {}) vlan_id = ipv4.get("VlanId") or ipv4.get("VLANID") or 0 - - if vlan_id == 0: + + if vlan_id == 0 or vlan_id in hardcoded_ids: continue - - # Skip VLAN 2 and VLAN 7 since they're already hardcoded above - if vlan_id == 2 or vlan_id == 7: + + if not self._is_bmc_relevant_vlan(group_name): continue - - # Only include BMC-relevant VLANs (can be customized) - if self._is_bmc_relevant_vlan(group_name): - vlan_entry = { - "vlan_id": vlan_id, - "name": ipv4.get("Name", f"VLAN_{vlan_id}") - } - - # Add interface configuration for management VLANs - if group_name.startswith("BMC") and ipv4.get("SwitchSVI", False): - # For BMC, we need to determine the correct IP address - gateway_ip = ipv4.get("Gateway", "") - - # Based on your manual JSON, BMC gets a different IP than gateway - # This logic can be refined based on your requirements - if gateway_ip: - # Parse IP and calculate BMC switch IP (e.g., gateway + 60) - import ipaddress - try: - network = ipaddress.IPv4Network(f"{ipv4.get('Network')}/{ipv4.get('Cidr', 24)}", strict=False) - gateway = ipaddress.IPv4Address(gateway_ip) - # Calculate BMC switch IP (using last available IP in range) - bmc_ip = str(network.broadcast_address - 1) - except: - bmc_ip = gateway_ip # Fallback to gateway - else: - bmc_ip = "" - - interface = { + + vlan_entry: dict = { + "vlan_id": vlan_id, + "name": ipv4.get("Name", f"VLAN_{vlan_id}"), + } + + # Add SVI for management VLANs that declare a gateway + if group_name.startswith("BMC") and ipv4.get("SwitchSVI", False): + import ipaddress + gateway_ip = ipv4.get("Gateway", "") + if gateway_ip: + try: + network = ipaddress.IPv4Network( + f"{ipv4.get('Network')}/{ipv4.get('Cidr', 24)}", strict=False + ) + bmc_ip = str(network.broadcast_address - 1) + except (ValueError, TypeError): + bmc_ip = gateway_ip + else: + bmc_ip = "" + + if bmc_ip: + vlan_entry["interface"] = { "ip": bmc_ip, "cidr": ipv4.get("Cidr", 24), - "mtu": JUMBO_MTU - # Note: No redundancy (HSRP/VRRP) for BMC switches + "mtu": JUMBO_MTU, } - if interface["ip"]: # Only add if IP is present - vlan_entry["interface"] = interface - - vlans_out.append(vlan_entry) - + + vlans_out.append(vlan_entry) + return sorted(vlans_out, key=lambda v: v["vlan_id"]) - - def _is_bmc_relevant_vlan(self, group_name: str) -> bool: - """ - Determine if a VLAN is relevant for BMC switches. - - Args: - group_name: VLAN group name from supernets - - Returns: - True if VLAN is relevant for BMC - """ - bmc_relevant_prefixes = ["BMC", "UNUSED", "NATIVE"] - return any(group_name.startswith(prefix) for prefix in bmc_relevant_prefixes) - + + @staticmethod + def _is_bmc_relevant_vlan(group_name: str) -> bool: + return any(group_name.startswith(prefix) for prefix in BMC_RELEVANT_GROUPS) + + # -- interfaces -------------------------------------------------------- + def _build_interfaces(self, switch_data: Dict) -> List[Dict]: - """ - Build interface configuration for BMC switch using template files only. - No hardcoded interfaces - everything comes from templates. - - Args: - switch_data: Dictionary containing switch information - - Returns: - List of interface dictionaries - """ + """Load interfaces from the model-specific template file.""" make = switch_data.get("Make", "").lower() model = switch_data.get("Model", "").upper() - - # Load interface template for BMC switch - template_relative = Path("input") / "switch_interface_templates" / make / f"{model}.json" - - # Try multiple path resolution strategies - import sys - if getattr(sys, 'frozen', False): - # Running as PyInstaller bundle - use _MEIPASS - base_path = Path(sys._MEIPASS) - template_path = base_path / template_relative - else: - # Running as script - try both current directory and parent directory - template_path = template_relative.resolve() - if not template_path.exists(): - # Try from parent directory (in case we're running from src/) - template_path = (Path("..") / template_relative).resolve() - + + template_path = get_real_path( + Path("input/switch_interface_templates") / make / f"{model}.json" + ) + if not template_path.exists(): - import sys - debug_info = f"sys.frozen={getattr(sys, 'frozen', False)}, sys._MEIPASS={getattr(sys, '_MEIPASS', 'N/A')}" raise FileNotFoundError( - f"[!] BMC interface template not found!\n" - f" Looking for model: {model} (make: {make})\n" - f" Relative path: {template_relative}\n" - f" Resolved path: {template_path}\n" - f" File exists: {template_path.exists()}\n" - f" Debug: {debug_info}" + f"BMC interface template not found: {template_path} " + f"(model={model}, make={make})" ) - + try: - with open(template_path) as f: - template_data = json.load(f) - - # Extract common interfaces from template - common_templates = template_data.get("interface_templates", {}).get("common", []) - - if not common_templates: - raise ValueError(f"[!] No common interfaces found in template: {template_path}") - - interfaces = [] - for template in common_templates: - # Deep copy to avoid modifying original template - interface = deepcopy(template) - interfaces.append(interface) - - print(f"[✓] Loaded BMC interface template: {template_path}") - return interfaces - - except (json.JSONDecodeError, KeyError) as e: - raise RuntimeError(f"[!] Error loading BMC template {template_path}: {e}") - except Exception as e: - raise RuntimeError(f"[!] Unexpected error loading BMC template {template_path}: {e}") + with template_path.open() as fh: + template_data = json.load(fh) + except json.JSONDecodeError as exc: + raise RuntimeError(f"Invalid JSON in BMC template {template_path}: {exc}") from exc + + common_templates = template_data.get("interface_templates", {}).get("common", []) + if not common_templates: + raise ValueError(f"No common interfaces found in template: {template_path}") + logger.info("Loaded BMC interface template: %s", template_path) + return [deepcopy(t) for t in common_templates] + + +# ── Module-level convenience function ────────────────────────────────────── def convert_bmc_switches(input_data: Dict, output_dir: str = DEFAULT_OUTPUT_DIR) -> None: - """ - Main function to convert BMC switches from lab definition to standard JSON. - This function can be called from the main converter. - - Args: - input_data: Dictionary containing the lab definition JSON - output_dir: Directory where output files will be written - """ + """Entry point called from the TOR converter to process BMC switches.""" converter = BMCSwitchConverter(input_data, output_dir) converter.convert_all_bmc_switches() - -# Example usage for testing -if __name__ == "__main__": - # This allows the module to be run standalone for testing - import sys - if len(sys.argv) > 1: - input_file = sys.argv[1] - with open(input_file, 'r') as f: - test_data = json.load(f) - convert_bmc_switches(test_data) - else: - print("❌ Error: Missing input file!") - print("💡 This script converts BMC switch definitions from lab input JSON to standardized format.") diff --git a/src/convertors/convertors_lab_switch_json.py b/src/convertors/convertors_lab_switch_json.py index 7026eba..9329f18 100644 --- a/src/convertors/convertors_lab_switch_json.py +++ b/src/convertors/convertors_lab_switch_json.py @@ -1,18 +1,40 @@ +""" +Lab-format → Standard JSON converter for TOR switches. + +Reads an Azure Stack lab definition JSON, extracts per-switch data for each +TOR (TOR1, TOR2), resolves VLANs/IPs from Supernets, loads model-specific +interface templates, and writes one standard JSON per switch. Also triggers +the BMC converter if available. +""" + import json +import logging from copy import deepcopy from pathlib import Path from collections import defaultdict # IMPORTANT: Unconditional import for PyInstaller detection # PyInstaller's static analysis needs to see this import at module level without any conditionals -from . import convertors_bmc_switch_json - -try: - from ..loader import get_real_path # package style -except ImportError: - from loader import get_real_path # fallback script style - -# Import BMC converter function with fallback handling +from . import convertors_bmc_switch_json # noqa: F401 + +from ..loader import get_real_path +from ..constants import ( + TOR1, TOR2, BMC, + CISCO, DELL, NXOS, OS10, + DEFAULT_OUTPUT_DIR, OUTPUT_FILE_EXTENSION, + JUMBO_MTU, + HSRP, VRRP, + REDUNDANCY_PRIORITY_ACTIVE, REDUNDANCY_PRIORITY_STANDBY, + TOR_SWITCH_TYPES, + PATTERN_HYPERCONVERGED, PATTERN_FULLY_CONVERGED, + PATTERN_FULLY_CONVERGED1, PATTERN_FULLY_CONVERGED2, + SWITCH_TEMPLATE, SVI_TEMPLATE, VLAN_TEMPLATE, + IP_PREFIX_P2P_BORDER1, IP_PREFIX_P2P_BORDER2, + IP_PREFIX_LOOPBACK0, IP_PREFIX_P2P_IBGP, +) +from ..utils import infer_firmware, classify_vlan_group + +# Import BMC converter function try: from .convertors_bmc_switch_json import convert_bmc_switches _bmc_available = True @@ -20,55 +42,7 @@ convert_bmc_switches = None _bmc_available = False -# ── Static config ───────────────────────────────────────────────────────── -SWITCH_TYPES = ["TOR1", "TOR2"] -TOR1, TOR2 = "TOR1", "TOR2" -BMC = "BMC" - -CISCO, NXOS = "cisco", "nxos" -DELL, OS10 = "dellemc", "os10" - -OUTPUT_FILE_EXTENSION = ".json" -DEFAULT_OUTPUT_DIR = "output" - -JUMBO_MTU = 9216 -REDUNDANCY_PRIORITY_ACTIVE = 150 -REDUNDANCY_PRIORITY_STANDBY = 140 -HSRP = "hsrp" -VRRP = "vrrp" - -UNUSED_VLAN = "UNUSED_VLAN" -NATIVE_VLAN = "NATIVE_VLAN" - - -# ── In-code templates (never mutate these!) ─────────────────────────────── -SWITCH_TEMPLATE = { - "make" : "", - "model" : "", - "type" : "", - "hostname": "", - "version" : "", - "firmware": "", - "site" : "" -} - -SVI_TEMPLATE = { - "ip" : "", - "cidr" : 0, - "mtu" : JUMBO_MTU, - "redundancy": { # this whole block is removed for BMC - "type" : "", - "group" : 0, - "priority" : 0, - "virtual_ip": "" - } -} - -VLAN_TEMPLATE = { - "vlan_id" : 0, - "name" : "", - # "interface" key is added later only if needed -} +logger = logging.getLogger(__name__) # ── Builder class ───────────────────────────────────────────────────────── class StandardJSONBuilder: @@ -85,8 +59,8 @@ def __init__(self, input_data: dict): self.original_pattern = self.deployment_pattern # Initial translation for template compatibility - if self.deployment_pattern == "hyperconverged": - self.deployment_pattern = "fully_converged" + if self.deployment_pattern == PATTERN_HYPERCONVERGED: + self.deployment_pattern = PATTERN_FULLY_CONVERGED # ------------------------------------------------------------------ # # Build switch section @@ -111,11 +85,7 @@ def build_switch(self, switch_type: str): continue sw_make = sw.get("Make", "").lower() - firmware = ( - NXOS if sw_make == CISCO else - OS10 if sw_make == DELL else - sw.get("Firmware", "").lower() - ) + firmware = infer_firmware(sw_make) sw_entry = deepcopy(SWITCH_TEMPLATE) sw_entry.update( @@ -131,7 +101,7 @@ def build_switch(self, switch_type: str): self.sections["switch"][sw_type] = sw_entry if not self.sections["switch"]: - print("[!] No valid switches found in input.") + logger.warning("No valid switches found in input.") # ------------------------------------------------------------------ # # Build VLAN section @@ -149,21 +119,10 @@ def build_vlans(self, switch_type: str): if vlan_id == 0: continue # skip invalid IDs - # Construct M,C,S Mapping, GroupName hardcode defined - if group_name.startswith("HNVPA"): - self.vlan_map["C"].append(vlan_id) - elif group_name.startswith("INFRA"): - self.vlan_map["M"].append(vlan_id) - elif group_name.startswith("TENANT"): - self.vlan_map["C"].append(vlan_id) - elif group_name.startswith("L3FORWARD"): - self.vlan_map["C"].append(vlan_id) - elif group_name.startswith("STORAGE"): - self.vlan_map["S"].append(vlan_id) - elif group_name.startswith("UNUSED"): - self.vlan_map["UNUSED"].append(vlan_id) - elif group_name.startswith("NATIVE"): - self.vlan_map["NATIVE"].append(vlan_id) + # Classify VLAN into symbolic sets using shared utility + symbol = classify_vlan_group(group_name) + if symbol: + self.vlan_map[symbol].append(vlan_id) # collect TOR1 and TOR2 specific storage VLANs if vlan_name.endswith(TOR1): self.vlan_map["S1"].append(vlan_id) @@ -218,7 +177,7 @@ def build_vlans(self, switch_type: str): self.sections["vlans"] = sorted(vlans_out, key=lambda v: v["vlan_id"]) if not self.sections["vlans"]: - print(f"[!] No VLANs produced for {switch_type}") + logger.warning("No VLANs produced for %s", switch_type) # ------------------------------------------------------------------ # # Build interface and port-channels section @@ -229,7 +188,7 @@ def build_interfaces(self, switch_type: str): """ switch = self.sections["switch"].get(switch_type) if not switch: - print(f"[!] No switch of type {switch_type} found for interface build.") + logger.warning("No switch of type %s found for interface build.", switch_type) return make = switch.get("make", "").lower() @@ -255,7 +214,7 @@ def _build_interfaces_from_template(self, switch_type: str, template_data: dict) # Smart template selection for HyperConverged deployments effective_pattern = self.deployment_pattern - if self.original_pattern == "hyperconverged" and self.deployment_pattern == "fully_converged": + if self.original_pattern == PATTERN_HYPERCONVERGED and self.deployment_pattern == PATTERN_FULLY_CONVERGED: # Check which VLAN sets are available has_m = bool(self.vlan_map.get("M", [])) has_c = bool(self.vlan_map.get("C", [])) @@ -263,11 +222,11 @@ def _build_interfaces_from_template(self, switch_type: str, template_data: dict) # If only M exists (no C or S), use fully_converged2 (Access mode) if has_m and not has_c and not has_s: - effective_pattern = "fully_converged2" - print(f"[INFO] Using fully_converged2 template (Access mode) - only Infrastructure VLANs detected") + effective_pattern = PATTERN_FULLY_CONVERGED2 + logger.info("Using fully_converged2 template (Access mode) - only Infrastructure VLANs detected") # Otherwise use fully_converged (Trunk mode with M,C,S) else: - effective_pattern = "fully_converged1" + effective_pattern = PATTERN_FULLY_CONVERGED1 pattern_templates = templates.get(effective_pattern, []) @@ -306,35 +265,33 @@ def _build_ip_mapping(self): first_ip = ipv4.get("FirstAddress", "") last_ip = ipv4.get("LastAddress", "") - if group_name.startswith("HNVPA"): + # Classify using shared utility for standard groups + symbol = classify_vlan_group(group_name) + if symbol == "C" and group_name.startswith("HNVPA"): self.ip_map["HNVPA"].append(ip_subnet) - elif group_name.startswith("INFRA"): + elif symbol == "M": self.ip_map["M"].append(ip_subnet) - elif group_name.startswith("TENANT"): + elif symbol == "C": self.ip_map["C"].append(ip_subnet) - elif group_name.startswith("L3FORWARD"): - self.ip_map["C"].append(ip_subnet) - elif vlan_name.endswith(TOR1) and vlan_name.startswith("P2P_BORDER1"): - self.ip_map["P2P_BORDER1_TOR1"].append(f"{last_ip}/{cidr}") - self.ip_map["P2P_TOR1_BORDER1"].append(f"{first_ip}") - elif vlan_name.endswith(TOR1) and vlan_name.startswith("P2P_BORDER2"): - self.ip_map["P2P_BORDER2_TOR1"].append(f"{last_ip}/{cidr}") - self.ip_map["P2P_TOR1_BORDER2"].append(f"{first_ip}") - elif vlan_name.endswith(TOR2) and vlan_name.startswith("P2P_BORDER1"): - self.ip_map["P2P_BORDER1_TOR2"].append(f"{last_ip}/{cidr}") - self.ip_map["P2P_TOR2_BORDER1"].append(f"{first_ip}") - elif vlan_name.endswith(TOR2) and vlan_name.startswith("P2P_BORDER2"): - self.ip_map["P2P_BORDER2_TOR2"].append(f"{last_ip}/{cidr}") - self.ip_map["P2P_TOR2_BORDER2"].append(f"{first_ip}") + elif vlan_name.endswith(TOR1) and vlan_name.startswith(IP_PREFIX_P2P_BORDER1): + self.ip_map[f"{IP_PREFIX_P2P_BORDER1}_{TOR1}"].append(f"{last_ip}/{cidr}") + self.ip_map[f"P2P_{TOR1}_BORDER1"].append(f"{first_ip}") + elif vlan_name.endswith(TOR1) and vlan_name.startswith(IP_PREFIX_P2P_BORDER2): + self.ip_map[f"{IP_PREFIX_P2P_BORDER2}_{TOR1}"].append(f"{last_ip}/{cidr}") + self.ip_map[f"P2P_{TOR1}_BORDER2"].append(f"{first_ip}") + elif vlan_name.endswith(TOR2) and vlan_name.startswith(IP_PREFIX_P2P_BORDER1): + self.ip_map[f"{IP_PREFIX_P2P_BORDER1}_{TOR2}"].append(f"{last_ip}/{cidr}") + self.ip_map[f"P2P_{TOR2}_BORDER1"].append(f"{first_ip}") + elif vlan_name.endswith(TOR2) and vlan_name.startswith(IP_PREFIX_P2P_BORDER2): + self.ip_map[f"{IP_PREFIX_P2P_BORDER2}_{TOR2}"].append(f"{last_ip}/{cidr}") + self.ip_map[f"P2P_{TOR2}_BORDER2"].append(f"{first_ip}") elif vlan_name.endswith(TOR1) and vlan_name.startswith("LOOPBACK"): - self.ip_map["LOOPBACK0_TOR1"].append(ip_subnet) - elif vlan_name.endswith(TOR2) and vlan_name.startswith("LOOPBACK"): - self.ip_map["LOOPBACK0_TOR2"].append(ip_subnet) + self.ip_map[f"{IP_PREFIX_LOOPBACK0}_{TOR1}"].append(ip_subnet) elif vlan_name.endswith(TOR2) and vlan_name.startswith("LOOPBACK"): - self.ip_map["LOOPBACK0_TOR2"].append(ip_subnet) - elif vlan_name.startswith("P2P_IBGP"): - self.ip_map["P2P_IBGP_TOR1"].append(first_ip) - self.ip_map["P2P_IBGP_TOR2"].append(last_ip) + self.ip_map[f"{IP_PREFIX_LOOPBACK0}_{TOR2}"].append(ip_subnet) + elif vlan_name.startswith(IP_PREFIX_P2P_IBGP): + self.ip_map[f"{IP_PREFIX_P2P_IBGP}_{TOR1}"].append(first_ip) + self.ip_map[f"{IP_PREFIX_P2P_IBGP}_{TOR2}"].append(last_ip) def _process_interface_template(self , switch_type: str, template: dict) -> dict: """ @@ -460,7 +417,7 @@ def build_bgp(self, switch_type: str): import ipaddress switch = self.sections["switch"].get(switch_type) if not switch: - print(f"[!] No switch info for BGP") + logger.warning("No switch info for BGP") return # Build networks list using subnet prefixes @@ -600,24 +557,14 @@ def build_qos(self): self.sections["qos"] = True - # ------------------------------------------------------------------ # - # Generate all sections for a specific switch type - def generate_for_switch(self, switch_type): - self.build_switch(switch_type) - self.build_vlans(switch_type) - self.build_interfaces(switch_type) - return self.sections - - - # ── Helper to create per-switch JSON files ──────────────────────────────── -def convert_switch_input_json(input_data: dict, output_dir: str = DEFAULT_OUTPUT_DIR): +def convert_switch_input_json(input_data: dict, output_dir: str = DEFAULT_OUTPUT_DIR, *, debug: bool = False): out_path = Path(output_dir) out_path.mkdir(exist_ok=True, parents=True) builder = StandardJSONBuilder(input_data) - for sw_type in SWITCH_TYPES: + for sw_type in TOR_SWITCH_TYPES: builder.sections = {} # reset between runs builder.build_switch(sw_type) builder.build_vlans(sw_type) @@ -628,7 +575,7 @@ def convert_switch_input_json(input_data: dict, output_dir: str = DEFAULT_OUTPUT s_vlans = builder.vlan_map.get("S", []) s1_vlans = builder.vlan_map.get("S1", []) s2_vlans = builder.vlan_map.get("S2", []) - print(f"[DEBUG] VLAN sets for {sw_type}: M={m_vlans} C={c_vlans} S={s_vlans} S1={s1_vlans} S2={s2_vlans}") + logger.debug("VLAN sets for %s: M=%s C=%s S=%s S1=%s S2=%s", sw_type, m_vlans, c_vlans, s_vlans, s1_vlans, s2_vlans) # Validation: Check VLAN requirements based on deployment pattern missing_critical = [] @@ -636,14 +583,14 @@ def convert_switch_input_json(input_data: dict, output_dir: str = DEFAULT_OUTPUT missing_critical.append("M") # For HyperConverged: allow M-only (uses fully_converged2/Access mode) or M+C+S (uses fully_converged1/Trunk mode) - is_hyperconverged = builder.original_pattern == "hyperconverged" + is_hyperconverged = builder.original_pattern == PATTERN_HYPERCONVERGED has_c = bool(c_vlans) has_s = bool(s_vlans) or bool(s1_vlans) or bool(s2_vlans) if is_hyperconverged: # HyperConverged: M-only is valid (Access mode), or require full M+C for Trunk mode if m_vlans and not has_c and not has_s: - print(f"[INFO] HyperConverged deployment with M-only: using Access mode (fully_converged2)") + logger.info("HyperConverged deployment with M-only: using Access mode (fully_converged2)") elif not has_c: missing_critical.append("C") else: @@ -661,7 +608,7 @@ def convert_switch_input_json(input_data: dict, output_dir: str = DEFAULT_OUTPUT ) if not s_vlans and not s1_vlans and not s2_vlans: - print(f"[WARN] Storage VLAN set S is empty for {sw_type}; proceeding without storage tagging.") + logger.warning("Storage VLAN set S is empty for %s; proceeding without storage tagging.", sw_type) builder.build_interfaces(sw_type) # Per-interface VLAN security belt: ensure required VLAN values resolved @@ -686,7 +633,7 @@ def convert_switch_input_json(input_data: dict, output_dir: str = DEFAULT_OUTPUT raise ValueError(f"Port-channel '{desc}' missing native_vlan. Define native VLAN or remove trunk type.") # tagged_vlans may be intentionally empty (e.g., only native) so only warn if not str(pc.get("tagged_vlans", "")).strip(): - print(f"[WARN] Port-channel '{desc}' has no tagged_vlans; only native VLAN will be carried.") + logger.warning("Port-channel '%s' has no tagged_vlans; only native VLAN will be carried.", desc) builder.build_bgp(sw_type) builder.build_prefix_lists() builder.build_qos() @@ -704,7 +651,11 @@ def convert_switch_input_json(input_data: dict, output_dir: str = DEFAULT_OUTPUT "bgp": builder.sections["bgp"], "prefix_lists": builder.sections["prefix_lists"], "qos": builder.sections["qos"], - "debug": { + } + + # Only include debug data when explicitly requested (DC3) + if debug: + final_json["debug"] = { "vlan_map": dict(builder.vlan_map), "ip_map": dict(builder.ip_map), "resolved_trunks": [ @@ -717,35 +668,16 @@ def convert_switch_input_json(input_data: dict, output_dir: str = DEFAULT_OUTPUT if iface.get("type") == "Trunk" ] } - } out_file = out_path / f"{hostname}{OUTPUT_FILE_EXTENSION}" with out_file.open("w", encoding="utf-8") as f: json.dump(final_json, f, indent=2) - print(f"[✓] Wrote {out_file}") + logger.info("Wrote %s", out_file) # Convert BMC switches using the module-level import if _bmc_available and convert_bmc_switches: try: convert_bmc_switches(input_data, output_dir) except Exception as e: - print(f"[!] Error converting BMC switches: {e}") - import traceback - traceback.print_exc() - else: - print(f"[!] BMC converter not available - module not imported") - - -def convert_all_switches_json(input_data: dict, output_dir: str = DEFAULT_OUTPUT_DIR): - """ - Convert all switches (ToRs and BMC) to standard JSON format. - This function calls both ToR and BMC conversion functions. - """ - print("[*] Converting ToR switches...") - convert_switch_input_json(input_data, output_dir) - - # BMC converter already called within convert_switch_input_json - # No need to call again here to avoid duplicate conversion - print("[✓] All switch conversions completed.") - + logger.error("Error converting BMC switches: %s", e) diff --git a/src/generator.py b/src/generator.py index 0bb44b5..07287dd 100644 --- a/src/generator.py +++ b/src/generator.py @@ -1,66 +1,81 @@ +""" +Config generator — renders Jinja2 templates against a standard-format JSON. +""" + +from __future__ import annotations + +import logging from pathlib import Path -# Support both execution as part of the 'src' package (python -m src.main) and -# direct script execution (python src/main.py) by attempting relative import first. -try: # package style - from .loader import load_input_json, load_template # type: ignore -except ImportError: # fallback to script style - from loader import load_input_json, load_template # type: ignore -import os -import warnings - -def generate_config(input_std_json, template_folder, output_folder): - input_std_json_path = Path(input_std_json).resolve() - template_folder_path = Path(template_folder) # already resolved by main.py - output_folder_path = Path(output_folder).resolve() - - # ✅ Step 1: Validate input JSON - if not input_std_json_path.exists(): - raise FileNotFoundError(f"[ERROR] Input JSON not found: {input_std_json_path}") - - data = load_input_json(str(input_std_json_path)) - if data is None: - raise ValueError(f"[ERROR] Input JSON was empty or failed to parse: {input_std_json_path}") - - # ✅ Step 2: Extract metadata +from .loader import load_input_json, load_template + +logger = logging.getLogger(__name__) + + +def generate_config( + input_std_json: str | Path, + template_folder: str | Path, + output_folder: str | Path, +) -> None: + """Render every ``.j2`` template in the vendor/firmware subfolder. + + Parameters + ---------- + input_std_json: + Path to a standard-format JSON file (one switch). + template_folder: + Root folder containing ``//*.j2`` templates. + output_folder: + Directory where ``generated_.cfg`` files are written. + + Raises + ------ + FileNotFoundError + If the input JSON, template folder, or vendor subfolder is missing. + ValueError + If required switch metadata is absent or JSON cannot be parsed. + RuntimeError + If a template fails to render. + """ + input_path = Path(input_std_json).resolve() + template_root = Path(template_folder) + output_path = Path(output_folder).resolve() + + if not input_path.exists(): + raise FileNotFoundError(f"Input JSON not found: {input_path}") + + data = load_input_json(input_path) + + # Extract vendor routing info try: make = data["switch"]["make"].lower() firmware = data["switch"]["firmware"].lower() - version = data["switch"].get("version", "").lower() # Optional, not currently used - except KeyError as e: - raise ValueError(f"[ERROR] Missing expected switch metadata: {e}") + except KeyError as exc: + raise ValueError(f"Missing expected switch metadata key: {exc}") from exc - # ✅ Step 3: Resolve template subfolder - template_dir = template_folder_path / make / firmware - print(f"[INFO] Looking for templates in: {template_dir}") + template_dir = template_root / make / firmware + logger.info("Looking for templates in: %s", template_dir) if not template_dir.exists(): - raise FileNotFoundError(f"[ERROR] Template path not found: {template_dir}") + raise FileNotFoundError(f"Template path not found: {template_dir}") template_files = sorted(template_dir.glob("*.j2")) if not template_files: - raise FileNotFoundError(f"[WARN] No templates found in: {template_dir}") + raise FileNotFoundError(f"No .j2 templates found in: {template_dir}") - print(f"[INFO] Rendering {len(template_files)} templates (compact mode)") + logger.info("Rendering %d template(s)", len(template_files)) - # ✅ Step 4: Render each template (compact single-line logging) - os.makedirs(output_folder_path, exist_ok=True) + output_path.mkdir(parents=True, exist_ok=True) - for template_path in template_files: - template_name = template_path.name - stem = template_path.stem - try: - template = load_template(str(template_dir), template_name) - rendered = template.render(data) + for tpl_path in template_files: + template = load_template(str(template_dir), tpl_path.name) + rendered = template.render(data) - if not rendered.strip(): - print(f"[–] {template_name}: skipped (empty)") - continue + if not rendered.strip(): + logger.debug("Template %s produced empty output — skipped", tpl_path.name) + continue - output_file = output_folder_path / f"generated_{stem}.cfg" - with open(output_file, "w", encoding="utf-8") as f: - f.write(rendered) - print(f"[✓] {template_name} -> {output_file.name}") - except Exception as e: - warnings.warn(f"[!] {template_name} failed: {e}", UserWarning) + out_file = output_path / f"generated_{tpl_path.stem}.cfg" + out_file.write_text(rendered, encoding="utf-8") + logger.info("[OK] %s -> %s", tpl_path.name, out_file.name) - print(f"\n=== Done generating for: {input_std_json_path.name} ===\n") + logger.info("Done generating for: %s", input_path.name) diff --git a/src/loader.py b/src/loader.py index b27b7b0..f8c5740 100644 --- a/src/loader.py +++ b/src/loader.py @@ -1,56 +1,64 @@ +""" +File loading utilities for the AzureStack Network Switch Config Generator. + +Provides path resolution (PyInstaller-aware), JSON loading, and Jinja2 +template loading. +""" + +from __future__ import annotations + import json -import os -from pathlib import Path +import logging import sys +from pathlib import Path + from jinja2 import Environment, FileSystemLoader +logger = logging.getLogger(__name__) + + def get_real_path(relative_path: Path) -> Path: + """Resolve *relative_path* whether running as a script or inside a + PyInstaller bundle. + + When frozen (``sys.frozen``), paths are relative to ``sys._MEIPASS``. + Otherwise they are resolved against the current working directory. """ - Resolve the actual path whether running as script or bundled by PyInstaller. - """ - if getattr(sys, 'frozen', False): - return Path(sys._MEIPASS) / relative_path + if getattr(sys, "frozen", False): + return Path(sys._MEIPASS) / relative_path # type: ignore[attr-defined] return relative_path.resolve() -def load_input_json(filepath, verbose=False): - """ - Load and parse a JSON file safely. - """ - if not os.path.exists(filepath): - print(f"[ERROR] File not found: {filepath}") - return None - try: - with open(filepath, "r", encoding="utf-8") as file: - data = json.load(file) - if verbose: - print(f"[✓] Loaded JSON from: {filepath}") - if isinstance(data, dict): - print(f" Top-level keys: {list(data.keys())}") - return data - except json.JSONDecodeError as e: - print(f"[ERROR] Failed to parse JSON ({filepath}): {e}") - return None - except Exception as e: - print(f"[ERROR] Unexpected error while loading {filepath}: {e}") - return None - -def pretty_print_json(data, output_path): - """ - Pretty-print JSON data to a file. +def load_input_json(filepath: str | Path) -> dict: + """Load and parse a JSON file. + + Raises + ------ + FileNotFoundError + If *filepath* does not exist. + ValueError + If the file cannot be decoded as JSON. """ + path = Path(filepath) + if not path.exists(): + raise FileNotFoundError(f"Input file not found: {path}") + try: - os.makedirs(os.path.dirname(output_path), exist_ok=True) - with open(output_path, "w", encoding="utf-8") as f: - json.dump(data, f, indent=2) - print(f"[✓] Pretty-printed JSON saved to: {output_path}") - except Exception as e: - print(f"[ERROR] Failed to write pretty JSON: {e}") - -def load_template(template_dir, template_file): - """ - Load a Jinja2 template from a folder (safe for PyInstaller). + with path.open("r", encoding="utf-8") as fh: + data = json.load(fh) + except json.JSONDecodeError as exc: + raise ValueError(f"Failed to parse JSON ({path}): {exc}") from exc + + logger.debug("Loaded JSON from %s (keys: %s)", path, list(data.keys()) if isinstance(data, dict) else "N/A") + return data + + +def load_template(template_dir: str | Path, template_file: str): + """Load a single Jinja2 template from *template_dir*. + + The directory is resolved via :func:`get_real_path` so that templates + bundled inside a PyInstaller executable are found correctly. """ - real_template_dir = get_real_path(Path(template_dir)) - env = Environment(loader=FileSystemLoader(str(real_template_dir))) + real_dir = get_real_path(Path(template_dir)) + env = Environment(loader=FileSystemLoader(str(real_dir))) return env.get_template(template_file) diff --git a/src/main.py b/src/main.py index 0c62ee1..bbfd07b 100644 --- a/src/main.py +++ b/src/main.py @@ -1,285 +1,261 @@ +"""CLI entry point for the AzureStack Network Switch Config Generator.""" + +from __future__ import annotations + import argparse -from pathlib import Path -import sys -import json +import logging import shutil +import sys +from pathlib import Path -# Support both execution styles: -# 1. python src/main.py (src not a package on sys.path root) -# 2. python -m src.main (src is a package) -# Try relative imports first (package style), then fall back to absolute (script style). -try: # Package style - from .generator import generate_config # type: ignore - from .loader import get_real_path, load_input_json # type: ignore -except ImportError: # Fallback to script style - from generator import generate_config # type: ignore - from loader import get_real_path, load_input_json # type: ignore # Only used for PyInstaller-packed assets - -# Configure UTF-8 encoding for Windows console (fixes emoji display issues in executables) -if sys.platform == "win32": - try: - # Try to set console to UTF-8 mode - import os - os.system("chcp 65001 > nul 2>&1") - # Reconfigure stdout/stderr with UTF-8 encoding - if hasattr(sys.stdout, 'reconfigure'): - sys.stdout.reconfigure(encoding='utf-8', errors='replace') - sys.stderr.reconfigure(encoding='utf-8', errors='replace') - except: - pass # If it fails, we'll use safe_print fallback - -def safe_print(text): - """ - Safely print text, handling Unicode characters that might not be supported in console. - Falls back to ASCII-safe alternatives if encoding fails. - """ +from .generator import generate_config +from .loader import get_real_path, load_input_json + +logger = logging.getLogger(__name__) + + +# ── CLI helpers ─────────────────────────────────────────────────────────── + +def _configure_logging(debug: bool = False) -> None: + """Set up root logger with a readable format.""" + level = logging.DEBUG if debug else logging.INFO + logging.basicConfig( + level=level, + format="%(levelname)-7s %(message)s", + force=True, + ) + + +def _safe_print(text: str) -> None: + """Print with a fallback for consoles that cannot render Unicode.""" try: print(text) except UnicodeEncodeError: - # Remove or replace problematic Unicode characters - safe_text = text.encode('ascii', errors='replace').decode('ascii') - print(safe_text) + print(text.encode("ascii", errors="replace").decode("ascii")) -def load_convertor(convertor_name): - """ - Load a convertor function from the static registry. - - Args: - convertor_name: String name of convertor (e.g., "convertors.convertors_lab_switch_json" or "lab") - - Returns: - Function that can convert input data to standard format - """ + +def _configure_windows_console() -> None: + """Enable UTF-8 output on Windows consoles.""" + if sys.platform != "win32": + return try: - from convertors import CONVERTORS - - if convertor_name in CONVERTORS: - return CONVERTORS[convertor_name] - else: - available = ', '.join(CONVERTORS.keys()) - raise ValueError( - f"Unknown convertor '{convertor_name}'.\n" - f"Available convertors: {available}" - ) - - except ImportError as e: - raise ImportError(f"Failed to import convertors package: {e}") - except Exception as e: - raise RuntimeError(f"Failed to load convertor '{convertor_name}': {e}") + import os + os.system("chcp 65001 > nul 2>&1") + if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8", errors="replace") + sys.stderr.reconfigure(encoding="utf-8", errors="replace") + except Exception: + pass -def is_standard_format(data): - """ - Check if the JSON data is in standard format by looking for expected top-level keys. - Standard format should have: switch, vlans, interfaces, port_channels, bgp, prefix_lists, qos - Lab format will have: Version, Description, InputData + +# ── convertor loading ───────────────────────────────────────────────────── + +def load_convertor(convertor_name: str): + """Load a convertor function from the static registry. + + Raises + ------ + ValueError + If *convertor_name* is not registered. """ + from .convertors import CONVERTORS + + if convertor_name in CONVERTORS: + return CONVERTORS[convertor_name] + + available = ", ".join(CONVERTORS.keys()) + raise ValueError( + f"Unknown convertor '{convertor_name}'.\nAvailable: {available}" + ) + + +# ── format detection ───────────────────────────────────────────────────── + +def is_standard_format(data: dict) -> bool: + """Return True when *data* looks like a per-switch standard JSON.""" if not isinstance(data, dict): return False - - # Standard format indicators standard_keys = {"switch", "vlans", "interfaces"} - has_standard_keys = any(key in data for key in standard_keys) - - # Lab format indicators lab_keys = {"Version", "Description", "InputData"} - has_lab_keys = any(key in data for key in lab_keys) - - return has_standard_keys and not has_lab_keys + return bool(standard_keys & data.keys()) and not bool(lab_keys & data.keys()) + + +# ── conversion pipeline ────────────────────────────────────────────────── + +def convert_to_standard_format( + input_file_path: Path, + output_dir: str, + convertor_module_path: str, + *, + debug: bool = False, +) -> list[Path]: + """Run the lab→standard converter and return generated file paths.""" + _safe_print("Converting from lab format to standard format...") + _safe_print(f"Using convertor: {convertor_module_path}") -def convert_to_standard_format(input_file_path, output_dir, convertor_module_path): - """ - Convert lab format to standard format JSON files using specified convertor. - Returns list of generated standard format files. - """ - safe_print("🔄 Converting from lab format to standard format...") - safe_print(f"📦 Using convertor: {convertor_module_path}") - - # Load lab format data data = load_input_json(str(input_file_path)) - if data is None: - raise ValueError(f"Failed to load input file: {input_file_path}") - - # Load the convertor function + convert_function = load_convertor(convertor_module_path) - - # Convert to standard format - convert_function(data, output_dir) - - # Find generated standard format files - output_path = Path(output_dir) - generated_files = list(output_path.glob("*.json")) - + + # Pass debug flag if the converter supports it + import inspect + sig = inspect.signature(convert_function) + if "debug" in sig.parameters: + convert_function(data, output_dir, debug=debug) + else: + convert_function(data, output_dir) + + generated_files = list(Path(output_dir).glob("*.json")) if not generated_files: raise RuntimeError("No standard format files were generated during conversion") - - safe_print(f"✅ Generated {len(generated_files)} standard format files:") - for file in generated_files: - print(f" - {file}") - + + _safe_print(f"Generated {len(generated_files)} standard format file(s):") + for f in generated_files: + print(f" - {f}") return generated_files -def main(): + +# ── main ────────────────────────────────────────────────────────────────── + +def main() -> None: + _configure_windows_console() + parser = argparse.ArgumentParser( - epilog=""" + epilog="""\ Examples: %(prog)s --input_json input/standard_input.json --output_folder output/ %(prog)s --input_json my_lab_input.json --output_folder configs/ --convertor lab - """, - formatter_class=argparse.RawDescriptionHelpFormatter +""", + formatter_class=argparse.RawDescriptionHelpFormatter, ) - parser.add_argument("--input_json", required=True, help="Path to input JSON file (lab or standard format)") - parser.add_argument("--template_folder", default="input/jinja2_templates", - help="Folder containing Jinja2 templates (default: input/jinja2_templates)") - + help="Folder containing Jinja2 templates (default: %(default)s)") parser.add_argument("--output_folder", default=None, - help="Directory to save generated configs (default: same directory as input file)" - ) - + help="Directory to save generated configs (default: same as input file)") parser.add_argument("--convertor", default="convertors.convertors_lab_switch_json", - help="Convertor to use for non-standard input formats (default: convertors.convertors_lab_switch_json)") - + help="Convertor to use for lab format (default: %(default)s)") + parser.add_argument("--debug", action="store_true", + help="Include debug data (vlan_map, ip_map) in converted JSON output") args = parser.parse_args() - # Resolve paths + _configure_logging(debug=args.debug) + + # ── resolve paths ──────────────────────────────────────────────────── input_json_path = Path(args.input_json).resolve() - - # Auto-detect output folder: default to same directory as input file - if args.output_folder is None: - output_folder_path = input_json_path.parent - else: - output_folder_path = Path(args.output_folder).resolve() - + output_folder_path = ( + input_json_path.parent + if args.output_folder is None + else Path(args.output_folder).resolve() + ) template_folder_arg = Path(args.template_folder) + template_folder = ( + get_real_path(template_folder_arg) + if args.template_folder == parser.get_default("template_folder") + else template_folder_arg.resolve() + ) - # Only use get_real_path if user did NOT override default - if args.template_folder == parser.get_default('template_folder'): - template_folder = get_real_path(template_folder_arg) - else: - template_folder = template_folder_arg.resolve() - - safe_print(f"🧾 Input JSON File: {input_json_path}") - safe_print(f"🧩 Template Folder: {template_folder}") - safe_print(f"📁 Output Directory: {output_folder_path}") - if args.convertor != parser.get_default('convertor'): - safe_print(f"🔄 Custom Convertor: {args.convertor}") + _safe_print(f"Input JSON: {input_json_path}") + _safe_print(f"Template folder: {template_folder}") + _safe_print(f"Output dir: {output_folder_path}") + if args.convertor != parser.get_default("convertor"): + _safe_print(f"Custom convertor: {args.convertor}") + if args.debug: + _safe_print("Debug mode: ON") - # === Validation === + # ── validate ───────────────────────────────────────────────────────── if not input_json_path.exists(): - print(f"[ERROR] Input file not found: {input_json_path}") + logger.error("Input file not found: %s", input_json_path) sys.exit(1) - if not template_folder.exists(): - print(f"[ERROR] Template folder not found: {template_folder}") + logger.error("Template folder not found: %s", template_folder) sys.exit(1) - output_folder_path.mkdir(parents=True, exist_ok=True) - # === Step 1: Check if input is in standard format === - safe_print("🔍 Checking input format...") + # ── step 1: format detection / conversion ──────────────────────────── + _safe_print("Checking input format...") data = load_input_json(str(input_json_path)) - if data is None: - print(f"[ERROR] Failed to load input JSON: {input_json_path}") - sys.exit(1) - standard_format_files = [] + standard_format_files: list[Path] = [] + conversion_used = False if is_standard_format(data): - safe_print("✅ Input is already in standard format") + _safe_print("Input is already in standard format") standard_format_files = [input_json_path] else: - safe_print("⚠️ Input is in lab format - conversion required") + _safe_print("Input is in lab format — conversion required") + conversion_used = True try: - # Create temporary subdirectory for conversion within output folder - temp_conversion_subdir = output_folder_path / ".temp_conversion" - temp_conversion_subdir.mkdir(parents=True, exist_ok=True) - - # Convert to standard format using temporary subdirectory + temp_dir = output_folder_path / ".temp_conversion" + temp_dir.mkdir(parents=True, exist_ok=True) standard_format_files = convert_to_standard_format( - input_json_path, - str(temp_conversion_subdir), - args.convertor + input_json_path, str(temp_dir), args.convertor, debug=args.debug, ) - except Exception as e: - err_msg = str(e) - safe_print(f"❌ Failed to convert to standard format: {err_msg}") - - # Specialized guidance for missing VLAN symbol sets - if "Required VLAN set(s) missing" in err_msg: - safe_print("\n➡ Action Required:") - safe_print(" 1. Open the input JSON (the --input_json file).") - safe_print(" 2. Under 'Supernets', add entries so the following symbolic VLAN sets exist:") - safe_print(" - Infrastructure (M): GroupName starting 'Infrastructure' or similar.") - safe_print(" - Tenant/Compute (C): GroupName starting 'Tenant', 'L3Forward', or 'HNVPA'.") - safe_print(" - (Optional) Storage (S): GroupName starting 'Storage' for storage VLAN placeholders.") - safe_print(" 3. Re-run the command once these are defined.") - safe_print(" 4. If you cannot update the file, file a GitHub issue referencing this error message.") - else: - safe_print("\n💡 Basic Checks:") - safe_print(f" - Confirm the input JSON matches the expected lab schema for convertor '{args.convertor}'.") - safe_print(" - Verify 'Supernets' contains all required VLAN groups.") - safe_print(" - If still failing, file an issue with the error string above.") - + except Exception as exc: + _safe_print(f"Failed to convert to standard format: {exc}") + _print_conversion_guidance(str(exc), args.convertor) sys.exit(1) - # === Step 2: Generate configs for each standard format file === - safe_print(f"\n🏗️ Generating configs for {len(standard_format_files)} switch(es)...") - + # ── step 2: generate configs ───────────────────────────────────────── + _safe_print(f"\nGenerating configs for {len(standard_format_files)} switch(es)...") + total_success = 0 total_failed = 0 - conversion_used = not is_standard_format(data) for std_file in standard_format_files: - safe_print(f"\n📝 Processing: {std_file.name}") - + _safe_print(f"\nProcessing: {std_file.name}") try: - # Create subdirectory for each switch's output switch_output_dir = output_folder_path / std_file.stem switch_output_dir.mkdir(parents=True, exist_ok=True) - - # If conversion was used, copy the standard JSON to the switch output directory for troubleshooting + if conversion_used: - import shutil - std_json_copy = switch_output_dir / f"std_{std_file.name}" - shutil.copy2(std_file, std_json_copy) - safe_print(f"📄 Standard JSON saved: {std_json_copy.name}") - + std_copy = switch_output_dir / f"std_{std_file.name}" + shutil.copy2(std_file, std_copy) + _safe_print(f"Standard JSON saved: {std_copy.name}") + generate_config( input_std_json=str(std_file), template_folder=str(template_folder), - output_folder=str(switch_output_dir) + output_folder=str(switch_output_dir), ) total_success += 1 - safe_print(f"✅ Generated configs for {std_file.name} in {switch_output_dir}") - - except Exception as e: - safe_print(f"❌ Failed to generate configs for {std_file.name}: {e}") + _safe_print(f"Generated configs for {std_file.name} in {switch_output_dir}") + except Exception as exc: + _safe_print(f"Failed to generate configs for {std_file.name}: {exc}") total_failed += 1 - # === Cleanup conversion artifacts === + # ── cleanup ────────────────────────────────────────────────────────── if conversion_used: - # Clean up temporary conversion subdirectory - temp_conversion_subdir = output_folder_path / ".temp_conversion" - if temp_conversion_subdir.exists(): - safe_print(f"\n🧹 Cleaning up temporary conversion directory...") - shutil.rmtree(temp_conversion_subdir, ignore_errors=True) - - # Keep the original converted JSON files in the root directory for user verification - safe_print("📋 Original converted JSON files kept in output directory for verification") - - # === Summary === - safe_print(f"\n🎯 Summary:") - safe_print(f" ✅ Successfully processed: {total_success} switch(es)") - if total_failed > 0: - safe_print(f" ❌ Failed to process: {total_failed} switch(es)") - safe_print(f" 📁 Output directory: {output_folder_path}") - - if total_failed > 0: + temp_dir = output_folder_path / ".temp_conversion" + if temp_dir.exists(): + shutil.rmtree(temp_dir, ignore_errors=True) + + # ── summary ────────────────────────────────────────────────────────── + _safe_print(f"\nSummary:") + _safe_print(f" Successfully processed: {total_success} switch(es)") + if total_failed: + _safe_print(f" Failed: {total_failed} switch(es)") + _safe_print(f" Output directory: {output_folder_path}") + + if total_failed: sys.exit(1) + _safe_print("All configs generated successfully!") + + +def _print_conversion_guidance(error_msg: str, convertor: str) -> None: + """Print contextual troubleshooting hints after a conversion failure.""" + if "Required VLAN set(s) missing" in error_msg: + _safe_print("\nAction Required:") + _safe_print(" 1. Open the input JSON.") + _safe_print(" 2. Under 'Supernets', add entries so these symbolic VLAN sets exist:") + _safe_print(" - Infrastructure (M): GroupName starting 'Infrastructure'.") + _safe_print(" - Tenant/Compute (C): GroupName starting 'Tenant', 'L3Forward', or 'HNVPA'.") + _safe_print(" - (Optional) Storage (S): GroupName starting 'Storage'.") + _safe_print(" 3. Re-run the command.") else: - safe_print("🎉 All configs generated successfully!") + _safe_print(f"\nConfirm the input JSON matches the lab schema for convertor '{convertor}'.") + if __name__ == "__main__": main() diff --git a/src/utils.py b/src/utils.py new file mode 100644 index 0000000..f2c2cee --- /dev/null +++ b/src/utils.py @@ -0,0 +1,43 @@ +""" +Shared utility functions for the AzureStack Network Switch Config Generator. + +Houses logic that is used by multiple modules so it isn't duplicated across +converters, loaders, or the CLI entry point. +""" + +from __future__ import annotations + +from .constants import VENDOR_FIRMWARE_MAP, VLAN_GROUP_MAP + + +def infer_firmware(make: str) -> str: + """Derive firmware identifier from vendor make string. + + >>> infer_firmware("cisco") + 'nxos' + >>> infer_firmware("dellemc") + 'os10' + >>> infer_firmware("juniper") + 'juniper' + """ + make_lower = make.lower().strip() + return VENDOR_FIRMWARE_MAP.get(make_lower, make_lower) + + +def classify_vlan_group(group_name: str) -> str | None: + """Map a supernet GroupName to its symbolic VLAN-set key (M, C, S, …). + + Returns ``None`` when no mapping matches. + + >>> classify_vlan_group("HNVPA_Pool1") + 'C' + >>> classify_vlan_group("STORAGE_A") + 'S' + >>> classify_vlan_group("RANDOM_STUFF") is None + True + """ + upper = group_name.upper() + for prefix, symbol in VLAN_GROUP_MAP.items(): + if upper.startswith(prefix): + return symbol + return None diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..e12d290 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,82 @@ +""" +Shared test fixtures and configuration for the config-generator test suite. +""" + +from __future__ import annotations + +import json +import logging +import sys +from pathlib import Path + +import pytest + +# ── path setup ──────────────────────────────────────────────────────────── +ROOT_DIR = Path(__file__).resolve().parent.parent +TEST_CASES_ROOT = ROOT_DIR / "tests" / "test_cases" +TEMPLATE_ROOT = ROOT_DIR / "input" / "jinja2_templates" + +if str(ROOT_DIR) not in sys.path: + sys.path.insert(0, str(ROOT_DIR)) + +# Suppress noisy logging during tests +logging.basicConfig(level=logging.WARNING, force=True) + + +# ── helpers ─────────────────────────────────────────────────────────────── + +def load_json(path: Path) -> dict: + """Load a JSON file or raise a clear assertion error.""" + assert path.exists(), f"JSON file not found: {path}" + return json.loads(path.read_text(encoding="utf-8")) + + +def find_json_differences(expected, actual, path: str = "", max_diff: int = 10) -> list[str]: + """Return a list of human-readable differences between two JSON trees.""" + diffs: list[str] = [] + + if type(expected) is not type(actual): + return [f"Type mismatch at '{path}': expected {type(expected).__name__}, got {type(actual).__name__}"] + + if isinstance(expected, dict): + for key in sorted(set(expected) | set(actual)): + child = f"{path}.{key}" if path else key + if key not in expected: + diffs.append(f"Unexpected key at '{child}': {actual[key]!r}") + elif key not in actual: + diffs.append(f"Missing key at '{child}'") + else: + diffs.extend(find_json_differences(expected[key], actual[key], child, max_diff)) + if len(diffs) >= max_diff: + break + + elif isinstance(expected, list): + if len(expected) != len(actual): + diffs.append(f"List length at '{path}': expected {len(expected)}, got {len(actual)}") + for i in range(min(len(expected), len(actual))): + diffs.extend(find_json_differences(expected[i], actual[i], f"{path}[{i}]", max_diff)) + if len(diffs) >= max_diff: + break + + elif expected != actual: + diffs.append(f"Value at '{path}': expected {expected!r}, got {actual!r}") + + return diffs[:max_diff] + + +def find_text_differences(expected: str, actual: str, max_lines: int = 10) -> list[str]: + """Line-by-line diff between two text blobs.""" + exp_lines = expected.splitlines() + act_lines = actual.splitlines() + diffs: list[str] = [] + + if len(exp_lines) != len(act_lines): + diffs.append(f"Line count: expected {len(exp_lines)}, got {len(act_lines)}") + + for i in range(min(len(exp_lines), len(act_lines))): + if exp_lines[i] != act_lines[i]: + diffs.append(f"Line {i + 1}: expected {exp_lines[i][:60]!r} got {act_lines[i][:60]!r}") + if len(diffs) >= max_lines: + break + + return diffs diff --git a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json index 65e26ca..21a16ac 100644 --- a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json +++ b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json @@ -13,13 +13,9 @@ "name": "UNUSED_VLAN", "shutdown": true }, - { - "vlan_id": 7, - "name": "Infra_7" - }, { "vlan_id": 99, - "name": "NativeVlan" + "name": "NATIVE_VLAN" }, { "vlan_id": 125, diff --git a/tests/test_convertors.py b/tests/test_convertors.py index ddb17b0..57a388f 100644 --- a/tests/test_convertors.py +++ b/tests/test_convertors.py @@ -1,283 +1,95 @@ -from pathlib import Path -import sys -import json -import pytest -import warnings -from collections import defaultdict - -# === Path setup === -ROOT_DIR = Path(__file__).resolve().parent.parent -SRC_PATH = ROOT_DIR / "src" -TEMPLATE_ROOT = ROOT_DIR / "input" / "templates" -TEST_CASES_ROOT = ROOT_DIR / "tests" / "test_cases" - -# Add src to sys.path -if str(SRC_PATH) not in sys.path: - sys.path.insert(0, str(SRC_PATH)) - -# === Imports from your project === -from convertors import convert_lab_switches -from loader import load_input_json +""" +Golden-file tests for the lab→standard JSON converters. -# === Test result tracking === -convertor_results = defaultdict(lambda: {"passed": 0, "skipped": 0, "failed": 0, "errors": []}) - -# === Helper function for better diff reporting === -def find_json_differences(expected, actual, path="", max_diff=10): - """Find specific differences between two JSON structures.""" - differences = [] - - if type(expected) != type(actual): - differences.append(f"Type mismatch at '{path}': expected {type(expected).__name__}, got {type(actual).__name__}") - return differences - - if isinstance(expected, dict): - all_keys = set(expected.keys()) | set(actual.keys()) - for key in sorted(all_keys): - current_path = f"{path}.{key}" if path else key - if key not in expected: - differences.append(f"Unexpected key at '{current_path}': {actual[key]}") - elif key not in actual: - differences.append(f"Missing key at '{current_path}'") - else: - differences.extend(find_json_differences(expected[key], actual[key], current_path)) - - if len(differences) >= max_diff: - break - - elif isinstance(expected, list): - if len(expected) != len(actual): - differences.append(f"List length mismatch at '{path}': expected {len(expected)}, got {len(actual)}") - - for i in range(min(len(expected), len(actual))): - current_path = f"{path}[{i}]" if path else f"[{i}]" - differences.extend(find_json_differences(expected[i], actual[i], current_path)) - - if len(differences) >= max_diff: - break - - else: - if expected != actual: - differences.append(f"Value mismatch at '{path}': expected '{expected}', got '{actual}'") - - return differences[:max_diff] +Each test case lives in a folder under ``tests/test_cases/convert_*``. +The folder must contain: + - A ``*_input.json`` file (lab format) + - An ``expected_outputs/`` directory with the expected standard JSON files +""" +from __future__ import annotations -def validate_json_structure(data, required_fields=None): - """Validate that JSON has expected structure.""" - errors = [] - - if not isinstance(data, dict): - errors.append(f"Expected dict, got {type(data).__name__}") - return errors - - if required_fields: - for field in required_fields: - if field not in data: - errors.append(f"Missing required field: '{field}'") - - return errors +import io +import json +import sys +from pathlib import Path +import pytest -def validate_lab_format(data): - """Validate that input JSON is in lab format.""" - required_keys = ["Version", "Description", "InputData"] - return validate_json_structure(data, required_keys) +from conftest import TEST_CASES_ROOT, load_json, find_json_differences +# ── import converter ────────────────────────────────────────────────────── +from src.convertors import convert_lab_switches +from src.loader import load_input_json -def validate_standard_format(data): - """Validate that converted JSON is in standard format.""" - required_keys = ["switch"] - missing = [] - - for key in required_keys: - if key not in data: - missing.append(f"Missing required key: '{key}'") - - # Validate switch object has essential properties - if "switch" in data and isinstance(data["switch"], dict): - switch_required = ["make", "firmware"] - for key in switch_required: - if key not in data["switch"]: - missing.append(f"Missing in switch: '{key}'") - - return missing +# ── discover test cases ─────────────────────────────────────────────────── -# === Step 1: Find test folders with *_input.json === -def find_input_cases(): - input_cases = [] - for folder in TEST_CASES_ROOT.iterdir(): - if not folder.is_dir(): - continue - if not folder.name.startswith("convert_"): +def _find_convert_cases() -> list[tuple[str, Path]]: + cases = [] + for folder in sorted(TEST_CASES_ROOT.iterdir()): + if not folder.is_dir() or not folder.name.startswith("convert_"): continue - for input_file in folder.glob("*_input.json"): - input_cases.append((folder.name, input_file)) + cases.append((folder.name, input_file)) + return cases + - return input_cases +_ALL_CASES = _find_convert_cases() -# === Step 2: Core convertor test logic === -def run_convert_and_compare(folder_name, input_file): - folder_path = TEST_CASES_ROOT / folder_name - expected_dir = folder_path / "expected_outputs" - output_dir = folder_path / "generated_outputs" - output_dir.mkdir(exist_ok=True) - # Load input JSON - input_data = load_input_json(input_file) - assert input_data is not None, "Failed to load input JSON" +# ── parametrised tests ──────────────────────────────────────────────────── - # Validate input format - format_errors = validate_lab_format(input_data) - if format_errors: - error_msg = f"Invalid lab format in {folder_name}:\n" + "\n".join(f" • {e}" for e in format_errors) - pytest.fail(error_msg, pytrace=False) +@pytest.mark.parametrize("case", _ALL_CASES, ids=lambda c: c[0]) +def test_convert_golden(case, tmp_path): + """Convert lab JSON → standard JSON and compare against expected output.""" + folder_name, input_file = case + expected_dir = TEST_CASES_ROOT / folder_name / "expected_outputs" - # Run convertor (writes JSON files into output_dir) - # Suppress print output during testing - import io, sys - old_stdout = sys.stdout + # Load & convert + input_data = load_json(input_file) + assert {"Version", "Description", "InputData"} & input_data.keys(), \ + f"Input does not look like lab format: {input_file}" + + # Suppress converter stdout + old = sys.stdout sys.stdout = io.StringIO() try: - convert_lab_switches(input_data, output_dir) - except Exception as e: - sys.stdout = old_stdout - convertor_results[folder_name]["failed"] += 1 - convertor_results[folder_name]["errors"].append(str(e)) - pytest.fail(f"Convertor failed: {e}", pytrace=False) + convert_lab_switches(input_data, str(tmp_path)) finally: - sys.stdout = old_stdout - - # Compare each generated output file with its corresponding expected file - generated_files = list(output_dir.glob("*.json")) - - if not generated_files: - convertor_results[folder_name]["skipped"] += 1 - pytest.skip(f"No output files generated for {folder_name}") - return - - compared_files = 0 - missing_files = [] - format_issues = [] - - for generated_file in sorted(generated_files): - expected_file = expected_dir / generated_file.name - - if not expected_file.exists(): - missing_files.append(generated_file.name) - continue + sys.stdout = old - with open(expected_file, "r", encoding="utf-8") as f: - expected_data = json.load(f) - with open(generated_file, "r", encoding="utf-8") as f: - generated_data = json.load(f) + generated_files = sorted(tmp_path.glob("*.json")) + assert generated_files, f"No output files produced for {folder_name}" - # Validate generated format - validation_errors = validate_standard_format(generated_data) - if validation_errors: - format_issues.extend([f"{generated_file.name}: {e}" for e in validation_errors]) + compared = 0 + for gen_file in generated_files: + exp_file = expected_dir / gen_file.name + if not exp_file.exists(): + continue # extra files are OK — new switches added - # Content comparison - if expected_data != generated_data: - # Find and report specific differences - differences = find_json_differences(expected_data, generated_data) - error_msg = f"❌ {generated_file.name} - Differences found:" - for diff in differences[:5]: # Show first 5 differences - error_msg += f"\n • {diff}" - if len(differences) > 5: - error_msg += f"\n ... and {len(differences) - 5} more differences" - - # Print the error for immediate visibility, then fail - print(error_msg) - convertor_results[folder_name]["failed"] += 1 - convertor_results[folder_name]["errors"].append(generated_file.name) - pytest.fail(f"File comparison failed: {generated_file.name}", pytrace=False) - - compared_files += 1 - convertor_results[folder_name]["passed"] += 1 + expected = json.loads(exp_file.read_text("utf-8")) + actual = json.loads(gen_file.read_text("utf-8")) - # Report format issues as warnings if content matched - if format_issues and compared_files > 0: - for issue in format_issues: - print(f"⚠️ {issue}") + # Strip debug section from both sides (DC6) + expected.pop("debug", None) + actual.pop("debug", None) - # Report results - if compared_files == 0: - if missing_files: - skip_msg = f"All expected files missing: {', '.join(missing_files)}" - print(f"⏭️ {folder_name}: SKIPPED - {skip_msg}") - convertor_results[folder_name]["skipped"] += 1 - pytest.skip(skip_msg) - else: - skip_msg = "No files to compare" - print(f"⏭️ {folder_name}: SKIPPED - {skip_msg}") - convertor_results[folder_name]["skipped"] += 1 - pytest.skip(skip_msg) - else: - print(f"✅ {folder_name}: {compared_files} file(s) verified") - if missing_files: - print(f"⚠️ {folder_name}: {len(missing_files)} expected file(s) missing: {', '.join(missing_files)}") - - -# === Step 3: Parametrize test for pytest === -ALL_INPUT_CASES = find_input_cases() - -@pytest.mark.parametrize("input_case", ALL_INPUT_CASES, ids=lambda val: val[0]) -def test_convert_switch_input_json(input_case): - folder_name, input_file = input_case - run_convert_and_compare(folder_name, input_file) - - -# === Additional validation tests === -@pytest.mark.parametrize("input_case", ALL_INPUT_CASES, ids=lambda val: f"input_format_{val[0]}") -def test_input_format_validation(input_case): - """Verify that input files conform to expected lab format.""" - folder_name, input_file = input_case - - input_data = load_input_json(input_file) - assert input_data is not None, f"Failed to load {input_file}" - - # Validate lab format structure - errors = validate_lab_format(input_data) - assert not errors, f"Format validation failed for {folder_name}:\n" + "\n".join(f" • {e}" for e in errors) + if expected != actual: + diffs = find_json_differences(expected, actual) + msg = f"{gen_file.name} differs:\n" + "\n".join(f" - {d}" for d in diffs[:5]) + pytest.fail(msg, pytrace=False) + compared += 1 -@pytest.mark.parametrize("input_case", ALL_INPUT_CASES, ids=lambda val: f"output_format_{val[0]}") -def test_output_format_validation(input_case): - """Verify that generated output conforms to standard format.""" - folder_name, input_file = input_case - folder_path = TEST_CASES_ROOT / folder_name - output_dir = folder_path / "generated_outputs" - - if not output_dir.exists() or not list(output_dir.glob("*.json")): - pytest.skip(f"No generated outputs for {folder_name}") - - # Validate each generated file - for output_file in output_dir.glob("*.json"): - with open(output_file, "r", encoding="utf-8") as f: - output_data = json.load(f) - - errors = validate_standard_format(output_data) - assert not errors, f"Format validation failed for {output_file.name}:\n" + "\n".join(f" • {e}" for e in errors) + if compared == 0: + pytest.skip(f"No expected output files found for {folder_name}") -def pytest_sessionfinish(session, exitstatus): - """Print final summary of convertor tests.""" - if convertor_results: - print(f"\n📊 Convertor Test Summary:") - total_passed = sum(r["passed"] for r in convertor_results.values()) - total_skipped = sum(r["skipped"] for r in convertor_results.values()) - total_failed = sum(r["failed"] for r in convertor_results.values()) - total_cases = len(convertor_results) - - print(f"📈 {total_cases} convertor cases: {total_passed} passed, {total_skipped} skipped, {total_failed} failed") - - if total_failed > 0: - print("\n❌ Failed cases:") - for case_name, results in sorted(convertor_results.items()): - if results["failed"] > 0: - print(f" • {case_name}: {results['failed']} failure(s)") - for error in results["errors"][:3]: - print(f" - {error}") +@pytest.mark.parametrize("case", _ALL_CASES, ids=lambda c: f"input_format_{c[0]}") +def test_input_is_lab_format(case): + """Verify that each test input is valid lab-format JSON.""" + _, input_file = case + data = load_json(input_file) + missing = {"Version", "Description", "InputData"} - data.keys() + assert not missing, f"Missing lab-format keys: {missing}" diff --git a/tests/test_generator.py b/tests/test_generator.py index e8b95cb..d791471 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -1,289 +1,96 @@ -from pathlib import Path -import sys -import pytest -import warnings -from collections import defaultdict -import re - -# === Test result tracking === -case_results = defaultdict(lambda: {"passed": 0, "skipped": 0, "failed": 0, "files": []}) -case_summary_shown = set() - -# === Path setup === -ROOT_DIR = Path(__file__).resolve().parent.parent -SRC_PATH = ROOT_DIR / "src" -TEMPLATE_ROOT = ROOT_DIR / "input" / "jinja2_templates" -TEST_CASES_ROOT = ROOT_DIR / "tests" / "test_cases" - -# Add src to sys.path -if str(SRC_PATH) not in sys.path: - sys.path.insert(0, str(SRC_PATH)) - -from generator import generate_config +""" +Golden-file tests for the Jinja2 config generator. -# === Helper function for better diff reporting === -def find_text_differences(expected, actual, max_lines=10): - """Find specific differences between two text files.""" - expected_lines = expected.split('\n') - actual_lines = actual.split('\n') - differences = [] - - # Check line count difference - if len(expected_lines) != len(actual_lines): - differences.append(f"Line count mismatch: expected {len(expected_lines)}, got {len(actual_lines)}") - - # Compare line by line - max_compare = min(len(expected_lines), len(actual_lines)) - for i in range(max_compare): - if expected_lines[i] != actual_lines[i]: - differences.append(f"Line {i+1}: expected '{expected_lines[i][:50]}...', got '{actual_lines[i][:50]}...'") - if len(differences) >= max_lines: - break - - return differences +Each test case lives in a folder under ``tests/test_cases/std_*``. +The folder contains: + - A ``*_input.json`` file (standard format) + - ``expected_
.cfg`` files for comparison +""" +from __future__ import annotations -def validate_config_syntax(content, file_type="cfg"): - """Validate configuration file syntax.""" - errors = [] - lines = content.split('\n') - - if file_type == "cfg": - # Basic validation for Cisco/Dell config files - bracket_stack = [] - for line_num, line in enumerate(lines, 1): - stripped = line.strip() - - # Skip comments and empty lines - if not stripped or stripped.startswith('!') or stripped.startswith('#'): - continue - - # Check for unbalanced brackets/braces - for char in stripped: - if char == '{': - bracket_stack.append('{') - elif char == '}': - if not bracket_stack or bracket_stack[-1] != '{': - errors.append(f"Line {line_num}: Unbalanced closing brace") - else: - bracket_stack.pop() - - if bracket_stack: - errors.append(f"Unclosed braces: {len(bracket_stack)} opening brace(s) without closing") - - # Check for common configuration errors - if 'interface' in content.lower(): - # Basic interface validation - interface_lines = [l for l in lines if 'interface' in l.lower()] - if interface_lines and len(interface_lines) < 2: - warnings.warn(f"Config may be incomplete: found {len(interface_lines)} interface definition(s)", UserWarning) - - return errors - +import io +import sys +from pathlib import Path -def validate_generated_structure(output_folder): - """Validate that required output files were generated.""" - output_folder = Path(output_folder) - expected_file_types = [".cfg"] - generated_files = [] - - for file_type in expected_file_types: - generated_files.extend(output_folder.glob(f"*{file_type}")) - - return len(generated_files) > 0, len(generated_files) +import pytest +from conftest import TEST_CASES_ROOT, TEMPLATE_ROOT, find_text_differences +# ── import generator ────────────────────────────────────────────────────── +from src.generator import generate_config -# === Step 1: Find test folders with input === -def find_input_cases(): - input_cases = [] - for folder in TEST_CASES_ROOT.iterdir(): - if not folder.is_dir(): - continue +# ── discover test cases ─────────────────────────────────────────────────── - # Only process test case folders that start with 'std_' - if not folder.name.startswith("std_"): +def _find_std_cases() -> list[tuple[str, Path]]: + cases = [] + for folder in sorted(TEST_CASES_ROOT.iterdir()): + if not folder.is_dir() or not folder.name.startswith("std_"): continue - for input_file in folder.glob("*_input.json"): - input_cases.append((folder.name, input_file)) + cases.append((folder.name, input_file)) + return cases - return input_cases +def _discover_generated_pairs() -> list[tuple[str, str, Path, Path]]: + """Generate configs into tmp dirs and return (folder, section, gen, exp) tuples.""" + pairs: list[tuple[str, str, Path, Path]] = [] -# === Step 4: Render each template (compact single-line logging) === -def generate_all_configs(input_case): - folder_name, input_file = input_case - folder_path = TEST_CASES_ROOT / folder_name - output_folder = folder_path + for folder_name, input_file in _find_std_cases(): + folder_path = TEST_CASES_ROOT / folder_name + + # Generate into the test-case folder (idempotent) + old = sys.stdout + sys.stdout = io.StringIO() + try: + generate_config( + input_std_json=str(input_file), + template_folder=str(TEMPLATE_ROOT), + output_folder=str(folder_path), + ) + except Exception: + pass # template-path issues are expected for some vendors + finally: + sys.stdout = old - # Suppress print output during generation - import io, sys - old_stdout = sys.stdout - sys.stdout = io.StringIO() - try: - generate_config( - input_std_json=str(input_file), - template_folder=str(TEMPLATE_ROOT), - output_folder=str(output_folder) - ) - except Exception as e: - sys.stdout = old_stdout - # Only log critical errors, suppress template path warnings during test discovery - if "Template path not found" not in str(e): - warnings.warn(f"Failed to generate configs for {folder_name}: {e}") - return [] - finally: - sys.stdout = old_stdout + for gen_file in sorted(folder_path.glob("generated_*.cfg")): + section = gen_file.stem.replace("generated_", "") + exp_file = folder_path / f"expected_{section}.cfg" + pairs.append((folder_name, section, gen_file, exp_file)) - # Gather all output files and map to their expected counterparts - return [ - ( - folder_name, - output_file.stem.replace("generated_", ""), - str(output_file), - str(folder_path / f"expected_{output_file.stem.replace('generated_', '')}.cfg") - ) - for output_file in sorted(output_folder.glob("generated_*.cfg")) - ] + return pairs -def discover_test_cases(): - all_cases = [] - input_folders = find_input_cases() - for case in input_folders: - case_tests = generate_all_configs(case) - all_cases.extend(case_tests) +_ALL_PAIRS = _discover_generated_pairs() +_ALL_STD_CASES = _find_std_cases() - return all_cases -# === Run pytest parametrize === -ALL_TEST_CASES = discover_test_cases() +# ── parametrised tests ──────────────────────────────────────────────────── @pytest.mark.parametrize( - "folder_name,case_name,generated_path,expected_path", - ALL_TEST_CASES, - ids=lambda val: f"{val[0]}/{val[1]}" if isinstance(val, tuple) and len(val) >= 2 else str(val) + "folder_name, section, gen_path, exp_path", + _ALL_PAIRS, + ids=[f"{folder}-{section}" for folder, section, _, _ in _ALL_PAIRS], ) -def test_generated_config_output(folder_name, case_name, generated_path, expected_path): - expected_file = Path(expected_path) - test_name = f"{folder_name}/{case_name}" - - if not expected_file.exists(): - case_results[folder_name]["skipped"] += 1 - case_results[folder_name]["files"].append(f"⏭️ {case_name}") - - # Show case summary when the last file for this case is processed - show_case_summary_if_complete(folder_name) - pytest.skip("Expected file missing") - return +def test_generated_config(folder_name, section, gen_path, exp_path): + """Compare a single generated .cfg against its expected golden file.""" + if not exp_path.exists(): + pytest.skip(f"No expected file: {exp_path.name}") - with open(generated_path) as gen, open(expected_file) as exp: - generated = gen.read().strip() - expected = exp.read().strip() + generated = gen_path.read_text("utf-8").strip() + expected = exp_path.read_text("utf-8").strip() - # Validate syntax before comparison - syntax_errors = validate_config_syntax(generated, "cfg") - if syntax_errors: - case_results[folder_name]["failed"] += 1 - case_results[folder_name]["files"].append(f"❌ {case_name} (syntax)") - error_msg = f"❌ {test_name} - Syntax errors:\n" - for err in syntax_errors[:3]: - error_msg += f" • {err}\n" - print(error_msg) - show_case_summary_if_complete(folder_name) - pytest.fail(f"Config syntax validation failed", pytrace=False) - - # Content comparison if expected != generated: - case_results[folder_name]["failed"] += 1 - case_results[folder_name]["files"].append(f"❌ {case_name}") - - # Find and report specific differences - differences = find_text_differences(expected, generated) - error_msg = f"❌ {test_name} - Differences found:" - for diff in differences[:3]: # Show first 3 differences for config files - error_msg += f"\n • {diff}" - if len(differences) > 3: - error_msg += f"\n ... and {len(differences) - 3} more differences" - - # Print the error for immediate visibility, then fail - print(error_msg) - show_case_summary_if_complete(folder_name) - pytest.fail(f"Config comparison failed", pytrace=False) - - case_results[folder_name]["passed"] += 1 - case_results[folder_name]["files"].append(f"✅ {case_name}") - show_case_summary_if_complete(folder_name) - -def show_case_summary_if_complete(folder_name): - """Show summary for a test case if all its files have been processed""" - if folder_name in case_summary_shown: - return - - results = case_results[folder_name] - total_files = results["passed"] + results["skipped"] + results["failed"] - expected_total = get_expected_file_count(folder_name) - - if total_files >= expected_total: - case_summary_shown.add(folder_name) - status_icon = "✅" if results["failed"] == 0 else "❌" - print(f"\n{status_icon} {folder_name}: {results['passed']} passed, {results['skipped']} skipped, {results['failed']} failed") - -def get_expected_file_count(folder_name): - """Get the expected number of test files for a case""" - # Count the number of generated files to determine expected count - folder_path = TEST_CASES_ROOT / folder_name - return len(list(folder_path.glob("generated_*.cfg"))) + diffs = find_text_differences(expected, generated) + msg = f"{folder_name}/{section} differs:\n" + "\n".join(f" - {d}" for d in diffs[:5]) + pytest.fail(msg, pytrace=False) -# === Additional validation tests === -@pytest.mark.parametrize("input_case", find_input_cases(), ids=lambda val: f"config_syntax_{val[0]}") -def test_config_syntax_validation(input_case): - """Verify that generated configuration files have valid syntax.""" - folder_name, input_file = input_case +@pytest.mark.parametrize("case", _ALL_STD_CASES, ids=lambda c: f"has_output_{c[0]}") +def test_output_files_generated(case): + """At least one .cfg file should be generated for each test case.""" + folder_name, _ = case folder_path = TEST_CASES_ROOT / folder_name - - # Generate configs - config_files = list(folder_path.glob("generated_*.cfg")) - - if not config_files: - pytest.skip(f"No generated configs for {folder_name}") - - # Validate syntax of each config - for config_file in config_files: - with open(config_file, "r", encoding="utf-8") as f: - content = f.read() - - errors = validate_config_syntax(content, "cfg") - assert not errors, f"Syntax errors in {config_file.name}:\n" + "\n".join(f" • {e}" for e in errors) - - -@pytest.mark.parametrize("input_case", find_input_cases(), ids=lambda val: f"output_generation_{val[0]}") -def test_output_file_generation(input_case): - """Verify that output files are generated correctly.""" - folder_name, input_file = input_case - folder_path = TEST_CASES_ROOT / folder_name - - has_output, file_count = validate_generated_structure(folder_path) - assert has_output, f"No output files generated for {folder_name}" - assert file_count > 0, f"Expected at least 1 output file, got {file_count}" - - -def pytest_sessionfinish(session, exitstatus): - """Print final summary""" - if case_results: - print(f"\n📊 Generator Test Summary:") - total_passed = sum(r["passed"] for r in case_results.values()) - total_skipped = sum(r["skipped"] for r in case_results.values()) - total_failed = sum(r["failed"] for r in case_results.values()) - total_cases = len(case_results) - print(f"📈 {total_cases} test cases: {total_passed} passed, {total_skipped} skipped, {total_failed} failed") - - if total_failed > 0: - print("\n❌ Failed tests:") - for folder_name, results in sorted(case_results.items()): - if results["failed"] > 0: - print(f" • {folder_name}: {results['failed']} failure(s)") - + generated = list(folder_path.glob("generated_*.cfg")) + assert generated, f"No generated .cfg files for {folder_name}" \ No newline at end of file diff --git a/tests/test_unit.py b/tests/test_unit.py new file mode 100644 index 0000000..b988cc0 --- /dev/null +++ b/tests/test_unit.py @@ -0,0 +1,127 @@ +"""Unit tests for src/constants.py, src/utils.py, and src/loader.py.""" + +from __future__ import annotations + +import json +import sys +from pathlib import Path + +import pytest + +ROOT_DIR = Path(__file__).resolve().parent.parent +SRC_PATH = ROOT_DIR / "src" +if str(ROOT_DIR) not in sys.path: + sys.path.insert(0, str(ROOT_DIR)) + +from src.constants import ( + CISCO, DELL, NXOS, OS10, TOR1, TOR2, BMC, + VLAN_GROUP_MAP, VENDOR_FIRMWARE_MAP, + TOR_SWITCH_TYPES, BMC_HARDCODED_VLANS, BMC_RELEVANT_GROUPS, + JUMBO_MTU, DEFAULT_OUTPUT_DIR, + SWITCH_TEMPLATE, SVI_TEMPLATE, VLAN_TEMPLATE, +) +from src.utils import infer_firmware, classify_vlan_group +from src.loader import load_input_json, get_real_path + + +# ── infer_firmware ──────────────────────────────────────────────────────── + +class TestInferFirmware: + def test_cisco(self): + assert infer_firmware("cisco") == "nxos" + + def test_dell(self): + assert infer_firmware("dellemc") == "os10" + + def test_cisco_uppercase(self): + assert infer_firmware("Cisco") == "nxos" + + def test_unknown_vendor_passthrough(self): + assert infer_firmware("juniper") == "juniper" + + def test_empty_string(self): + assert infer_firmware("") == "" + + def test_whitespace(self): + assert infer_firmware(" cisco ") == "nxos" + + +# ── classify_vlan_group ────────────────────────────────────────────────── + +class TestClassifyVlanGroup: + @pytest.mark.parametrize("group_name,expected", [ + ("HNVPA_Pool1", "C"), + ("INFRA_Mgmt", "M"), + ("TENANT_1", "C"), + ("L3FORWARD_1", "C"), + ("STORAGE_A", "S"), + ("UNUSED_1", "UNUSED"), + ("NATIVE_1", "NATIVE"), + ]) + def test_known_groups(self, group_name, expected): + assert classify_vlan_group(group_name) == expected + + def test_case_insensitive(self): + assert classify_vlan_group("hnvpa_lower") == "C" + + def test_unknown_returns_none(self): + assert classify_vlan_group("RANDOM_STUFF") is None + + def test_empty_returns_none(self): + assert classify_vlan_group("") is None + + +# ── load_input_json ────────────────────────────────────────────────────── + +class TestLoadInputJson: + def test_valid_json(self, tmp_path): + f = tmp_path / "valid.json" + f.write_text('{"a": 1}', encoding="utf-8") + assert load_input_json(f) == {"a": 1} + + def test_file_not_found(self, tmp_path): + with pytest.raises(FileNotFoundError): + load_input_json(tmp_path / "nope.json") + + def test_invalid_json(self, tmp_path): + f = tmp_path / "bad.json" + f.write_text("{not json", encoding="utf-8") + with pytest.raises(ValueError, match="Failed to parse JSON"): + load_input_json(f) + + +# ── get_real_path ──────────────────────────────────────────────────────── + +class TestGetRealPath: + def test_resolves_relative(self): + result = get_real_path(Path("input")) + assert result.is_absolute() + + def test_frozen_mode(self, monkeypatch): + monkeypatch.setattr(sys, "frozen", True, raising=False) + monkeypatch.setattr(sys, "_MEIPASS", "/fake/meipass", raising=False) + result = get_real_path(Path("input/templates")) + assert str(result) == "/fake/meipass/input/templates" + + +# ── constants sanity ───────────────────────────────────────────────────── + +class TestConstants: + def test_tor_switch_types(self): + assert TOR_SWITCH_TYPES == [TOR1, TOR2] + + def test_vendor_firmware_map_complete(self): + assert CISCO in VENDOR_FIRMWARE_MAP + assert DELL in VENDOR_FIRMWARE_MAP + + def test_bmc_hardcoded_vlans_structure(self): + assert len(BMC_HARDCODED_VLANS) >= 1 + for vlan in BMC_HARDCODED_VLANS: + assert "vlan_id" in vlan + assert "name" in vlan + + def test_templates_not_mutated(self): + """Ensure template dicts haven't been accidentally modified.""" + assert SWITCH_TEMPLATE["make"] == "" + assert SVI_TEMPLATE["ip"] == "" + assert VLAN_TEMPLATE["vlan_id"] == 0 From ca6b9439b7c8fe6837b2056da852bfc46f92a5d3 Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Sat, 7 Feb 2026 00:02:04 +0000 Subject: [PATCH 02/11] feat: Phase 1 - Cisco BMC switch foundation - Create input/switch_interface_templates/cisco/9348GC-FXP.json (16-node BMC) - Create input/switch_interface_templates/cisco/9348GC-FX3.json (20-node BMC) - Enhance BMC converter: add port_channels, static_routes, site field - _load_template() extracted for reuse by interfaces and port_channels - _build_port_channels() reads from template (Trunk type, no IP enrichment) - _build_static_routes() derives default route from BMC supernet gateway - _build_switch_info() reads site from MainEnvData (consistent with TOR) - Add Cisco BMC expected outputs for switched (9348GC-FXP) and FC (9348GC-FX3) - Update Dell BMC expected output with new fields (port_channels, static_routes, site) - Add 17 new unit tests for BMC converter (switch info, VLANs, port-channels, static routes, interfaces) All 73 tests pass (42 unit + 8 converter + 23 generator). --- .../cisco/9348GC-FX3.json | 64 ++++++ .../cisco/9348GC-FXP.json | 64 ++++++ src/convertors/convertors_bmc_switch_json.py | 108 ++++++--- .../s46-r21-9348bmc-24-1.json | 98 +++++++++ .../s46-r21-9348bmc-24-1.json | 98 +++++++++ .../expected_outputs/s46-r06-3248bmc-6-1.json | 11 +- tests/test_unit.py | 207 +++++++++++++++++- 7 files changed, 622 insertions(+), 28 deletions(-) create mode 100644 input/switch_interface_templates/cisco/9348GC-FX3.json create mode 100644 input/switch_interface_templates/cisco/9348GC-FXP.json create mode 100644 tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-9348bmc-24-1.json create mode 100644 tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-9348bmc-24-1.json diff --git a/input/switch_interface_templates/cisco/9348GC-FX3.json b/input/switch_interface_templates/cisco/9348GC-FX3.json new file mode 100644 index 0000000..5456f8b --- /dev/null +++ b/input/switch_interface_templates/cisco/9348GC-FX3.json @@ -0,0 +1,64 @@ +{ + "Make": "Cisco", + "Model": "9348GC-FX3", + "Type": "BMC", + "interface_templates": { + "common": [ + { + "name": "Unused", + "type": "Access", + "description": "initial unused for all interfaces then config as defined", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/54", + "access_vlan": "2", + "shutdown": true + }, + { + "name": "Host_BMC", + "type": "Access", + "description": "Host BMC Connection", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/20", + "access_vlan": "125" + }, + { + "name": "HLH_BMC", + "type": "Access", + "description": "HLH BMC Connection", + "intf_type": "Ethernet", + "intf": "1/46", + "access_vlan": "125" + }, + { + "name": "HLH_OS", + "type": "Access", + "description": "HLH OS Connection", + "intf_type": "Ethernet", + "start_intf": "1/49", + "end_intf": "1/50", + "access_vlan": "125" + }, + { + "name": "To_TORs", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/51", + "end_intf": "1/52", + "native_vlan": "99", + "tagged_vlans": "125" + } + ] + }, + "port_channels": [ + { + "id": 102, + "description": "TOR_BMC", + "type": "Trunk", + "native_vlan": "99", + "tagged_vlans": "125", + "members": ["1/51", "1/52"] + } + ] +} diff --git a/input/switch_interface_templates/cisco/9348GC-FXP.json b/input/switch_interface_templates/cisco/9348GC-FXP.json new file mode 100644 index 0000000..7a53352 --- /dev/null +++ b/input/switch_interface_templates/cisco/9348GC-FXP.json @@ -0,0 +1,64 @@ +{ + "Make": "Cisco", + "Model": "9348GC-FXP", + "Type": "BMC", + "interface_templates": { + "common": [ + { + "name": "Unused", + "type": "Access", + "description": "initial unused for all interfaces then config as defined", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/54", + "access_vlan": "2", + "shutdown": true + }, + { + "name": "Host_BMC", + "type": "Access", + "description": "Host BMC Connection", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/16", + "access_vlan": "125" + }, + { + "name": "HLH_BMC", + "type": "Access", + "description": "HLH BMC Connection", + "intf_type": "Ethernet", + "intf": "1/46", + "access_vlan": "125" + }, + { + "name": "HLH_OS", + "type": "Access", + "description": "HLH OS Connection", + "intf_type": "Ethernet", + "start_intf": "1/49", + "end_intf": "1/50", + "access_vlan": "125" + }, + { + "name": "To_TORs", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/51", + "end_intf": "1/52", + "native_vlan": "99", + "tagged_vlans": "125" + } + ] + }, + "port_channels": [ + { + "id": 102, + "description": "TOR_BMC", + "type": "Trunk", + "native_vlan": "99", + "tagged_vlans": "125", + "members": ["1/51", "1/52"] + } + ] +} diff --git a/src/convertors/convertors_bmc_switch_json.py b/src/convertors/convertors_bmc_switch_json.py index 4b74afb..3014cff 100644 --- a/src/convertors/convertors_bmc_switch_json.py +++ b/src/convertors/convertors_bmc_switch_json.py @@ -10,6 +10,7 @@ from __future__ import annotations +import ipaddress import json import logging from copy import deepcopy @@ -56,14 +57,19 @@ def convert_all_bmc_switches(self) -> None: # ── private helpers ─────────────────────────────────────────────────── def _convert_single_bmc(self, switch_data: Dict) -> None: + template_data = self._load_template(switch_data) switch_info = self._build_switch_info(switch_data) vlans = self._build_vlans() - interfaces = self._build_interfaces(switch_data) + interfaces = self._build_interfaces(template_data) + port_channels = self._build_port_channels(template_data) + static_routes = self._build_static_routes() bmc_json: dict = { "switch": switch_info, "vlans": vlans, "interfaces": interfaces, + "port_channels": port_channels, + "static_routes": static_routes, } hostname = switch_info.get("hostname", "bmc") @@ -71,11 +77,41 @@ def _convert_single_bmc(self, switch_data: Dict) -> None: output_file.write_text(json.dumps(bmc_json, indent=2), encoding="utf-8") logger.info("Generated BMC config: %s", output_file) - # -- switch metadata --------------------------------------------------- + # -- template loading -------------------------------------------------- @staticmethod - def _build_switch_info(switch_data: Dict) -> Dict: + def _load_template(switch_data: Dict) -> Dict: + """Load the model-specific interface template JSON.""" + make = switch_data.get("Make", "").lower() + model = switch_data.get("Model", "").upper() + + template_path = get_real_path( + Path("input/switch_interface_templates") / make / f"{model}.json" + ) + + if not template_path.exists(): + raise FileNotFoundError( + f"BMC interface template not found: {template_path} " + f"(model={model}, make={make})" + ) + + try: + with template_path.open() as fh: + template_data = json.load(fh) + except json.JSONDecodeError as exc: + raise RuntimeError(f"Invalid JSON in BMC template {template_path}: {exc}") from exc + + logger.info("Loaded BMC interface template: %s", template_path) + return template_data + + # -- switch metadata --------------------------------------------------- + + def _build_switch_info(self, switch_data: Dict) -> Dict: + """Build switch metadata dict including site from input data.""" sw_make = switch_data.get("Make", "").lower() + # Site is stored in MainEnvData[0].Site (same path as TOR converter) + main_env = self.input_data.get("InputData", {}).get("MainEnvData", [{}]) + site = main_env[0].get("Site", "") if main_env else "" return { "make": sw_make, "model": switch_data.get("Model", "").lower(), @@ -83,6 +119,7 @@ def _build_switch_info(switch_data: Dict) -> Dict: "hostname": switch_data.get("Hostname", "").lower(), "version": switch_data.get("Firmware", "").lower(), "firmware": infer_firmware(sw_make), + "site": site.lower() if site else "", } # -- VLANs ------------------------------------------------------------- @@ -117,7 +154,6 @@ def _build_vlans(self) -> List[Dict]: # Add SVI for management VLANs that declare a gateway if group_name.startswith("BMC") and ipv4.get("SwitchSVI", False): - import ipaddress gateway_ip = ipv4.get("Gateway", "") if gateway_ip: try: @@ -147,33 +183,53 @@ def _is_bmc_relevant_vlan(group_name: str) -> bool: # -- interfaces -------------------------------------------------------- - def _build_interfaces(self, switch_data: Dict) -> List[Dict]: - """Load interfaces from the model-specific template file.""" - make = switch_data.get("Make", "").lower() - model = switch_data.get("Model", "").upper() + @staticmethod + def _build_interfaces(template_data: Dict) -> List[Dict]: + """Extract common interfaces from the loaded template.""" + common_templates = template_data.get("interface_templates", {}).get("common", []) + if not common_templates: + raise ValueError("No common interfaces found in BMC template") + return [deepcopy(t) for t in common_templates] - template_path = get_real_path( - Path("input/switch_interface_templates") / make / f"{model}.json" - ) + # -- port channels ----------------------------------------------------- - if not template_path.exists(): - raise FileNotFoundError( - f"BMC interface template not found: {template_path} " - f"(model={model}, make={make})" - ) + @staticmethod + def _build_port_channels(template_data: Dict) -> List[Dict]: + """Extract port-channels from the loaded template. - try: - with template_path.open() as fh: - template_data = json.load(fh) - except json.JSONDecodeError as exc: - raise RuntimeError(f"Invalid JSON in BMC template {template_path}: {exc}") from exc + BMC port-channels (e.g. TOR_BMC trunk) are defined in the template + and used as-is — no IP enrichment needed (unlike TOR P2P_IBGP). + """ + port_channels = template_data.get("port_channels", []) + return [deepcopy(pc) for pc in port_channels] - common_templates = template_data.get("interface_templates", {}).get("common", []) - if not common_templates: - raise ValueError(f"No common interfaces found in template: {template_path}") + # -- static routes ----------------------------------------------------- - logger.info("Loaded BMC interface template: %s", template_path) - return [deepcopy(t) for t in common_templates] + def _build_static_routes(self) -> List[Dict]: + """Build static routes for the BMC switch. + + The BMC switch typically has a default route pointing to the BMC + management VLAN gateway (derived from the BMC supernet). + """ + supernets = self.input_data.get("InputData", {}).get("Supernets", []) + + for net in supernets: + group_name = net.get("GroupName", "").upper() + if not group_name.startswith("BMC"): + continue + + ipv4 = net.get("IPv4", {}) + gateway = ipv4.get("Gateway", "") + if gateway: + return [ + { + "prefix": "0.0.0.0/0", + "next_hop": gateway, + "description": "BMC default gateway", + } + ] + + return [] # ── Module-level convenience function ────────────────────────────────────── diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-9348bmc-24-1.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-9348bmc-24-1.json new file mode 100644 index 0000000..38687a5 --- /dev/null +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-9348bmc-24-1.json @@ -0,0 +1,98 @@ +{ + "switch": { + "make": "cisco", + "model": "9348gc-fx3", + "type": "BMC", + "hostname": "s46-r21-9348bmc-24-1", + "version": "10.3(4a)", + "firmware": "nxos", + "site": "rr1" + }, + "vlans": [ + { + "vlan_id": 2, + "name": "UNUSED_VLAN", + "shutdown": true + }, + { + "vlan_id": 99, + "name": "NATIVE_VLAN" + }, + { + "vlan_id": 125, + "name": "BMC_Mgmt_125", + "interface": { + "ip": "100.71.85.126", + "cidr": 26, + "mtu": 9216 + } + } + ], + "interfaces": [ + { + "name": "Unused", + "type": "Access", + "description": "initial unused for all interfaces then config as defined", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/54", + "access_vlan": "2", + "shutdown": true + }, + { + "name": "Host_BMC", + "type": "Access", + "description": "Host BMC Connection", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/20", + "access_vlan": "125" + }, + { + "name": "HLH_BMC", + "type": "Access", + "description": "HLH BMC Connection", + "intf_type": "Ethernet", + "intf": "1/46", + "access_vlan": "125" + }, + { + "name": "HLH_OS", + "type": "Access", + "description": "HLH OS Connection", + "intf_type": "Ethernet", + "start_intf": "1/49", + "end_intf": "1/50", + "access_vlan": "125" + }, + { + "name": "To_TORs", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/51", + "end_intf": "1/52", + "native_vlan": "99", + "tagged_vlans": "125" + } + ], + "port_channels": [ + { + "id": 102, + "description": "TOR_BMC", + "type": "Trunk", + "native_vlan": "99", + "tagged_vlans": "125", + "members": [ + "1/51", + "1/52" + ] + } + ], + "static_routes": [ + { + "prefix": "0.0.0.0/0", + "next_hop": "100.71.85.65", + "description": "BMC default gateway" + } + ] +} diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-9348bmc-24-1.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-9348bmc-24-1.json new file mode 100644 index 0000000..c188452 --- /dev/null +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-9348bmc-24-1.json @@ -0,0 +1,98 @@ +{ + "switch": { + "make": "cisco", + "model": "9348gc-fxp", + "type": "BMC", + "hostname": "s46-r21-9348bmc-24-1", + "version": "9.3(11)", + "firmware": "nxos", + "site": "rr1" + }, + "vlans": [ + { + "vlan_id": 2, + "name": "UNUSED_VLAN", + "shutdown": true + }, + { + "vlan_id": 99, + "name": "NATIVE_VLAN" + }, + { + "vlan_id": 125, + "name": "BMC_Mgmt_125", + "interface": { + "ip": "100.71.85.126", + "cidr": 26, + "mtu": 9216 + } + } + ], + "interfaces": [ + { + "name": "Unused", + "type": "Access", + "description": "initial unused for all interfaces then config as defined", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/54", + "access_vlan": "2", + "shutdown": true + }, + { + "name": "Host_BMC", + "type": "Access", + "description": "Host BMC Connection", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/16", + "access_vlan": "125" + }, + { + "name": "HLH_BMC", + "type": "Access", + "description": "HLH BMC Connection", + "intf_type": "Ethernet", + "intf": "1/46", + "access_vlan": "125" + }, + { + "name": "HLH_OS", + "type": "Access", + "description": "HLH OS Connection", + "intf_type": "Ethernet", + "start_intf": "1/49", + "end_intf": "1/50", + "access_vlan": "125" + }, + { + "name": "To_TORs", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/51", + "end_intf": "1/52", + "native_vlan": "99", + "tagged_vlans": "125" + } + ], + "port_channels": [ + { + "id": 102, + "description": "TOR_BMC", + "type": "Trunk", + "native_vlan": "99", + "tagged_vlans": "125", + "members": [ + "1/51", + "1/52" + ] + } + ], + "static_routes": [ + { + "prefix": "0.0.0.0/0", + "next_hop": "100.71.85.65", + "description": "BMC default gateway" + } + ] +} diff --git a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json index 21a16ac..ca13084 100644 --- a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json +++ b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json @@ -5,7 +5,8 @@ "type": "BMC", "hostname": "s46-r06-3248bmc-6-1", "version": "10.5.5.5", - "firmware": "os10" + "firmware": "os10", + "site": "rr1" }, "vlans": [ { @@ -73,5 +74,13 @@ "native_vlan": "99", "tagged_vlans": "7,125" } + ], + "port_channels": [], + "static_routes": [ + { + "prefix": "0.0.0.0/0", + "next_hop": "100.71.12.65", + "description": "BMC default gateway" + } ] } \ No newline at end of file diff --git a/tests/test_unit.py b/tests/test_unit.py index b988cc0..3095e61 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -1,4 +1,4 @@ -"""Unit tests for src/constants.py, src/utils.py, and src/loader.py.""" +"""Unit tests for src/constants.py, src/utils.py, src/loader.py, and BMC converter.""" from __future__ import annotations @@ -22,6 +22,7 @@ ) from src.utils import infer_firmware, classify_vlan_group from src.loader import load_input_json, get_real_path +from src.convertors.convertors_bmc_switch_json import BMCSwitchConverter # ── infer_firmware ──────────────────────────────────────────────────────── @@ -125,3 +126,207 @@ def test_templates_not_mutated(self): assert SWITCH_TEMPLATE["make"] == "" assert SVI_TEMPLATE["ip"] == "" assert VLAN_TEMPLATE["vlan_id"] == 0 + + +# ── BMC converter ──────────────────────────────────────────────────────── + +def _make_bmc_input(*, site="testsite", bmc_make="Cisco", bmc_model="9348GC-FXP", + bmc_hostname="test-bmc-1", bmc_firmware="10.4.5", + bmc_gateway="10.0.0.1", bmc_network="10.0.0.0", bmc_cidr=24, + bmc_vlan_id=125): + """Helper to create a minimal lab input with BMC switch and supernets.""" + return { + "InputData": { + "MainEnvData": [{"Site": site}], + "Switches": [ + { + "Make": bmc_make, + "Model": bmc_model, + "Type": "BMC", + "Hostname": bmc_hostname, + "ASN": None, + "Firmware": bmc_firmware, + } + ], + "Supernets": [ + { + "GroupName": "BMC", + "Name": f"BMC_Mgmt_{bmc_vlan_id}", + "VLANID": bmc_vlan_id, + "IPv4": { + "SwitchSVI": True, + "Name": f"BMC_Mgmt_{bmc_vlan_id}", + "VLANID": bmc_vlan_id, + "Cidr": bmc_cidr, + "Network": bmc_network, + "Gateway": bmc_gateway, + }, + }, + { + "GroupName": "UNUSED_VLAN", + "Name": "UNUSED_VLAN", + "IPv4": {"Name": "UNUSED_VLAN", "VLANID": 2}, + }, + { + "GroupName": "NativeVlan", + "Name": "NativeVlan", + "IPv4": {"Name": "NativeVlan", "VLANID": 99}, + }, + ], + } + } + + +class TestBMCSwitchInfo: + def test_site_from_main_env_data(self, tmp_path): + input_data = _make_bmc_input(site="lab42") + conv = BMCSwitchConverter(input_data, str(tmp_path)) + switch_data = input_data["InputData"]["Switches"][0] + info = conv._build_switch_info(switch_data) + assert info["site"] == "lab42" + + def test_site_empty_when_missing(self, tmp_path): + input_data = _make_bmc_input() + input_data["InputData"]["MainEnvData"] = [] + conv = BMCSwitchConverter(input_data, str(tmp_path)) + switch_data = input_data["InputData"]["Switches"][0] + info = conv._build_switch_info(switch_data) + assert info["site"] == "" + + def test_firmware_inferred(self, tmp_path): + input_data = _make_bmc_input(bmc_make="Cisco") + conv = BMCSwitchConverter(input_data, str(tmp_path)) + switch_data = input_data["InputData"]["Switches"][0] + info = conv._build_switch_info(switch_data) + assert info["firmware"] == "nxos" + assert info["make"] == "cisco" + + def test_hostname_lowered(self, tmp_path): + input_data = _make_bmc_input(bmc_hostname="TEST-BMC-Upper") + conv = BMCSwitchConverter(input_data, str(tmp_path)) + switch_data = input_data["InputData"]["Switches"][0] + info = conv._build_switch_info(switch_data) + assert info["hostname"] == "test-bmc-upper" + + +class TestBMCVlans: + def test_hardcoded_vlans_always_present(self, tmp_path): + input_data = _make_bmc_input() + conv = BMCSwitchConverter(input_data, str(tmp_path)) + vlans = conv._build_vlans() + vlan_ids = {v["vlan_id"] for v in vlans} + assert 2 in vlan_ids + assert 99 in vlan_ids + + def test_bmc_vlan_from_supernet(self, tmp_path): + input_data = _make_bmc_input(bmc_vlan_id=125) + conv = BMCSwitchConverter(input_data, str(tmp_path)) + vlans = conv._build_vlans() + v125 = next((v for v in vlans if v["vlan_id"] == 125), None) + assert v125 is not None + assert v125["name"] == "BMC_Mgmt_125" + + def test_bmc_svi_populated(self, tmp_path): + input_data = _make_bmc_input(bmc_gateway="10.0.0.1", bmc_network="10.0.0.0", + bmc_cidr=24, bmc_vlan_id=125) + conv = BMCSwitchConverter(input_data, str(tmp_path)) + vlans = conv._build_vlans() + v125 = next(v for v in vlans if v["vlan_id"] == 125) + assert "interface" in v125 + assert v125["interface"]["cidr"] == 24 + assert v125["interface"]["mtu"] == JUMBO_MTU + + def test_vlans_sorted_by_id(self, tmp_path): + input_data = _make_bmc_input() + conv = BMCSwitchConverter(input_data, str(tmp_path)) + vlans = conv._build_vlans() + ids = [v["vlan_id"] for v in vlans] + assert ids == sorted(ids) + + def test_hardcoded_vlans_not_mutated(self, tmp_path): + """Calling _build_vlans should not modify BMC_HARDCODED_VLANS.""" + before = [dict(v) for v in BMC_HARDCODED_VLANS] + input_data = _make_bmc_input() + conv = BMCSwitchConverter(input_data, str(tmp_path)) + conv._build_vlans() + after = [dict(v) for v in BMC_HARDCODED_VLANS] + assert before == after + + +class TestBMCPortChannels: + def test_port_channels_from_template(self, tmp_path): + template_data = { + "interface_templates": {"common": [{"name": "test", "type": "Access"}]}, + "port_channels": [ + {"id": 102, "description": "TOR_BMC", "type": "Trunk", + "native_vlan": "99", "tagged_vlans": "125", "members": ["1/51", "1/52"]} + ], + } + pcs = BMCSwitchConverter._build_port_channels(template_data) + assert len(pcs) == 1 + assert pcs[0]["id"] == 102 + assert pcs[0]["members"] == ["1/51", "1/52"] + + def test_empty_when_no_port_channels(self, tmp_path): + template_data = {"interface_templates": {"common": [{"name": "test"}]}} + pcs = BMCSwitchConverter._build_port_channels(template_data) + assert pcs == [] + + def test_deep_copy_prevents_mutation(self, tmp_path): + original = [{"id": 1, "members": ["1/1"]}] + template_data = {"port_channels": original} + pcs = BMCSwitchConverter._build_port_channels(template_data) + pcs[0]["id"] = 999 + assert original[0]["id"] == 1 + + +class TestBMCStaticRoutes: + def test_default_route_from_bmc_gateway(self, tmp_path): + input_data = _make_bmc_input(bmc_gateway="10.0.0.1") + conv = BMCSwitchConverter(input_data, str(tmp_path)) + routes = conv._build_static_routes() + assert len(routes) == 1 + assert routes[0]["prefix"] == "0.0.0.0/0" + assert routes[0]["next_hop"] == "10.0.0.1" + + def test_no_routes_without_bmc_supernet(self, tmp_path): + input_data = _make_bmc_input() + # Remove BMC supernet + input_data["InputData"]["Supernets"] = [ + s for s in input_data["InputData"]["Supernets"] + if not s.get("GroupName", "").upper().startswith("BMC") + ] + conv = BMCSwitchConverter(input_data, str(tmp_path)) + routes = conv._build_static_routes() + assert routes == [] + + def test_no_routes_without_gateway(self, tmp_path): + input_data = _make_bmc_input() + # Remove gateway + for s in input_data["InputData"]["Supernets"]: + if s.get("GroupName", "").upper().startswith("BMC"): + s["IPv4"]["Gateway"] = "" + conv = BMCSwitchConverter(input_data, str(tmp_path)) + routes = conv._build_static_routes() + assert routes == [] + + +class TestBMCInterfaces: + def test_interfaces_from_template(self, tmp_path): + template_data = { + "interface_templates": { + "common": [ + {"name": "Unused", "type": "Access", "access_vlan": "2"}, + {"name": "Host_BMC", "type": "Access", "access_vlan": "125"}, + ] + } + } + intfs = BMCSwitchConverter._build_interfaces(template_data) + assert len(intfs) == 2 + assert intfs[0]["name"] == "Unused" + assert intfs[1]["name"] == "Host_BMC" + + def test_raises_on_empty_common(self, tmp_path): + template_data = {"interface_templates": {"common": []}} + with pytest.raises(ValueError, match="No common interfaces"): + BMCSwitchConverter._build_interfaces(template_data) From 7e9ba51e768bf917a0024cb613cb6f04f9ca1227 Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Sat, 7 Feb 2026 00:09:06 +0000 Subject: [PATCH 03/11] docs: add Design Principle 8 (TOR=production, BMC=internal) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ROADMAP.md: Added principle 8 — TOR configs must be template-driven and production-quality; BMC configs may hardcode values but must have clear comments for future troubleshooting. - constants.py: Enhanced BMC_HARDCODED_VLANS and BMC_RELEVANT_GROUPS comments explaining what each VLAN/prefix means, why it exists, and what to update. - convertors_bmc_switch_json.py: Updated module docstring to reference the principle; improved docstrings on _build_port_channels and _build_static_routes with change-guidance for future engineers. --- src/constants.py | 20 ++++++++++++++---- src/convertors/convertors_bmc_switch_json.py | 22 ++++++++++++++------ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/constants.py b/src/constants.py index 03ea21e..ce17f1d 100644 --- a/src/constants.py +++ b/src/constants.py @@ -57,14 +57,26 @@ "NATIVE": "NATIVE", } -# ── BMC VLAN definitions (hardcoded for POC — DC4) ─────────────────────── -# These are the VLANs that every BMC switch gets, regardless of vendor. -# Consistent for all vendors since BMC is lab-internal. +# ── BMC VLAN definitions (hardcoded — DC4, Design Principle 8) ──────── +# BMC switches are internal-only; these VLANs are hardcoded for simplicity. +# +# VLAN 2 – "UNUSED_VLAN": assigned to all ports by default then overridden; +# keeps unused ports on a dead-end VLAN (security best practice). +# VLAN 99 – "NATIVE_VLAN": native/untagged VLAN on trunk links (To_TORs +# port-channel). Must match the native_vlan in the BMC interface +# templates (e.g. 9348GC-FXP.json port_channels[].native_vlan). +# +# To change: update both this list AND the corresponding template JSONs. BMC_HARDCODED_VLANS: list[dict] = [ {"vlan_id": 2, "name": "UNUSED_VLAN", "shutdown": True}, {"vlan_id": 99, "name": "NATIVE_VLAN"}, ] -# BMC-relevant supernet group prefixes (additional VLANs pulled from input) + +# Supernet GroupName prefixes that produce VLANs on the BMC switch. +# "BMC" — the actual BMC management network (VLAN 125 in typical deployments) +# "UNUSED"/"NATIVE" — reserved VLANs already covered by the hardcoded list +# above, but included so the converter doesn't silently +# drop them if their IDs change in the input. BMC_RELEVANT_GROUPS: list[str] = ["BMC", "UNUSED", "NATIVE"] # ── IP map key prefixes (used by _build_ip_mapping) ────────────────────── diff --git a/src/convertors/convertors_bmc_switch_json.py b/src/convertors/convertors_bmc_switch_json.py index 3014cff..95935ed 100644 --- a/src/convertors/convertors_bmc_switch_json.py +++ b/src/convertors/convertors_bmc_switch_json.py @@ -4,8 +4,12 @@ Converts BMC switch definitions from lab input JSON to standardised JSON format. Called from the main TOR converter but kept separate for modularity. -Since BMC switches are for internal lab use only, some configurations are hardcoded -for simplicity (see DC4 decision) and can be refined later. +Design Principle 8 (TOR=production, BMC=internal): + BMC switches are internal-only tooling — complex settings (VLANs, port-channels, + static routes, QoS) are hardcoded for simplicity rather than fully parameterised. + Every hardcoded value has a comment explaining what it is and why, so future + engineers can update values without reverse-engineering the logic. + See DC4 decision in ROADMAP.md for the VLAN hardcoding rationale. """ from __future__ import annotations @@ -197,8 +201,11 @@ def _build_interfaces(template_data: Dict) -> List[Dict]: def _build_port_channels(template_data: Dict) -> List[Dict]: """Extract port-channels from the loaded template. - BMC port-channels (e.g. TOR_BMC trunk) are defined in the template - and used as-is — no IP enrichment needed (unlike TOR P2P_IBGP). + BMC port-channels are hardcoded in the per-model template JSON + (e.g. port-channel 102 = TOR_BMC trunk on Eth1/51-1/52). + Used as-is — no IP enrichment needed (unlike TOR P2P_IBGP channels). + To change port-channel IDs or members, edit the template JSON in + input/switch_interface_templates//.json. """ port_channels = template_data.get("port_channels", []) return [deepcopy(pc) for pc in port_channels] @@ -208,8 +215,11 @@ def _build_port_channels(template_data: Dict) -> List[Dict]: def _build_static_routes(self) -> List[Dict]: """Build static routes for the BMC switch. - The BMC switch typically has a default route pointing to the BMC - management VLAN gateway (derived from the BMC supernet). + Hardcoded: a single 0.0.0.0/0 default route pointing to the BMC + management VLAN gateway (derived from the first BMC supernet). + This is sufficient because BMC switches only need reachability to + the management network — they don't participate in BGP/OSPF. + To add more routes, append to the returned list. """ supernets = self.input_data.get("InputData", {}).get("Supernets", []) From 3d9b44a0d4f05d878bb21434bf1a2f1ad3815073 Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Sat, 7 Feb 2026 05:00:17 +0000 Subject: [PATCH 04/11] refactor(tests): sanitize lab identifiers and reorganize unit tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test data sanitization: - Replaced all lab-specific hostnames (s46-r21-*, b88-b11-*, etc.) with generic role-based names (tor-1a, border-1a, bmc-1, mux-1) - Replaced all lab IPs (100.71.85.x, 100.69.x, etc.) with private 10.x.x.x addresses, preserving subnet alignment for /23 and /22 networks - Replaced domains (masd.stbtest.microsoft.com → test.example.com), sites (rr1 → site1, b88 → site2), naming prefixes, and regions - Renamed 12 expected output files and 1 reference config to match sanitized hostnames - 49 files modified, zero lab identifiers remaining test_unit.py rewrite: - Clear module docstring explaining organization by module under test - Added pytest fixtures (bmc_converter, bmc_switch_data) to reduce boilerplate — BMC tests that use static methods no longer need tmp_path - Consolidated similar tests via parametrize (e.g. vendor mapping) - Class-level docstrings describing what each test group validates - Shared template data as class attributes where appropriate - Same test count (42 unit tests), same coverage, cleaner structure All 73 tests pass, 8 skipped. --- .../{s46-r21-9348bmc-24-1.json => bmc-1.json} | 8 +- ...s46-r21-93180hl-24-1a.json => tor-1a.json} | 226 ++-- ...s46-r21-93180hl-24-1b.json => tor-1b.json} | 226 ++-- .../lab_cisco_nxos_switch_input.json | 824 +++++++-------- .../{s46-r21-9348bmc-24-1.json => bmc-1.json} | 8 +- ...s46-r21-93180hl-24-1a.json => tor-1a.json} | 226 ++-- ...s46-r21-93180hl-24-1b.json => tor-1b.json} | 226 ++-- .../lab_cisco_nxos_switch_input.json | 824 +++++++-------- ...{b88-b11-93108hl-2-1a.json => tor-1a.json} | 228 ++--- ...{b88-b11-93108hl-2-1b.json => tor-1b.json} | 228 ++--- .../lab_cisco_nxos_switch_input.json | 968 +++++++++--------- .../{s46-r06-3248bmc-6-1.json => bmc-1.json} | 8 +- .../{s46-r06-5248hl-6-1a.json => tor-1a.json} | 228 ++--- .../{s46-r06-5248hl-6-1b.json => tor-1b.json} | 228 ++--- .../lab_dell_os10_switch_input.json | 824 +++++++-------- .../std_cisco_nxos_fc/expected_bgp.cfg | 54 +- .../std_cisco_nxos_fc_input.json | 148 +-- ...r21-93180hl-24-1a.config => tor-1a.config} | 178 ++-- .../std_cisco_nxos_switched/expected_bgp.cfg | 54 +- .../expected_full_config.cfg | 154 +-- .../expected_interface.cfg | 6 +- .../expected_port_channel.cfg | 2 +- .../expected_system.cfg | 6 +- .../std_cisco_nxos_switched/expected_vlan.cfg | 86 +- .../std_cisco_nxos_switched_input.json | 150 +-- .../std_dell_os10_fc/expected_bgp.cfg | 54 +- .../std_dell_os10_fc/expected_full_config.cfg | 156 +-- .../std_dell_os10_fc/expected_interface.cfg | 6 +- .../expected_port_channel.cfg | 2 +- .../std_dell_os10_fc/expected_system.cfg | 6 +- .../std_dell_os10_fc/expected_vlan.cfg | 88 +- .../std_dell_os10_fc_input.json | 152 +-- tests/test_unit.py | 429 ++++---- 33 files changed, 3511 insertions(+), 3500 deletions(-) rename tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/{s46-r21-9348bmc-24-1.json => bmc-1.json} (93%) rename tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/{s46-r21-93180hl-24-1a.json => tor-1a.json} (73%) rename tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/{s46-r21-93180hl-24-1b.json => tor-1b.json} (73%) rename tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/{s46-r21-9348bmc-24-1.json => bmc-1.json} (93%) rename tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/{s46-r21-93180hl-24-1a.json => tor-1a.json} (74%) rename tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/{s46-r21-93180hl-24-1b.json => tor-1b.json} (74%) rename tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/{b88-b11-93108hl-2-1a.json => tor-1a.json} (73%) rename tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/{b88-b11-93108hl-2-1b.json => tor-1b.json} (73%) rename tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/{s46-r06-3248bmc-6-1.json => bmc-1.json} (93%) rename tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/{s46-r06-5248hl-6-1a.json => tor-1a.json} (74%) rename tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/{s46-r06-5248hl-6-1b.json => tor-1b.json} (74%) rename tests/test_cases/std_cisco_nxos_fc/{s46-r21-93180hl-24-1a.config => tor-1a.config} (91%) diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-9348bmc-24-1.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/bmc-1.json similarity index 93% rename from tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-9348bmc-24-1.json rename to tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/bmc-1.json index 38687a5..6635d88 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-9348bmc-24-1.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/bmc-1.json @@ -3,10 +3,10 @@ "make": "cisco", "model": "9348gc-fx3", "type": "BMC", - "hostname": "s46-r21-9348bmc-24-1", + "hostname": "bmc-1", "version": "10.3(4a)", "firmware": "nxos", - "site": "rr1" + "site": "site1" }, "vlans": [ { @@ -22,7 +22,7 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.85.126", + "ip": "10.1.1.126", "cidr": 26, "mtu": 9216 } @@ -91,7 +91,7 @@ "static_routes": [ { "prefix": "0.0.0.0/0", - "next_hop": "100.71.85.65", + "next_hop": "10.1.1.65", "description": "BMC default gateway" } ] diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-93180hl-24-1a.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/tor-1a.json similarity index 73% rename from tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-93180hl-24-1a.json rename to tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/tor-1a.json index 7c091e0..5d12306 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-93180hl-24-1a.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/tor-1a.json @@ -3,10 +3,10 @@ "make": "cisco", "model": "93180yc-fx3", "type": "TOR1", - "hostname": "s46-r21-93180hl-24-1a", + "hostname": "tor-1a", "version": "10.3(4a)", "firmware": "nxos", - "site": "rr1" + "site": "site1" }, "vlans": [ { @@ -18,14 +18,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.71.131.2", + "ip": "10.2.1.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 6, "priority": 150, - "virtual_ip": "100.71.131.1" + "virtual_ip": "10.2.1.1" } } }, @@ -33,14 +33,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.69.176.2", + "ip": "10.3.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 7, "priority": 150, - "virtual_ip": "100.69.176.1" + "virtual_ip": "10.3.1.1" } } }, @@ -52,14 +52,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.85.123", + "ip": "10.1.1.123", "cidr": 26, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 125, "priority": 150, - "virtual_ip": "100.71.85.65" + "virtual_ip": "10.1.1.65" } } }, @@ -67,14 +67,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.69.177.2", + "ip": "10.4.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 201, "priority": 150, - "virtual_ip": "100.69.177.1" + "virtual_ip": "10.4.1.1" } } }, @@ -82,14 +82,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.69.178.2", + "ip": "10.5.2.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 301, "priority": 150, - "virtual_ip": "100.69.178.1" + "virtual_ip": "10.5.2.1" } } }, @@ -97,14 +97,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.69.178.130", + "ip": "10.5.2.130", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 401, "priority": 150, - "virtual_ip": "100.69.178.129" + "virtual_ip": "10.5.2.129" } } }, @@ -112,14 +112,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.69.179.2", + "ip": "10.5.1.2", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 501, "priority": 150, - "virtual_ip": "100.69.179.1" + "virtual_ip": "10.5.1.1" } } }, @@ -127,14 +127,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.69.179.18", + "ip": "10.5.1.18", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 502, "priority": 150, - "virtual_ip": "100.69.179.17" + "virtual_ip": "10.5.1.17" } } }, @@ -142,14 +142,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.69.179.34", + "ip": "10.5.1.34", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 503, "priority": 150, - "virtual_ip": "100.69.179.33" + "virtual_ip": "10.5.1.33" } } }, @@ -157,14 +157,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.69.179.50", + "ip": "10.5.1.50", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 504, "priority": 150, - "virtual_ip": "100.69.179.49" + "virtual_ip": "10.5.1.49" } } }, @@ -172,14 +172,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.69.179.66", + "ip": "10.5.1.66", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 505, "priority": 150, - "virtual_ip": "100.69.179.65" + "virtual_ip": "10.5.1.65" } } }, @@ -187,14 +187,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.69.179.82", + "ip": "10.5.1.82", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 506, "priority": 150, - "virtual_ip": "100.69.179.81" + "virtual_ip": "10.5.1.81" } } }, @@ -202,14 +202,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.69.179.98", + "ip": "10.5.1.98", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 507, "priority": 150, - "virtual_ip": "100.69.179.97" + "virtual_ip": "10.5.1.97" } } }, @@ -217,14 +217,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.69.179.114", + "ip": "10.5.1.114", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 508, "priority": 150, - "virtual_ip": "100.69.179.113" + "virtual_ip": "10.5.1.113" } } }, @@ -232,14 +232,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.69.179.130", + "ip": "10.5.1.130", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 509, "priority": 150, - "virtual_ip": "100.69.179.129" + "virtual_ip": "10.5.1.129" } } }, @@ -247,7 +247,7 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.69.179.145", + "ip": "10.5.1.145", "cidr": 28, "mtu": 9216, "redundancy": { @@ -262,14 +262,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.69.179.162", + "ip": "10.5.1.162", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 511, "priority": 150, - "virtual_ip": "100.69.179.161" + "virtual_ip": "10.5.1.161" } } }, @@ -277,14 +277,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.69.179.178", + "ip": "10.5.1.178", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 512, "priority": 150, - "virtual_ip": "100.69.179.177" + "virtual_ip": "10.5.1.177" } } }, @@ -292,14 +292,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.69.179.194", + "ip": "10.5.1.194", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 513, "priority": 150, - "virtual_ip": "100.69.179.193" + "virtual_ip": "10.5.1.193" } } }, @@ -307,14 +307,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.69.179.210", + "ip": "10.5.1.210", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 514, "priority": 150, - "virtual_ip": "100.69.179.209" + "virtual_ip": "10.5.1.209" } } }, @@ -322,14 +322,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.69.179.226", + "ip": "10.5.1.226", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 515, "priority": 150, - "virtual_ip": "100.69.179.225" + "virtual_ip": "10.5.1.225" } } }, @@ -337,14 +337,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.69.179.242", + "ip": "10.5.1.242", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 516, "priority": 150, - "virtual_ip": "100.69.179.241" + "virtual_ip": "10.5.1.241" } } }, @@ -373,21 +373,21 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.71.85.21/32" + "ipv4": "10.1.1.21/32" }, { "name": "P2P_Border1", "type": "L3", "intf_type": "Ethernet", "intf": "1/48", - "ipv4": "100.71.85.2/30" + "ipv4": "10.1.1.2/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/47", - "ipv4": "100.71.85.10/30" + "ipv4": "10.1.1.10/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -403,7 +403,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.71.85.17", + "ipv4": "10.1.1.17", "members": [ "1/41", "1/42" @@ -423,38 +423,38 @@ ], "bgp": { "asn": 65242, - "router_id": "100.71.85.21", + "router_id": "10.1.1.21", "networks": [ - "100.71.85.2/30", - "100.71.85.10/30", - "100.71.85.21/32", - "100.71.85.16/30", - "100.71.131.0/25", - "100.69.176.0/24", - "100.71.85.64/26", - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.1.1.2/30", + "10.1.1.10/30", + "10.1.1.21/32", + "10.1.1.16/30", + "10.2.1.0/25", + "10.3.1.0/24", + "10.1.1.64/26", + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ], "neighbors": [ { - "ip": "100.71.85.1", + "ip": "10.1.1.1", "description": "TO_Border1", "remote_as": 64846, "af_ipv4_unicast": { @@ -462,7 +462,7 @@ } }, { - "ip": "100.71.85.9", + "ip": "10.1.1.9", "description": "TO_Border2", "remote_as": 64846, "af_ipv4_unicast": { @@ -470,13 +470,13 @@ } }, { - "ip": "100.71.85.18", + "ip": "10.1.1.18", "description": "iBGP_PEER", "remote_as": 65242, "af_ipv4_unicast": {} }, { - "ip": "100.71.131.0/25", + "ip": "10.2.1.0/25", "description": "TO_HNVPA", "remote_as": 65112, "update_source": "Loopback0", @@ -549,67 +549,67 @@ }, "ip_map": { "P2P_BORDER1_TOR1": [ - "100.71.85.2/30" + "10.1.1.2/30" ], "P2P_TOR1_BORDER1": [ - "100.71.85.1" + "10.1.1.1" ], "P2P_BORDER1_TOR2": [ - "100.71.85.6/30" + "10.1.1.6/30" ], "P2P_TOR2_BORDER1": [ - "100.71.85.5" + "10.1.1.5" ], "P2P_BORDER2_TOR1": [ - "100.71.85.10/30" + "10.1.1.10/30" ], "P2P_TOR1_BORDER2": [ - "100.71.85.9" + "10.1.1.9" ], "P2P_BORDER2_TOR2": [ - "100.71.85.14/30" + "10.1.1.14/30" ], "P2P_TOR2_BORDER2": [ - "100.71.85.13" + "10.1.1.13" ], "P2P_IBGP_TOR1": [ - "100.71.85.17" + "10.1.1.17" ], "P2P_IBGP_TOR2": [ - "100.71.85.18" + "10.1.1.18" ], "LOOPBACK0_TOR1": [ - "100.71.85.21/32" + "10.1.1.21/32" ], "LOOPBACK0_TOR2": [ - "100.71.85.22/32" + "10.1.1.22/32" ], "HNVPA": [ - "100.71.131.0/25" + "10.2.1.0/25" ], "M": [ - "100.69.176.0/24" + "10.3.1.0/24" ], "C": [ - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ] }, "resolved_trunks": [ diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-93180hl-24-1b.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/tor-1b.json similarity index 73% rename from tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-93180hl-24-1b.json rename to tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/tor-1b.json index 91be8bd..cd66689 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/s46-r21-93180hl-24-1b.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/expected_outputs/tor-1b.json @@ -3,10 +3,10 @@ "make": "cisco", "model": "93180yc-fx3", "type": "TOR2", - "hostname": "s46-r21-93180hl-24-1b", + "hostname": "tor-1b", "version": "10.3(4a)", "firmware": "nxos", - "site": "rr1" + "site": "site1" }, "vlans": [ { @@ -18,14 +18,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.71.131.3", + "ip": "10.2.1.3", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 6, "priority": 140, - "virtual_ip": "100.71.131.1" + "virtual_ip": "10.2.1.1" } } }, @@ -33,14 +33,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.69.176.3", + "ip": "10.3.1.3", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 7, "priority": 140, - "virtual_ip": "100.69.176.1" + "virtual_ip": "10.3.1.1" } } }, @@ -52,14 +52,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.85.124", + "ip": "10.1.1.124", "cidr": 26, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 125, "priority": 140, - "virtual_ip": "100.71.85.65" + "virtual_ip": "10.1.1.65" } } }, @@ -67,14 +67,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.69.177.3", + "ip": "10.4.1.3", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 201, "priority": 140, - "virtual_ip": "100.69.177.1" + "virtual_ip": "10.4.1.1" } } }, @@ -82,14 +82,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.69.178.3", + "ip": "10.5.2.3", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 301, "priority": 140, - "virtual_ip": "100.69.178.1" + "virtual_ip": "10.5.2.1" } } }, @@ -97,14 +97,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.69.178.131", + "ip": "10.5.2.131", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 401, "priority": 140, - "virtual_ip": "100.69.178.129" + "virtual_ip": "10.5.2.129" } } }, @@ -112,14 +112,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.69.179.3", + "ip": "10.5.1.3", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 501, "priority": 140, - "virtual_ip": "100.69.179.1" + "virtual_ip": "10.5.1.1" } } }, @@ -127,14 +127,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.69.179.19", + "ip": "10.5.1.19", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 502, "priority": 140, - "virtual_ip": "100.69.179.17" + "virtual_ip": "10.5.1.17" } } }, @@ -142,14 +142,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.69.179.35", + "ip": "10.5.1.35", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 503, "priority": 140, - "virtual_ip": "100.69.179.33" + "virtual_ip": "10.5.1.33" } } }, @@ -157,14 +157,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.69.179.51", + "ip": "10.5.1.51", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 504, "priority": 140, - "virtual_ip": "100.69.179.49" + "virtual_ip": "10.5.1.49" } } }, @@ -172,14 +172,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.69.179.67", + "ip": "10.5.1.67", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 505, "priority": 140, - "virtual_ip": "100.69.179.65" + "virtual_ip": "10.5.1.65" } } }, @@ -187,14 +187,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.69.179.83", + "ip": "10.5.1.83", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 506, "priority": 140, - "virtual_ip": "100.69.179.81" + "virtual_ip": "10.5.1.81" } } }, @@ -202,14 +202,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.69.179.99", + "ip": "10.5.1.99", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 507, "priority": 140, - "virtual_ip": "100.69.179.97" + "virtual_ip": "10.5.1.97" } } }, @@ -217,14 +217,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.69.179.115", + "ip": "10.5.1.115", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 508, "priority": 140, - "virtual_ip": "100.69.179.113" + "virtual_ip": "10.5.1.113" } } }, @@ -232,14 +232,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.69.179.131", + "ip": "10.5.1.131", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 509, "priority": 140, - "virtual_ip": "100.69.179.129" + "virtual_ip": "10.5.1.129" } } }, @@ -247,7 +247,7 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.69.179.146", + "ip": "10.5.1.146", "cidr": 28, "mtu": 9216, "redundancy": { @@ -262,14 +262,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.69.179.163", + "ip": "10.5.1.163", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 511, "priority": 140, - "virtual_ip": "100.69.179.161" + "virtual_ip": "10.5.1.161" } } }, @@ -277,14 +277,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.69.179.179", + "ip": "10.5.1.179", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 512, "priority": 140, - "virtual_ip": "100.69.179.177" + "virtual_ip": "10.5.1.177" } } }, @@ -292,14 +292,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.69.179.195", + "ip": "10.5.1.195", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 513, "priority": 140, - "virtual_ip": "100.69.179.193" + "virtual_ip": "10.5.1.193" } } }, @@ -307,14 +307,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.69.179.211", + "ip": "10.5.1.211", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 514, "priority": 140, - "virtual_ip": "100.69.179.209" + "virtual_ip": "10.5.1.209" } } }, @@ -322,14 +322,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.69.179.227", + "ip": "10.5.1.227", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 515, "priority": 140, - "virtual_ip": "100.69.179.225" + "virtual_ip": "10.5.1.225" } } }, @@ -337,14 +337,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.69.179.243", + "ip": "10.5.1.243", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 516, "priority": 140, - "virtual_ip": "100.69.179.241" + "virtual_ip": "10.5.1.241" } } }, @@ -373,21 +373,21 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.71.85.22/32" + "ipv4": "10.1.1.22/32" }, { "name": "P2P_Border1", "type": "L3", "intf_type": "Ethernet", "intf": "1/48", - "ipv4": "100.71.85.6/30" + "ipv4": "10.1.1.6/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/47", - "ipv4": "100.71.85.14/30" + "ipv4": "10.1.1.14/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -403,7 +403,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.71.85.18", + "ipv4": "10.1.1.18", "members": [ "1/41", "1/42" @@ -423,38 +423,38 @@ ], "bgp": { "asn": 65242, - "router_id": "100.71.85.22", + "router_id": "10.1.1.22", "networks": [ - "100.71.85.6/30", - "100.71.85.14/30", - "100.71.85.22/32", - "100.71.85.16/30", - "100.71.131.0/25", - "100.69.176.0/24", - "100.71.85.64/26", - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.1.1.6/30", + "10.1.1.14/30", + "10.1.1.22/32", + "10.1.1.16/30", + "10.2.1.0/25", + "10.3.1.0/24", + "10.1.1.64/26", + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ], "neighbors": [ { - "ip": "100.71.85.5", + "ip": "10.1.1.5", "description": "TO_Border1", "remote_as": 64846, "af_ipv4_unicast": { @@ -462,7 +462,7 @@ } }, { - "ip": "100.71.85.13", + "ip": "10.1.1.13", "description": "TO_Border2", "remote_as": 64846, "af_ipv4_unicast": { @@ -470,13 +470,13 @@ } }, { - "ip": "100.71.85.17", + "ip": "10.1.1.17", "description": "iBGP_PEER", "remote_as": 65242, "af_ipv4_unicast": {} }, { - "ip": "100.71.131.0/25", + "ip": "10.2.1.0/25", "description": "TO_HNVPA", "remote_as": 65112, "update_source": "Loopback0", @@ -549,67 +549,67 @@ }, "ip_map": { "P2P_BORDER1_TOR1": [ - "100.71.85.2/30" + "10.1.1.2/30" ], "P2P_TOR1_BORDER1": [ - "100.71.85.1" + "10.1.1.1" ], "P2P_BORDER1_TOR2": [ - "100.71.85.6/30" + "10.1.1.6/30" ], "P2P_TOR2_BORDER1": [ - "100.71.85.5" + "10.1.1.5" ], "P2P_BORDER2_TOR1": [ - "100.71.85.10/30" + "10.1.1.10/30" ], "P2P_TOR1_BORDER2": [ - "100.71.85.9" + "10.1.1.9" ], "P2P_BORDER2_TOR2": [ - "100.71.85.14/30" + "10.1.1.14/30" ], "P2P_TOR2_BORDER2": [ - "100.71.85.13" + "10.1.1.13" ], "P2P_IBGP_TOR1": [ - "100.71.85.17" + "10.1.1.17" ], "P2P_IBGP_TOR2": [ - "100.71.85.18" + "10.1.1.18" ], "LOOPBACK0_TOR1": [ - "100.71.85.21/32" + "10.1.1.21/32" ], "LOOPBACK0_TOR2": [ - "100.71.85.22/32" + "10.1.1.22/32" ], "HNVPA": [ - "100.71.131.0/25" + "10.2.1.0/25" ], "M": [ - "100.69.176.0/24" + "10.3.1.0/24" ], "C": [ - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ] }, "resolved_trunks": [ diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/lab_cisco_nxos_switch_input.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/lab_cisco_nxos_switch_input.json index fc10184..f002be0 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/lab_cisco_nxos_switch_input.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_fc/lab_cisco_nxos_switch_input.json @@ -5,8 +5,8 @@ "MainEnvData": [ { "Id": "Env01", - "Site": "rr1", - "RackName": "s46r21", + "Site": "site1", + "RackName": "rack01", "NodeCount": 16, "ConnectType": "connected", "ClusterUnits": [ @@ -14,57 +14,57 @@ "Name": "Cl01", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r2101", - "PhysicalNamingPrefix": "s46r2101", + "NamingPrefix": "node01", + "PhysicalNamingPrefix": "node01", "Topology": "HyperConverged", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r2101.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r2101.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node01.test.example.com", + "ExternalDomainFQDN": "ext-node01.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl02", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r2102", - "PhysicalNamingPrefix": "s46r2102", + "NamingPrefix": "node02", + "PhysicalNamingPrefix": "node02", "Topology": "HyperConverged", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r2102.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r2102.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node02.test.example.com", + "ExternalDomainFQDN": "ext-node02.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl03", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r2103", - "PhysicalNamingPrefix": "s46r2103", + "NamingPrefix": "node03", + "PhysicalNamingPrefix": "node03", "Topology": "HyperConverged", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r2103.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r2103.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node03.test.example.com", + "ExternalDomainFQDN": "ext-node03.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl04", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r2104", - "PhysicalNamingPrefix": "s46r2104", + "NamingPrefix": "node04", + "PhysicalNamingPrefix": "node04", "Topology": "HyperConverged", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r2104.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r2104.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node04.test.example.com", + "ExternalDomainFQDN": "ext-node04.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" } ] } @@ -73,14 +73,14 @@ { "Make": "Cisco", "Model": "C9336C-FX2", - "Hostname": "s46-r01-x32ssp-1a", + "Hostname": "border-1a", "Type": "Border1", "ASN": 64846 }, { "Make": "Cisco", "Model": "C9336C-FX2", - "Hostname": "s46-r01-x32ssp-1b", + "Hostname": "border-1b", "Type": "Border2", "ASN": 64846 }, @@ -88,7 +88,7 @@ "Make": "Cisco", "Model": "93180YC-FX3", "Type": "TOR1", - "Hostname": "s46-r21-93180hl-24-1a", + "Hostname": "tor-1a", "ASN": 65242, "Firmware": "10.3(4a)" }, @@ -96,7 +96,7 @@ "Make": "Cisco", "Model": "93180YC-FX3", "Type": "TOR2", - "Hostname": "s46-r21-93180hl-24-1b", + "Hostname": "tor-1b", "ASN": 65242, "Firmware": "10.3(4a)" }, @@ -104,15 +104,15 @@ "Make": "Cisco", "Model": "9348GC-FX3", "Type": "BMC", - "Hostname": "s46-r21-9348bmc-24-1", + "Hostname": "bmc-1", "ASN": null, "Firmware": "10.3(4a)" }, { - "Make": "Microsoft", + "Make": "Contoso", "Model": null, "Type": "MUX", - "Hostname": "s46-r21-MUX-1", + "Hostname": "mux-1", "ASN": 65112, "Firmware": null } @@ -132,25 +132,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.0/30", - "Network": "100.71.85.0", + "Subnet": "10.1.1.0/30", + "Network": "10.1.1.0", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.3", - "FirstAddress": "100.71.85.1", - "LastAddress": "100.71.85.2", + "BroadcastAddress": "10.1.1.3", + "FirstAddress": "10.1.1.1", + "LastAddress": "10.1.1.2", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.0" + "IP": "10.1.1.0" }, { "Name": "Border1", - "IP": "100.71.85.1" + "IP": "10.1.1.1" }, { "Name": "TOR1", - "IP": "100.71.85.2" + "IP": "10.1.1.2" } ] }, @@ -167,25 +167,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.4/30", - "Network": "100.71.85.4", + "Subnet": "10.1.1.4/30", + "Network": "10.1.1.4", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.7", - "FirstAddress": "100.71.85.5", - "LastAddress": "100.71.85.6", + "BroadcastAddress": "10.1.1.7", + "FirstAddress": "10.1.1.5", + "LastAddress": "10.1.1.6", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.4" + "IP": "10.1.1.4" }, { "Name": "Border1", - "IP": "100.71.85.5" + "IP": "10.1.1.5" }, { "Name": "TOR2", - "IP": "100.71.85.6" + "IP": "10.1.1.6" } ] }, @@ -202,25 +202,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.8/30", - "Network": "100.71.85.8", + "Subnet": "10.1.1.8/30", + "Network": "10.1.1.8", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.11", - "FirstAddress": "100.71.85.9", - "LastAddress": "100.71.85.10", + "BroadcastAddress": "10.1.1.11", + "FirstAddress": "10.1.1.9", + "LastAddress": "10.1.1.10", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.8" + "IP": "10.1.1.8" }, { "Name": "Border2", - "IP": "100.71.85.9" + "IP": "10.1.1.9" }, { "Name": "TOR1", - "IP": "100.71.85.10" + "IP": "10.1.1.10" } ] }, @@ -237,25 +237,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.12/30", - "Network": "100.71.85.12", + "Subnet": "10.1.1.12/30", + "Network": "10.1.1.12", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.15", - "FirstAddress": "100.71.85.13", - "LastAddress": "100.71.85.14", + "BroadcastAddress": "10.1.1.15", + "FirstAddress": "10.1.1.13", + "LastAddress": "10.1.1.14", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.12" + "IP": "10.1.1.12" }, { "Name": "Border2", - "IP": "100.71.85.13" + "IP": "10.1.1.13" }, { "Name": "TOR2", - "IP": "100.71.85.14" + "IP": "10.1.1.14" } ] }, @@ -272,25 +272,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.16/30", - "Network": "100.71.85.16", + "Subnet": "10.1.1.16/30", + "Network": "10.1.1.16", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.19", - "FirstAddress": "100.71.85.17", - "LastAddress": "100.71.85.18", + "BroadcastAddress": "10.1.1.19", + "FirstAddress": "10.1.1.17", + "LastAddress": "10.1.1.18", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.16" + "IP": "10.1.1.16" }, { "Name": "TOR1", - "IP": "100.71.85.17" + "IP": "10.1.1.17" }, { "Name": "TOR2", - "IP": "100.71.85.18" + "IP": "10.1.1.18" } ] }, @@ -307,8 +307,8 @@ "Cidr": 32, "TORGroup": "", "NetworkType": "Loopback", - "Subnet": "100.71.85.21/32", - "Network": "100.71.85.21", + "Subnet": "10.1.1.21/32", + "Network": "10.1.1.21", "Netmask": "255.255.255.255", "Gateway": "", "BroadcastAddress": "", @@ -317,7 +317,7 @@ "Assignment": [ { "Name": "TOR1", - "IP": "100.71.85.21" + "IP": "10.1.1.21" } ] }, @@ -334,8 +334,8 @@ "Cidr": 32, "TORGroup": "", "NetworkType": "Loopback", - "Subnet": "100.71.85.22/32", - "Network": "100.71.85.22", + "Subnet": "10.1.1.22/32", + "Network": "10.1.1.22", "Netmask": "255.255.255.255", "Gateway": "", "BroadcastAddress": "", @@ -344,7 +344,7 @@ "Assignment": [ { "Name": "TOR2", - "IP": "100.71.85.22" + "IP": "10.1.1.22" } ] }, @@ -362,152 +362,152 @@ "Cidr": 26, "TORGroup": "", "NetworkType": "Infrastructure", - "Subnet": "100.71.85.64/26", - "Network": "100.71.85.64", + "Subnet": "10.1.1.64/26", + "Network": "10.1.1.64", "Netmask": "255.255.255.192", - "Gateway": "100.71.85.65", - "BroadcastAddress": "100.71.85.127", - "FirstAddress": "100.71.85.65", - "LastAddress": "100.71.85.126", + "Gateway": "10.1.1.65", + "BroadcastAddress": "10.1.1.127", + "FirstAddress": "10.1.1.65", + "LastAddress": "10.1.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.64", + "IP": "10.1.1.64", "ClusterID": null }, { "Name": "Gateway", - "IP": "100.71.85.65", + "IP": "10.1.1.65", "ClusterID": null }, { "Name": "HLH-BMC", - "IP": "100.71.85.66", + "IP": "10.1.1.66", "ClusterID": null }, { "Name": "CL01-N01", - "IP": "100.71.85.67", + "IP": "10.1.1.67", "ClusterID": "CL01" }, { "Name": "CL01-N02", - "IP": "100.71.85.68", + "IP": "10.1.1.68", "ClusterID": "CL01" }, { "Name": "CL01-N03", - "IP": "100.71.85.69", + "IP": "10.1.1.69", "ClusterID": "CL01" }, { "Name": "CL01-N04", - "IP": "100.71.85.70", + "IP": "10.1.1.70", "ClusterID": "CL01" }, { "Name": "CL02-N01", - "IP": "100.71.85.71", + "IP": "10.1.1.71", "ClusterID": "CL02" }, { "Name": "CL02-N02", - "IP": "100.71.85.72", + "IP": "10.1.1.72", "ClusterID": "CL02" }, { "Name": "CL02-N03", - "IP": "100.71.85.73", + "IP": "10.1.1.73", "ClusterID": "CL02" }, { "Name": "CL02-N04", - "IP": "100.71.85.74", + "IP": "10.1.1.74", "ClusterID": "CL02" }, { "Name": "CL03-N01", - "IP": "100.71.85.75", + "IP": "10.1.1.75", "ClusterID": "CL03" }, { "Name": "CL03-N02", - "IP": "100.71.85.76", + "IP": "10.1.1.76", "ClusterID": "CL03" }, { "Name": "CL03-N03", - "IP": "100.71.85.77", + "IP": "10.1.1.77", "ClusterID": "CL03" }, { "Name": "CL03-N04", - "IP": "100.71.85.78", + "IP": "10.1.1.78", "ClusterID": "CL03" }, { "Name": "CL04-N01", - "IP": "100.71.85.79", + "IP": "10.1.1.79", "ClusterID": "CL04" }, { "Name": "CL04-N02", - "IP": "100.71.85.80", + "IP": "10.1.1.80", "ClusterID": "CL04" }, { "Name": "CL04-N03", - "IP": "100.71.85.81", + "IP": "10.1.1.81", "ClusterID": "CL04" }, { "Name": "CL04-N04", - "IP": "100.71.85.82", + "IP": "10.1.1.82", "ClusterID": "CL04" }, { "Name": "CL01-HLH-DVM01", - "IP": "100.71.85.107", + "IP": "10.1.1.107", "ClusterID": "CL01" }, { "Name": "CL02-HLH-DVM02", - "IP": "100.71.85.108", + "IP": "10.1.1.108", "ClusterID": "CL02" }, { "Name": "CL03-HLH-DVM03", - "IP": "100.71.85.109", + "IP": "10.1.1.109", "ClusterID": "CL03" }, { "Name": "CL04-HLH-DVM04", - "IP": "100.71.85.110", + "IP": "10.1.1.110", "ClusterID": "CL04" }, { "Name": "Tor1-Mgmt", - "IP": "100.71.85.123", + "IP": "10.1.1.123", "ClusterID": null }, { "Name": "Tor2-Mgmt", - "IP": "100.71.85.124", + "IP": "10.1.1.124", "ClusterID": null }, { "Name": "BMC-Mgmt", - "IP": "100.71.85.125", + "IP": "10.1.1.125", "ClusterID": null }, { "Name": "HLH-OS", - "IP": "100.71.85.126", + "IP": "10.1.1.126", "ClusterID": null }, { "Name": "Broadcast", - "IP": "100.71.85.127", + "IP": "10.1.1.127", "ClusterID": null } ] @@ -526,51 +526,51 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "PA", - "Subnet": "100.71.131.0/25", - "Network": "100.71.131.0", + "Subnet": "10.2.1.0/25", + "Network": "10.2.1.0", "Netmask": "255.255.255.128", - "Gateway": "100.71.131.1", - "BroadcastAddress": "100.71.131.127", - "FirstAddress": "100.71.131.1", - "LastAddress": "100.71.131.126", + "Gateway": "10.2.1.1", + "BroadcastAddress": "10.2.1.127", + "FirstAddress": "10.2.1.1", + "LastAddress": "10.2.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.71.131.0" + "IP": "10.2.1.0" }, { "Name": "Gateway", - "IP": "100.71.131.1" + "IP": "10.2.1.1" }, { "Name": "TOR1", - "IP": "100.71.131.2" + "IP": "10.2.1.2" }, { "Name": "TOR2", - "IP": "100.71.131.3" + "IP": "10.2.1.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.71.131.4", - "EndingAddress": "100.71.131.31" + "StartingAddress": "10.2.1.4", + "EndingAddress": "10.2.1.31" }, { "Name": "CL02", - "StartingAddress": "100.71.131.32", - "EndingAddress": "100.71.131.63" + "StartingAddress": "10.2.1.32", + "EndingAddress": "10.2.1.63" }, { "Name": "CL03", - "StartingAddress": "100.71.131.64", - "EndingAddress": "100.71.131.95" + "StartingAddress": "10.2.1.64", + "EndingAddress": "10.2.1.95" }, { "Name": "CL04", - "StartingAddress": "100.71.131.96", - "EndingAddress": "100.71.131.126" + "StartingAddress": "10.2.1.96", + "EndingAddress": "10.2.1.126" } ] }, @@ -588,115 +588,115 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Infrastructure", - "Subnet": "100.69.176.0/24", - "Network": "100.69.176.0", + "Subnet": "10.3.1.0/24", + "Network": "10.3.1.0", "Netmask": "255.255.255.0", - "Gateway": "100.69.176.1", - "BroadcastAddress": "100.69.176.255", - "FirstAddress": "100.69.176.1", - "LastAddress": "100.69.176.254", + "Gateway": "10.3.1.1", + "BroadcastAddress": "10.3.1.255", + "FirstAddress": "10.3.1.1", + "LastAddress": "10.3.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.69.176.0" + "IP": "10.3.1.0" }, { "Name": "Gateway", - "IP": "100.69.176.1" + "IP": "10.3.1.1" }, { "Name": "TOR1", - "IP": "100.69.176.2" + "IP": "10.3.1.2" }, { "Name": "TOR2", - "IP": "100.69.176.3" + "IP": "10.3.1.3" }, { "Name": "CL01-N01", - "IP": "100.69.176.4" + "IP": "10.3.1.4" }, { "Name": "CL01-N02", - "IP": "100.69.176.5" + "IP": "10.3.1.5" }, { "Name": "CL01-N03", - "IP": "100.69.176.6" + "IP": "10.3.1.6" }, { "Name": "CL01-N04", - "IP": "100.69.176.7" + "IP": "10.3.1.7" }, { "Name": "CL02-N01", - "IP": "100.69.176.64" + "IP": "10.3.1.64" }, { "Name": "CL02-N02", - "IP": "100.69.176.65" + "IP": "10.3.1.65" }, { "Name": "CL02-N03", - "IP": "100.69.176.66" + "IP": "10.3.1.66" }, { "Name": "CL02-N04", - "IP": "100.69.176.67" + "IP": "10.3.1.67" }, { "Name": "CL03-N01", - "IP": "100.69.176.128" + "IP": "10.3.1.128" }, { "Name": "CL03-N02", - "IP": "100.69.176.129" + "IP": "10.3.1.129" }, { "Name": "CL03-N03", - "IP": "100.69.176.130" + "IP": "10.3.1.130" }, { "Name": "CL03-N04", - "IP": "100.69.176.131" + "IP": "10.3.1.131" }, { "Name": "CL04-N01", - "IP": "100.69.176.192" + "IP": "10.3.1.192" }, { "Name": "CL04-N02", - "IP": "100.69.176.193" + "IP": "10.3.1.193" }, { "Name": "CL04-N03", - "IP": "100.69.176.194" + "IP": "10.3.1.194" }, { "Name": "CL04-N04", - "IP": "100.69.176.195" + "IP": "10.3.1.195" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.69.176.8", - "EndingAddress": "100.69.176.63" + "StartingAddress": "10.3.1.8", + "EndingAddress": "10.3.1.63" }, { "Name": "CL02", - "StartingAddress": "100.69.176.68", - "EndingAddress": "100.69.176.127" + "StartingAddress": "10.3.1.68", + "EndingAddress": "10.3.1.127" }, { "Name": "CL03", - "StartingAddress": "100.69.176.132", - "EndingAddress": "100.69.176.191" + "StartingAddress": "10.3.1.132", + "EndingAddress": "10.3.1.191" }, { "Name": "CL04", - "StartingAddress": "100.69.176.196", - "EndingAddress": "100.69.176.254" + "StartingAddress": "10.3.1.196", + "EndingAddress": "10.3.1.254" } ] }, @@ -714,51 +714,51 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.69.177.0/24", - "Network": "100.69.177.0", + "Subnet": "10.4.1.0/24", + "Network": "10.4.1.0", "Netmask": "255.255.255.0", - "Gateway": "100.69.177.1", - "BroadcastAddress": "100.69.177.255", - "FirstAddress": "100.69.177.1", - "LastAddress": "100.69.177.254", + "Gateway": "10.4.1.1", + "BroadcastAddress": "10.4.1.255", + "FirstAddress": "10.4.1.1", + "LastAddress": "10.4.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.69.177.0" + "IP": "10.4.1.0" }, { "Name": "Gateway", - "IP": "100.69.177.1" + "IP": "10.4.1.1" }, { "Name": "TOR1", - "IP": "100.69.177.2" + "IP": "10.4.1.2" }, { "Name": "TOR2", - "IP": "100.69.177.3" + "IP": "10.4.1.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.69.177.4", - "EndingAddress": "100.69.177.63" + "StartingAddress": "10.4.1.4", + "EndingAddress": "10.4.1.63" }, { "Name": "CL02", - "StartingAddress": "100.69.177.64", - "EndingAddress": "100.69.177.127" + "StartingAddress": "10.4.1.64", + "EndingAddress": "10.4.1.127" }, { "Name": "CL03", - "StartingAddress": "100.69.177.128", - "EndingAddress": "100.69.177.191" + "StartingAddress": "10.4.1.128", + "EndingAddress": "10.4.1.191" }, { "Name": "CL04", - "StartingAddress": "100.69.177.192", - "EndingAddress": "100.69.177.254" + "StartingAddress": "10.4.1.192", + "EndingAddress": "10.4.1.254" } ] }, @@ -776,51 +776,51 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.69.178.0/25", - "Network": "100.69.178.0", + "Subnet": "10.5.2.0/25", + "Network": "10.5.2.0", "Netmask": "255.255.255.128", - "Gateway": "100.69.178.1", - "BroadcastAddress": "100.69.178.127", - "FirstAddress": "100.69.178.1", - "LastAddress": "100.69.178.126", + "Gateway": "10.5.2.1", + "BroadcastAddress": "10.5.2.127", + "FirstAddress": "10.5.2.1", + "LastAddress": "10.5.2.126", "Assignment": [ { "Name": "Network", - "IP": "100.69.178.0" + "IP": "10.5.2.0" }, { "Name": "Gateway", - "IP": "100.69.178.1" + "IP": "10.5.2.1" }, { "Name": "TOR1", - "IP": "100.69.178.2" + "IP": "10.5.2.2" }, { "Name": "TOR2", - "IP": "100.69.178.3" + "IP": "10.5.2.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.69.178.4", - "EndingAddress": "100.69.178.31" + "StartingAddress": "10.5.2.4", + "EndingAddress": "10.5.2.31" }, { "Name": "CL02", - "StartingAddress": "100.69.178.32", - "EndingAddress": "100.69.178.63" + "StartingAddress": "10.5.2.32", + "EndingAddress": "10.5.2.63" }, { "Name": "CL03", - "StartingAddress": "100.69.178.64", - "EndingAddress": "100.69.178.95" + "StartingAddress": "10.5.2.64", + "EndingAddress": "10.5.2.95" }, { "Name": "CL04", - "StartingAddress": "100.69.178.96", - "EndingAddress": "100.69.178.126" + "StartingAddress": "10.5.2.96", + "EndingAddress": "10.5.2.126" } ] }, @@ -838,29 +838,29 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.69.178.128/25", - "Network": "100.69.178.128", + "Subnet": "10.5.2.128/25", + "Network": "10.5.2.128", "Netmask": "255.255.255.128", - "Gateway": "100.69.178.129", - "BroadcastAddress": "100.69.178.255", - "FirstAddress": "100.69.178.129", - "LastAddress": "100.69.178.254", + "Gateway": "10.5.2.129", + "BroadcastAddress": "10.5.2.255", + "FirstAddress": "10.5.2.129", + "LastAddress": "10.5.2.254", "Assignment": [ { "Name": "Network", - "IP": "100.69.178.128" + "IP": "10.5.2.128" }, { "Name": "Gateway", - "IP": "100.69.178.129" + "IP": "10.5.2.129" }, { "Name": "TOR1", - "IP": "100.69.178.130" + "IP": "10.5.2.130" }, { "Name": "TOR2", - "IP": "100.69.178.131" + "IP": "10.5.2.131" } ] }, @@ -878,29 +878,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.0/28", - "Network": "100.69.179.0", + "Subnet": "10.5.1.0/28", + "Network": "10.5.1.0", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.1", - "BroadcastAddress": "100.69.179.15", - "FirstAddress": "100.69.179.1", - "LastAddress": "100.69.179.14", + "Gateway": "10.5.1.1", + "BroadcastAddress": "10.5.1.15", + "FirstAddress": "10.5.1.1", + "LastAddress": "10.5.1.14", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.0" + "IP": "10.5.1.0" }, { "Name": "Gateway", - "IP": "100.69.179.1" + "IP": "10.5.1.1" }, { "Name": "TOR1", - "IP": "100.69.179.2" + "IP": "10.5.1.2" }, { "Name": "TOR2", - "IP": "100.69.179.3" + "IP": "10.5.1.3" } ] }, @@ -918,29 +918,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.16/28", - "Network": "100.69.179.16", + "Subnet": "10.5.1.16/28", + "Network": "10.5.1.16", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.17", - "BroadcastAddress": "100.69.179.31", - "FirstAddress": "100.69.179.17", - "LastAddress": "100.69.179.30", + "Gateway": "10.5.1.17", + "BroadcastAddress": "10.5.1.31", + "FirstAddress": "10.5.1.17", + "LastAddress": "10.5.1.30", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.16" + "IP": "10.5.1.16" }, { "Name": "Gateway", - "IP": "100.69.179.17" + "IP": "10.5.1.17" }, { "Name": "TOR1", - "IP": "100.69.179.18" + "IP": "10.5.1.18" }, { "Name": "TOR2", - "IP": "100.69.179.19" + "IP": "10.5.1.19" } ] }, @@ -958,29 +958,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.32/28", - "Network": "100.69.179.32", + "Subnet": "10.5.1.32/28", + "Network": "10.5.1.32", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.33", - "BroadcastAddress": "100.69.179.47", - "FirstAddress": "100.69.179.33", - "LastAddress": "100.69.179.46", + "Gateway": "10.5.1.33", + "BroadcastAddress": "10.5.1.47", + "FirstAddress": "10.5.1.33", + "LastAddress": "10.5.1.46", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.32" + "IP": "10.5.1.32" }, { "Name": "Gateway", - "IP": "100.69.179.33" + "IP": "10.5.1.33" }, { "Name": "TOR1", - "IP": "100.69.179.34" + "IP": "10.5.1.34" }, { "Name": "TOR2", - "IP": "100.69.179.35" + "IP": "10.5.1.35" } ] }, @@ -998,29 +998,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.48/28", - "Network": "100.69.179.48", + "Subnet": "10.5.1.48/28", + "Network": "10.5.1.48", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.49", - "BroadcastAddress": "100.69.179.63", - "FirstAddress": "100.69.179.49", - "LastAddress": "100.69.179.62", + "Gateway": "10.5.1.49", + "BroadcastAddress": "10.5.1.63", + "FirstAddress": "10.5.1.49", + "LastAddress": "10.5.1.62", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.48" + "IP": "10.5.1.48" }, { "Name": "Gateway", - "IP": "100.69.179.49" + "IP": "10.5.1.49" }, { "Name": "TOR1", - "IP": "100.69.179.50" + "IP": "10.5.1.50" }, { "Name": "TOR2", - "IP": "100.69.179.51" + "IP": "10.5.1.51" } ] }, @@ -1038,29 +1038,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.64/28", - "Network": "100.69.179.64", + "Subnet": "10.5.1.64/28", + "Network": "10.5.1.64", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.65", - "BroadcastAddress": "100.69.179.79", - "FirstAddress": "100.69.179.65", - "LastAddress": "100.69.179.78", + "Gateway": "10.5.1.65", + "BroadcastAddress": "10.5.1.79", + "FirstAddress": "10.5.1.65", + "LastAddress": "10.5.1.78", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.64" + "IP": "10.5.1.64" }, { "Name": "Gateway", - "IP": "100.69.179.65" + "IP": "10.5.1.65" }, { "Name": "TOR1", - "IP": "100.69.179.66" + "IP": "10.5.1.66" }, { "Name": "TOR2", - "IP": "100.69.179.67" + "IP": "10.5.1.67" } ] }, @@ -1078,29 +1078,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.80/28", - "Network": "100.69.179.80", + "Subnet": "10.5.1.80/28", + "Network": "10.5.1.80", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.81", - "BroadcastAddress": "100.69.179.95", - "FirstAddress": "100.69.179.81", - "LastAddress": "100.69.179.94", + "Gateway": "10.5.1.81", + "BroadcastAddress": "10.5.1.95", + "FirstAddress": "10.5.1.81", + "LastAddress": "10.5.1.94", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.80" + "IP": "10.5.1.80" }, { "Name": "Gateway", - "IP": "100.69.179.81" + "IP": "10.5.1.81" }, { "Name": "TOR1", - "IP": "100.69.179.82" + "IP": "10.5.1.82" }, { "Name": "TOR2", - "IP": "100.69.179.83" + "IP": "10.5.1.83" } ] }, @@ -1118,29 +1118,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.96/28", - "Network": "100.69.179.96", + "Subnet": "10.5.1.96/28", + "Network": "10.5.1.96", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.97", - "BroadcastAddress": "100.69.179.111", - "FirstAddress": "100.69.179.97", - "LastAddress": "100.69.179.110", + "Gateway": "10.5.1.97", + "BroadcastAddress": "10.5.1.111", + "FirstAddress": "10.5.1.97", + "LastAddress": "10.5.1.110", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.96" + "IP": "10.5.1.96" }, { "Name": "Gateway", - "IP": "100.69.179.97" + "IP": "10.5.1.97" }, { "Name": "TOR1", - "IP": "100.69.179.98" + "IP": "10.5.1.98" }, { "Name": "TOR2", - "IP": "100.69.179.99" + "IP": "10.5.1.99" } ] }, @@ -1158,29 +1158,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.112/28", - "Network": "100.69.179.112", + "Subnet": "10.5.1.112/28", + "Network": "10.5.1.112", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.113", - "BroadcastAddress": "100.69.179.127", - "FirstAddress": "100.69.179.113", - "LastAddress": "100.69.179.126", + "Gateway": "10.5.1.113", + "BroadcastAddress": "10.5.1.127", + "FirstAddress": "10.5.1.113", + "LastAddress": "10.5.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.112" + "IP": "10.5.1.112" }, { "Name": "Gateway", - "IP": "100.69.179.113" + "IP": "10.5.1.113" }, { "Name": "TOR1", - "IP": "100.69.179.114" + "IP": "10.5.1.114" }, { "Name": "TOR2", - "IP": "100.69.179.115" + "IP": "10.5.1.115" } ] }, @@ -1198,29 +1198,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.128/28", - "Network": "100.69.179.128", + "Subnet": "10.5.1.128/28", + "Network": "10.5.1.128", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.129", - "BroadcastAddress": "100.69.179.143", - "FirstAddress": "100.69.179.129", - "LastAddress": "100.69.179.142", + "Gateway": "10.5.1.129", + "BroadcastAddress": "10.5.1.143", + "FirstAddress": "10.5.1.129", + "LastAddress": "10.5.1.142", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.128" + "IP": "10.5.1.128" }, { "Name": "Gateway", - "IP": "100.69.179.129" + "IP": "10.5.1.129" }, { "Name": "TOR1", - "IP": "100.69.179.130" + "IP": "10.5.1.130" }, { "Name": "TOR2", - "IP": "100.69.179.131" + "IP": "10.5.1.131" } ] }, @@ -1238,29 +1238,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.144/28", - "Network": "100.69.179.144", + "Subnet": "10.5.1.144/28", + "Network": "10.5.1.144", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.145", - "BroadcastAddress": "100.69.179.159", - "FirstAddress": "100.69.179.145", - "LastAddress": "100.69.179.158", + "Gateway": "10.5.1.145", + "BroadcastAddress": "10.5.1.159", + "FirstAddress": "10.5.1.145", + "LastAddress": "10.5.1.158", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.144" + "IP": "10.5.1.144" }, { "Name": "IPv4", - "IP": "10.69.179.145" + "IP": "10.5.1.145" }, { "Name": "TOR1", - "IP": "100.69.179.145" + "IP": "10.5.1.145" }, { "Name": "TOR2", - "IP": "100.69.179.146" + "IP": "10.5.1.146" } ] }, @@ -1278,29 +1278,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.160/28", - "Network": "100.69.179.160", + "Subnet": "10.5.1.160/28", + "Network": "10.5.1.160", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.161", - "BroadcastAddress": "100.69.179.175", - "FirstAddress": "100.69.179.161", - "LastAddress": "100.69.179.174", + "Gateway": "10.5.1.161", + "BroadcastAddress": "10.5.1.175", + "FirstAddress": "10.5.1.161", + "LastAddress": "10.5.1.174", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.160" + "IP": "10.5.1.160" }, { "Name": "Gateway", - "IP": "100.69.179.161" + "IP": "10.5.1.161" }, { "Name": "TOR1", - "IP": "100.69.179.162" + "IP": "10.5.1.162" }, { "Name": "TOR2", - "IP": "100.69.179.163" + "IP": "10.5.1.163" } ] }, @@ -1318,29 +1318,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.176/28", - "Network": "100.69.179.176", + "Subnet": "10.5.1.176/28", + "Network": "10.5.1.176", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.177", - "BroadcastAddress": "100.69.179.191", - "FirstAddress": "100.69.179.177", - "LastAddress": "100.69.179.190", + "Gateway": "10.5.1.177", + "BroadcastAddress": "10.5.1.191", + "FirstAddress": "10.5.1.177", + "LastAddress": "10.5.1.190", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.176" + "IP": "10.5.1.176" }, { "Name": "Gateway", - "IP": "100.69.179.177" + "IP": "10.5.1.177" }, { "Name": "TOR1", - "IP": "100.69.179.178" + "IP": "10.5.1.178" }, { "Name": "TOR2", - "IP": "100.69.179.179" + "IP": "10.5.1.179" } ] }, @@ -1358,29 +1358,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.192/28", - "Network": "100.69.179.192", + "Subnet": "10.5.1.192/28", + "Network": "10.5.1.192", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.193", - "BroadcastAddress": "100.69.179.207", - "FirstAddress": "100.69.179.193", - "LastAddress": "100.69.179.206", + "Gateway": "10.5.1.193", + "BroadcastAddress": "10.5.1.207", + "FirstAddress": "10.5.1.193", + "LastAddress": "10.5.1.206", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.192" + "IP": "10.5.1.192" }, { "Name": "Gateway", - "IP": "100.69.179.193" + "IP": "10.5.1.193" }, { "Name": "TOR1", - "IP": "100.69.179.194" + "IP": "10.5.1.194" }, { "Name": "TOR2", - "IP": "100.69.179.195" + "IP": "10.5.1.195" } ] }, @@ -1398,29 +1398,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.208/28", - "Network": "100.69.179.208", + "Subnet": "10.5.1.208/28", + "Network": "10.5.1.208", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.209", - "BroadcastAddress": "100.69.179.223", - "FirstAddress": "100.69.179.209", - "LastAddress": "100.69.179.222", + "Gateway": "10.5.1.209", + "BroadcastAddress": "10.5.1.223", + "FirstAddress": "10.5.1.209", + "LastAddress": "10.5.1.222", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.208" + "IP": "10.5.1.208" }, { "Name": "Gateway", - "IP": "100.69.179.209" + "IP": "10.5.1.209" }, { "Name": "TOR1", - "IP": "100.69.179.210" + "IP": "10.5.1.210" }, { "Name": "TOR2", - "IP": "100.69.179.211" + "IP": "10.5.1.211" } ] }, @@ -1438,29 +1438,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.224/28", - "Network": "100.69.179.224", + "Subnet": "10.5.1.224/28", + "Network": "10.5.1.224", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.225", - "BroadcastAddress": "100.69.179.239", - "FirstAddress": "100.69.179.225", - "LastAddress": "100.69.179.238", + "Gateway": "10.5.1.225", + "BroadcastAddress": "10.5.1.239", + "FirstAddress": "10.5.1.225", + "LastAddress": "10.5.1.238", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.224" + "IP": "10.5.1.224" }, { "Name": "Gateway", - "IP": "100.69.179.225" + "IP": "10.5.1.225" }, { "Name": "TOR1", - "IP": "100.69.179.226" + "IP": "10.5.1.226" }, { "Name": "TOR2", - "IP": "100.69.179.227" + "IP": "10.5.1.227" } ] }, @@ -1478,29 +1478,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.240/28", - "Network": "100.69.179.240", + "Subnet": "10.5.1.240/28", + "Network": "10.5.1.240", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.241", - "BroadcastAddress": "100.69.179.255", - "FirstAddress": "100.69.179.241", - "LastAddress": "100.69.179.254", + "Gateway": "10.5.1.241", + "BroadcastAddress": "10.5.1.255", + "FirstAddress": "10.5.1.241", + "LastAddress": "10.5.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.240" + "IP": "10.5.1.240" }, { "Name": "Gateway", - "IP": "100.69.179.241" + "IP": "10.5.1.241" }, { "Name": "TOR1", - "IP": "100.69.179.242" + "IP": "10.5.1.242" }, { "Name": "TOR2", - "IP": "100.69.179.243" + "IP": "10.5.1.243" } ] }, @@ -1518,35 +1518,35 @@ "Cidr": 22, "TORGroup": "", "NetworkType": "ExternalIP", - "Subnet": "100.66.116.0/22", - "Network": "100.66.116.0", + "Subnet": "10.6.1.0/22", + "Network": "10.6.1.0", "Netmask": "255.255.252.0", "Gateway": null, - "BroadcastAddress": "100.66.119.255", - "FirstAddress": "100.66.116.1", - "LastAddress": "100.66.119.254", + "BroadcastAddress": "10.6.4.255", + "FirstAddress": "10.6.1.1", + "LastAddress": "10.6.4.254", "Assignment": [ { "Name": "Network", - "IP": "100.66.116.0" + "IP": "10.6.1.0" } ], "IPPools": [ { "Name": "CL01", - "Subnet": "100.66.116.0/24" + "Subnet": "10.6.1.0/24" }, { "Name": "CL02", - "Subnet": "100.66.117.0/24" + "Subnet": "10.6.2.0/24" }, { "Name": "CL03", - "Subnet": "100.66.118.0/24" + "Subnet": "10.6.3.0/24" }, { "Name": "CL04", - "Subnet": "100.66.119.0/24" + "Subnet": "10.6.4.0/24" } ] }, @@ -1564,35 +1564,35 @@ "Cidr": 26, "TORGroup": "", "NetworkType": "ExternalIP", - "Subnet": "100.76.1.128/26", - "Network": "100.76.1.128", + "Subnet": "10.7.1.128/26", + "Network": "10.7.1.128", "Netmask": "255.255.255.192", "Gateway": null, - "BroadcastAddress": "100.76.1.191", - "FirstAddress": "100.76.1.129", - "LastAddress": "100.76.1.190", + "BroadcastAddress": "10.7.1.191", + "FirstAddress": "10.7.1.129", + "LastAddress": "10.7.1.190", "Assignment": [ { "Name": "Network", - "IP": "100.76.1.128" + "IP": "10.7.1.128" } ], "IPPools": [ { "Name": "CL01", - "Subnet": "100.76.1.128/28" + "Subnet": "10.7.1.128/28" }, { "Name": "CL02", - "Subnet": "100.76.1.144/28" + "Subnet": "10.7.1.144/28" }, { "Name": "CL03", - "Subnet": "100.76.1.160/28" + "Subnet": "10.7.1.160/28" }, { "Name": "CL04", - "Subnet": "100.76.1.176/28" + "Subnet": "10.7.1.176/28" } ] }, @@ -1610,17 +1610,17 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Storage", - "Subnet": "10.71.1.0/24", - "Network": "10.71.1.0", + "Subnet": "10.8.1.0/24", + "Network": "10.8.1.0", "Netmask": "255.255.255.0", - "Gateway": "10.71.1.1", - "BroadcastAddress": "10.71.1.255", - "FirstAddress": "10.71.1.1", - "LastAddress": "10.71.1.254", + "Gateway": "10.8.1.1", + "BroadcastAddress": "10.8.1.255", + "FirstAddress": "10.8.1.1", + "LastAddress": "10.8.1.254", "Assignment": [ { "Name": "Network", - "IP": "10.71.1.0" + "IP": "10.8.1.0" } ] }, @@ -1638,17 +1638,17 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Storage", - "Subnet": "10.71.2.0/24", - "Network": "10.71.2.0", + "Subnet": "10.8.2.0/24", + "Network": "10.8.2.0", "Netmask": "255.255.255.0", - "Gateway": "10.71.2.1", - "BroadcastAddress": "10.71.2.255", - "FirstAddress": "10.71.2.1", - "LastAddress": "10.71.2.254", + "Gateway": "10.8.2.1", + "BroadcastAddress": "10.8.2.255", + "FirstAddress": "10.8.2.1", + "LastAddress": "10.8.2.254", "Assignment": [ { "Name": "Network", - "IP": "10.71.2.0" + "IP": "10.8.2.0" } ] }, @@ -1681,9 +1681,9 @@ ], "Setting": { "TimeZone": "Pacific Standard Time", - "TimeServer": ["10.10.240.20"], - "SyslogServer": ["10.10.43.111"], - "DNSForwarder": ["10.10.240.23", "10.10.240.24"] + "TimeServer": ["10.100.0.1"], + "SyslogServer": ["10.100.0.2"], + "DNSForwarder": ["10.100.0.3", "10.100.0.4"] } } } diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-9348bmc-24-1.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/bmc-1.json similarity index 93% rename from tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-9348bmc-24-1.json rename to tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/bmc-1.json index c188452..74cb50e 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-9348bmc-24-1.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/bmc-1.json @@ -3,10 +3,10 @@ "make": "cisco", "model": "9348gc-fxp", "type": "BMC", - "hostname": "s46-r21-9348bmc-24-1", + "hostname": "bmc-1", "version": "9.3(11)", "firmware": "nxos", - "site": "rr1" + "site": "site1" }, "vlans": [ { @@ -22,7 +22,7 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.85.126", + "ip": "10.1.1.126", "cidr": 26, "mtu": 9216 } @@ -91,7 +91,7 @@ "static_routes": [ { "prefix": "0.0.0.0/0", - "next_hop": "100.71.85.65", + "next_hop": "10.1.1.65", "description": "BMC default gateway" } ] diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-93180hl-24-1a.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/tor-1a.json similarity index 74% rename from tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-93180hl-24-1a.json rename to tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/tor-1a.json index b231a8a..d1f4c8e 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-93180hl-24-1a.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/tor-1a.json @@ -3,10 +3,10 @@ "make": "cisco", "model": "93180yc-fx", "type": "TOR1", - "hostname": "s46-r21-93180hl-24-1a", + "hostname": "tor-1a", "version": "9.3(11)", "firmware": "nxos", - "site": "rr1" + "site": "site1" }, "vlans": [ { @@ -18,14 +18,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.71.131.2", + "ip": "10.2.1.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 6, "priority": 150, - "virtual_ip": "100.71.131.1" + "virtual_ip": "10.2.1.1" } } }, @@ -33,14 +33,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.69.176.2", + "ip": "10.3.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 7, "priority": 150, - "virtual_ip": "100.69.176.1" + "virtual_ip": "10.3.1.1" } } }, @@ -52,14 +52,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.85.123", + "ip": "10.1.1.123", "cidr": 26, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 125, "priority": 150, - "virtual_ip": "100.71.85.65" + "virtual_ip": "10.1.1.65" } } }, @@ -67,14 +67,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.69.177.2", + "ip": "10.4.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 201, "priority": 150, - "virtual_ip": "100.69.177.1" + "virtual_ip": "10.4.1.1" } } }, @@ -82,14 +82,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.69.178.2", + "ip": "10.5.2.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 301, "priority": 150, - "virtual_ip": "100.69.178.1" + "virtual_ip": "10.5.2.1" } } }, @@ -97,14 +97,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.69.178.130", + "ip": "10.5.2.130", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 401, "priority": 150, - "virtual_ip": "100.69.178.129" + "virtual_ip": "10.5.2.129" } } }, @@ -112,14 +112,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.69.179.2", + "ip": "10.5.1.2", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 501, "priority": 150, - "virtual_ip": "100.69.179.1" + "virtual_ip": "10.5.1.1" } } }, @@ -127,14 +127,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.69.179.18", + "ip": "10.5.1.18", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 502, "priority": 150, - "virtual_ip": "100.69.179.17" + "virtual_ip": "10.5.1.17" } } }, @@ -142,14 +142,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.69.179.34", + "ip": "10.5.1.34", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 503, "priority": 150, - "virtual_ip": "100.69.179.33" + "virtual_ip": "10.5.1.33" } } }, @@ -157,14 +157,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.69.179.50", + "ip": "10.5.1.50", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 504, "priority": 150, - "virtual_ip": "100.69.179.49" + "virtual_ip": "10.5.1.49" } } }, @@ -172,14 +172,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.69.179.66", + "ip": "10.5.1.66", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 505, "priority": 150, - "virtual_ip": "100.69.179.65" + "virtual_ip": "10.5.1.65" } } }, @@ -187,14 +187,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.69.179.82", + "ip": "10.5.1.82", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 506, "priority": 150, - "virtual_ip": "100.69.179.81" + "virtual_ip": "10.5.1.81" } } }, @@ -202,14 +202,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.69.179.98", + "ip": "10.5.1.98", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 507, "priority": 150, - "virtual_ip": "100.69.179.97" + "virtual_ip": "10.5.1.97" } } }, @@ -217,14 +217,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.69.179.114", + "ip": "10.5.1.114", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 508, "priority": 150, - "virtual_ip": "100.69.179.113" + "virtual_ip": "10.5.1.113" } } }, @@ -232,14 +232,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.69.179.130", + "ip": "10.5.1.130", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 509, "priority": 150, - "virtual_ip": "100.69.179.129" + "virtual_ip": "10.5.1.129" } } }, @@ -247,7 +247,7 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.69.179.145", + "ip": "10.5.1.145", "cidr": 28, "mtu": 9216, "redundancy": { @@ -262,14 +262,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.69.179.162", + "ip": "10.5.1.162", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 511, "priority": 150, - "virtual_ip": "100.69.179.161" + "virtual_ip": "10.5.1.161" } } }, @@ -277,14 +277,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.69.179.178", + "ip": "10.5.1.178", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 512, "priority": 150, - "virtual_ip": "100.69.179.177" + "virtual_ip": "10.5.1.177" } } }, @@ -292,14 +292,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.69.179.194", + "ip": "10.5.1.194", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 513, "priority": 150, - "virtual_ip": "100.69.179.193" + "virtual_ip": "10.5.1.193" } } }, @@ -307,14 +307,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.69.179.210", + "ip": "10.5.1.210", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 514, "priority": 150, - "virtual_ip": "100.69.179.209" + "virtual_ip": "10.5.1.209" } } }, @@ -322,14 +322,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.69.179.226", + "ip": "10.5.1.226", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 515, "priority": 150, - "virtual_ip": "100.69.179.225" + "virtual_ip": "10.5.1.225" } } }, @@ -337,14 +337,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.69.179.242", + "ip": "10.5.1.242", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 516, "priority": 150, - "virtual_ip": "100.69.179.241" + "virtual_ip": "10.5.1.241" } } }, @@ -373,21 +373,21 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.71.85.21/32" + "ipv4": "10.1.1.21/32" }, { "name": "P2P_Border1", "type": "L3", "intf_type": "Ethernet", "intf": "1/48", - "ipv4": "100.71.85.2/30" + "ipv4": "10.1.1.2/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/47", - "ipv4": "100.71.85.10/30" + "ipv4": "10.1.1.10/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -424,7 +424,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.71.85.17", + "ipv4": "10.1.1.17", "members": [ "1/41", "1/42" @@ -444,38 +444,38 @@ ], "bgp": { "asn": 65242, - "router_id": "100.71.85.21", + "router_id": "10.1.1.21", "networks": [ - "100.71.85.2/30", - "100.71.85.10/30", - "100.71.85.21/32", - "100.71.85.16/30", - "100.71.131.0/25", - "100.69.176.0/24", - "100.71.85.64/26", - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.1.1.2/30", + "10.1.1.10/30", + "10.1.1.21/32", + "10.1.1.16/30", + "10.2.1.0/25", + "10.3.1.0/24", + "10.1.1.64/26", + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ], "neighbors": [ { - "ip": "100.71.85.1", + "ip": "10.1.1.1", "description": "TO_Border1", "remote_as": 64846, "af_ipv4_unicast": { @@ -483,7 +483,7 @@ } }, { - "ip": "100.71.85.9", + "ip": "10.1.1.9", "description": "TO_Border2", "remote_as": 64846, "af_ipv4_unicast": { @@ -491,13 +491,13 @@ } }, { - "ip": "100.71.85.18", + "ip": "10.1.1.18", "description": "iBGP_PEER", "remote_as": 65242, "af_ipv4_unicast": {} }, { - "ip": "100.71.131.0/25", + "ip": "10.2.1.0/25", "description": "TO_HNVPA", "remote_as": 65112, "update_source": "Loopback0", @@ -570,67 +570,67 @@ }, "ip_map": { "P2P_BORDER1_TOR1": [ - "100.71.85.2/30" + "10.1.1.2/30" ], "P2P_TOR1_BORDER1": [ - "100.71.85.1" + "10.1.1.1" ], "P2P_BORDER1_TOR2": [ - "100.71.85.6/30" + "10.1.1.6/30" ], "P2P_TOR2_BORDER1": [ - "100.71.85.5" + "10.1.1.5" ], "P2P_BORDER2_TOR1": [ - "100.71.85.10/30" + "10.1.1.10/30" ], "P2P_TOR1_BORDER2": [ - "100.71.85.9" + "10.1.1.9" ], "P2P_BORDER2_TOR2": [ - "100.71.85.14/30" + "10.1.1.14/30" ], "P2P_TOR2_BORDER2": [ - "100.71.85.13" + "10.1.1.13" ], "P2P_IBGP_TOR1": [ - "100.71.85.17" + "10.1.1.17" ], "P2P_IBGP_TOR2": [ - "100.71.85.18" + "10.1.1.18" ], "LOOPBACK0_TOR1": [ - "100.71.85.21/32" + "10.1.1.21/32" ], "LOOPBACK0_TOR2": [ - "100.71.85.22/32" + "10.1.1.22/32" ], "HNVPA": [ - "100.71.131.0/25" + "10.2.1.0/25" ], "M": [ - "100.69.176.0/24" + "10.3.1.0/24" ], "C": [ - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ] }, "resolved_trunks": [ diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-93180hl-24-1b.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/tor-1b.json similarity index 74% rename from tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-93180hl-24-1b.json rename to tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/tor-1b.json index 78d3b8b..f67fc5c 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/s46-r21-93180hl-24-1b.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/expected_outputs/tor-1b.json @@ -3,10 +3,10 @@ "make": "cisco", "model": "93180yc-fx", "type": "TOR2", - "hostname": "s46-r21-93180hl-24-1b", + "hostname": "tor-1b", "version": "9.3(11)", "firmware": "nxos", - "site": "rr1" + "site": "site1" }, "vlans": [ { @@ -18,14 +18,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.71.131.3", + "ip": "10.2.1.3", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 6, "priority": 140, - "virtual_ip": "100.71.131.1" + "virtual_ip": "10.2.1.1" } } }, @@ -33,14 +33,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.69.176.3", + "ip": "10.3.1.3", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 7, "priority": 140, - "virtual_ip": "100.69.176.1" + "virtual_ip": "10.3.1.1" } } }, @@ -52,14 +52,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.85.124", + "ip": "10.1.1.124", "cidr": 26, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 125, "priority": 140, - "virtual_ip": "100.71.85.65" + "virtual_ip": "10.1.1.65" } } }, @@ -67,14 +67,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.69.177.3", + "ip": "10.4.1.3", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 201, "priority": 140, - "virtual_ip": "100.69.177.1" + "virtual_ip": "10.4.1.1" } } }, @@ -82,14 +82,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.69.178.3", + "ip": "10.5.2.3", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 301, "priority": 140, - "virtual_ip": "100.69.178.1" + "virtual_ip": "10.5.2.1" } } }, @@ -97,14 +97,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.69.178.131", + "ip": "10.5.2.131", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 401, "priority": 140, - "virtual_ip": "100.69.178.129" + "virtual_ip": "10.5.2.129" } } }, @@ -112,14 +112,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.69.179.3", + "ip": "10.5.1.3", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 501, "priority": 140, - "virtual_ip": "100.69.179.1" + "virtual_ip": "10.5.1.1" } } }, @@ -127,14 +127,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.69.179.19", + "ip": "10.5.1.19", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 502, "priority": 140, - "virtual_ip": "100.69.179.17" + "virtual_ip": "10.5.1.17" } } }, @@ -142,14 +142,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.69.179.35", + "ip": "10.5.1.35", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 503, "priority": 140, - "virtual_ip": "100.69.179.33" + "virtual_ip": "10.5.1.33" } } }, @@ -157,14 +157,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.69.179.51", + "ip": "10.5.1.51", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 504, "priority": 140, - "virtual_ip": "100.69.179.49" + "virtual_ip": "10.5.1.49" } } }, @@ -172,14 +172,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.69.179.67", + "ip": "10.5.1.67", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 505, "priority": 140, - "virtual_ip": "100.69.179.65" + "virtual_ip": "10.5.1.65" } } }, @@ -187,14 +187,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.69.179.83", + "ip": "10.5.1.83", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 506, "priority": 140, - "virtual_ip": "100.69.179.81" + "virtual_ip": "10.5.1.81" } } }, @@ -202,14 +202,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.69.179.99", + "ip": "10.5.1.99", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 507, "priority": 140, - "virtual_ip": "100.69.179.97" + "virtual_ip": "10.5.1.97" } } }, @@ -217,14 +217,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.69.179.115", + "ip": "10.5.1.115", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 508, "priority": 140, - "virtual_ip": "100.69.179.113" + "virtual_ip": "10.5.1.113" } } }, @@ -232,14 +232,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.69.179.131", + "ip": "10.5.1.131", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 509, "priority": 140, - "virtual_ip": "100.69.179.129" + "virtual_ip": "10.5.1.129" } } }, @@ -247,7 +247,7 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.69.179.146", + "ip": "10.5.1.146", "cidr": 28, "mtu": 9216, "redundancy": { @@ -262,14 +262,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.69.179.163", + "ip": "10.5.1.163", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 511, "priority": 140, - "virtual_ip": "100.69.179.161" + "virtual_ip": "10.5.1.161" } } }, @@ -277,14 +277,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.69.179.179", + "ip": "10.5.1.179", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 512, "priority": 140, - "virtual_ip": "100.69.179.177" + "virtual_ip": "10.5.1.177" } } }, @@ -292,14 +292,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.69.179.195", + "ip": "10.5.1.195", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 513, "priority": 140, - "virtual_ip": "100.69.179.193" + "virtual_ip": "10.5.1.193" } } }, @@ -307,14 +307,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.69.179.211", + "ip": "10.5.1.211", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 514, "priority": 140, - "virtual_ip": "100.69.179.209" + "virtual_ip": "10.5.1.209" } } }, @@ -322,14 +322,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.69.179.227", + "ip": "10.5.1.227", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 515, "priority": 140, - "virtual_ip": "100.69.179.225" + "virtual_ip": "10.5.1.225" } } }, @@ -337,14 +337,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.69.179.243", + "ip": "10.5.1.243", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 516, "priority": 140, - "virtual_ip": "100.69.179.241" + "virtual_ip": "10.5.1.241" } } }, @@ -373,21 +373,21 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.71.85.22/32" + "ipv4": "10.1.1.22/32" }, { "name": "P2P_Border1", "type": "L3", "intf_type": "Ethernet", "intf": "1/48", - "ipv4": "100.71.85.6/30" + "ipv4": "10.1.1.6/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/47", - "ipv4": "100.71.85.14/30" + "ipv4": "10.1.1.14/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -424,7 +424,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.71.85.18", + "ipv4": "10.1.1.18", "members": [ "1/41", "1/42" @@ -444,38 +444,38 @@ ], "bgp": { "asn": 65242, - "router_id": "100.71.85.22", + "router_id": "10.1.1.22", "networks": [ - "100.71.85.6/30", - "100.71.85.14/30", - "100.71.85.22/32", - "100.71.85.16/30", - "100.71.131.0/25", - "100.69.176.0/24", - "100.71.85.64/26", - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.1.1.6/30", + "10.1.1.14/30", + "10.1.1.22/32", + "10.1.1.16/30", + "10.2.1.0/25", + "10.3.1.0/24", + "10.1.1.64/26", + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ], "neighbors": [ { - "ip": "100.71.85.5", + "ip": "10.1.1.5", "description": "TO_Border1", "remote_as": 64846, "af_ipv4_unicast": { @@ -483,7 +483,7 @@ } }, { - "ip": "100.71.85.13", + "ip": "10.1.1.13", "description": "TO_Border2", "remote_as": 64846, "af_ipv4_unicast": { @@ -491,13 +491,13 @@ } }, { - "ip": "100.71.85.17", + "ip": "10.1.1.17", "description": "iBGP_PEER", "remote_as": 65242, "af_ipv4_unicast": {} }, { - "ip": "100.71.131.0/25", + "ip": "10.2.1.0/25", "description": "TO_HNVPA", "remote_as": 65112, "update_source": "Loopback0", @@ -570,67 +570,67 @@ }, "ip_map": { "P2P_BORDER1_TOR1": [ - "100.71.85.2/30" + "10.1.1.2/30" ], "P2P_TOR1_BORDER1": [ - "100.71.85.1" + "10.1.1.1" ], "P2P_BORDER1_TOR2": [ - "100.71.85.6/30" + "10.1.1.6/30" ], "P2P_TOR2_BORDER1": [ - "100.71.85.5" + "10.1.1.5" ], "P2P_BORDER2_TOR1": [ - "100.71.85.10/30" + "10.1.1.10/30" ], "P2P_TOR1_BORDER2": [ - "100.71.85.9" + "10.1.1.9" ], "P2P_BORDER2_TOR2": [ - "100.71.85.14/30" + "10.1.1.14/30" ], "P2P_TOR2_BORDER2": [ - "100.71.85.13" + "10.1.1.13" ], "P2P_IBGP_TOR1": [ - "100.71.85.17" + "10.1.1.17" ], "P2P_IBGP_TOR2": [ - "100.71.85.18" + "10.1.1.18" ], "LOOPBACK0_TOR1": [ - "100.71.85.21/32" + "10.1.1.21/32" ], "LOOPBACK0_TOR2": [ - "100.71.85.22/32" + "10.1.1.22/32" ], "HNVPA": [ - "100.71.131.0/25" + "10.2.1.0/25" ], "M": [ - "100.69.176.0/24" + "10.3.1.0/24" ], "C": [ - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ] }, "resolved_trunks": [ diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/lab_cisco_nxos_switch_input.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/lab_cisco_nxos_switch_input.json index de7b744..c9ee830 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/lab_cisco_nxos_switch_input.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched/lab_cisco_nxos_switch_input.json @@ -5,8 +5,8 @@ "MainEnvData": [ { "Id": "Env01", - "Site": "rr1", - "RackName": "s46r21STR", + "Site": "site1", + "RackName": "rack01", "NodeCount": 16, "ConnectType": "connected", "ClusterUnits": [ @@ -14,57 +14,57 @@ "Name": "Cl01", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r21STR01", - "PhysicalNamingPrefix": "s46r21STR01", + "NamingPrefix": "node01", + "PhysicalNamingPrefix": "node01", "Topology": "SWITCHED", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r21STR01.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r21STR01.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node01.test.example.com", + "ExternalDomainFQDN": "ext-node01.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl02", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r21STR02", - "PhysicalNamingPrefix": "s46r21STR02", + "NamingPrefix": "node02", + "PhysicalNamingPrefix": "node02", "Topology": "SWITCHED", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r21STR02.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r21STR02.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node02.test.example.com", + "ExternalDomainFQDN": "ext-node02.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl03", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r21STR03", - "PhysicalNamingPrefix": "s46r21STR03", + "NamingPrefix": "node03", + "PhysicalNamingPrefix": "node03", "Topology": "SWITCHED", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r21STR03.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r21STR03.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node03.test.example.com", + "ExternalDomainFQDN": "ext-node03.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl04", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r21STR04", - "PhysicalNamingPrefix": "s46r21STR04", + "NamingPrefix": "node04", + "PhysicalNamingPrefix": "node04", "Topology": "SWITCHED", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r21STR04.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r21STR04.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node04.test.example.com", + "ExternalDomainFQDN": "ext-node04.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" } ] } @@ -73,14 +73,14 @@ { "Make": "Cisco", "Model": "C9336C-FX2", - "Hostname": "s46-r01-x32ssp-1a", + "Hostname": "border-1a", "Type": "Border1", "ASN": 64846 }, { "Make": "Cisco", "Model": "C9336C-FX2", - "Hostname": "s46-r01-x32ssp-1b", + "Hostname": "border-1b", "Type": "Border2", "ASN": 64846 }, @@ -88,7 +88,7 @@ "Make": "Cisco", "Model": "93180YC-FX", "Type": "TOR1", - "Hostname": "s46-r21-93180hl-24-1a", + "Hostname": "tor-1a", "ASN": 65242, "Firmware": "9.3(11)" }, @@ -96,7 +96,7 @@ "Make": "Cisco", "Model": "93180YC-FX", "Type": "TOR2", - "Hostname": "s46-r21-93180hl-24-1b", + "Hostname": "tor-1b", "ASN": 65242, "Firmware": "9.3(11)" }, @@ -104,15 +104,15 @@ "Make": "Cisco", "Model": "9348GC-FXP", "Type": "BMC", - "Hostname": "s46-r21-9348bmc-24-1", + "Hostname": "bmc-1", "ASN": null, "Firmware": "9.3(11)" }, { - "Make": "Microsoft", + "Make": "Contoso", "Model": null, "Type": "MUX", - "Hostname": "s46-r21-MUX-1", + "Hostname": "mux-1", "ASN": 65112, "Firmware": null } @@ -132,25 +132,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.0/30", - "Network": "100.71.85.0", + "Subnet": "10.1.1.0/30", + "Network": "10.1.1.0", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.3", - "FirstAddress": "100.71.85.1", - "LastAddress": "100.71.85.2", + "BroadcastAddress": "10.1.1.3", + "FirstAddress": "10.1.1.1", + "LastAddress": "10.1.1.2", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.0" + "IP": "10.1.1.0" }, { "Name": "Border1", - "IP": "100.71.85.1" + "IP": "10.1.1.1" }, { "Name": "TOR1", - "IP": "100.71.85.2" + "IP": "10.1.1.2" } ] }, @@ -167,25 +167,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.4/30", - "Network": "100.71.85.4", + "Subnet": "10.1.1.4/30", + "Network": "10.1.1.4", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.7", - "FirstAddress": "100.71.85.5", - "LastAddress": "100.71.85.6", + "BroadcastAddress": "10.1.1.7", + "FirstAddress": "10.1.1.5", + "LastAddress": "10.1.1.6", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.4" + "IP": "10.1.1.4" }, { "Name": "Border1", - "IP": "100.71.85.5" + "IP": "10.1.1.5" }, { "Name": "TOR2", - "IP": "100.71.85.6" + "IP": "10.1.1.6" } ] }, @@ -202,25 +202,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.8/30", - "Network": "100.71.85.8", + "Subnet": "10.1.1.8/30", + "Network": "10.1.1.8", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.11", - "FirstAddress": "100.71.85.9", - "LastAddress": "100.71.85.10", + "BroadcastAddress": "10.1.1.11", + "FirstAddress": "10.1.1.9", + "LastAddress": "10.1.1.10", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.8" + "IP": "10.1.1.8" }, { "Name": "Border2", - "IP": "100.71.85.9" + "IP": "10.1.1.9" }, { "Name": "TOR1", - "IP": "100.71.85.10" + "IP": "10.1.1.10" } ] }, @@ -237,25 +237,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.12/30", - "Network": "100.71.85.12", + "Subnet": "10.1.1.12/30", + "Network": "10.1.1.12", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.15", - "FirstAddress": "100.71.85.13", - "LastAddress": "100.71.85.14", + "BroadcastAddress": "10.1.1.15", + "FirstAddress": "10.1.1.13", + "LastAddress": "10.1.1.14", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.12" + "IP": "10.1.1.12" }, { "Name": "Border2", - "IP": "100.71.85.13" + "IP": "10.1.1.13" }, { "Name": "TOR2", - "IP": "100.71.85.14" + "IP": "10.1.1.14" } ] }, @@ -272,25 +272,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.85.16/30", - "Network": "100.71.85.16", + "Subnet": "10.1.1.16/30", + "Network": "10.1.1.16", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.85.19", - "FirstAddress": "100.71.85.17", - "LastAddress": "100.71.85.18", + "BroadcastAddress": "10.1.1.19", + "FirstAddress": "10.1.1.17", + "LastAddress": "10.1.1.18", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.16" + "IP": "10.1.1.16" }, { "Name": "TOR1", - "IP": "100.71.85.17" + "IP": "10.1.1.17" }, { "Name": "TOR2", - "IP": "100.71.85.18" + "IP": "10.1.1.18" } ] }, @@ -307,8 +307,8 @@ "Cidr": 32, "TORGroup": "", "NetworkType": "Loopback", - "Subnet": "100.71.85.21/32", - "Network": "100.71.85.21", + "Subnet": "10.1.1.21/32", + "Network": "10.1.1.21", "Netmask": "255.255.255.255", "Gateway": "", "BroadcastAddress": "", @@ -317,7 +317,7 @@ "Assignment": [ { "Name": "TOR1", - "IP": "100.71.85.21" + "IP": "10.1.1.21" } ] }, @@ -334,8 +334,8 @@ "Cidr": 32, "TORGroup": "", "NetworkType": "Loopback", - "Subnet": "100.71.85.22/32", - "Network": "100.71.85.22", + "Subnet": "10.1.1.22/32", + "Network": "10.1.1.22", "Netmask": "255.255.255.255", "Gateway": "", "BroadcastAddress": "", @@ -344,7 +344,7 @@ "Assignment": [ { "Name": "TOR2", - "IP": "100.71.85.22" + "IP": "10.1.1.22" } ] }, @@ -362,152 +362,152 @@ "Cidr": 26, "TORGroup": "", "NetworkType": "Infrastructure", - "Subnet": "100.71.85.64/26", - "Network": "100.71.85.64", + "Subnet": "10.1.1.64/26", + "Network": "10.1.1.64", "Netmask": "255.255.255.192", - "Gateway": "100.71.85.65", - "BroadcastAddress": "100.71.85.127", - "FirstAddress": "100.71.85.65", - "LastAddress": "100.71.85.126", + "Gateway": "10.1.1.65", + "BroadcastAddress": "10.1.1.127", + "FirstAddress": "10.1.1.65", + "LastAddress": "10.1.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.71.85.64", + "IP": "10.1.1.64", "ClusterID": null }, { "Name": "Gateway", - "IP": "100.71.85.65", + "IP": "10.1.1.65", "ClusterID": null }, { "Name": "HLH-BMC", - "IP": "100.71.85.66", + "IP": "10.1.1.66", "ClusterID": null }, { "Name": "CL01-N01", - "IP": "100.71.85.67", + "IP": "10.1.1.67", "ClusterID": "CL01" }, { "Name": "CL01-N02", - "IP": "100.71.85.68", + "IP": "10.1.1.68", "ClusterID": "CL01" }, { "Name": "CL01-N03", - "IP": "100.71.85.69", + "IP": "10.1.1.69", "ClusterID": "CL01" }, { "Name": "CL01-N04", - "IP": "100.71.85.70", + "IP": "10.1.1.70", "ClusterID": "CL01" }, { "Name": "CL02-N01", - "IP": "100.71.85.71", + "IP": "10.1.1.71", "ClusterID": "CL02" }, { "Name": "CL02-N02", - "IP": "100.71.85.72", + "IP": "10.1.1.72", "ClusterID": "CL02" }, { "Name": "CL02-N03", - "IP": "100.71.85.73", + "IP": "10.1.1.73", "ClusterID": "CL02" }, { "Name": "CL02-N04", - "IP": "100.71.85.74", + "IP": "10.1.1.74", "ClusterID": "CL02" }, { "Name": "CL03-N01", - "IP": "100.71.85.75", + "IP": "10.1.1.75", "ClusterID": "CL03" }, { "Name": "CL03-N02", - "IP": "100.71.85.76", + "IP": "10.1.1.76", "ClusterID": "CL03" }, { "Name": "CL03-N03", - "IP": "100.71.85.77", + "IP": "10.1.1.77", "ClusterID": "CL03" }, { "Name": "CL03-N04", - "IP": "100.71.85.78", + "IP": "10.1.1.78", "ClusterID": "CL03" }, { "Name": "CL04-N01", - "IP": "100.71.85.79", + "IP": "10.1.1.79", "ClusterID": "CL04" }, { "Name": "CL04-N02", - "IP": "100.71.85.80", + "IP": "10.1.1.80", "ClusterID": "CL04" }, { "Name": "CL04-N03", - "IP": "100.71.85.81", + "IP": "10.1.1.81", "ClusterID": "CL04" }, { "Name": "CL04-N04", - "IP": "100.71.85.82", + "IP": "10.1.1.82", "ClusterID": "CL04" }, { "Name": "CL01-HLH-DVM01", - "IP": "100.71.85.107", + "IP": "10.1.1.107", "ClusterID": "CL01" }, { "Name": "CL02-HLH-DVM02", - "IP": "100.71.85.108", + "IP": "10.1.1.108", "ClusterID": "CL02" }, { "Name": "CL03-HLH-DVM03", - "IP": "100.71.85.109", + "IP": "10.1.1.109", "ClusterID": "CL03" }, { "Name": "CL04-HLH-DVM04", - "IP": "100.71.85.110", + "IP": "10.1.1.110", "ClusterID": "CL04" }, { "Name": "Tor1-Mgmt", - "IP": "100.71.85.123", + "IP": "10.1.1.123", "ClusterID": null }, { "Name": "Tor2-Mgmt", - "IP": "100.71.85.124", + "IP": "10.1.1.124", "ClusterID": null }, { "Name": "BMC-Mgmt", - "IP": "100.71.85.125", + "IP": "10.1.1.125", "ClusterID": null }, { "Name": "HLH-OS", - "IP": "100.71.85.126", + "IP": "10.1.1.126", "ClusterID": null }, { "Name": "Broadcast", - "IP": "100.71.85.127", + "IP": "10.1.1.127", "ClusterID": null } ] @@ -526,51 +526,51 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "PA", - "Subnet": "100.71.131.0/25", - "Network": "100.71.131.0", + "Subnet": "10.2.1.0/25", + "Network": "10.2.1.0", "Netmask": "255.255.255.128", - "Gateway": "100.71.131.1", - "BroadcastAddress": "100.71.131.127", - "FirstAddress": "100.71.131.1", - "LastAddress": "100.71.131.126", + "Gateway": "10.2.1.1", + "BroadcastAddress": "10.2.1.127", + "FirstAddress": "10.2.1.1", + "LastAddress": "10.2.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.71.131.0" + "IP": "10.2.1.0" }, { "Name": "Gateway", - "IP": "100.71.131.1" + "IP": "10.2.1.1" }, { "Name": "TOR1", - "IP": "100.71.131.2" + "IP": "10.2.1.2" }, { "Name": "TOR2", - "IP": "100.71.131.3" + "IP": "10.2.1.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.71.131.4", - "EndingAddress": "100.71.131.31" + "StartingAddress": "10.2.1.4", + "EndingAddress": "10.2.1.31" }, { "Name": "CL02", - "StartingAddress": "100.71.131.32", - "EndingAddress": "100.71.131.63" + "StartingAddress": "10.2.1.32", + "EndingAddress": "10.2.1.63" }, { "Name": "CL03", - "StartingAddress": "100.71.131.64", - "EndingAddress": "100.71.131.95" + "StartingAddress": "10.2.1.64", + "EndingAddress": "10.2.1.95" }, { "Name": "CL04", - "StartingAddress": "100.71.131.96", - "EndingAddress": "100.71.131.126" + "StartingAddress": "10.2.1.96", + "EndingAddress": "10.2.1.126" } ] }, @@ -588,115 +588,115 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Infrastructure", - "Subnet": "100.69.176.0/24", - "Network": "100.69.176.0", + "Subnet": "10.3.1.0/24", + "Network": "10.3.1.0", "Netmask": "255.255.255.0", - "Gateway": "100.69.176.1", - "BroadcastAddress": "100.69.176.255", - "FirstAddress": "100.69.176.1", - "LastAddress": "100.69.176.254", + "Gateway": "10.3.1.1", + "BroadcastAddress": "10.3.1.255", + "FirstAddress": "10.3.1.1", + "LastAddress": "10.3.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.69.176.0" + "IP": "10.3.1.0" }, { "Name": "Gateway", - "IP": "100.69.176.1" + "IP": "10.3.1.1" }, { "Name": "TOR1", - "IP": "100.69.176.2" + "IP": "10.3.1.2" }, { "Name": "TOR2", - "IP": "100.69.176.3" + "IP": "10.3.1.3" }, { "Name": "CL01-N01", - "IP": "100.69.176.4" + "IP": "10.3.1.4" }, { "Name": "CL01-N02", - "IP": "100.69.176.5" + "IP": "10.3.1.5" }, { "Name": "CL01-N03", - "IP": "100.69.176.6" + "IP": "10.3.1.6" }, { "Name": "CL01-N04", - "IP": "100.69.176.7" + "IP": "10.3.1.7" }, { "Name": "CL02-N01", - "IP": "100.69.176.64" + "IP": "10.3.1.64" }, { "Name": "CL02-N02", - "IP": "100.69.176.65" + "IP": "10.3.1.65" }, { "Name": "CL02-N03", - "IP": "100.69.176.66" + "IP": "10.3.1.66" }, { "Name": "CL02-N04", - "IP": "100.69.176.67" + "IP": "10.3.1.67" }, { "Name": "CL03-N01", - "IP": "100.69.176.128" + "IP": "10.3.1.128" }, { "Name": "CL03-N02", - "IP": "100.69.176.129" + "IP": "10.3.1.129" }, { "Name": "CL03-N03", - "IP": "100.69.176.130" + "IP": "10.3.1.130" }, { "Name": "CL03-N04", - "IP": "100.69.176.131" + "IP": "10.3.1.131" }, { "Name": "CL04-N01", - "IP": "100.69.176.192" + "IP": "10.3.1.192" }, { "Name": "CL04-N02", - "IP": "100.69.176.193" + "IP": "10.3.1.193" }, { "Name": "CL04-N03", - "IP": "100.69.176.194" + "IP": "10.3.1.194" }, { "Name": "CL04-N04", - "IP": "100.69.176.195" + "IP": "10.3.1.195" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.69.176.8", - "EndingAddress": "100.69.176.63" + "StartingAddress": "10.3.1.8", + "EndingAddress": "10.3.1.63" }, { "Name": "CL02", - "StartingAddress": "100.69.176.68", - "EndingAddress": "100.69.176.127" + "StartingAddress": "10.3.1.68", + "EndingAddress": "10.3.1.127" }, { "Name": "CL03", - "StartingAddress": "100.69.176.132", - "EndingAddress": "100.69.176.191" + "StartingAddress": "10.3.1.132", + "EndingAddress": "10.3.1.191" }, { "Name": "CL04", - "StartingAddress": "100.69.176.196", - "EndingAddress": "100.69.176.254" + "StartingAddress": "10.3.1.196", + "EndingAddress": "10.3.1.254" } ] }, @@ -714,51 +714,51 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.69.177.0/24", - "Network": "100.69.177.0", + "Subnet": "10.4.1.0/24", + "Network": "10.4.1.0", "Netmask": "255.255.255.0", - "Gateway": "100.69.177.1", - "BroadcastAddress": "100.69.177.255", - "FirstAddress": "100.69.177.1", - "LastAddress": "100.69.177.254", + "Gateway": "10.4.1.1", + "BroadcastAddress": "10.4.1.255", + "FirstAddress": "10.4.1.1", + "LastAddress": "10.4.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.69.177.0" + "IP": "10.4.1.0" }, { "Name": "Gateway", - "IP": "100.69.177.1" + "IP": "10.4.1.1" }, { "Name": "TOR1", - "IP": "100.69.177.2" + "IP": "10.4.1.2" }, { "Name": "TOR2", - "IP": "100.69.177.3" + "IP": "10.4.1.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.69.177.4", - "EndingAddress": "100.69.177.63" + "StartingAddress": "10.4.1.4", + "EndingAddress": "10.4.1.63" }, { "Name": "CL02", - "StartingAddress": "100.69.177.64", - "EndingAddress": "100.69.177.127" + "StartingAddress": "10.4.1.64", + "EndingAddress": "10.4.1.127" }, { "Name": "CL03", - "StartingAddress": "100.69.177.128", - "EndingAddress": "100.69.177.191" + "StartingAddress": "10.4.1.128", + "EndingAddress": "10.4.1.191" }, { "Name": "CL04", - "StartingAddress": "100.69.177.192", - "EndingAddress": "100.69.177.254" + "StartingAddress": "10.4.1.192", + "EndingAddress": "10.4.1.254" } ] }, @@ -776,51 +776,51 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.69.178.0/25", - "Network": "100.69.178.0", + "Subnet": "10.5.2.0/25", + "Network": "10.5.2.0", "Netmask": "255.255.255.128", - "Gateway": "100.69.178.1", - "BroadcastAddress": "100.69.178.127", - "FirstAddress": "100.69.178.1", - "LastAddress": "100.69.178.126", + "Gateway": "10.5.2.1", + "BroadcastAddress": "10.5.2.127", + "FirstAddress": "10.5.2.1", + "LastAddress": "10.5.2.126", "Assignment": [ { "Name": "Network", - "IP": "100.69.178.0" + "IP": "10.5.2.0" }, { "Name": "Gateway", - "IP": "100.69.178.1" + "IP": "10.5.2.1" }, { "Name": "TOR1", - "IP": "100.69.178.2" + "IP": "10.5.2.2" }, { "Name": "TOR2", - "IP": "100.69.178.3" + "IP": "10.5.2.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.69.178.4", - "EndingAddress": "100.69.178.31" + "StartingAddress": "10.5.2.4", + "EndingAddress": "10.5.2.31" }, { "Name": "CL02", - "StartingAddress": "100.69.178.32", - "EndingAddress": "100.69.178.63" + "StartingAddress": "10.5.2.32", + "EndingAddress": "10.5.2.63" }, { "Name": "CL03", - "StartingAddress": "100.69.178.64", - "EndingAddress": "100.69.178.95" + "StartingAddress": "10.5.2.64", + "EndingAddress": "10.5.2.95" }, { "Name": "CL04", - "StartingAddress": "100.69.178.96", - "EndingAddress": "100.69.178.126" + "StartingAddress": "10.5.2.96", + "EndingAddress": "10.5.2.126" } ] }, @@ -838,29 +838,29 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.69.178.128/25", - "Network": "100.69.178.128", + "Subnet": "10.5.2.128/25", + "Network": "10.5.2.128", "Netmask": "255.255.255.128", - "Gateway": "100.69.178.129", - "BroadcastAddress": "100.69.178.255", - "FirstAddress": "100.69.178.129", - "LastAddress": "100.69.178.254", + "Gateway": "10.5.2.129", + "BroadcastAddress": "10.5.2.255", + "FirstAddress": "10.5.2.129", + "LastAddress": "10.5.2.254", "Assignment": [ { "Name": "Network", - "IP": "100.69.178.128" + "IP": "10.5.2.128" }, { "Name": "Gateway", - "IP": "100.69.178.129" + "IP": "10.5.2.129" }, { "Name": "TOR1", - "IP": "100.69.178.130" + "IP": "10.5.2.130" }, { "Name": "TOR2", - "IP": "100.69.178.131" + "IP": "10.5.2.131" } ] }, @@ -878,29 +878,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.0/28", - "Network": "100.69.179.0", + "Subnet": "10.5.1.0/28", + "Network": "10.5.1.0", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.1", - "BroadcastAddress": "100.69.179.15", - "FirstAddress": "100.69.179.1", - "LastAddress": "100.69.179.14", + "Gateway": "10.5.1.1", + "BroadcastAddress": "10.5.1.15", + "FirstAddress": "10.5.1.1", + "LastAddress": "10.5.1.14", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.0" + "IP": "10.5.1.0" }, { "Name": "Gateway", - "IP": "100.69.179.1" + "IP": "10.5.1.1" }, { "Name": "TOR1", - "IP": "100.69.179.2" + "IP": "10.5.1.2" }, { "Name": "TOR2", - "IP": "100.69.179.3" + "IP": "10.5.1.3" } ] }, @@ -918,29 +918,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.16/28", - "Network": "100.69.179.16", + "Subnet": "10.5.1.16/28", + "Network": "10.5.1.16", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.17", - "BroadcastAddress": "100.69.179.31", - "FirstAddress": "100.69.179.17", - "LastAddress": "100.69.179.30", + "Gateway": "10.5.1.17", + "BroadcastAddress": "10.5.1.31", + "FirstAddress": "10.5.1.17", + "LastAddress": "10.5.1.30", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.16" + "IP": "10.5.1.16" }, { "Name": "Gateway", - "IP": "100.69.179.17" + "IP": "10.5.1.17" }, { "Name": "TOR1", - "IP": "100.69.179.18" + "IP": "10.5.1.18" }, { "Name": "TOR2", - "IP": "100.69.179.19" + "IP": "10.5.1.19" } ] }, @@ -958,29 +958,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.32/28", - "Network": "100.69.179.32", + "Subnet": "10.5.1.32/28", + "Network": "10.5.1.32", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.33", - "BroadcastAddress": "100.69.179.47", - "FirstAddress": "100.69.179.33", - "LastAddress": "100.69.179.46", + "Gateway": "10.5.1.33", + "BroadcastAddress": "10.5.1.47", + "FirstAddress": "10.5.1.33", + "LastAddress": "10.5.1.46", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.32" + "IP": "10.5.1.32" }, { "Name": "Gateway", - "IP": "100.69.179.33" + "IP": "10.5.1.33" }, { "Name": "TOR1", - "IP": "100.69.179.34" + "IP": "10.5.1.34" }, { "Name": "TOR2", - "IP": "100.69.179.35" + "IP": "10.5.1.35" } ] }, @@ -998,29 +998,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.48/28", - "Network": "100.69.179.48", + "Subnet": "10.5.1.48/28", + "Network": "10.5.1.48", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.49", - "BroadcastAddress": "100.69.179.63", - "FirstAddress": "100.69.179.49", - "LastAddress": "100.69.179.62", + "Gateway": "10.5.1.49", + "BroadcastAddress": "10.5.1.63", + "FirstAddress": "10.5.1.49", + "LastAddress": "10.5.1.62", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.48" + "IP": "10.5.1.48" }, { "Name": "Gateway", - "IP": "100.69.179.49" + "IP": "10.5.1.49" }, { "Name": "TOR1", - "IP": "100.69.179.50" + "IP": "10.5.1.50" }, { "Name": "TOR2", - "IP": "100.69.179.51" + "IP": "10.5.1.51" } ] }, @@ -1038,29 +1038,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.64/28", - "Network": "100.69.179.64", + "Subnet": "10.5.1.64/28", + "Network": "10.5.1.64", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.65", - "BroadcastAddress": "100.69.179.79", - "FirstAddress": "100.69.179.65", - "LastAddress": "100.69.179.78", + "Gateway": "10.5.1.65", + "BroadcastAddress": "10.5.1.79", + "FirstAddress": "10.5.1.65", + "LastAddress": "10.5.1.78", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.64" + "IP": "10.5.1.64" }, { "Name": "Gateway", - "IP": "100.69.179.65" + "IP": "10.5.1.65" }, { "Name": "TOR1", - "IP": "100.69.179.66" + "IP": "10.5.1.66" }, { "Name": "TOR2", - "IP": "100.69.179.67" + "IP": "10.5.1.67" } ] }, @@ -1078,29 +1078,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.80/28", - "Network": "100.69.179.80", + "Subnet": "10.5.1.80/28", + "Network": "10.5.1.80", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.81", - "BroadcastAddress": "100.69.179.95", - "FirstAddress": "100.69.179.81", - "LastAddress": "100.69.179.94", + "Gateway": "10.5.1.81", + "BroadcastAddress": "10.5.1.95", + "FirstAddress": "10.5.1.81", + "LastAddress": "10.5.1.94", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.80" + "IP": "10.5.1.80" }, { "Name": "Gateway", - "IP": "100.69.179.81" + "IP": "10.5.1.81" }, { "Name": "TOR1", - "IP": "100.69.179.82" + "IP": "10.5.1.82" }, { "Name": "TOR2", - "IP": "100.69.179.83" + "IP": "10.5.1.83" } ] }, @@ -1118,29 +1118,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.96/28", - "Network": "100.69.179.96", + "Subnet": "10.5.1.96/28", + "Network": "10.5.1.96", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.97", - "BroadcastAddress": "100.69.179.111", - "FirstAddress": "100.69.179.97", - "LastAddress": "100.69.179.110", + "Gateway": "10.5.1.97", + "BroadcastAddress": "10.5.1.111", + "FirstAddress": "10.5.1.97", + "LastAddress": "10.5.1.110", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.96" + "IP": "10.5.1.96" }, { "Name": "Gateway", - "IP": "100.69.179.97" + "IP": "10.5.1.97" }, { "Name": "TOR1", - "IP": "100.69.179.98" + "IP": "10.5.1.98" }, { "Name": "TOR2", - "IP": "100.69.179.99" + "IP": "10.5.1.99" } ] }, @@ -1158,29 +1158,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.112/28", - "Network": "100.69.179.112", + "Subnet": "10.5.1.112/28", + "Network": "10.5.1.112", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.113", - "BroadcastAddress": "100.69.179.127", - "FirstAddress": "100.69.179.113", - "LastAddress": "100.69.179.126", + "Gateway": "10.5.1.113", + "BroadcastAddress": "10.5.1.127", + "FirstAddress": "10.5.1.113", + "LastAddress": "10.5.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.112" + "IP": "10.5.1.112" }, { "Name": "Gateway", - "IP": "100.69.179.113" + "IP": "10.5.1.113" }, { "Name": "TOR1", - "IP": "100.69.179.114" + "IP": "10.5.1.114" }, { "Name": "TOR2", - "IP": "100.69.179.115" + "IP": "10.5.1.115" } ] }, @@ -1198,29 +1198,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.128/28", - "Network": "100.69.179.128", + "Subnet": "10.5.1.128/28", + "Network": "10.5.1.128", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.129", - "BroadcastAddress": "100.69.179.143", - "FirstAddress": "100.69.179.129", - "LastAddress": "100.69.179.142", + "Gateway": "10.5.1.129", + "BroadcastAddress": "10.5.1.143", + "FirstAddress": "10.5.1.129", + "LastAddress": "10.5.1.142", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.128" + "IP": "10.5.1.128" }, { "Name": "Gateway", - "IP": "100.69.179.129" + "IP": "10.5.1.129" }, { "Name": "TOR1", - "IP": "100.69.179.130" + "IP": "10.5.1.130" }, { "Name": "TOR2", - "IP": "100.69.179.131" + "IP": "10.5.1.131" } ] }, @@ -1238,29 +1238,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.144/28", - "Network": "100.69.179.144", + "Subnet": "10.5.1.144/28", + "Network": "10.5.1.144", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.145", - "BroadcastAddress": "100.69.179.159", - "FirstAddress": "100.69.179.145", - "LastAddress": "100.69.179.158", + "Gateway": "10.5.1.145", + "BroadcastAddress": "10.5.1.159", + "FirstAddress": "10.5.1.145", + "LastAddress": "10.5.1.158", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.144" + "IP": "10.5.1.144" }, { "Name": "IPv4", - "IP": "10.69.179.145" + "IP": "10.5.1.145" }, { "Name": "TOR1", - "IP": "100.69.179.145" + "IP": "10.5.1.145" }, { "Name": "TOR2", - "IP": "100.69.179.146" + "IP": "10.5.1.146" } ] }, @@ -1278,29 +1278,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.160/28", - "Network": "100.69.179.160", + "Subnet": "10.5.1.160/28", + "Network": "10.5.1.160", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.161", - "BroadcastAddress": "100.69.179.175", - "FirstAddress": "100.69.179.161", - "LastAddress": "100.69.179.174", + "Gateway": "10.5.1.161", + "BroadcastAddress": "10.5.1.175", + "FirstAddress": "10.5.1.161", + "LastAddress": "10.5.1.174", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.160" + "IP": "10.5.1.160" }, { "Name": "Gateway", - "IP": "100.69.179.161" + "IP": "10.5.1.161" }, { "Name": "TOR1", - "IP": "100.69.179.162" + "IP": "10.5.1.162" }, { "Name": "TOR2", - "IP": "100.69.179.163" + "IP": "10.5.1.163" } ] }, @@ -1318,29 +1318,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.176/28", - "Network": "100.69.179.176", + "Subnet": "10.5.1.176/28", + "Network": "10.5.1.176", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.177", - "BroadcastAddress": "100.69.179.191", - "FirstAddress": "100.69.179.177", - "LastAddress": "100.69.179.190", + "Gateway": "10.5.1.177", + "BroadcastAddress": "10.5.1.191", + "FirstAddress": "10.5.1.177", + "LastAddress": "10.5.1.190", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.176" + "IP": "10.5.1.176" }, { "Name": "Gateway", - "IP": "100.69.179.177" + "IP": "10.5.1.177" }, { "Name": "TOR1", - "IP": "100.69.179.178" + "IP": "10.5.1.178" }, { "Name": "TOR2", - "IP": "100.69.179.179" + "IP": "10.5.1.179" } ] }, @@ -1358,29 +1358,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.192/28", - "Network": "100.69.179.192", + "Subnet": "10.5.1.192/28", + "Network": "10.5.1.192", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.193", - "BroadcastAddress": "100.69.179.207", - "FirstAddress": "100.69.179.193", - "LastAddress": "100.69.179.206", + "Gateway": "10.5.1.193", + "BroadcastAddress": "10.5.1.207", + "FirstAddress": "10.5.1.193", + "LastAddress": "10.5.1.206", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.192" + "IP": "10.5.1.192" }, { "Name": "Gateway", - "IP": "100.69.179.193" + "IP": "10.5.1.193" }, { "Name": "TOR1", - "IP": "100.69.179.194" + "IP": "10.5.1.194" }, { "Name": "TOR2", - "IP": "100.69.179.195" + "IP": "10.5.1.195" } ] }, @@ -1398,29 +1398,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.208/28", - "Network": "100.69.179.208", + "Subnet": "10.5.1.208/28", + "Network": "10.5.1.208", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.209", - "BroadcastAddress": "100.69.179.223", - "FirstAddress": "100.69.179.209", - "LastAddress": "100.69.179.222", + "Gateway": "10.5.1.209", + "BroadcastAddress": "10.5.1.223", + "FirstAddress": "10.5.1.209", + "LastAddress": "10.5.1.222", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.208" + "IP": "10.5.1.208" }, { "Name": "Gateway", - "IP": "100.69.179.209" + "IP": "10.5.1.209" }, { "Name": "TOR1", - "IP": "100.69.179.210" + "IP": "10.5.1.210" }, { "Name": "TOR2", - "IP": "100.69.179.211" + "IP": "10.5.1.211" } ] }, @@ -1438,29 +1438,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.224/28", - "Network": "100.69.179.224", + "Subnet": "10.5.1.224/28", + "Network": "10.5.1.224", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.225", - "BroadcastAddress": "100.69.179.239", - "FirstAddress": "100.69.179.225", - "LastAddress": "100.69.179.238", + "Gateway": "10.5.1.225", + "BroadcastAddress": "10.5.1.239", + "FirstAddress": "10.5.1.225", + "LastAddress": "10.5.1.238", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.224" + "IP": "10.5.1.224" }, { "Name": "Gateway", - "IP": "100.69.179.225" + "IP": "10.5.1.225" }, { "Name": "TOR1", - "IP": "100.69.179.226" + "IP": "10.5.1.226" }, { "Name": "TOR2", - "IP": "100.69.179.227" + "IP": "10.5.1.227" } ] }, @@ -1478,29 +1478,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.69.179.240/28", - "Network": "100.69.179.240", + "Subnet": "10.5.1.240/28", + "Network": "10.5.1.240", "Netmask": "255.255.255.240", - "Gateway": "100.69.179.241", - "BroadcastAddress": "100.69.179.255", - "FirstAddress": "100.69.179.241", - "LastAddress": "100.69.179.254", + "Gateway": "10.5.1.241", + "BroadcastAddress": "10.5.1.255", + "FirstAddress": "10.5.1.241", + "LastAddress": "10.5.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.69.179.240" + "IP": "10.5.1.240" }, { "Name": "Gateway", - "IP": "100.69.179.241" + "IP": "10.5.1.241" }, { "Name": "TOR1", - "IP": "100.69.179.242" + "IP": "10.5.1.242" }, { "Name": "TOR2", - "IP": "100.69.179.243" + "IP": "10.5.1.243" } ] }, @@ -1518,35 +1518,35 @@ "Cidr": 22, "TORGroup": "", "NetworkType": "ExternalIP", - "Subnet": "100.66.116.0/22", - "Network": "100.66.116.0", + "Subnet": "10.6.1.0/22", + "Network": "10.6.1.0", "Netmask": "255.255.252.0", "Gateway": null, - "BroadcastAddress": "100.66.119.255", - "FirstAddress": "100.66.116.1", - "LastAddress": "100.66.119.254", + "BroadcastAddress": "10.6.4.255", + "FirstAddress": "10.6.1.1", + "LastAddress": "10.6.4.254", "Assignment": [ { "Name": "Network", - "IP": "100.66.116.0" + "IP": "10.6.1.0" } ], "IPPools": [ { "Name": "CL01", - "Subnet": "100.66.116.0/24" + "Subnet": "10.6.1.0/24" }, { "Name": "CL02", - "Subnet": "100.66.117.0/24" + "Subnet": "10.6.2.0/24" }, { "Name": "CL03", - "Subnet": "100.66.118.0/24" + "Subnet": "10.6.3.0/24" }, { "Name": "CL04", - "Subnet": "100.66.119.0/24" + "Subnet": "10.6.4.0/24" } ] }, @@ -1564,35 +1564,35 @@ "Cidr": 26, "TORGroup": "", "NetworkType": "ExternalIP", - "Subnet": "100.76.1.128/26", - "Network": "100.76.1.128", + "Subnet": "10.7.1.128/26", + "Network": "10.7.1.128", "Netmask": "255.255.255.192", "Gateway": null, - "BroadcastAddress": "100.76.1.191", - "FirstAddress": "100.76.1.129", - "LastAddress": "100.76.1.190", + "BroadcastAddress": "10.7.1.191", + "FirstAddress": "10.7.1.129", + "LastAddress": "10.7.1.190", "Assignment": [ { "Name": "Network", - "IP": "100.76.1.128" + "IP": "10.7.1.128" } ], "IPPools": [ { "Name": "CL01", - "Subnet": "100.76.1.128/28" + "Subnet": "10.7.1.128/28" }, { "Name": "CL02", - "Subnet": "100.76.1.144/28" + "Subnet": "10.7.1.144/28" }, { "Name": "CL03", - "Subnet": "100.76.1.160/28" + "Subnet": "10.7.1.160/28" }, { "Name": "CL04", - "Subnet": "100.76.1.176/28" + "Subnet": "10.7.1.176/28" } ] }, @@ -1610,17 +1610,17 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Storage", - "Subnet": "10.71.1.0/24", - "Network": "10.71.1.0", + "Subnet": "10.8.1.0/24", + "Network": "10.8.1.0", "Netmask": "255.255.255.0", - "Gateway": "10.71.1.1", - "BroadcastAddress": "10.71.1.255", - "FirstAddress": "10.71.1.1", - "LastAddress": "10.71.1.254", + "Gateway": "10.8.1.1", + "BroadcastAddress": "10.8.1.255", + "FirstAddress": "10.8.1.1", + "LastAddress": "10.8.1.254", "Assignment": [ { "Name": "Network", - "IP": "10.71.1.0" + "IP": "10.8.1.0" } ] }, @@ -1638,17 +1638,17 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Storage", - "Subnet": "10.71.2.0/24", - "Network": "10.71.2.0", + "Subnet": "10.8.2.0/24", + "Network": "10.8.2.0", "Netmask": "255.255.255.0", - "Gateway": "10.71.2.1", - "BroadcastAddress": "10.71.2.255", - "FirstAddress": "10.71.2.1", - "LastAddress": "10.71.2.254", + "Gateway": "10.8.2.1", + "BroadcastAddress": "10.8.2.255", + "FirstAddress": "10.8.2.1", + "LastAddress": "10.8.2.254", "Assignment": [ { "Name": "Network", - "IP": "10.71.2.0" + "IP": "10.8.2.0" } ] }, @@ -1681,9 +1681,9 @@ ], "Setting": { "TimeZone": "Pacific Standard Time", - "TimeServer": ["10.10.240.20"], - "SyslogServer": ["10.10.43.111"], - "DNSForwarder": ["10.10.240.23", "10.10.240.24"] + "TimeServer": ["10.100.0.1"], + "SyslogServer": ["10.100.0.2"], + "DNSForwarder": ["10.100.0.3", "10.100.0.4"] } } } diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/b88-b11-93108hl-2-1a.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/tor-1a.json similarity index 73% rename from tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/b88-b11-93108hl-2-1a.json rename to tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/tor-1a.json index a82080d..01bc31e 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/b88-b11-93108hl-2-1a.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/tor-1a.json @@ -3,10 +3,10 @@ "make": "cisco", "model": "93108tc-fx3p", "type": "TOR1", - "hostname": "b88-b11-93108hl-2-1a", + "hostname": "tor-1a", "version": "10.3(4a)", "firmware": "nxos", - "site": "b88" + "site": "site2" }, "vlans": [ { @@ -18,14 +18,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.100.162.130", + "ip": "10.12.1.130", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 6, "priority": 150, - "virtual_ip": "100.100.162.129" + "virtual_ip": "10.12.1.129" } } }, @@ -33,14 +33,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.103.96.2", + "ip": "10.13.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 7, "priority": 150, - "virtual_ip": "100.103.96.1" + "virtual_ip": "10.13.1.1" } } }, @@ -52,14 +52,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.100.69.123", + "ip": "10.11.1.123", "cidr": 26, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 125, "priority": 150, - "virtual_ip": "100.100.69.65" + "virtual_ip": "10.11.1.65" } } }, @@ -67,14 +67,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.99.20.2", + "ip": "10.14.20.2", "cidr": 23, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 201, "priority": 150, - "virtual_ip": "100.99.20.1" + "virtual_ip": "10.14.20.1" } } }, @@ -82,14 +82,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.99.22.2", + "ip": "10.14.22.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 301, "priority": 150, - "virtual_ip": "100.99.22.1" + "virtual_ip": "10.14.22.1" } } }, @@ -97,14 +97,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.99.23.2", + "ip": "10.14.23.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 401, "priority": 150, - "virtual_ip": "100.99.23.1" + "virtual_ip": "10.14.23.1" } } }, @@ -112,14 +112,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.103.97.2", + "ip": "10.15.1.2", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 501, "priority": 150, - "virtual_ip": "100.103.97.1" + "virtual_ip": "10.15.1.1" } } }, @@ -127,14 +127,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.103.97.18", + "ip": "10.15.1.18", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 502, "priority": 150, - "virtual_ip": "100.103.97.17" + "virtual_ip": "10.15.1.17" } } }, @@ -142,14 +142,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.103.97.34", + "ip": "10.15.1.34", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 503, "priority": 150, - "virtual_ip": "100.103.97.33" + "virtual_ip": "10.15.1.33" } } }, @@ -157,14 +157,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.103.97.50", + "ip": "10.15.1.50", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 504, "priority": 150, - "virtual_ip": "100.103.97.49" + "virtual_ip": "10.15.1.49" } } }, @@ -172,14 +172,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.103.97.66", + "ip": "10.15.1.66", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 505, "priority": 150, - "virtual_ip": "100.103.97.65" + "virtual_ip": "10.15.1.65" } } }, @@ -187,14 +187,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.103.97.82", + "ip": "10.15.1.82", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 506, "priority": 150, - "virtual_ip": "100.103.97.81" + "virtual_ip": "10.15.1.81" } } }, @@ -202,14 +202,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.103.97.98", + "ip": "10.15.1.98", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 507, "priority": 150, - "virtual_ip": "100.103.97.97" + "virtual_ip": "10.15.1.97" } } }, @@ -217,14 +217,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.103.97.114", + "ip": "10.15.1.114", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 508, "priority": 150, - "virtual_ip": "100.103.97.113" + "virtual_ip": "10.15.1.113" } } }, @@ -232,14 +232,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.103.97.130", + "ip": "10.15.1.130", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 509, "priority": 150, - "virtual_ip": "100.103.97.129" + "virtual_ip": "10.15.1.129" } } }, @@ -247,14 +247,14 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.103.97.146", + "ip": "10.15.1.146", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 510, "priority": 150, - "virtual_ip": "100.103.97.145" + "virtual_ip": "10.15.1.145" } } }, @@ -262,14 +262,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.103.97.162", + "ip": "10.15.1.162", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 511, "priority": 150, - "virtual_ip": "100.103.97.161" + "virtual_ip": "10.15.1.161" } } }, @@ -277,14 +277,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.103.97.178", + "ip": "10.15.1.178", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 512, "priority": 150, - "virtual_ip": "100.103.97.177" + "virtual_ip": "10.15.1.177" } } }, @@ -292,14 +292,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.103.97.194", + "ip": "10.15.1.194", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 513, "priority": 150, - "virtual_ip": "100.103.97.193" + "virtual_ip": "10.15.1.193" } } }, @@ -307,14 +307,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.103.97.210", + "ip": "10.15.1.210", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 514, "priority": 150, - "virtual_ip": "100.103.97.209" + "virtual_ip": "10.15.1.209" } } }, @@ -322,14 +322,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.103.97.226", + "ip": "10.15.1.226", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 515, "priority": 150, - "virtual_ip": "100.103.97.225" + "virtual_ip": "10.15.1.225" } } }, @@ -337,14 +337,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.103.97.242", + "ip": "10.15.1.242", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 516, "priority": 150, - "virtual_ip": "100.103.97.241" + "virtual_ip": "10.15.1.241" } } }, @@ -373,21 +373,21 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.100.69.21/32" + "ipv4": "10.11.1.21/32" }, { "name": "P2P_Border1", "type": "L3", "intf_type": "Ethernet", "intf": "1/48", - "ipv4": "100.100.69.2/30" + "ipv4": "10.11.1.2/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/47", - "ipv4": "100.100.69.10/30" + "ipv4": "10.11.1.10/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -412,7 +412,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.100.69.17", + "ipv4": "10.11.1.17", "members": [ "1/41", "1/42" @@ -433,38 +433,38 @@ ], "bgp": { "asn": 64576, - "router_id": "100.100.69.21", + "router_id": "10.11.1.21", "networks": [ - "100.100.69.2/30", - "100.100.69.10/30", - "100.100.69.21/32", - "100.100.69.16/30", - "100.100.162.128/25", - "100.103.96.0/24", - "100.100.69.64/26", - "100.99.20.0/23", - "100.99.22.0/24", - "100.99.23.0/24", - "100.103.97.0/28", - "100.103.97.16/28", - "100.103.97.32/28", - "100.103.97.48/28", - "100.103.97.64/28", - "100.103.97.80/28", - "100.103.97.96/28", - "100.103.97.112/28", - "100.103.97.128/28", - "100.103.97.144/28", - "100.103.97.160/28", - "100.103.97.176/28", - "100.103.97.192/28", - "100.103.97.208/28", - "100.103.97.224/28", - "100.103.97.240/28" + "10.11.1.2/30", + "10.11.1.10/30", + "10.11.1.21/32", + "10.11.1.16/30", + "10.12.1.128/25", + "10.13.1.0/24", + "10.11.1.64/26", + "10.14.20.0/23", + "10.14.22.0/24", + "10.14.23.0/24", + "10.15.1.0/28", + "10.15.1.16/28", + "10.15.1.32/28", + "10.15.1.48/28", + "10.15.1.64/28", + "10.15.1.80/28", + "10.15.1.96/28", + "10.15.1.112/28", + "10.15.1.128/28", + "10.15.1.144/28", + "10.15.1.160/28", + "10.15.1.176/28", + "10.15.1.192/28", + "10.15.1.208/28", + "10.15.1.224/28", + "10.15.1.240/28" ], "neighbors": [ { - "ip": "100.100.69.1", + "ip": "10.11.1.1", "description": "TO_Border1", "remote_as": 64809, "af_ipv4_unicast": { @@ -472,7 +472,7 @@ } }, { - "ip": "100.100.69.9", + "ip": "10.11.1.9", "description": "TO_Border2", "remote_as": 64809, "af_ipv4_unicast": { @@ -480,13 +480,13 @@ } }, { - "ip": "100.100.69.18", + "ip": "10.11.1.18", "description": "iBGP_PEER", "remote_as": 64576, "af_ipv4_unicast": {} }, { - "ip": "100.100.162.128/25", + "ip": "10.12.1.128/25", "description": "TO_HNVPA", "remote_as": 65044, "update_source": "Loopback0", @@ -559,67 +559,67 @@ }, "ip_map": { "P2P_BORDER1_TOR1": [ - "100.100.69.2/30" + "10.11.1.2/30" ], "P2P_TOR1_BORDER1": [ - "100.100.69.1" + "10.11.1.1" ], "P2P_BORDER1_TOR2": [ - "100.100.69.6/30" + "10.11.1.6/30" ], "P2P_TOR2_BORDER1": [ - "100.100.69.5" + "10.11.1.5" ], "P2P_BORDER2_TOR1": [ - "100.100.69.10/30" + "10.11.1.10/30" ], "P2P_TOR1_BORDER2": [ - "100.100.69.9" + "10.11.1.9" ], "P2P_BORDER2_TOR2": [ - "100.100.69.14/30" + "10.11.1.14/30" ], "P2P_TOR2_BORDER2": [ - "100.100.69.13" + "10.11.1.13" ], "P2P_IBGP_TOR1": [ - "100.100.69.17" + "10.11.1.17" ], "P2P_IBGP_TOR2": [ - "100.100.69.18" + "10.11.1.18" ], "LOOPBACK0_TOR1": [ - "100.100.69.21/32" + "10.11.1.21/32" ], "LOOPBACK0_TOR2": [ - "100.100.69.22/32" + "10.11.1.22/32" ], "HNVPA": [ - "100.100.162.128/25" + "10.12.1.128/25" ], "M": [ - "100.103.96.0/24" + "10.13.1.0/24" ], "C": [ - "100.99.20.0/23", - "100.99.22.0/24", - "100.99.23.0/24", - "100.103.97.0/28", - "100.103.97.16/28", - "100.103.97.32/28", - "100.103.97.48/28", - "100.103.97.64/28", - "100.103.97.80/28", - "100.103.97.96/28", - "100.103.97.112/28", - "100.103.97.128/28", - "100.103.97.144/28", - "100.103.97.160/28", - "100.103.97.176/28", - "100.103.97.192/28", - "100.103.97.208/28", - "100.103.97.224/28", - "100.103.97.240/28" + "10.14.20.0/23", + "10.14.22.0/24", + "10.14.23.0/24", + "10.15.1.0/28", + "10.15.1.16/28", + "10.15.1.32/28", + "10.15.1.48/28", + "10.15.1.64/28", + "10.15.1.80/28", + "10.15.1.96/28", + "10.15.1.112/28", + "10.15.1.128/28", + "10.15.1.144/28", + "10.15.1.160/28", + "10.15.1.176/28", + "10.15.1.192/28", + "10.15.1.208/28", + "10.15.1.224/28", + "10.15.1.240/28" ] }, "resolved_trunks": [ diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/b88-b11-93108hl-2-1b.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/tor-1b.json similarity index 73% rename from tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/b88-b11-93108hl-2-1b.json rename to tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/tor-1b.json index ca2563d..04cece5 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/b88-b11-93108hl-2-1b.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/expected_outputs/tor-1b.json @@ -3,10 +3,10 @@ "make": "cisco", "model": "93108tc-fx3p", "type": "TOR2", - "hostname": "b88-b11-93108hl-2-1b", + "hostname": "tor-1b", "version": "10.3(4a)", "firmware": "nxos", - "site": "b88" + "site": "site2" }, "vlans": [ { @@ -18,14 +18,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.100.162.131", + "ip": "10.12.1.131", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 6, "priority": 140, - "virtual_ip": "100.100.162.129" + "virtual_ip": "10.12.1.129" } } }, @@ -33,14 +33,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.103.96.3", + "ip": "10.13.1.3", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 7, "priority": 140, - "virtual_ip": "100.103.96.1" + "virtual_ip": "10.13.1.1" } } }, @@ -52,14 +52,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.100.69.124", + "ip": "10.11.1.124", "cidr": 26, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 125, "priority": 140, - "virtual_ip": "100.100.69.65" + "virtual_ip": "10.11.1.65" } } }, @@ -67,14 +67,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.99.20.3", + "ip": "10.14.20.3", "cidr": 23, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 201, "priority": 140, - "virtual_ip": "100.99.20.1" + "virtual_ip": "10.14.20.1" } } }, @@ -82,14 +82,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.99.22.3", + "ip": "10.14.22.3", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 301, "priority": 140, - "virtual_ip": "100.99.22.1" + "virtual_ip": "10.14.22.1" } } }, @@ -97,14 +97,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.99.23.3", + "ip": "10.14.23.3", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 401, "priority": 140, - "virtual_ip": "100.99.23.1" + "virtual_ip": "10.14.23.1" } } }, @@ -112,14 +112,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.103.97.3", + "ip": "10.15.1.3", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 501, "priority": 140, - "virtual_ip": "100.103.97.1" + "virtual_ip": "10.15.1.1" } } }, @@ -127,14 +127,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.103.97.19", + "ip": "10.15.1.19", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 502, "priority": 140, - "virtual_ip": "100.103.97.17" + "virtual_ip": "10.15.1.17" } } }, @@ -142,14 +142,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.103.97.35", + "ip": "10.15.1.35", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 503, "priority": 140, - "virtual_ip": "100.103.97.33" + "virtual_ip": "10.15.1.33" } } }, @@ -157,14 +157,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.103.97.51", + "ip": "10.15.1.51", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 504, "priority": 140, - "virtual_ip": "100.103.97.49" + "virtual_ip": "10.15.1.49" } } }, @@ -172,14 +172,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.103.97.67", + "ip": "10.15.1.67", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 505, "priority": 140, - "virtual_ip": "100.103.97.65" + "virtual_ip": "10.15.1.65" } } }, @@ -187,14 +187,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.103.97.83", + "ip": "10.15.1.83", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 506, "priority": 140, - "virtual_ip": "100.103.97.81" + "virtual_ip": "10.15.1.81" } } }, @@ -202,14 +202,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.103.97.99", + "ip": "10.15.1.99", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 507, "priority": 140, - "virtual_ip": "100.103.97.97" + "virtual_ip": "10.15.1.97" } } }, @@ -217,14 +217,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.103.97.115", + "ip": "10.15.1.115", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 508, "priority": 140, - "virtual_ip": "100.103.97.113" + "virtual_ip": "10.15.1.113" } } }, @@ -232,14 +232,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.103.97.131", + "ip": "10.15.1.131", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 509, "priority": 140, - "virtual_ip": "100.103.97.129" + "virtual_ip": "10.15.1.129" } } }, @@ -247,14 +247,14 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.103.97.147", + "ip": "10.15.1.147", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 510, "priority": 140, - "virtual_ip": "100.103.97.145" + "virtual_ip": "10.15.1.145" } } }, @@ -262,14 +262,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.103.97.163", + "ip": "10.15.1.163", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 511, "priority": 140, - "virtual_ip": "100.103.97.161" + "virtual_ip": "10.15.1.161" } } }, @@ -277,14 +277,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.103.97.179", + "ip": "10.15.1.179", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 512, "priority": 140, - "virtual_ip": "100.103.97.177" + "virtual_ip": "10.15.1.177" } } }, @@ -292,14 +292,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.103.97.195", + "ip": "10.15.1.195", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 513, "priority": 140, - "virtual_ip": "100.103.97.193" + "virtual_ip": "10.15.1.193" } } }, @@ -307,14 +307,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.103.97.211", + "ip": "10.15.1.211", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 514, "priority": 140, - "virtual_ip": "100.103.97.209" + "virtual_ip": "10.15.1.209" } } }, @@ -322,14 +322,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.103.97.227", + "ip": "10.15.1.227", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 515, "priority": 140, - "virtual_ip": "100.103.97.225" + "virtual_ip": "10.15.1.225" } } }, @@ -337,14 +337,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.103.97.243", + "ip": "10.15.1.243", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 516, "priority": 140, - "virtual_ip": "100.103.97.241" + "virtual_ip": "10.15.1.241" } } }, @@ -373,21 +373,21 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.100.69.22/32" + "ipv4": "10.11.1.22/32" }, { "name": "P2P_Border1", "type": "L3", "intf_type": "Ethernet", "intf": "1/48", - "ipv4": "100.100.69.6/30" + "ipv4": "10.11.1.6/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/47", - "ipv4": "100.100.69.14/30" + "ipv4": "10.11.1.14/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -412,7 +412,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.100.69.18", + "ipv4": "10.11.1.18", "members": [ "1/41", "1/42" @@ -433,38 +433,38 @@ ], "bgp": { "asn": 64576, - "router_id": "100.100.69.22", + "router_id": "10.11.1.22", "networks": [ - "100.100.69.6/30", - "100.100.69.14/30", - "100.100.69.22/32", - "100.100.69.16/30", - "100.100.162.128/25", - "100.103.96.0/24", - "100.100.69.64/26", - "100.99.20.0/23", - "100.99.22.0/24", - "100.99.23.0/24", - "100.103.97.0/28", - "100.103.97.16/28", - "100.103.97.32/28", - "100.103.97.48/28", - "100.103.97.64/28", - "100.103.97.80/28", - "100.103.97.96/28", - "100.103.97.112/28", - "100.103.97.128/28", - "100.103.97.144/28", - "100.103.97.160/28", - "100.103.97.176/28", - "100.103.97.192/28", - "100.103.97.208/28", - "100.103.97.224/28", - "100.103.97.240/28" + "10.11.1.6/30", + "10.11.1.14/30", + "10.11.1.22/32", + "10.11.1.16/30", + "10.12.1.128/25", + "10.13.1.0/24", + "10.11.1.64/26", + "10.14.20.0/23", + "10.14.22.0/24", + "10.14.23.0/24", + "10.15.1.0/28", + "10.15.1.16/28", + "10.15.1.32/28", + "10.15.1.48/28", + "10.15.1.64/28", + "10.15.1.80/28", + "10.15.1.96/28", + "10.15.1.112/28", + "10.15.1.128/28", + "10.15.1.144/28", + "10.15.1.160/28", + "10.15.1.176/28", + "10.15.1.192/28", + "10.15.1.208/28", + "10.15.1.224/28", + "10.15.1.240/28" ], "neighbors": [ { - "ip": "100.100.69.5", + "ip": "10.11.1.5", "description": "TO_Border1", "remote_as": 64809, "af_ipv4_unicast": { @@ -472,7 +472,7 @@ } }, { - "ip": "100.100.69.13", + "ip": "10.11.1.13", "description": "TO_Border2", "remote_as": 64809, "af_ipv4_unicast": { @@ -480,13 +480,13 @@ } }, { - "ip": "100.100.69.17", + "ip": "10.11.1.17", "description": "iBGP_PEER", "remote_as": 64576, "af_ipv4_unicast": {} }, { - "ip": "100.100.162.128/25", + "ip": "10.12.1.128/25", "description": "TO_HNVPA", "remote_as": 65044, "update_source": "Loopback0", @@ -559,67 +559,67 @@ }, "ip_map": { "P2P_BORDER1_TOR1": [ - "100.100.69.2/30" + "10.11.1.2/30" ], "P2P_TOR1_BORDER1": [ - "100.100.69.1" + "10.11.1.1" ], "P2P_BORDER1_TOR2": [ - "100.100.69.6/30" + "10.11.1.6/30" ], "P2P_TOR2_BORDER1": [ - "100.100.69.5" + "10.11.1.5" ], "P2P_BORDER2_TOR1": [ - "100.100.69.10/30" + "10.11.1.10/30" ], "P2P_TOR1_BORDER2": [ - "100.100.69.9" + "10.11.1.9" ], "P2P_BORDER2_TOR2": [ - "100.100.69.14/30" + "10.11.1.14/30" ], "P2P_TOR2_BORDER2": [ - "100.100.69.13" + "10.11.1.13" ], "P2P_IBGP_TOR1": [ - "100.100.69.17" + "10.11.1.17" ], "P2P_IBGP_TOR2": [ - "100.100.69.18" + "10.11.1.18" ], "LOOPBACK0_TOR1": [ - "100.100.69.21/32" + "10.11.1.21/32" ], "LOOPBACK0_TOR2": [ - "100.100.69.22/32" + "10.11.1.22/32" ], "HNVPA": [ - "100.100.162.128/25" + "10.12.1.128/25" ], "M": [ - "100.103.96.0/24" + "10.13.1.0/24" ], "C": [ - "100.99.20.0/23", - "100.99.22.0/24", - "100.99.23.0/24", - "100.103.97.0/28", - "100.103.97.16/28", - "100.103.97.32/28", - "100.103.97.48/28", - "100.103.97.64/28", - "100.103.97.80/28", - "100.103.97.96/28", - "100.103.97.112/28", - "100.103.97.128/28", - "100.103.97.144/28", - "100.103.97.160/28", - "100.103.97.176/28", - "100.103.97.192/28", - "100.103.97.208/28", - "100.103.97.224/28", - "100.103.97.240/28" + "10.14.20.0/23", + "10.14.22.0/24", + "10.14.23.0/24", + "10.15.1.0/28", + "10.15.1.16/28", + "10.15.1.32/28", + "10.15.1.48/28", + "10.15.1.64/28", + "10.15.1.80/28", + "10.15.1.96/28", + "10.15.1.112/28", + "10.15.1.128/28", + "10.15.1.144/28", + "10.15.1.160/28", + "10.15.1.176/28", + "10.15.1.192/28", + "10.15.1.208/28", + "10.15.1.224/28", + "10.15.1.240/28" ] }, "resolved_trunks": [ diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/lab_cisco_nxos_switch_input.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/lab_cisco_nxos_switch_input.json index 86f7cea..93a136a 100644 --- a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/lab_cisco_nxos_switch_input.json +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switchless/lab_cisco_nxos_switch_input.json @@ -5,8 +5,8 @@ "MainEnvData": [ { "Id": "Env01", - "Site": "b88", - "RackName": "rb11", + "Site": "site2", + "RackName": "rack02", "NodeCount": 16, "ConnectType": "connected", "CiEnabled": "yes", @@ -15,113 +15,113 @@ "Name": "Cl01", "NodeCount": 2, "RackId": "Rack01", - "NamingPrefix": "rb1101", - "PhysicalNamingPrefix": "rb1101", + "NamingPrefix": "node01", + "PhysicalNamingPrefix": "node01", "Topology": "Switchless", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "rb1101.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-rb1101.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node01.test.example.com", + "ExternalDomainFQDN": "ext-node01.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl02", "NodeCount": 2, "RackId": "Rack01", - "NamingPrefix": "rb1102", - "PhysicalNamingPrefix": "rb1102", + "NamingPrefix": "node02", + "PhysicalNamingPrefix": "node02", "Topology": "Switchless", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "rb1102.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-rb1102.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node02.test.example.com", + "ExternalDomainFQDN": "ext-node02.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl03", "NodeCount": 2, "RackId": "Rack01", - "NamingPrefix": "rb1103", - "PhysicalNamingPrefix": "rb1103", + "NamingPrefix": "node03", + "PhysicalNamingPrefix": "node03", "Topology": "Switchless", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "rb1103.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-rb1103.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node03.test.example.com", + "ExternalDomainFQDN": "ext-node03.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl04", "NodeCount": 2, "RackId": "Rack01", - "NamingPrefix": "rb1104", - "PhysicalNamingPrefix": "rb1104", + "NamingPrefix": "node04", + "PhysicalNamingPrefix": "node04", "Topology": "Switchless", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "rb1104.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-rb1104.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node04.test.example.com", + "ExternalDomainFQDN": "ext-node04.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl05", "NodeCount": 2, "RackId": "Rack01", - "NamingPrefix": "rb1105", - "PhysicalNamingPrefix": "rb1105", + "NamingPrefix": "node05", + "PhysicalNamingPrefix": "node05", "Topology": "Switchless", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "rb1105.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-rb1105.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node05.test.example.com", + "ExternalDomainFQDN": "ext-node05.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl06", "NodeCount": 2, "RackId": "Rack01", - "NamingPrefix": "rb1106", - "PhysicalNamingPrefix": "rb1106", + "NamingPrefix": "node06", + "PhysicalNamingPrefix": "node06", "Topology": "Switchless", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "rb1106.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-rb1106.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node06.test.example.com", + "ExternalDomainFQDN": "ext-node06.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl07", "NodeCount": 2, "RackId": "Rack01", - "NamingPrefix": "rb1107", - "PhysicalNamingPrefix": "rb1107", + "NamingPrefix": "node07", + "PhysicalNamingPrefix": "node07", "Topology": "Switchless", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "rb1107.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-rb1107.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node07.test.example.com", + "ExternalDomainFQDN": "ext-node07.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl08", "NodeCount": 2, "RackId": "Rack01", - "NamingPrefix": "rb1108", - "PhysicalNamingPrefix": "rb1108", + "NamingPrefix": "node08", + "PhysicalNamingPrefix": "node08", "Topology": "Switchless", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "rb1108.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-rb1108.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node08.test.example.com", + "ExternalDomainFQDN": "ext-node08.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" } ] } @@ -130,14 +130,14 @@ { "Make": "Cisco", "Model": "C9336C-FX2", - "Hostname": "b88-1501-J03-9336ssp-1a", + "Hostname": "border-1a", "Type": "Border1", "ASN": 64809 }, { "Make": "Cisco", "Model": "C9336C-FX2", - "Hostname": "b88-1501-J03-9336ssp-1b", + "Hostname": "border-1b", "Type": "Border2", "ASN": 64809 }, @@ -145,7 +145,7 @@ "Make": "Cisco", "Model": "93108TC-FX3P", "Type": "TOR1", - "Hostname": "b88-b11-93108hl-2-1a", + "Hostname": "tor-1a", "ASN": 64576, "Firmware": "10.3(4a)" }, @@ -153,7 +153,7 @@ "Make": "Cisco", "Model": "93108TC-FX3P", "Type": "TOR2", - "Hostname": "b88-b11-93108hl-2-1b", + "Hostname": "tor-1b", "ASN": 64576, "Firmware": "10.3(4a)" }, @@ -166,10 +166,10 @@ "Firmware": "None" }, { - "Make": "Microsoft", + "Make": "Contoso", "Model": null, "Type": "MUX", - "Hostname": "b88-b11-MUX-1", + "Hostname": "mux-1", "ASN": 65044, "Firmware": null } @@ -189,25 +189,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.100.69.0/30", - "Network": "100.100.69.0", + "Subnet": "10.11.1.0/30", + "Network": "10.11.1.0", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.100.69.3", - "FirstAddress": "100.100.69.1", - "LastAddress": "100.100.69.2", + "BroadcastAddress": "10.11.1.3", + "FirstAddress": "10.11.1.1", + "LastAddress": "10.11.1.2", "Assignment": [ { "Name": "Network", - "IP": "100.100.69.0" + "IP": "10.11.1.0" }, { "Name": "Border1", - "IP": "100.100.69.1" + "IP": "10.11.1.1" }, { "Name": "TOR1", - "IP": "100.100.69.2" + "IP": "10.11.1.2" } ] }, @@ -224,25 +224,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.100.69.4/30", - "Network": "100.100.69.4", + "Subnet": "10.11.1.4/30", + "Network": "10.11.1.4", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.100.69.7", - "FirstAddress": "100.100.69.5", - "LastAddress": "100.100.69.6", + "BroadcastAddress": "10.11.1.7", + "FirstAddress": "10.11.1.5", + "LastAddress": "10.11.1.6", "Assignment": [ { "Name": "Network", - "IP": "100.100.69.4" + "IP": "10.11.1.4" }, { "Name": "Border1", - "IP": "100.100.69.5" + "IP": "10.11.1.5" }, { "Name": "TOR2", - "IP": "100.100.69.6" + "IP": "10.11.1.6" } ] }, @@ -259,25 +259,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.100.69.8/30", - "Network": "100.100.69.8", + "Subnet": "10.11.1.8/30", + "Network": "10.11.1.8", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.100.69.11", - "FirstAddress": "100.100.69.9", - "LastAddress": "100.100.69.10", + "BroadcastAddress": "10.11.1.11", + "FirstAddress": "10.11.1.9", + "LastAddress": "10.11.1.10", "Assignment": [ { "Name": "Network", - "IP": "100.100.69.8" + "IP": "10.11.1.8" }, { "Name": "Border2", - "IP": "100.100.69.9" + "IP": "10.11.1.9" }, { "Name": "TOR1", - "IP": "100.100.69.10" + "IP": "10.11.1.10" } ] }, @@ -294,25 +294,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.100.69.12/30", - "Network": "100.100.69.12", + "Subnet": "10.11.1.12/30", + "Network": "10.11.1.12", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.100.69.15", - "FirstAddress": "100.100.69.13", - "LastAddress": "100.100.69.14", + "BroadcastAddress": "10.11.1.15", + "FirstAddress": "10.11.1.13", + "LastAddress": "10.11.1.14", "Assignment": [ { "Name": "Network", - "IP": "100.100.69.12" + "IP": "10.11.1.12" }, { "Name": "Border2", - "IP": "100.100.69.13" + "IP": "10.11.1.13" }, { "Name": "TOR2", - "IP": "100.100.69.14" + "IP": "10.11.1.14" } ] }, @@ -329,25 +329,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.100.69.16/30", - "Network": "100.100.69.16", + "Subnet": "10.11.1.16/30", + "Network": "10.11.1.16", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.100.69.19", - "FirstAddress": "100.100.69.17", - "LastAddress": "100.100.69.18", + "BroadcastAddress": "10.11.1.19", + "FirstAddress": "10.11.1.17", + "LastAddress": "10.11.1.18", "Assignment": [ { "Name": "Network", - "IP": "100.100.69.16" + "IP": "10.11.1.16" }, { "Name": "TOR1", - "IP": "100.100.69.17" + "IP": "10.11.1.17" }, { "Name": "TOR2", - "IP": "100.100.69.18" + "IP": "10.11.1.18" } ] }, @@ -364,8 +364,8 @@ "Cidr": 32, "TORGroup": "", "NetworkType": "Loopback", - "Subnet": "100.100.69.21/32", - "Network": "100.100.69.21", + "Subnet": "10.11.1.21/32", + "Network": "10.11.1.21", "Netmask": "255.255.255.255", "Gateway": "", "BroadcastAddress": "", @@ -374,7 +374,7 @@ "Assignment": [ { "Name": "TOR1", - "IP": "100.100.69.21" + "IP": "10.11.1.21" } ] }, @@ -391,8 +391,8 @@ "Cidr": 32, "TORGroup": "", "NetworkType": "Loopback", - "Subnet": "100.100.69.22/32", - "Network": "100.100.69.22", + "Subnet": "10.11.1.22/32", + "Network": "10.11.1.22", "Netmask": "255.255.255.255", "Gateway": "", "BroadcastAddress": "", @@ -401,7 +401,7 @@ "Assignment": [ { "Name": "TOR2", - "IP": "100.100.69.22" + "IP": "10.11.1.22" } ] }, @@ -419,172 +419,172 @@ "Cidr": 26, "TORGroup": "", "NetworkType": "Infrastructure", - "Subnet": "100.100.69.64/26", - "Network": "100.100.69.64", + "Subnet": "10.11.1.64/26", + "Network": "10.11.1.64", "Netmask": "255.255.255.192", - "Gateway": "100.100.69.65", - "BroadcastAddress": "100.100.69.127", - "FirstAddress": "100.100.69.65", - "LastAddress": "100.100.69.126", + "Gateway": "10.11.1.65", + "BroadcastAddress": "10.11.1.127", + "FirstAddress": "10.11.1.65", + "LastAddress": "10.11.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.100.69.64", + "IP": "10.11.1.64", "ClusterID": null }, { "Name": "Gateway", - "IP": "100.100.69.65", + "IP": "10.11.1.65", "ClusterID": null }, { "Name": "HLH-BMC", - "IP": "100.100.69.66", + "IP": "10.11.1.66", "ClusterID": null }, { "Name": "CL01-N01", - "IP": "100.100.69.67", + "IP": "10.11.1.67", "ClusterID": "CL01" }, { "Name": "CL01-N02", - "IP": "100.100.69.68", + "IP": "10.11.1.68", "ClusterID": "CL01" }, { "Name": "CL02-N01", - "IP": "100.100.69.69", + "IP": "10.11.1.69", "ClusterID": "CL02" }, { "Name": "CL02-N02", - "IP": "100.100.69.70", + "IP": "10.11.1.70", "ClusterID": "CL02" }, { "Name": "CL03-N01", - "IP": "100.100.69.71", + "IP": "10.11.1.71", "ClusterID": "CL03" }, { "Name": "CL03-N02", - "IP": "100.100.69.72", + "IP": "10.11.1.72", "ClusterID": "CL03" }, { "Name": "CL04-N01", - "IP": "100.100.69.73", + "IP": "10.11.1.73", "ClusterID": "CL04" }, { "Name": "CL04-N02", - "IP": "100.100.69.74", + "IP": "10.11.1.74", "ClusterID": "CL04" }, { "Name": "CL05-N01", - "IP": "100.100.69.75", + "IP": "10.11.1.75", "ClusterID": "CL05" }, { "Name": "CL05-N02", - "IP": "100.100.69.76", + "IP": "10.11.1.76", "ClusterID": "CL05" }, { "Name": "CL06-N01", - "IP": "100.100.69.77", + "IP": "10.11.1.77", "ClusterID": "CL06" }, { "Name": "CL06-N02", - "IP": "100.100.69.78", + "IP": "10.11.1.78", "ClusterID": "CL06" }, { "Name": "CL07-N01", - "IP": "100.100.69.79", + "IP": "10.11.1.79", "ClusterID": "CL07" }, { "Name": "CL07-N02", - "IP": "100.100.69.80", + "IP": "10.11.1.80", "ClusterID": "CL07" }, { "Name": "CL08-N01", - "IP": "100.100.69.81", + "IP": "10.11.1.81", "ClusterID": "CL08" }, { "Name": "CL08-N02", - "IP": "100.100.69.82", + "IP": "10.11.1.82", "ClusterID": "CL08" }, { "Name": "CL01-HLH-DVM01", - "IP": "100.100.69.107", + "IP": "10.11.1.107", "ClusterID": "CL01" }, { "Name": "CL02-HLH-DVM02", - "IP": "100.100.69.108", + "IP": "10.11.1.108", "ClusterID": "CL02" }, { "Name": "CL03-HLH-DVM03", - "IP": "100.100.69.109", + "IP": "10.11.1.109", "ClusterID": "CL03" }, { "Name": "CL04-HLH-DVM04", - "IP": "100.100.69.110", + "IP": "10.11.1.110", "ClusterID": "CL04" }, { "Name": "CL05-HLH-DVM05", - "IP": "100.100.69.111", + "IP": "10.11.1.111", "ClusterID": "CL05" }, { "Name": "CL06-HLH-DVM06", - "IP": "100.100.69.112", + "IP": "10.11.1.112", "ClusterID": "CL06" }, { "Name": "CL07-HLH-DVM07", - "IP": "100.100.69.113", + "IP": "10.11.1.113", "ClusterID": "CL07" }, { "Name": "CL08-HLH-DVM08", - "IP": "100.100.69.114", + "IP": "10.11.1.114", "ClusterID": "CL08" }, { "Name": "Tor1-Mgmt", - "IP": "100.100.69.123", + "IP": "10.11.1.123", "ClusterID": null }, { "Name": "Tor2-Mgmt", - "IP": "100.100.69.124", + "IP": "10.11.1.124", "ClusterID": null }, { "Name": "BMC-Mgmt", - "IP": "100.100.69.125", + "IP": "10.11.1.125", "ClusterID": null }, { "Name": "HLH-OS", - "IP": "100.100.69.126", + "IP": "10.11.1.126", "ClusterID": null }, { "Name": "Broadcast", - "IP": "100.100.69.127", + "IP": "10.11.1.127", "ClusterID": null } ] @@ -603,71 +603,71 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "PA", - "Subnet": "100.100.162.128/25", - "Network": "100.100.162.128", + "Subnet": "10.12.1.128/25", + "Network": "10.12.1.128", "Netmask": "255.255.255.128", - "Gateway": "100.100.162.129", - "BroadcastAddress": "100.100.162.255", - "FirstAddress": "100.100.162.129", - "LastAddress": "100.100.162.254", + "Gateway": "10.12.1.129", + "BroadcastAddress": "10.12.1.255", + "FirstAddress": "10.12.1.129", + "LastAddress": "10.12.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.100.162.128" + "IP": "10.12.1.128" }, { "Name": "Gateway", - "IP": "100.100.162.129" + "IP": "10.12.1.129" }, { "Name": "TOR1", - "IP": "100.100.162.130" + "IP": "10.12.1.130" }, { "Name": "TOR2", - "IP": "100.100.162.131" + "IP": "10.12.1.131" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.100.162.132", - "EndingAddress": "100.100.162.143" + "StartingAddress": "10.12.1.132", + "EndingAddress": "10.12.1.143" }, { "Name": "CL02", - "StartingAddress": "100.100.162.144", - "EndingAddress": "100.100.162.159" + "StartingAddress": "10.12.1.144", + "EndingAddress": "10.12.1.159" }, { "Name": "CL03", - "StartingAddress": "100.100.162.160", - "EndingAddress": "100.100.162.175" + "StartingAddress": "10.12.1.160", + "EndingAddress": "10.12.1.175" }, { "Name": "CL04", - "StartingAddress": "100.100.162.176", - "EndingAddress": "100.100.162.191" + "StartingAddress": "10.12.1.176", + "EndingAddress": "10.12.1.191" }, { "Name": "CL05", - "StartingAddress": "100.100.162.192", - "EndingAddress": "100.100.162.207" + "StartingAddress": "10.12.1.192", + "EndingAddress": "10.12.1.207" }, { "Name": "CL06", - "StartingAddress": "100.100.162.208", - "EndingAddress": "100.100.162.223" + "StartingAddress": "10.12.1.208", + "EndingAddress": "10.12.1.223" }, { "Name": "CL07", - "StartingAddress": "100.100.162.224", - "EndingAddress": "100.100.162.239" + "StartingAddress": "10.12.1.224", + "EndingAddress": "10.12.1.239" }, { "Name": "CL08", - "StartingAddress": "100.100.162.240", - "EndingAddress": "100.100.162.254" + "StartingAddress": "10.12.1.240", + "EndingAddress": "10.12.1.254" } ] }, @@ -685,135 +685,135 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Infrastructure", - "Subnet": "100.103.96.0/24", - "Network": "100.103.96.0", + "Subnet": "10.13.1.0/24", + "Network": "10.13.1.0", "Netmask": "255.255.255.0", - "Gateway": "100.103.96.1", - "BroadcastAddress": "100.103.96.255", - "FirstAddress": "100.103.96.1", - "LastAddress": "100.103.96.254", + "Gateway": "10.13.1.1", + "BroadcastAddress": "10.13.1.255", + "FirstAddress": "10.13.1.1", + "LastAddress": "10.13.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.103.96.0" + "IP": "10.13.1.0" }, { "Name": "Gateway", - "IP": "100.103.96.1" + "IP": "10.13.1.1" }, { "Name": "TOR1", - "IP": "100.103.96.2" + "IP": "10.13.1.2" }, { "Name": "TOR2", - "IP": "100.103.96.3" + "IP": "10.13.1.3" }, { "Name": "CL01-N01", - "IP": "100.103.96.4" + "IP": "10.13.1.4" }, { "Name": "CL01-N02", - "IP": "100.103.96.5" + "IP": "10.13.1.5" }, { "Name": "CL02-N01", - "IP": "100.103.96.32" + "IP": "10.13.1.32" }, { "Name": "CL02-N02", - "IP": "100.103.96.33" + "IP": "10.13.1.33" }, { "Name": "CL03-N01", - "IP": "100.103.96.64" + "IP": "10.13.1.64" }, { "Name": "CL03-N02", - "IP": "100.103.96.65" + "IP": "10.13.1.65" }, { "Name": "CL04-N01", - "IP": "100.103.96.96" + "IP": "10.13.1.96" }, { "Name": "CL04-N02", - "IP": "100.103.96.97" + "IP": "10.13.1.97" }, { "Name": "CL05-N01", - "IP": "100.103.96.128" + "IP": "10.13.1.128" }, { "Name": "CL05-N02", - "IP": "100.103.96.129" + "IP": "10.13.1.129" }, { "Name": "CL06-N01", - "IP": "100.103.96.160" + "IP": "10.13.1.160" }, { "Name": "CL06-N02", - "IP": "100.103.96.161" + "IP": "10.13.1.161" }, { "Name": "CL07-N01", - "IP": "100.103.96.192" + "IP": "10.13.1.192" }, { "Name": "CL07-N02", - "IP": "100.103.96.193" + "IP": "10.13.1.193" }, { "Name": "CL08-N01", - "IP": "100.103.96.224" + "IP": "10.13.1.224" }, { "Name": "CL08-N02", - "IP": "100.103.96.225" + "IP": "10.13.1.225" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.103.96.6", - "EndingAddress": "100.103.96.31" + "StartingAddress": "10.13.1.6", + "EndingAddress": "10.13.1.31" }, { "Name": "CL02", - "StartingAddress": "100.103.96.34", - "EndingAddress": "100.103.96.63" + "StartingAddress": "10.13.1.34", + "EndingAddress": "10.13.1.63" }, { "Name": "CL03", - "StartingAddress": "100.103.96.66", - "EndingAddress": "100.103.96.95" + "StartingAddress": "10.13.1.66", + "EndingAddress": "10.13.1.95" }, { "Name": "CL04", - "StartingAddress": "100.103.96.98", - "EndingAddress": "100.103.96.127" + "StartingAddress": "10.13.1.98", + "EndingAddress": "10.13.1.127" }, { "Name": "CL05", - "StartingAddress": "100.103.96.130", - "EndingAddress": "100.103.96.159" + "StartingAddress": "10.13.1.130", + "EndingAddress": "10.13.1.159" }, { "Name": "CL06", - "StartingAddress": "100.103.96.162", - "EndingAddress": "100.103.96.191" + "StartingAddress": "10.13.1.162", + "EndingAddress": "10.13.1.191" }, { "Name": "CL07", - "StartingAddress": "100.103.96.194", - "EndingAddress": "100.103.96.223" + "StartingAddress": "10.13.1.194", + "EndingAddress": "10.13.1.223" }, { "Name": "CL08", - "StartingAddress": "100.103.96.226", - "EndingAddress": "100.103.96.254" + "StartingAddress": "10.13.1.226", + "EndingAddress": "10.13.1.254" } ] }, @@ -831,71 +831,71 @@ "Cidr": 23, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.99.20.0/23", - "Network": "100.99.20.0", + "Subnet": "10.14.20.0/23", + "Network": "10.14.20.0", "Netmask": "255.255.254.0", - "Gateway": "100.99.20.1", - "BroadcastAddress": "100.99.21.255", - "FirstAddress": "100.99.20.1", - "LastAddress": "100.99.21.254", + "Gateway": "10.14.20.1", + "BroadcastAddress": "10.14.21.255", + "FirstAddress": "10.14.20.1", + "LastAddress": "10.14.21.254", "Assignment": [ { "Name": "Network", - "IP": "100.99.20.0" + "IP": "10.14.20.0" }, { "Name": "Gateway", - "IP": "100.99.20.1" + "IP": "10.14.20.1" }, { "Name": "TOR1", - "IP": "100.99.20.2" + "IP": "10.14.20.2" }, { "Name": "TOR2", - "IP": "100.99.20.3" + "IP": "10.14.20.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.99.20.4", - "EndingAddress": "100.99.20.63" + "StartingAddress": "10.14.20.4", + "EndingAddress": "10.14.20.63" }, { "Name": "CL02", - "StartingAddress": "100.99.20.64", - "EndingAddress": "100.99.20.127" + "StartingAddress": "10.14.20.64", + "EndingAddress": "10.14.20.127" }, { "Name": "CL03", - "StartingAddress": "100.99.20.128", - "EndingAddress": "100.99.20.191" + "StartingAddress": "10.14.20.128", + "EndingAddress": "10.14.20.191" }, { "Name": "CL04", - "StartingAddress": "100.99.20.192", - "EndingAddress": "100.99.20.255" + "StartingAddress": "10.14.20.192", + "EndingAddress": "10.14.20.255" }, { "Name": "CL05", - "StartingAddress": "100.99.21.0", - "EndingAddress": "100.99.21.63" + "StartingAddress": "10.14.21.0", + "EndingAddress": "10.14.21.63" }, { "Name": "CL06", - "StartingAddress": "100.99.21.64", - "EndingAddress": "100.99.21.127" + "StartingAddress": "10.14.21.64", + "EndingAddress": "10.14.21.127" }, { "Name": "CL07", - "StartingAddress": "100.99.21.128", - "EndingAddress": "100.99.21.191" + "StartingAddress": "10.14.21.128", + "EndingAddress": "10.14.21.191" }, { "Name": "CL08", - "StartingAddress": "100.99.21.192", - "EndingAddress": "100.99.21.254" + "StartingAddress": "10.14.21.192", + "EndingAddress": "10.14.21.254" } ] }, @@ -913,71 +913,71 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.99.22.0/24", - "Network": "100.99.22.0", + "Subnet": "10.14.22.0/24", + "Network": "10.14.22.0", "Netmask": "255.255.255.0", - "Gateway": "100.99.22.1", - "BroadcastAddress": "100.99.22.255", - "FirstAddress": "100.99.22.1", - "LastAddress": "100.99.22.254", + "Gateway": "10.14.22.1", + "BroadcastAddress": "10.14.22.255", + "FirstAddress": "10.14.22.1", + "LastAddress": "10.14.22.254", "Assignment": [ { "Name": "Network", - "IP": "100.99.22.0" + "IP": "10.14.22.0" }, { "Name": "Gateway", - "IP": "100.99.22.1" + "IP": "10.14.22.1" }, { "Name": "TOR1", - "IP": "100.99.22.2" + "IP": "10.14.22.2" }, { "Name": "TOR2", - "IP": "100.99.22.3" + "IP": "10.14.22.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.99.22.4", - "EndingAddress": "100.99.22.31" + "StartingAddress": "10.14.22.4", + "EndingAddress": "10.14.22.31" }, { "Name": "CL02", - "StartingAddress": "100.99.22.32", - "EndingAddress": "100.99.22.63" + "StartingAddress": "10.14.22.32", + "EndingAddress": "10.14.22.63" }, { "Name": "CL03", - "StartingAddress": "100.99.22.64", - "EndingAddress": "100.99.22.95" + "StartingAddress": "10.14.22.64", + "EndingAddress": "10.14.22.95" }, { "Name": "CL04", - "StartingAddress": "100.99.22.96", - "EndingAddress": "100.99.22.127" + "StartingAddress": "10.14.22.96", + "EndingAddress": "10.14.22.127" }, { "Name": "CL05", - "StartingAddress": "100.99.22.128", - "EndingAddress": "100.99.22.159" + "StartingAddress": "10.14.22.128", + "EndingAddress": "10.14.22.159" }, { "Name": "CL06", - "StartingAddress": "100.99.22.160", - "EndingAddress": "100.99.22.191" + "StartingAddress": "10.14.22.160", + "EndingAddress": "10.14.22.191" }, { "Name": "CL07", - "StartingAddress": "100.99.22.192", - "EndingAddress": "100.99.22.223" + "StartingAddress": "10.14.22.192", + "EndingAddress": "10.14.22.223" }, { "Name": "CL08", - "StartingAddress": "100.99.22.224", - "EndingAddress": "100.99.22.254" + "StartingAddress": "10.14.22.224", + "EndingAddress": "10.14.22.254" } ] }, @@ -995,29 +995,29 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.99.23.0/24", - "Network": "100.99.23.0", + "Subnet": "10.14.23.0/24", + "Network": "10.14.23.0", "Netmask": "255.255.255.0", - "Gateway": "100.99.23.1", - "BroadcastAddress": "100.99.23.255", - "FirstAddress": "100.99.23.1", - "LastAddress": "100.99.23.254", + "Gateway": "10.14.23.1", + "BroadcastAddress": "10.14.23.255", + "FirstAddress": "10.14.23.1", + "LastAddress": "10.14.23.254", "Assignment": [ { "Name": "Network", - "IP": "100.99.23.0" + "IP": "10.14.23.0" }, { "Name": "Gateway", - "IP": "100.99.23.1" + "IP": "10.14.23.1" }, { "Name": "TOR1", - "IP": "100.99.23.2" + "IP": "10.14.23.2" }, { "Name": "TOR2", - "IP": "100.99.23.3" + "IP": "10.14.23.3" } ] }, @@ -1035,29 +1035,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.0/28", - "Network": "100.103.97.0", + "Subnet": "10.15.1.0/28", + "Network": "10.15.1.0", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.1", - "BroadcastAddress": "100.103.97.15", - "FirstAddress": "100.103.97.1", - "LastAddress": "100.103.97.14", + "Gateway": "10.15.1.1", + "BroadcastAddress": "10.15.1.15", + "FirstAddress": "10.15.1.1", + "LastAddress": "10.15.1.14", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.0" + "IP": "10.15.1.0" }, { "Name": "Gateway", - "IP": "100.103.97.1" + "IP": "10.15.1.1" }, { "Name": "TOR1", - "IP": "100.103.97.2" + "IP": "10.15.1.2" }, { "Name": "TOR2", - "IP": "100.103.97.3" + "IP": "10.15.1.3" } ] }, @@ -1075,29 +1075,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.16/28", - "Network": "100.103.97.16", + "Subnet": "10.15.1.16/28", + "Network": "10.15.1.16", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.17", - "BroadcastAddress": "100.103.97.31", - "FirstAddress": "100.103.97.17", - "LastAddress": "100.103.97.30", + "Gateway": "10.15.1.17", + "BroadcastAddress": "10.15.1.31", + "FirstAddress": "10.15.1.17", + "LastAddress": "10.15.1.30", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.16" + "IP": "10.15.1.16" }, { "Name": "Gateway", - "IP": "100.103.97.17" + "IP": "10.15.1.17" }, { "Name": "TOR1", - "IP": "100.103.97.18" + "IP": "10.15.1.18" }, { "Name": "TOR2", - "IP": "100.103.97.19" + "IP": "10.15.1.19" } ] }, @@ -1115,29 +1115,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.32/28", - "Network": "100.103.97.32", + "Subnet": "10.15.1.32/28", + "Network": "10.15.1.32", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.33", - "BroadcastAddress": "100.103.97.47", - "FirstAddress": "100.103.97.33", - "LastAddress": "100.103.97.46", + "Gateway": "10.15.1.33", + "BroadcastAddress": "10.15.1.47", + "FirstAddress": "10.15.1.33", + "LastAddress": "10.15.1.46", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.32" + "IP": "10.15.1.32" }, { "Name": "Gateway", - "IP": "100.103.97.33" + "IP": "10.15.1.33" }, { "Name": "TOR1", - "IP": "100.103.97.34" + "IP": "10.15.1.34" }, { "Name": "TOR2", - "IP": "100.103.97.35" + "IP": "10.15.1.35" } ] }, @@ -1155,29 +1155,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.48/28", - "Network": "100.103.97.48", + "Subnet": "10.15.1.48/28", + "Network": "10.15.1.48", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.49", - "BroadcastAddress": "100.103.97.63", - "FirstAddress": "100.103.97.49", - "LastAddress": "100.103.97.62", + "Gateway": "10.15.1.49", + "BroadcastAddress": "10.15.1.63", + "FirstAddress": "10.15.1.49", + "LastAddress": "10.15.1.62", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.48" + "IP": "10.15.1.48" }, { "Name": "Gateway", - "IP": "100.103.97.49" + "IP": "10.15.1.49" }, { "Name": "TOR1", - "IP": "100.103.97.50" + "IP": "10.15.1.50" }, { "Name": "TOR2", - "IP": "100.103.97.51" + "IP": "10.15.1.51" } ] }, @@ -1195,29 +1195,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.64/28", - "Network": "100.103.97.64", + "Subnet": "10.15.1.64/28", + "Network": "10.15.1.64", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.65", - "BroadcastAddress": "100.103.97.79", - "FirstAddress": "100.103.97.65", - "LastAddress": "100.103.97.78", + "Gateway": "10.15.1.65", + "BroadcastAddress": "10.15.1.79", + "FirstAddress": "10.15.1.65", + "LastAddress": "10.15.1.78", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.64" + "IP": "10.15.1.64" }, { "Name": "Gateway", - "IP": "100.103.97.65" + "IP": "10.15.1.65" }, { "Name": "TOR1", - "IP": "100.103.97.66" + "IP": "10.15.1.66" }, { "Name": "TOR2", - "IP": "100.103.97.67" + "IP": "10.15.1.67" } ] }, @@ -1235,29 +1235,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.80/28", - "Network": "100.103.97.80", + "Subnet": "10.15.1.80/28", + "Network": "10.15.1.80", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.81", - "BroadcastAddress": "100.103.97.95", - "FirstAddress": "100.103.97.81", - "LastAddress": "100.103.97.94", + "Gateway": "10.15.1.81", + "BroadcastAddress": "10.15.1.95", + "FirstAddress": "10.15.1.81", + "LastAddress": "10.15.1.94", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.80" + "IP": "10.15.1.80" }, { "Name": "Gateway", - "IP": "100.103.97.81" + "IP": "10.15.1.81" }, { "Name": "TOR1", - "IP": "100.103.97.82" + "IP": "10.15.1.82" }, { "Name": "TOR2", - "IP": "100.103.97.83" + "IP": "10.15.1.83" } ] }, @@ -1275,29 +1275,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.96/28", - "Network": "100.103.97.96", + "Subnet": "10.15.1.96/28", + "Network": "10.15.1.96", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.97", - "BroadcastAddress": "100.103.97.111", - "FirstAddress": "100.103.97.97", - "LastAddress": "100.103.97.110", + "Gateway": "10.15.1.97", + "BroadcastAddress": "10.15.1.111", + "FirstAddress": "10.15.1.97", + "LastAddress": "10.15.1.110", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.96" + "IP": "10.15.1.96" }, { "Name": "Gateway", - "IP": "100.103.97.97" + "IP": "10.15.1.97" }, { "Name": "TOR1", - "IP": "100.103.97.98" + "IP": "10.15.1.98" }, { "Name": "TOR2", - "IP": "100.103.97.99" + "IP": "10.15.1.99" } ] }, @@ -1315,29 +1315,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.112/28", - "Network": "100.103.97.112", + "Subnet": "10.15.1.112/28", + "Network": "10.15.1.112", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.113", - "BroadcastAddress": "100.103.97.127", - "FirstAddress": "100.103.97.113", - "LastAddress": "100.103.97.126", + "Gateway": "10.15.1.113", + "BroadcastAddress": "10.15.1.127", + "FirstAddress": "10.15.1.113", + "LastAddress": "10.15.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.112" + "IP": "10.15.1.112" }, { "Name": "Gateway", - "IP": "100.103.97.113" + "IP": "10.15.1.113" }, { "Name": "TOR1", - "IP": "100.103.97.114" + "IP": "10.15.1.114" }, { "Name": "TOR2", - "IP": "100.103.97.115" + "IP": "10.15.1.115" } ] }, @@ -1355,29 +1355,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.128/28", - "Network": "100.103.97.128", + "Subnet": "10.15.1.128/28", + "Network": "10.15.1.128", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.129", - "BroadcastAddress": "100.103.97.143", - "FirstAddress": "100.103.97.129", - "LastAddress": "100.103.97.142", + "Gateway": "10.15.1.129", + "BroadcastAddress": "10.15.1.143", + "FirstAddress": "10.15.1.129", + "LastAddress": "10.15.1.142", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.128" + "IP": "10.15.1.128" }, { "Name": "Gateway", - "IP": "100.103.97.129" + "IP": "10.15.1.129" }, { "Name": "TOR1", - "IP": "100.103.97.130" + "IP": "10.15.1.130" }, { "Name": "TOR2", - "IP": "100.103.97.131" + "IP": "10.15.1.131" } ] }, @@ -1395,29 +1395,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.144/28", - "Network": "100.103.97.144", + "Subnet": "10.15.1.144/28", + "Network": "10.15.1.144", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.145", - "BroadcastAddress": "100.103.97.159", - "FirstAddress": "100.103.97.145", - "LastAddress": "100.103.97.158", + "Gateway": "10.15.1.145", + "BroadcastAddress": "10.15.1.159", + "FirstAddress": "10.15.1.145", + "LastAddress": "10.15.1.158", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.144" + "IP": "10.15.1.144" }, { "Name": "Gateway", - "IP": "100.103.97.145" + "IP": "10.15.1.145" }, { "Name": "TOR1", - "IP": "100.103.97.146" + "IP": "10.15.1.146" }, { "Name": "TOR2", - "IP": "100.103.97.147" + "IP": "10.15.1.147" } ] }, @@ -1435,29 +1435,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.160/28", - "Network": "100.103.97.160", + "Subnet": "10.15.1.160/28", + "Network": "10.15.1.160", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.161", - "BroadcastAddress": "100.103.97.175", - "FirstAddress": "100.103.97.161", - "LastAddress": "100.103.97.174", + "Gateway": "10.15.1.161", + "BroadcastAddress": "10.15.1.175", + "FirstAddress": "10.15.1.161", + "LastAddress": "10.15.1.174", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.160" + "IP": "10.15.1.160" }, { "Name": "Gateway", - "IP": "100.103.97.161" + "IP": "10.15.1.161" }, { "Name": "TOR1", - "IP": "100.103.97.162" + "IP": "10.15.1.162" }, { "Name": "TOR2", - "IP": "100.103.97.163" + "IP": "10.15.1.163" } ] }, @@ -1475,29 +1475,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.176/28", - "Network": "100.103.97.176", + "Subnet": "10.15.1.176/28", + "Network": "10.15.1.176", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.177", - "BroadcastAddress": "100.103.97.191", - "FirstAddress": "100.103.97.177", - "LastAddress": "100.103.97.190", + "Gateway": "10.15.1.177", + "BroadcastAddress": "10.15.1.191", + "FirstAddress": "10.15.1.177", + "LastAddress": "10.15.1.190", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.176" + "IP": "10.15.1.176" }, { "Name": "Gateway", - "IP": "100.103.97.177" + "IP": "10.15.1.177" }, { "Name": "TOR1", - "IP": "100.103.97.178" + "IP": "10.15.1.178" }, { "Name": "TOR2", - "IP": "100.103.97.179" + "IP": "10.15.1.179" } ] }, @@ -1515,29 +1515,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.192/28", - "Network": "100.103.97.192", + "Subnet": "10.15.1.192/28", + "Network": "10.15.1.192", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.193", - "BroadcastAddress": "100.103.97.207", - "FirstAddress": "100.103.97.193", - "LastAddress": "100.103.97.206", + "Gateway": "10.15.1.193", + "BroadcastAddress": "10.15.1.207", + "FirstAddress": "10.15.1.193", + "LastAddress": "10.15.1.206", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.192" + "IP": "10.15.1.192" }, { "Name": "Gateway", - "IP": "100.103.97.193" + "IP": "10.15.1.193" }, { "Name": "TOR1", - "IP": "100.103.97.194" + "IP": "10.15.1.194" }, { "Name": "TOR2", - "IP": "100.103.97.195" + "IP": "10.15.1.195" } ] }, @@ -1555,29 +1555,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.208/28", - "Network": "100.103.97.208", + "Subnet": "10.15.1.208/28", + "Network": "10.15.1.208", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.209", - "BroadcastAddress": "100.103.97.223", - "FirstAddress": "100.103.97.209", - "LastAddress": "100.103.97.222", + "Gateway": "10.15.1.209", + "BroadcastAddress": "10.15.1.223", + "FirstAddress": "10.15.1.209", + "LastAddress": "10.15.1.222", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.208" + "IP": "10.15.1.208" }, { "Name": "Gateway", - "IP": "100.103.97.209" + "IP": "10.15.1.209" }, { "Name": "TOR1", - "IP": "100.103.97.210" + "IP": "10.15.1.210" }, { "Name": "TOR2", - "IP": "100.103.97.211" + "IP": "10.15.1.211" } ] }, @@ -1595,29 +1595,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.224/28", - "Network": "100.103.97.224", + "Subnet": "10.15.1.224/28", + "Network": "10.15.1.224", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.225", - "BroadcastAddress": "100.103.97.239", - "FirstAddress": "100.103.97.225", - "LastAddress": "100.103.97.238", + "Gateway": "10.15.1.225", + "BroadcastAddress": "10.15.1.239", + "FirstAddress": "10.15.1.225", + "LastAddress": "10.15.1.238", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.224" + "IP": "10.15.1.224" }, { "Name": "Gateway", - "IP": "100.103.97.225" + "IP": "10.15.1.225" }, { "Name": "TOR1", - "IP": "100.103.97.226" + "IP": "10.15.1.226" }, { "Name": "TOR2", - "IP": "100.103.97.227" + "IP": "10.15.1.227" } ] }, @@ -1635,29 +1635,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.103.97.240/28", - "Network": "100.103.97.240", + "Subnet": "10.15.1.240/28", + "Network": "10.15.1.240", "Netmask": "255.255.255.240", - "Gateway": "100.103.97.241", - "BroadcastAddress": "100.103.97.255", - "FirstAddress": "100.103.97.241", - "LastAddress": "100.103.97.254", + "Gateway": "10.15.1.241", + "BroadcastAddress": "10.15.1.255", + "FirstAddress": "10.15.1.241", + "LastAddress": "10.15.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.103.97.240" + "IP": "10.15.1.240" }, { "Name": "Gateway", - "IP": "100.103.97.241" + "IP": "10.15.1.241" }, { "Name": "TOR1", - "IP": "100.103.97.242" + "IP": "10.15.1.242" }, { "Name": "TOR2", - "IP": "100.103.97.243" + "IP": "10.15.1.243" } ] }, @@ -1675,51 +1675,51 @@ "Cidr": 23, "TORGroup": "", "NetworkType": "ExternalIP", - "Subnet": "100.97.152.0/23", - "Network": "100.97.152.0", + "Subnet": "10.16.1.0/23", + "Network": "10.16.1.0", "Netmask": "255.255.254.0", "Gateway": null, - "BroadcastAddress": "100.97.153.255", - "FirstAddress": "100.97.152.1", - "LastAddress": "100.97.153.254", + "BroadcastAddress": "10.16.2.255", + "FirstAddress": "10.16.1.1", + "LastAddress": "10.16.2.254", "Assignment": [ { "Name": "Network", - "IP": "100.97.152.0" + "IP": "10.16.1.0" } ], "IPPools": [ { "Name": "CL01", - "Subnet": "100.97.152.0/26" + "Subnet": "10.16.1.0/26" }, { "Name": "CL02", - "Subnet": "100.97.152.64/26" + "Subnet": "10.16.1.64/26" }, { "Name": "CL03", - "Subnet": "100.97.152.128/26" + "Subnet": "10.16.1.128/26" }, { "Name": "CL04", - "Subnet": "100.97.152.192/26" + "Subnet": "10.16.1.192/26" }, { "Name": "CL05", - "Subnet": "100.97.153.0/26" + "Subnet": "10.16.2.0/26" }, { "Name": "CL06", - "Subnet": "100.97.153.64/26" + "Subnet": "10.16.2.64/26" }, { "Name": "CL07", - "Subnet": "100.97.153.128/26" + "Subnet": "10.16.2.128/26" }, { "Name": "CL08", - "Subnet": "100.97.153.192/26" + "Subnet": "10.16.2.192/26" } ] }, @@ -1737,51 +1737,51 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "ExternalIP", - "Subnet": "100.102.19.0/25", - "Network": "100.102.19.0", + "Subnet": "10.17.1.0/25", + "Network": "10.17.1.0", "Netmask": "255.255.255.128", "Gateway": null, - "BroadcastAddress": "100.102.19.127", - "FirstAddress": "100.102.19.1", - "LastAddress": "100.102.19.126", + "BroadcastAddress": "10.17.1.127", + "FirstAddress": "10.17.1.1", + "LastAddress": "10.17.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.102.19.0" + "IP": "10.17.1.0" } ], "IPPools": [ { "Name": "CL01", - "Subnet": "100.102.19.0/28" + "Subnet": "10.17.1.0/28" }, { "Name": "CL02", - "Subnet": "100.102.19.16/28" + "Subnet": "10.17.1.16/28" }, { "Name": "CL03", - "Subnet": "100.102.19.32/28" + "Subnet": "10.17.1.32/28" }, { "Name": "CL04", - "Subnet": "100.102.19.48/28" + "Subnet": "10.17.1.48/28" }, { "Name": "CL05", - "Subnet": "100.102.19.64/28" + "Subnet": "10.17.1.64/28" }, { "Name": "CL06", - "Subnet": "100.102.19.80/28" + "Subnet": "10.17.1.80/28" }, { "Name": "CL07", - "Subnet": "100.102.19.96/28" + "Subnet": "10.17.1.96/28" }, { "Name": "CL08", - "Subnet": "100.102.19.112/28" + "Subnet": "10.17.1.112/28" } ] }, @@ -1799,17 +1799,17 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Storage", - "Subnet": "10.71.1.0/24", - "Network": "10.71.1.0", + "Subnet": "10.8.1.0/24", + "Network": "10.8.1.0", "Netmask": "255.255.255.0", - "Gateway": "10.71.1.1", - "BroadcastAddress": "10.71.1.255", - "FirstAddress": "10.71.1.1", - "LastAddress": "10.71.1.254", + "Gateway": "10.8.1.1", + "BroadcastAddress": "10.8.1.255", + "FirstAddress": "10.8.1.1", + "LastAddress": "10.8.1.254", "Assignment": [ { "Name": "Network", - "IP": "10.71.1.0" + "IP": "10.8.1.0" } ] }, @@ -1827,17 +1827,17 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Storage", - "Subnet": "10.71.2.0/24", - "Network": "10.71.2.0", + "Subnet": "10.8.2.0/24", + "Network": "10.8.2.0", "Netmask": "255.255.255.0", - "Gateway": "10.71.2.1", - "BroadcastAddress": "10.71.2.255", - "FirstAddress": "10.71.2.1", - "LastAddress": "10.71.2.254", + "Gateway": "10.8.2.1", + "BroadcastAddress": "10.8.2.255", + "FirstAddress": "10.8.2.1", + "LastAddress": "10.8.2.254", "Assignment": [ { "Name": "Network", - "IP": "10.71.2.0" + "IP": "10.8.2.0" } ] }, @@ -1871,14 +1871,14 @@ "Setting": { "TimeZone": "Pacific Standard Time", "TimeServer": [ - "10.10.240.20" + "10.100.0.1" ], "SyslogServer": [ - "10.10.43.111" + "10.100.0.2" ], "DNSForwarder": [ - "10.10.240.23", - "10.10.240.24" + "10.100.0.3", + "10.100.0.4" ] } } diff --git a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/bmc-1.json similarity index 93% rename from tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json rename to tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/bmc-1.json index ca13084..a4773ac 100644 --- a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-3248bmc-6-1.json +++ b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/bmc-1.json @@ -3,10 +3,10 @@ "make": "dellemc", "model": "n3248te-on", "type": "BMC", - "hostname": "s46-r06-3248bmc-6-1", + "hostname": "bmc-1", "version": "10.5.5.5", "firmware": "os10", - "site": "rr1" + "site": "site1" }, "vlans": [ { @@ -22,7 +22,7 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.12.126", + "ip": "10.21.1.126", "cidr": 26, "mtu": 9216 } @@ -79,7 +79,7 @@ "static_routes": [ { "prefix": "0.0.0.0/0", - "next_hop": "100.71.12.65", + "next_hop": "10.21.1.65", "description": "BMC default gateway" } ] diff --git a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-5248hl-6-1a.json b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/tor-1a.json similarity index 74% rename from tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-5248hl-6-1a.json rename to tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/tor-1a.json index 5b1ff52..ab643db 100644 --- a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-5248hl-6-1a.json +++ b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/tor-1a.json @@ -3,10 +3,10 @@ "make": "dellemc", "model": "s5248f-on", "type": "TOR1", - "hostname": "s46-r06-5248hl-6-1a", + "hostname": "tor-1a", "version": "10.5.5.5", "firmware": "os10", - "site": "rr1" + "site": "site1" }, "vlans": [ { @@ -18,14 +18,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.71.143.2", + "ip": "10.22.1.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 6, "priority": 150, - "virtual_ip": "100.71.143.1" + "virtual_ip": "10.22.1.1" } } }, @@ -33,14 +33,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.68.148.2", + "ip": "10.23.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 7, "priority": 150, - "virtual_ip": "100.68.148.1" + "virtual_ip": "10.23.1.1" } } }, @@ -52,14 +52,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.12.123", + "ip": "10.21.1.123", "cidr": 26, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 125, "priority": 150, - "virtual_ip": "100.71.12.65" + "virtual_ip": "10.21.1.65" } } }, @@ -67,14 +67,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.68.149.2", + "ip": "10.24.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 201, "priority": 150, - "virtual_ip": "100.68.149.1" + "virtual_ip": "10.24.1.1" } } }, @@ -82,14 +82,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.68.150.2", + "ip": "10.24.150.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 301, "priority": 150, - "virtual_ip": "100.68.150.1" + "virtual_ip": "10.24.150.1" } } }, @@ -97,14 +97,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.68.150.130", + "ip": "10.24.150.130", "cidr": 25, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 401, "priority": 150, - "virtual_ip": "100.68.150.129" + "virtual_ip": "10.24.150.129" } } }, @@ -112,14 +112,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.68.151.2", + "ip": "10.25.1.2", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 501, "priority": 150, - "virtual_ip": "100.68.151.1" + "virtual_ip": "10.25.1.1" } } }, @@ -127,14 +127,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.68.151.18", + "ip": "10.25.1.18", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 502, "priority": 150, - "virtual_ip": "100.68.151.17" + "virtual_ip": "10.25.1.17" } } }, @@ -142,14 +142,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.68.151.34", + "ip": "10.25.1.34", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 503, "priority": 150, - "virtual_ip": "100.68.151.33" + "virtual_ip": "10.25.1.33" } } }, @@ -157,14 +157,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.68.151.50", + "ip": "10.25.1.50", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 504, "priority": 150, - "virtual_ip": "100.68.151.49" + "virtual_ip": "10.25.1.49" } } }, @@ -172,14 +172,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.68.151.66", + "ip": "10.25.1.66", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 505, "priority": 150, - "virtual_ip": "100.68.151.65" + "virtual_ip": "10.25.1.65" } } }, @@ -187,14 +187,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.68.151.82", + "ip": "10.25.1.82", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 506, "priority": 150, - "virtual_ip": "100.68.151.81" + "virtual_ip": "10.25.1.81" } } }, @@ -202,14 +202,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.68.151.98", + "ip": "10.25.1.98", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 507, "priority": 150, - "virtual_ip": "100.68.151.97" + "virtual_ip": "10.25.1.97" } } }, @@ -217,14 +217,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.68.151.114", + "ip": "10.25.1.114", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 508, "priority": 150, - "virtual_ip": "100.68.151.113" + "virtual_ip": "10.25.1.113" } } }, @@ -232,14 +232,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.68.151.130", + "ip": "10.25.1.130", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 509, "priority": 150, - "virtual_ip": "100.68.151.129" + "virtual_ip": "10.25.1.129" } } }, @@ -247,14 +247,14 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.68.151.145", + "ip": "10.25.1.145", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 510, "priority": 150, - "virtual_ip": "10.69.179.145" + "virtual_ip": "10.5.1.145" } } }, @@ -262,14 +262,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.68.151.162", + "ip": "10.25.1.162", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 511, "priority": 150, - "virtual_ip": "100.68.151.161" + "virtual_ip": "10.25.1.161" } } }, @@ -277,14 +277,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.68.151.178", + "ip": "10.25.1.178", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 512, "priority": 150, - "virtual_ip": "100.68.151.177" + "virtual_ip": "10.25.1.177" } } }, @@ -292,14 +292,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.68.151.194", + "ip": "10.25.1.194", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 513, "priority": 150, - "virtual_ip": "100.68.151.193" + "virtual_ip": "10.25.1.193" } } }, @@ -307,14 +307,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.68.151.210", + "ip": "10.25.1.210", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 514, "priority": 150, - "virtual_ip": "100.68.151.209" + "virtual_ip": "10.25.1.209" } } }, @@ -322,14 +322,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.68.151.226", + "ip": "10.25.1.226", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 515, "priority": 150, - "virtual_ip": "100.68.151.225" + "virtual_ip": "10.25.1.225" } } }, @@ -337,14 +337,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.68.151.242", + "ip": "10.25.1.242", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 516, "priority": 150, - "virtual_ip": "100.68.151.241" + "virtual_ip": "10.25.1.241" } } }, @@ -373,7 +373,7 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.71.12.21/32" + "ipv4": "10.21.1.21/32" }, { "name": "MLAG_Peer_Links", @@ -387,14 +387,14 @@ "type": "L3", "intf_type": "Ethernet", "intf": "1/1/48:1", - "ipv4": "100.71.12.2/30" + "ipv4": "10.21.1.2/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/1/47:1", - "ipv4": "100.71.12.10/30" + "ipv4": "10.21.1.10/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -422,7 +422,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.71.12.17", + "ipv4": "10.21.1.17", "members": [ "1/1/45:1", "1/1/46:1" @@ -441,38 +441,38 @@ ], "bgp": { "asn": 64556, - "router_id": "100.71.12.21", + "router_id": "10.21.1.21", "networks": [ - "100.71.12.2/30", - "100.71.12.10/30", - "100.71.12.21/32", - "100.71.12.16/30", - "100.71.143.0/25", - "100.68.148.0/24", - "100.71.12.64/26", - "100.68.149.0/24", - "100.68.150.0/25", - "100.68.150.128/25", - "100.68.151.0/28", - "100.68.151.16/28", - "100.68.151.32/28", - "100.68.151.48/28", - "100.68.151.64/28", - "100.68.151.80/28", - "100.68.151.96/28", - "100.68.151.112/28", - "100.68.151.128/28", - "100.68.151.144/28", - "100.68.151.160/28", - "100.68.151.176/28", - "100.68.151.192/28", - "100.68.151.208/28", - "100.68.151.224/28", - "100.68.151.240/28" + "10.21.1.2/30", + "10.21.1.10/30", + "10.21.1.21/32", + "10.21.1.16/30", + "10.22.1.0/25", + "10.23.1.0/24", + "10.21.1.64/26", + "10.24.1.0/24", + "10.24.150.0/25", + "10.24.150.128/25", + "10.25.1.0/28", + "10.25.1.16/28", + "10.25.1.32/28", + "10.25.1.48/28", + "10.25.1.64/28", + "10.25.1.80/28", + "10.25.1.96/28", + "10.25.1.112/28", + "10.25.1.128/28", + "10.25.1.144/28", + "10.25.1.160/28", + "10.25.1.176/28", + "10.25.1.192/28", + "10.25.1.208/28", + "10.25.1.224/28", + "10.25.1.240/28" ], "neighbors": [ { - "ip": "100.71.12.1", + "ip": "10.21.1.1", "description": "TO_Border1", "remote_as": 64846, "af_ipv4_unicast": { @@ -480,7 +480,7 @@ } }, { - "ip": "100.71.12.9", + "ip": "10.21.1.9", "description": "TO_Border2", "remote_as": 64846, "af_ipv4_unicast": { @@ -488,13 +488,13 @@ } }, { - "ip": "100.71.12.18", + "ip": "10.21.1.18", "description": "iBGP_PEER", "remote_as": 64556, "af_ipv4_unicast": {} }, { - "ip": "100.71.143.0/25", + "ip": "10.22.1.0/25", "description": "TO_HNVPA", "remote_as": 65018, "update_source": "Loopback0", @@ -567,67 +567,67 @@ }, "ip_map": { "P2P_BORDER1_TOR1": [ - "100.71.12.2/30" + "10.21.1.2/30" ], "P2P_TOR1_BORDER1": [ - "100.71.12.1" + "10.21.1.1" ], "P2P_BORDER1_TOR2": [ - "100.71.12.6/30" + "10.21.1.6/30" ], "P2P_TOR2_BORDER1": [ - "100.71.12.5" + "10.21.1.5" ], "P2P_BORDER2_TOR1": [ - "100.71.12.10/30" + "10.21.1.10/30" ], "P2P_TOR1_BORDER2": [ - "100.71.12.9" + "10.21.1.9" ], "P2P_BORDER2_TOR2": [ - "100.71.12.14/30" + "10.21.1.14/30" ], "P2P_TOR2_BORDER2": [ - "100.71.12.13" + "10.21.1.13" ], "P2P_IBGP_TOR1": [ - "100.71.12.17" + "10.21.1.17" ], "P2P_IBGP_TOR2": [ - "100.71.12.18" + "10.21.1.18" ], "LOOPBACK0_TOR1": [ - "100.71.12.21/32" + "10.21.1.21/32" ], "LOOPBACK0_TOR2": [ - "100.71.12.22/32" + "10.21.1.22/32" ], "HNVPA": [ - "100.71.143.0/25" + "10.22.1.0/25" ], "M": [ - "100.68.148.0/24" + "10.23.1.0/24" ], "C": [ - "100.68.149.0/24", - "100.68.150.0/25", - "100.68.150.128/25", - "100.68.151.0/28", - "100.68.151.16/28", - "100.68.151.32/28", - "100.68.151.48/28", - "100.68.151.64/28", - "100.68.151.80/28", - "100.68.151.96/28", - "100.68.151.112/28", - "100.68.151.128/28", - "100.68.151.144/28", - "100.68.151.160/28", - "100.68.151.176/28", - "100.68.151.192/28", - "100.68.151.208/28", - "100.68.151.224/28", - "100.68.151.240/28" + "10.24.1.0/24", + "10.24.150.0/25", + "10.24.150.128/25", + "10.25.1.0/28", + "10.25.1.16/28", + "10.25.1.32/28", + "10.25.1.48/28", + "10.25.1.64/28", + "10.25.1.80/28", + "10.25.1.96/28", + "10.25.1.112/28", + "10.25.1.128/28", + "10.25.1.144/28", + "10.25.1.160/28", + "10.25.1.176/28", + "10.25.1.192/28", + "10.25.1.208/28", + "10.25.1.224/28", + "10.25.1.240/28" ] }, "resolved_trunks": [ diff --git a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-5248hl-6-1b.json b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/tor-1b.json similarity index 74% rename from tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-5248hl-6-1b.json rename to tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/tor-1b.json index f7c5cea..1c6a5f8 100644 --- a/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/s46-r06-5248hl-6-1b.json +++ b/tests/test_cases/convert_lab_switch_input_json_dell_os10/expected_outputs/tor-1b.json @@ -3,10 +3,10 @@ "make": "dellemc", "model": "s5248f-on", "type": "TOR2", - "hostname": "s46-r06-5248hl-6-1b", + "hostname": "tor-1b", "version": "10.5.5.5", "firmware": "os10", - "site": "rr1" + "site": "site1" }, "vlans": [ { @@ -18,14 +18,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.71.143.3", + "ip": "10.22.1.3", "cidr": 25, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 6, "priority": 140, - "virtual_ip": "100.71.143.1" + "virtual_ip": "10.22.1.1" } } }, @@ -33,14 +33,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.68.148.3", + "ip": "10.23.1.3", "cidr": 24, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 7, "priority": 140, - "virtual_ip": "100.68.148.1" + "virtual_ip": "10.23.1.1" } } }, @@ -52,14 +52,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.12.124", + "ip": "10.21.1.124", "cidr": 26, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 125, "priority": 140, - "virtual_ip": "100.71.12.65" + "virtual_ip": "10.21.1.65" } } }, @@ -67,14 +67,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.68.149.3", + "ip": "10.24.1.3", "cidr": 24, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 201, "priority": 140, - "virtual_ip": "100.68.149.1" + "virtual_ip": "10.24.1.1" } } }, @@ -82,14 +82,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.68.150.3", + "ip": "10.24.150.3", "cidr": 25, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 301, "priority": 140, - "virtual_ip": "100.68.150.1" + "virtual_ip": "10.24.150.1" } } }, @@ -97,14 +97,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.68.150.131", + "ip": "10.24.150.131", "cidr": 25, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 401, "priority": 140, - "virtual_ip": "100.68.150.129" + "virtual_ip": "10.24.150.129" } } }, @@ -112,14 +112,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.68.151.3", + "ip": "10.25.1.3", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 501, "priority": 140, - "virtual_ip": "100.68.151.1" + "virtual_ip": "10.25.1.1" } } }, @@ -127,14 +127,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.68.151.19", + "ip": "10.25.1.19", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 502, "priority": 140, - "virtual_ip": "100.68.151.17" + "virtual_ip": "10.25.1.17" } } }, @@ -142,14 +142,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.68.151.35", + "ip": "10.25.1.35", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 503, "priority": 140, - "virtual_ip": "100.68.151.33" + "virtual_ip": "10.25.1.33" } } }, @@ -157,14 +157,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.68.151.51", + "ip": "10.25.1.51", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 504, "priority": 140, - "virtual_ip": "100.68.151.49" + "virtual_ip": "10.25.1.49" } } }, @@ -172,14 +172,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.68.151.67", + "ip": "10.25.1.67", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 505, "priority": 140, - "virtual_ip": "100.68.151.65" + "virtual_ip": "10.25.1.65" } } }, @@ -187,14 +187,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.68.151.83", + "ip": "10.25.1.83", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 506, "priority": 140, - "virtual_ip": "100.68.151.81" + "virtual_ip": "10.25.1.81" } } }, @@ -202,14 +202,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.68.151.99", + "ip": "10.25.1.99", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 507, "priority": 140, - "virtual_ip": "100.68.151.97" + "virtual_ip": "10.25.1.97" } } }, @@ -217,14 +217,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.68.151.115", + "ip": "10.25.1.115", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 508, "priority": 140, - "virtual_ip": "100.68.151.113" + "virtual_ip": "10.25.1.113" } } }, @@ -232,14 +232,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.68.151.131", + "ip": "10.25.1.131", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 509, "priority": 140, - "virtual_ip": "100.68.151.129" + "virtual_ip": "10.25.1.129" } } }, @@ -247,14 +247,14 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.68.151.146", + "ip": "10.25.1.146", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 510, "priority": 140, - "virtual_ip": "10.69.179.145" + "virtual_ip": "10.5.1.145" } } }, @@ -262,14 +262,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.68.151.163", + "ip": "10.25.1.163", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 511, "priority": 140, - "virtual_ip": "100.68.151.161" + "virtual_ip": "10.25.1.161" } } }, @@ -277,14 +277,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.68.151.179", + "ip": "10.25.1.179", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 512, "priority": 140, - "virtual_ip": "100.68.151.177" + "virtual_ip": "10.25.1.177" } } }, @@ -292,14 +292,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.68.151.195", + "ip": "10.25.1.195", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 513, "priority": 140, - "virtual_ip": "100.68.151.193" + "virtual_ip": "10.25.1.193" } } }, @@ -307,14 +307,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.68.151.211", + "ip": "10.25.1.211", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 514, "priority": 140, - "virtual_ip": "100.68.151.209" + "virtual_ip": "10.25.1.209" } } }, @@ -322,14 +322,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.68.151.227", + "ip": "10.25.1.227", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 515, "priority": 140, - "virtual_ip": "100.68.151.225" + "virtual_ip": "10.25.1.225" } } }, @@ -337,14 +337,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.68.151.243", + "ip": "10.25.1.243", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 516, "priority": 140, - "virtual_ip": "100.68.151.241" + "virtual_ip": "10.25.1.241" } } }, @@ -373,7 +373,7 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.71.12.22/32" + "ipv4": "10.21.1.22/32" }, { "name": "MLAG_Peer_Links", @@ -387,14 +387,14 @@ "type": "L3", "intf_type": "Ethernet", "intf": "1/1/48:1", - "ipv4": "100.71.12.6/30" + "ipv4": "10.21.1.6/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/1/47:1", - "ipv4": "100.71.12.14/30" + "ipv4": "10.21.1.14/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -422,7 +422,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.71.12.18", + "ipv4": "10.21.1.18", "members": [ "1/1/45:1", "1/1/46:1" @@ -441,38 +441,38 @@ ], "bgp": { "asn": 64556, - "router_id": "100.71.12.22", + "router_id": "10.21.1.22", "networks": [ - "100.71.12.6/30", - "100.71.12.14/30", - "100.71.12.22/32", - "100.71.12.16/30", - "100.71.143.0/25", - "100.68.148.0/24", - "100.71.12.64/26", - "100.68.149.0/24", - "100.68.150.0/25", - "100.68.150.128/25", - "100.68.151.0/28", - "100.68.151.16/28", - "100.68.151.32/28", - "100.68.151.48/28", - "100.68.151.64/28", - "100.68.151.80/28", - "100.68.151.96/28", - "100.68.151.112/28", - "100.68.151.128/28", - "100.68.151.144/28", - "100.68.151.160/28", - "100.68.151.176/28", - "100.68.151.192/28", - "100.68.151.208/28", - "100.68.151.224/28", - "100.68.151.240/28" + "10.21.1.6/30", + "10.21.1.14/30", + "10.21.1.22/32", + "10.21.1.16/30", + "10.22.1.0/25", + "10.23.1.0/24", + "10.21.1.64/26", + "10.24.1.0/24", + "10.24.150.0/25", + "10.24.150.128/25", + "10.25.1.0/28", + "10.25.1.16/28", + "10.25.1.32/28", + "10.25.1.48/28", + "10.25.1.64/28", + "10.25.1.80/28", + "10.25.1.96/28", + "10.25.1.112/28", + "10.25.1.128/28", + "10.25.1.144/28", + "10.25.1.160/28", + "10.25.1.176/28", + "10.25.1.192/28", + "10.25.1.208/28", + "10.25.1.224/28", + "10.25.1.240/28" ], "neighbors": [ { - "ip": "100.71.12.5", + "ip": "10.21.1.5", "description": "TO_Border1", "remote_as": 64846, "af_ipv4_unicast": { @@ -480,7 +480,7 @@ } }, { - "ip": "100.71.12.13", + "ip": "10.21.1.13", "description": "TO_Border2", "remote_as": 64846, "af_ipv4_unicast": { @@ -488,13 +488,13 @@ } }, { - "ip": "100.71.12.17", + "ip": "10.21.1.17", "description": "iBGP_PEER", "remote_as": 64556, "af_ipv4_unicast": {} }, { - "ip": "100.71.143.0/25", + "ip": "10.22.1.0/25", "description": "TO_HNVPA", "remote_as": 65018, "update_source": "Loopback0", @@ -567,67 +567,67 @@ }, "ip_map": { "P2P_BORDER1_TOR1": [ - "100.71.12.2/30" + "10.21.1.2/30" ], "P2P_TOR1_BORDER1": [ - "100.71.12.1" + "10.21.1.1" ], "P2P_BORDER1_TOR2": [ - "100.71.12.6/30" + "10.21.1.6/30" ], "P2P_TOR2_BORDER1": [ - "100.71.12.5" + "10.21.1.5" ], "P2P_BORDER2_TOR1": [ - "100.71.12.10/30" + "10.21.1.10/30" ], "P2P_TOR1_BORDER2": [ - "100.71.12.9" + "10.21.1.9" ], "P2P_BORDER2_TOR2": [ - "100.71.12.14/30" + "10.21.1.14/30" ], "P2P_TOR2_BORDER2": [ - "100.71.12.13" + "10.21.1.13" ], "P2P_IBGP_TOR1": [ - "100.71.12.17" + "10.21.1.17" ], "P2P_IBGP_TOR2": [ - "100.71.12.18" + "10.21.1.18" ], "LOOPBACK0_TOR1": [ - "100.71.12.21/32" + "10.21.1.21/32" ], "LOOPBACK0_TOR2": [ - "100.71.12.22/32" + "10.21.1.22/32" ], "HNVPA": [ - "100.71.143.0/25" + "10.22.1.0/25" ], "M": [ - "100.68.148.0/24" + "10.23.1.0/24" ], "C": [ - "100.68.149.0/24", - "100.68.150.0/25", - "100.68.150.128/25", - "100.68.151.0/28", - "100.68.151.16/28", - "100.68.151.32/28", - "100.68.151.48/28", - "100.68.151.64/28", - "100.68.151.80/28", - "100.68.151.96/28", - "100.68.151.112/28", - "100.68.151.128/28", - "100.68.151.144/28", - "100.68.151.160/28", - "100.68.151.176/28", - "100.68.151.192/28", - "100.68.151.208/28", - "100.68.151.224/28", - "100.68.151.240/28" + "10.24.1.0/24", + "10.24.150.0/25", + "10.24.150.128/25", + "10.25.1.0/28", + "10.25.1.16/28", + "10.25.1.32/28", + "10.25.1.48/28", + "10.25.1.64/28", + "10.25.1.80/28", + "10.25.1.96/28", + "10.25.1.112/28", + "10.25.1.128/28", + "10.25.1.144/28", + "10.25.1.160/28", + "10.25.1.176/28", + "10.25.1.192/28", + "10.25.1.208/28", + "10.25.1.224/28", + "10.25.1.240/28" ] }, "resolved_trunks": [ diff --git a/tests/test_cases/convert_lab_switch_input_json_dell_os10/lab_dell_os10_switch_input.json b/tests/test_cases/convert_lab_switch_input_json_dell_os10/lab_dell_os10_switch_input.json index aa6bfd2..0ff7acd 100644 --- a/tests/test_cases/convert_lab_switch_input_json_dell_os10/lab_dell_os10_switch_input.json +++ b/tests/test_cases/convert_lab_switch_input_json_dell_os10/lab_dell_os10_switch_input.json @@ -5,8 +5,8 @@ "MainEnvData": [ { "Id": "Env01", - "Site": "rr1", - "RackName": "s46r06a", + "Site": "site1", + "RackName": "rack03", "NodeCount": 16, "ConnectType": "connected", "ClusterUnits": [ @@ -14,57 +14,57 @@ "Name": "Cl01", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r06a01", - "PhysicalNamingPrefix": "s46r06a01", + "NamingPrefix": "node01", + "PhysicalNamingPrefix": "node01", "Topology": "Switched", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r06a01.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r06a01.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node01.test.example.com", + "ExternalDomainFQDN": "ext-node01.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl02", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r06a02", - "PhysicalNamingPrefix": "s46r06a02", + "NamingPrefix": "node02", + "PhysicalNamingPrefix": "node02", "Topology": "Switched", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r06a02.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r06a02.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node02.test.example.com", + "ExternalDomainFQDN": "ext-node02.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl03", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r06a03", - "PhysicalNamingPrefix": "s46r06a03", + "NamingPrefix": "node03", + "PhysicalNamingPrefix": "node03", "Topology": "Switched", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r06a03.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r06a03.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node03.test.example.com", + "ExternalDomainFQDN": "ext-node03.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" }, { "Name": "Cl04", "NodeCount": 4, "RackId": "Rack01", - "NamingPrefix": "s46r06a04", - "PhysicalNamingPrefix": "s46r06a04", + "NamingPrefix": "node04", + "PhysicalNamingPrefix": "node04", "Topology": "Switched", - "CompanyName": "Microsoft", - "RegionName": "Redmond", - "DomainFQDN": "s46r06a04.masd.stbtest.microsoft.com", - "ExternalDomainFQDN": "ext-s46r06a04.masd.stbtest.microsoft.com", + "CompanyName": "Contoso", + "RegionName": "Region1", + "DomainFQDN": "node04.test.example.com", + "ExternalDomainFQDN": "ext-node04.test.example.com", "InfraAzureEnvironment": "AzureCloud", - "InfraAzureDirectoryTenantName": "msazurestack.microsoft.com" + "InfraAzureDirectoryTenantName": "azurestack.example.com" } ] } @@ -73,14 +73,14 @@ { "Make": "Cisco", "Model": "C9336C-FX2", - "Hostname": "s46-r01-9336ssp-1a", + "Hostname": "border-1a", "Type": "Border1", "ASN": 64846 }, { "Make": "Cisco", "Model": "C9336C-FX2", - "Hostname": "s46-r01-9336ssp-1b", + "Hostname": "border-1b", "Type": "Border2", "ASN": 64846 }, @@ -88,7 +88,7 @@ "Make": "DellEMC", "Model": "S5248F-ON", "Type": "TOR1", - "Hostname": "s46-r06-5248hl-6-1a", + "Hostname": "tor-1a", "ASN": 64556, "Firmware": "10.5.5.5" }, @@ -96,7 +96,7 @@ "Make": "DellEMC", "Model": "S5248F-ON", "Type": "TOR2", - "Hostname": "s46-r06-5248hl-6-1b", + "Hostname": "tor-1b", "ASN": 64556, "Firmware": "10.5.5.5" }, @@ -104,15 +104,15 @@ "Make": "DellEMC", "Model": "N3248TE-ON", "Type": "BMC", - "Hostname": "s46-r06-3248bmc-6-1", + "Hostname": "bmc-1", "ASN": null, "Firmware": "10.5.5.5" }, { - "Make": "Microsoft", + "Make": "Contoso", "Model": null, "Type": "MUX", - "Hostname": "s46-r06-MUX-1", + "Hostname": "mux-1", "ASN": 65018, "Firmware": null } @@ -132,25 +132,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.12.0/30", - "Network": "100.71.12.0", + "Subnet": "10.21.1.0/30", + "Network": "10.21.1.0", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.12.3", - "FirstAddress": "100.71.12.1", - "LastAddress": "100.71.12.2", + "BroadcastAddress": "10.21.1.3", + "FirstAddress": "10.21.1.1", + "LastAddress": "10.21.1.2", "Assignment": [ { "Name": "Network", - "IP": "100.71.12.0" + "IP": "10.21.1.0" }, { "Name": "Border1", - "IP": "100.71.12.1" + "IP": "10.21.1.1" }, { "Name": "TOR1", - "IP": "100.71.12.2" + "IP": "10.21.1.2" } ] }, @@ -167,25 +167,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.12.4/30", - "Network": "100.71.12.4", + "Subnet": "10.21.1.4/30", + "Network": "10.21.1.4", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.12.7", - "FirstAddress": "100.71.12.5", - "LastAddress": "100.71.12.6", + "BroadcastAddress": "10.21.1.7", + "FirstAddress": "10.21.1.5", + "LastAddress": "10.21.1.6", "Assignment": [ { "Name": "Network", - "IP": "100.71.12.4" + "IP": "10.21.1.4" }, { "Name": "Border1", - "IP": "100.71.12.5" + "IP": "10.21.1.5" }, { "Name": "TOR2", - "IP": "100.71.12.6" + "IP": "10.21.1.6" } ] }, @@ -202,25 +202,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.12.8/30", - "Network": "100.71.12.8", + "Subnet": "10.21.1.8/30", + "Network": "10.21.1.8", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.12.11", - "FirstAddress": "100.71.12.9", - "LastAddress": "100.71.12.10", + "BroadcastAddress": "10.21.1.11", + "FirstAddress": "10.21.1.9", + "LastAddress": "10.21.1.10", "Assignment": [ { "Name": "Network", - "IP": "100.71.12.8" + "IP": "10.21.1.8" }, { "Name": "Border2", - "IP": "100.71.12.9" + "IP": "10.21.1.9" }, { "Name": "TOR1", - "IP": "100.71.12.10" + "IP": "10.21.1.10" } ] }, @@ -237,25 +237,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.12.12/30", - "Network": "100.71.12.12", + "Subnet": "10.21.1.12/30", + "Network": "10.21.1.12", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.12.15", - "FirstAddress": "100.71.12.13", - "LastAddress": "100.71.12.14", + "BroadcastAddress": "10.21.1.15", + "FirstAddress": "10.21.1.13", + "LastAddress": "10.21.1.14", "Assignment": [ { "Name": "Network", - "IP": "100.71.12.12" + "IP": "10.21.1.12" }, { "Name": "Border2", - "IP": "100.71.12.13" + "IP": "10.21.1.13" }, { "Name": "TOR2", - "IP": "100.71.12.14" + "IP": "10.21.1.14" } ] }, @@ -272,25 +272,25 @@ "Cidr": 30, "TORGroup": "", "NetworkType": "P2P Link", - "Subnet": "100.71.12.16/30", - "Network": "100.71.12.16", + "Subnet": "10.21.1.16/30", + "Network": "10.21.1.16", "Netmask": "255.255.255.252", "Gateway": "", - "BroadcastAddress": "100.71.12.19", - "FirstAddress": "100.71.12.17", - "LastAddress": "100.71.12.18", + "BroadcastAddress": "10.21.1.19", + "FirstAddress": "10.21.1.17", + "LastAddress": "10.21.1.18", "Assignment": [ { "Name": "Network", - "IP": "100.71.12.16" + "IP": "10.21.1.16" }, { "Name": "TOR1", - "IP": "100.71.12.17" + "IP": "10.21.1.17" }, { "Name": "TOR2", - "IP": "100.71.12.18" + "IP": "10.21.1.18" } ] }, @@ -307,8 +307,8 @@ "Cidr": 32, "TORGroup": "", "NetworkType": "Loopback", - "Subnet": "100.71.12.21/32", - "Network": "100.71.12.21", + "Subnet": "10.21.1.21/32", + "Network": "10.21.1.21", "Netmask": "255.255.255.255", "Gateway": "", "BroadcastAddress": "", @@ -317,7 +317,7 @@ "Assignment": [ { "Name": "TOR1", - "IP": "100.71.12.21" + "IP": "10.21.1.21" } ] }, @@ -334,8 +334,8 @@ "Cidr": 32, "TORGroup": "", "NetworkType": "Loopback", - "Subnet": "100.71.12.22/32", - "Network": "100.71.12.22", + "Subnet": "10.21.1.22/32", + "Network": "10.21.1.22", "Netmask": "255.255.255.255", "Gateway": "", "BroadcastAddress": "", @@ -344,7 +344,7 @@ "Assignment": [ { "Name": "TOR2", - "IP": "100.71.12.22" + "IP": "10.21.1.22" } ] }, @@ -362,152 +362,152 @@ "Cidr": 26, "TORGroup": "", "NetworkType": "Infrastructure", - "Subnet": "100.71.12.64/26", - "Network": "100.71.12.64", + "Subnet": "10.21.1.64/26", + "Network": "10.21.1.64", "Netmask": "255.255.255.192", - "Gateway": "100.71.12.65", - "BroadcastAddress": "100.71.12.127", - "FirstAddress": "100.71.12.65", - "LastAddress": "100.71.12.126", + "Gateway": "10.21.1.65", + "BroadcastAddress": "10.21.1.127", + "FirstAddress": "10.21.1.65", + "LastAddress": "10.21.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.71.12.64", + "IP": "10.21.1.64", "ClusterID": null }, { "Name": "Gateway", - "IP": "100.71.12.65", + "IP": "10.21.1.65", "ClusterID": null }, { "Name": "HLH-BMC", - "IP": "100.71.12.66", + "IP": "10.21.1.66", "ClusterID": null }, { "Name": "CL01-N01", - "IP": "100.71.12.67", + "IP": "10.21.1.67", "ClusterID": "CL01" }, { "Name": "CL01-N02", - "IP": "100.71.12.68", + "IP": "10.21.1.68", "ClusterID": "CL01" }, { "Name": "CL01-N03", - "IP": "100.71.12.69", + "IP": "10.21.1.69", "ClusterID": "CL01" }, { "Name": "CL01-N04", - "IP": "100.71.12.70", + "IP": "10.21.1.70", "ClusterID": "CL01" }, { "Name": "CL02-N01", - "IP": "100.71.12.71", + "IP": "10.21.1.71", "ClusterID": "CL02" }, { "Name": "CL02-N02", - "IP": "100.71.12.72", + "IP": "10.21.1.72", "ClusterID": "CL02" }, { "Name": "CL02-N03", - "IP": "100.71.12.73", + "IP": "10.21.1.73", "ClusterID": "CL02" }, { "Name": "CL02-N04", - "IP": "100.71.12.74", + "IP": "10.21.1.74", "ClusterID": "CL02" }, { "Name": "CL03-N01", - "IP": "100.71.12.75", + "IP": "10.21.1.75", "ClusterID": "CL03" }, { "Name": "CL03-N02", - "IP": "100.71.12.76", + "IP": "10.21.1.76", "ClusterID": "CL03" }, { "Name": "CL03-N03", - "IP": "100.71.12.77", + "IP": "10.21.1.77", "ClusterID": "CL03" }, { "Name": "CL03-N04", - "IP": "100.71.12.78", + "IP": "10.21.1.78", "ClusterID": "CL03" }, { "Name": "CL04-N01", - "IP": "100.71.12.79", + "IP": "10.21.1.79", "ClusterID": "CL04" }, { "Name": "CL04-N02", - "IP": "100.71.12.80", + "IP": "10.21.1.80", "ClusterID": "CL04" }, { "Name": "CL04-N03", - "IP": "100.71.12.81", + "IP": "10.21.1.81", "ClusterID": "CL04" }, { "Name": "CL04-N04", - "IP": "100.71.12.82", + "IP": "10.21.1.82", "ClusterID": "CL04" }, { "Name": "CL01-HLH-DVM01", - "IP": "100.71.12.107", + "IP": "10.21.1.107", "ClusterID": "CL01" }, { "Name": "CL02-HLH-DVM02", - "IP": "100.71.12.108", + "IP": "10.21.1.108", "ClusterID": "CL02" }, { "Name": "CL03-HLH-DVM03", - "IP": "100.71.12.109", + "IP": "10.21.1.109", "ClusterID": "CL03" }, { "Name": "CL04-HLH-DVM04", - "IP": "100.71.12.110", + "IP": "10.21.1.110", "ClusterID": "CL04" }, { "Name": "Tor1-Mgmt", - "IP": "100.71.12.123", + "IP": "10.21.1.123", "ClusterID": null }, { "Name": "Tor2-Mgmt", - "IP": "100.71.12.124", + "IP": "10.21.1.124", "ClusterID": null }, { "Name": "BMC-Mgmt", - "IP": "100.71.12.125", + "IP": "10.21.1.125", "ClusterID": null }, { "Name": "HLH-OS", - "IP": "100.71.12.126", + "IP": "10.21.1.126", "ClusterID": null }, { "Name": "Broadcast", - "IP": "100.71.12.127", + "IP": "10.21.1.127", "ClusterID": null } ] @@ -526,51 +526,51 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "PA", - "Subnet": "100.71.143.0/25", - "Network": "100.71.143.0", + "Subnet": "10.22.1.0/25", + "Network": "10.22.1.0", "Netmask": "255.255.255.128", - "Gateway": "100.71.143.1", - "BroadcastAddress": "100.71.143.127", - "FirstAddress": "100.71.143.1", - "LastAddress": "100.71.143.126", + "Gateway": "10.22.1.1", + "BroadcastAddress": "10.22.1.127", + "FirstAddress": "10.22.1.1", + "LastAddress": "10.22.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.71.143.0" + "IP": "10.22.1.0" }, { "Name": "Gateway", - "IP": "100.71.143.1" + "IP": "10.22.1.1" }, { "Name": "TOR1", - "IP": "100.71.143.2" + "IP": "10.22.1.2" }, { "Name": "TOR2", - "IP": "100.71.143.3" + "IP": "10.22.1.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.71.143.4", - "EndingAddress": "100.71.143.31" + "StartingAddress": "10.22.1.4", + "EndingAddress": "10.22.1.31" }, { "Name": "CL02", - "StartingAddress": "100.71.143.32", - "EndingAddress": "100.71.143.63" + "StartingAddress": "10.22.1.32", + "EndingAddress": "10.22.1.63" }, { "Name": "CL03", - "StartingAddress": "100.71.143.64", - "EndingAddress": "100.71.143.95" + "StartingAddress": "10.22.1.64", + "EndingAddress": "10.22.1.95" }, { "Name": "CL04", - "StartingAddress": "100.71.143.96", - "EndingAddress": "100.71.143.126" + "StartingAddress": "10.22.1.96", + "EndingAddress": "10.22.1.126" } ] }, @@ -588,115 +588,115 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Infrastructure", - "Subnet": "100.68.148.0/24", - "Network": "100.68.148.0", + "Subnet": "10.23.1.0/24", + "Network": "10.23.1.0", "Netmask": "255.255.255.0", - "Gateway": "100.68.148.1", - "BroadcastAddress": "100.68.148.255", - "FirstAddress": "100.68.148.1", - "LastAddress": "100.68.148.254", + "Gateway": "10.23.1.1", + "BroadcastAddress": "10.23.1.255", + "FirstAddress": "10.23.1.1", + "LastAddress": "10.23.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.68.148.0" + "IP": "10.23.1.0" }, { "Name": "Gateway", - "IP": "100.68.148.1" + "IP": "10.23.1.1" }, { "Name": "TOR1", - "IP": "100.68.148.2" + "IP": "10.23.1.2" }, { "Name": "TOR2", - "IP": "100.68.148.3" + "IP": "10.23.1.3" }, { "Name": "CL01-N01", - "IP": "100.68.148.4" + "IP": "10.23.1.4" }, { "Name": "CL01-N02", - "IP": "100.68.148.5" + "IP": "10.23.1.5" }, { "Name": "CL01-N03", - "IP": "100.68.148.6" + "IP": "10.23.1.6" }, { "Name": "CL01-N04", - "IP": "100.68.148.7" + "IP": "10.23.1.7" }, { "Name": "CL02-N01", - "IP": "100.68.148.64" + "IP": "10.23.1.64" }, { "Name": "CL02-N02", - "IP": "100.68.148.65" + "IP": "10.23.1.65" }, { "Name": "CL02-N03", - "IP": "100.68.148.66" + "IP": "10.23.1.66" }, { "Name": "CL02-N04", - "IP": "100.68.148.67" + "IP": "10.23.1.67" }, { "Name": "CL03-N01", - "IP": "100.68.148.128" + "IP": "10.23.1.128" }, { "Name": "CL03-N02", - "IP": "100.68.148.129" + "IP": "10.23.1.129" }, { "Name": "CL03-N03", - "IP": "100.68.148.130" + "IP": "10.23.1.130" }, { "Name": "CL03-N04", - "IP": "100.68.148.131" + "IP": "10.23.1.131" }, { "Name": "CL04-N01", - "IP": "100.68.148.192" + "IP": "10.23.1.192" }, { "Name": "CL04-N02", - "IP": "100.68.148.193" + "IP": "10.23.1.193" }, { "Name": "CL04-N03", - "IP": "100.68.148.194" + "IP": "10.23.1.194" }, { "Name": "CL04-N04", - "IP": "100.68.148.195" + "IP": "10.23.1.195" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.68.148.8", - "EndingAddress": "100.68.148.63" + "StartingAddress": "10.23.1.8", + "EndingAddress": "10.23.1.63" }, { "Name": "CL02", - "StartingAddress": "100.68.148.68", - "EndingAddress": "100.68.148.127" + "StartingAddress": "10.23.1.68", + "EndingAddress": "10.23.1.127" }, { "Name": "CL03", - "StartingAddress": "100.68.148.132", - "EndingAddress": "100.68.148.191" + "StartingAddress": "10.23.1.132", + "EndingAddress": "10.23.1.191" }, { "Name": "CL04", - "StartingAddress": "100.68.148.196", - "EndingAddress": "100.68.148.254" + "StartingAddress": "10.23.1.196", + "EndingAddress": "10.23.1.254" } ] }, @@ -714,51 +714,51 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.68.149.0/24", - "Network": "100.68.149.0", + "Subnet": "10.24.1.0/24", + "Network": "10.24.1.0", "Netmask": "255.255.255.0", - "Gateway": "100.68.149.1", - "BroadcastAddress": "100.68.149.255", - "FirstAddress": "100.68.149.1", - "LastAddress": "100.68.149.254", + "Gateway": "10.24.1.1", + "BroadcastAddress": "10.24.1.255", + "FirstAddress": "10.24.1.1", + "LastAddress": "10.24.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.68.149.0" + "IP": "10.24.1.0" }, { "Name": "Gateway", - "IP": "100.68.149.1" + "IP": "10.24.1.1" }, { "Name": "TOR1", - "IP": "100.68.149.2" + "IP": "10.24.1.2" }, { "Name": "TOR2", - "IP": "100.68.149.3" + "IP": "10.24.1.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.68.149.4", - "EndingAddress": "100.68.149.63" + "StartingAddress": "10.24.1.4", + "EndingAddress": "10.24.1.63" }, { "Name": "CL02", - "StartingAddress": "100.68.149.64", - "EndingAddress": "100.68.149.127" + "StartingAddress": "10.24.1.64", + "EndingAddress": "10.24.1.127" }, { "Name": "CL03", - "StartingAddress": "100.68.149.128", - "EndingAddress": "100.68.149.191" + "StartingAddress": "10.24.1.128", + "EndingAddress": "10.24.1.191" }, { "Name": "CL04", - "StartingAddress": "100.68.149.192", - "EndingAddress": "100.68.149.254" + "StartingAddress": "10.24.1.192", + "EndingAddress": "10.24.1.254" } ] }, @@ -776,51 +776,51 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.68.150.0/25", - "Network": "100.68.150.0", + "Subnet": "10.24.150.0/25", + "Network": "10.24.150.0", "Netmask": "255.255.255.128", - "Gateway": "100.68.150.1", - "BroadcastAddress": "100.68.150.127", - "FirstAddress": "100.68.150.1", - "LastAddress": "100.68.150.126", + "Gateway": "10.24.150.1", + "BroadcastAddress": "10.24.150.127", + "FirstAddress": "10.24.150.1", + "LastAddress": "10.24.150.126", "Assignment": [ { "Name": "Network", - "IP": "100.68.150.0" + "IP": "10.24.150.0" }, { "Name": "Gateway", - "IP": "100.68.150.1" + "IP": "10.24.150.1" }, { "Name": "TOR1", - "IP": "100.68.150.2" + "IP": "10.24.150.2" }, { "Name": "TOR2", - "IP": "100.68.150.3" + "IP": "10.24.150.3" } ], "IPPools": [ { "Name": "CL01", - "StartingAddress": "100.68.150.4", - "EndingAddress": "100.68.150.31" + "StartingAddress": "10.24.150.4", + "EndingAddress": "10.24.150.31" }, { "Name": "CL02", - "StartingAddress": "100.68.150.32", - "EndingAddress": "100.68.150.63" + "StartingAddress": "10.24.150.32", + "EndingAddress": "10.24.150.63" }, { "Name": "CL03", - "StartingAddress": "100.68.150.64", - "EndingAddress": "100.68.150.95" + "StartingAddress": "10.24.150.64", + "EndingAddress": "10.24.150.95" }, { "Name": "CL04", - "StartingAddress": "100.68.150.96", - "EndingAddress": "100.68.150.126" + "StartingAddress": "10.24.150.96", + "EndingAddress": "10.24.150.126" } ] }, @@ -838,29 +838,29 @@ "Cidr": 25, "TORGroup": "", "NetworkType": "Tenant", - "Subnet": "100.68.150.128/25", - "Network": "100.68.150.128", + "Subnet": "10.24.150.128/25", + "Network": "10.24.150.128", "Netmask": "255.255.255.128", - "Gateway": "100.68.150.129", - "BroadcastAddress": "100.68.150.255", - "FirstAddress": "100.68.150.129", - "LastAddress": "100.68.150.254", + "Gateway": "10.24.150.129", + "BroadcastAddress": "10.24.150.255", + "FirstAddress": "10.24.150.129", + "LastAddress": "10.24.150.254", "Assignment": [ { "Name": "Network", - "IP": "100.68.150.128" + "IP": "10.24.150.128" }, { "Name": "Gateway", - "IP": "100.68.150.129" + "IP": "10.24.150.129" }, { "Name": "TOR1", - "IP": "100.68.150.130" + "IP": "10.24.150.130" }, { "Name": "TOR2", - "IP": "100.68.150.131" + "IP": "10.24.150.131" } ] }, @@ -878,29 +878,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.0/28", - "Network": "100.68.151.0", + "Subnet": "10.25.1.0/28", + "Network": "10.25.1.0", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.1", - "BroadcastAddress": "100.68.151.15", - "FirstAddress": "100.68.151.1", - "LastAddress": "100.68.151.14", + "Gateway": "10.25.1.1", + "BroadcastAddress": "10.25.1.15", + "FirstAddress": "10.25.1.1", + "LastAddress": "10.25.1.14", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.0" + "IP": "10.25.1.0" }, { "Name": "Gateway", - "IP": "100.68.151.1" + "IP": "10.25.1.1" }, { "Name": "TOR1", - "IP": "100.68.151.2" + "IP": "10.25.1.2" }, { "Name": "TOR2", - "IP": "100.68.151.3" + "IP": "10.25.1.3" } ] }, @@ -918,29 +918,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.16/28", - "Network": "100.68.151.16", + "Subnet": "10.25.1.16/28", + "Network": "10.25.1.16", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.17", - "BroadcastAddress": "100.68.151.31", - "FirstAddress": "100.68.151.17", - "LastAddress": "100.68.151.30", + "Gateway": "10.25.1.17", + "BroadcastAddress": "10.25.1.31", + "FirstAddress": "10.25.1.17", + "LastAddress": "10.25.1.30", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.16" + "IP": "10.25.1.16" }, { "Name": "Gateway", - "IP": "100.68.151.17" + "IP": "10.25.1.17" }, { "Name": "TOR1", - "IP": "100.68.151.18" + "IP": "10.25.1.18" }, { "Name": "TOR2", - "IP": "100.68.151.19" + "IP": "10.25.1.19" } ] }, @@ -958,29 +958,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.32/28", - "Network": "100.68.151.32", + "Subnet": "10.25.1.32/28", + "Network": "10.25.1.32", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.33", - "BroadcastAddress": "100.68.151.47", - "FirstAddress": "100.68.151.33", - "LastAddress": "100.68.151.46", + "Gateway": "10.25.1.33", + "BroadcastAddress": "10.25.1.47", + "FirstAddress": "10.25.1.33", + "LastAddress": "10.25.1.46", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.32" + "IP": "10.25.1.32" }, { "Name": "Gateway", - "IP": "100.68.151.33" + "IP": "10.25.1.33" }, { "Name": "TOR1", - "IP": "100.68.151.34" + "IP": "10.25.1.34" }, { "Name": "TOR2", - "IP": "100.68.151.35" + "IP": "10.25.1.35" } ] }, @@ -998,29 +998,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.48/28", - "Network": "100.68.151.48", + "Subnet": "10.25.1.48/28", + "Network": "10.25.1.48", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.49", - "BroadcastAddress": "100.68.151.63", - "FirstAddress": "100.68.151.49", - "LastAddress": "100.68.151.62", + "Gateway": "10.25.1.49", + "BroadcastAddress": "10.25.1.63", + "FirstAddress": "10.25.1.49", + "LastAddress": "10.25.1.62", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.48" + "IP": "10.25.1.48" }, { "Name": "Gateway", - "IP": "100.68.151.49" + "IP": "10.25.1.49" }, { "Name": "TOR1", - "IP": "100.68.151.50" + "IP": "10.25.1.50" }, { "Name": "TOR2", - "IP": "100.68.151.51" + "IP": "10.25.1.51" } ] }, @@ -1038,29 +1038,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.64/28", - "Network": "100.68.151.64", + "Subnet": "10.25.1.64/28", + "Network": "10.25.1.64", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.65", - "BroadcastAddress": "100.68.151.79", - "FirstAddress": "100.68.151.65", - "LastAddress": "100.68.151.78", + "Gateway": "10.25.1.65", + "BroadcastAddress": "10.25.1.79", + "FirstAddress": "10.25.1.65", + "LastAddress": "10.25.1.78", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.64" + "IP": "10.25.1.64" }, { "Name": "Gateway", - "IP": "100.68.151.65" + "IP": "10.25.1.65" }, { "Name": "TOR1", - "IP": "100.68.151.66" + "IP": "10.25.1.66" }, { "Name": "TOR2", - "IP": "100.68.151.67" + "IP": "10.25.1.67" } ] }, @@ -1078,29 +1078,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.80/28", - "Network": "100.68.151.80", + "Subnet": "10.25.1.80/28", + "Network": "10.25.1.80", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.81", - "BroadcastAddress": "100.68.151.95", - "FirstAddress": "100.68.151.81", - "LastAddress": "100.68.151.94", + "Gateway": "10.25.1.81", + "BroadcastAddress": "10.25.1.95", + "FirstAddress": "10.25.1.81", + "LastAddress": "10.25.1.94", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.80" + "IP": "10.25.1.80" }, { "Name": "Gateway", - "IP": "100.68.151.81" + "IP": "10.25.1.81" }, { "Name": "TOR1", - "IP": "100.68.151.82" + "IP": "10.25.1.82" }, { "Name": "TOR2", - "IP": "100.68.151.83" + "IP": "10.25.1.83" } ] }, @@ -1118,29 +1118,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.96/28", - "Network": "100.68.151.96", + "Subnet": "10.25.1.96/28", + "Network": "10.25.1.96", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.97", - "BroadcastAddress": "100.68.151.111", - "FirstAddress": "100.68.151.97", - "LastAddress": "100.68.151.110", + "Gateway": "10.25.1.97", + "BroadcastAddress": "10.25.1.111", + "FirstAddress": "10.25.1.97", + "LastAddress": "10.25.1.110", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.96" + "IP": "10.25.1.96" }, { "Name": "Gateway", - "IP": "100.68.151.97" + "IP": "10.25.1.97" }, { "Name": "TOR1", - "IP": "100.68.151.98" + "IP": "10.25.1.98" }, { "Name": "TOR2", - "IP": "100.68.151.99" + "IP": "10.25.1.99" } ] }, @@ -1158,29 +1158,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.112/28", - "Network": "100.68.151.112", + "Subnet": "10.25.1.112/28", + "Network": "10.25.1.112", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.113", - "BroadcastAddress": "100.68.151.127", - "FirstAddress": "100.68.151.113", - "LastAddress": "100.68.151.126", + "Gateway": "10.25.1.113", + "BroadcastAddress": "10.25.1.127", + "FirstAddress": "10.25.1.113", + "LastAddress": "10.25.1.126", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.112" + "IP": "10.25.1.112" }, { "Name": "Gateway", - "IP": "100.68.151.113" + "IP": "10.25.1.113" }, { "Name": "TOR1", - "IP": "100.68.151.114" + "IP": "10.25.1.114" }, { "Name": "TOR2", - "IP": "100.68.151.115" + "IP": "10.25.1.115" } ] }, @@ -1198,29 +1198,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.128/28", - "Network": "100.68.151.128", + "Subnet": "10.25.1.128/28", + "Network": "10.25.1.128", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.129", - "BroadcastAddress": "100.68.151.143", - "FirstAddress": "100.68.151.129", - "LastAddress": "100.68.151.142", + "Gateway": "10.25.1.129", + "BroadcastAddress": "10.25.1.143", + "FirstAddress": "10.25.1.129", + "LastAddress": "10.25.1.142", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.128" + "IP": "10.25.1.128" }, { "Name": "Gateway", - "IP": "100.68.151.129" + "IP": "10.25.1.129" }, { "Name": "TOR1", - "IP": "100.68.151.130" + "IP": "10.25.1.130" }, { "Name": "TOR2", - "IP": "100.68.151.131" + "IP": "10.25.1.131" } ] }, @@ -1238,29 +1238,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.144/28", - "Network": "100.68.151.144", + "Subnet": "10.25.1.144/28", + "Network": "10.25.1.144", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.145", - "BroadcastAddress": "100.68.151.159", - "FirstAddress": "100.68.151.145", - "LastAddress": "100.68.151.158", + "Gateway": "10.25.1.145", + "BroadcastAddress": "10.25.1.159", + "FirstAddress": "10.25.1.145", + "LastAddress": "10.25.1.158", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.144" + "IP": "10.25.1.144" }, { "Name": "Gateway", - "IP": "10.69.179.145" + "IP": "10.5.1.145" }, { "Name": "TOR1", - "IP": "100.68.151.145" + "IP": "10.25.1.145" }, { "Name": "TOR2", - "IP": "100.68.151.146" + "IP": "10.25.1.146" } ] }, @@ -1278,29 +1278,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.160/28", - "Network": "100.68.151.160", + "Subnet": "10.25.1.160/28", + "Network": "10.25.1.160", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.161", - "BroadcastAddress": "100.68.151.175", - "FirstAddress": "100.68.151.161", - "LastAddress": "100.68.151.174", + "Gateway": "10.25.1.161", + "BroadcastAddress": "10.25.1.175", + "FirstAddress": "10.25.1.161", + "LastAddress": "10.25.1.174", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.160" + "IP": "10.25.1.160" }, { "Name": "Gateway", - "IP": "100.68.151.161" + "IP": "10.25.1.161" }, { "Name": "TOR1", - "IP": "100.68.151.162" + "IP": "10.25.1.162" }, { "Name": "TOR2", - "IP": "100.68.151.163" + "IP": "10.25.1.163" } ] }, @@ -1318,29 +1318,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.176/28", - "Network": "100.68.151.176", + "Subnet": "10.25.1.176/28", + "Network": "10.25.1.176", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.177", - "BroadcastAddress": "100.68.151.191", - "FirstAddress": "100.68.151.177", - "LastAddress": "100.68.151.190", + "Gateway": "10.25.1.177", + "BroadcastAddress": "10.25.1.191", + "FirstAddress": "10.25.1.177", + "LastAddress": "10.25.1.190", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.176" + "IP": "10.25.1.176" }, { "Name": "Gateway", - "IP": "100.68.151.177" + "IP": "10.25.1.177" }, { "Name": "TOR1", - "IP": "100.68.151.178" + "IP": "10.25.1.178" }, { "Name": "TOR2", - "IP": "100.68.151.179" + "IP": "10.25.1.179" } ] }, @@ -1358,29 +1358,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.192/28", - "Network": "100.68.151.192", + "Subnet": "10.25.1.192/28", + "Network": "10.25.1.192", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.193", - "BroadcastAddress": "100.68.151.207", - "FirstAddress": "100.68.151.193", - "LastAddress": "100.68.151.206", + "Gateway": "10.25.1.193", + "BroadcastAddress": "10.25.1.207", + "FirstAddress": "10.25.1.193", + "LastAddress": "10.25.1.206", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.192" + "IP": "10.25.1.192" }, { "Name": "Gateway", - "IP": "100.68.151.193" + "IP": "10.25.1.193" }, { "Name": "TOR1", - "IP": "100.68.151.194" + "IP": "10.25.1.194" }, { "Name": "TOR2", - "IP": "100.68.151.195" + "IP": "10.25.1.195" } ] }, @@ -1398,29 +1398,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.208/28", - "Network": "100.68.151.208", + "Subnet": "10.25.1.208/28", + "Network": "10.25.1.208", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.209", - "BroadcastAddress": "100.68.151.223", - "FirstAddress": "100.68.151.209", - "LastAddress": "100.68.151.222", + "Gateway": "10.25.1.209", + "BroadcastAddress": "10.25.1.223", + "FirstAddress": "10.25.1.209", + "LastAddress": "10.25.1.222", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.208" + "IP": "10.25.1.208" }, { "Name": "Gateway", - "IP": "100.68.151.209" + "IP": "10.25.1.209" }, { "Name": "TOR1", - "IP": "100.68.151.210" + "IP": "10.25.1.210" }, { "Name": "TOR2", - "IP": "100.68.151.211" + "IP": "10.25.1.211" } ] }, @@ -1438,29 +1438,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.224/28", - "Network": "100.68.151.224", + "Subnet": "10.25.1.224/28", + "Network": "10.25.1.224", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.225", - "BroadcastAddress": "100.68.151.239", - "FirstAddress": "100.68.151.225", - "LastAddress": "100.68.151.238", + "Gateway": "10.25.1.225", + "BroadcastAddress": "10.25.1.239", + "FirstAddress": "10.25.1.225", + "LastAddress": "10.25.1.238", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.224" + "IP": "10.25.1.224" }, { "Name": "Gateway", - "IP": "100.68.151.225" + "IP": "10.25.1.225" }, { "Name": "TOR1", - "IP": "100.68.151.226" + "IP": "10.25.1.226" }, { "Name": "TOR2", - "IP": "100.68.151.227" + "IP": "10.25.1.227" } ] }, @@ -1478,29 +1478,29 @@ "Cidr": 28, "TORGroup": "", "NetworkType": "L3forward", - "Subnet": "100.68.151.240/28", - "Network": "100.68.151.240", + "Subnet": "10.25.1.240/28", + "Network": "10.25.1.240", "Netmask": "255.255.255.240", - "Gateway": "100.68.151.241", - "BroadcastAddress": "100.68.151.255", - "FirstAddress": "100.68.151.241", - "LastAddress": "100.68.151.254", + "Gateway": "10.25.1.241", + "BroadcastAddress": "10.25.1.255", + "FirstAddress": "10.25.1.241", + "LastAddress": "10.25.1.254", "Assignment": [ { "Name": "Network", - "IP": "100.68.151.240" + "IP": "10.25.1.240" }, { "Name": "Gateway", - "IP": "100.68.151.241" + "IP": "10.25.1.241" }, { "Name": "TOR1", - "IP": "100.68.151.242" + "IP": "10.25.1.242" }, { "Name": "TOR2", - "IP": "100.68.151.243" + "IP": "10.25.1.243" } ] }, @@ -1518,35 +1518,35 @@ "Cidr": 22, "TORGroup": "", "NetworkType": "ExternalIP", - "Subnet": "100.65.24.0/22", - "Network": "100.65.24.0", + "Subnet": "10.26.1.0/22", + "Network": "10.26.1.0", "Netmask": "255.255.252.0", "Gateway": null, - "BroadcastAddress": "100.65.27.255", - "FirstAddress": "100.65.24.1", - "LastAddress": "100.65.27.254", + "BroadcastAddress": "10.26.4.255", + "FirstAddress": "10.26.1.1", + "LastAddress": "10.26.4.254", "Assignment": [ { "Name": "Network", - "IP": "100.65.24.0" + "IP": "10.26.1.0" } ], "IPPools": [ { "Name": "CL01", - "Subnet": "100.65.24.0/24" + "Subnet": "10.26.1.0/24" }, { "Name": "CL02", - "Subnet": "100.65.25.0/24" + "Subnet": "10.26.2.0/24" }, { "Name": "CL03", - "Subnet": "100.65.26.0/24" + "Subnet": "10.26.3.0/24" }, { "Name": "CL04", - "Subnet": "100.65.27.0/24" + "Subnet": "10.26.4.0/24" } ] }, @@ -1564,35 +1564,35 @@ "Cidr": 26, "TORGroup": "", "NetworkType": "ExternalIP", - "Subnet": "100.76.7.128/26", - "Network": "100.76.7.128", + "Subnet": "10.27.1.128/26", + "Network": "10.27.1.128", "Netmask": "255.255.255.192", "Gateway": null, - "BroadcastAddress": "100.76.7.191", - "FirstAddress": "100.76.7.129", - "LastAddress": "100.76.7.190", + "BroadcastAddress": "10.27.1.191", + "FirstAddress": "10.27.1.129", + "LastAddress": "10.27.1.190", "Assignment": [ { "Name": "Network", - "IP": "100.76.7.128" + "IP": "10.27.1.128" } ], "IPPools": [ { "Name": "CL01", - "Subnet": "100.76.7.128/28" + "Subnet": "10.27.1.128/28" }, { "Name": "CL02", - "Subnet": "100.76.7.144/28" + "Subnet": "10.27.1.144/28" }, { "Name": "CL03", - "Subnet": "100.76.7.160/28" + "Subnet": "10.27.1.160/28" }, { "Name": "CL04", - "Subnet": "100.76.7.176/28" + "Subnet": "10.27.1.176/28" } ] }, @@ -1610,17 +1610,17 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Storage", - "Subnet": "10.71.1.0/24", - "Network": "10.71.1.0", + "Subnet": "10.8.1.0/24", + "Network": "10.8.1.0", "Netmask": "255.255.255.0", - "Gateway": "10.71.1.1", - "BroadcastAddress": "10.71.1.255", - "FirstAddress": "10.71.1.1", - "LastAddress": "10.71.1.254", + "Gateway": "10.8.1.1", + "BroadcastAddress": "10.8.1.255", + "FirstAddress": "10.8.1.1", + "LastAddress": "10.8.1.254", "Assignment": [ { "Name": "Network", - "IP": "10.71.1.0" + "IP": "10.8.1.0" } ] }, @@ -1638,17 +1638,17 @@ "Cidr": 24, "TORGroup": "", "NetworkType": "Storage", - "Subnet": "10.71.2.0/24", - "Network": "10.71.2.0", + "Subnet": "10.8.2.0/24", + "Network": "10.8.2.0", "Netmask": "255.255.255.0", - "Gateway": "10.71.2.1", - "BroadcastAddress": "10.71.2.255", - "FirstAddress": "10.71.2.1", - "LastAddress": "10.71.2.254", + "Gateway": "10.8.2.1", + "BroadcastAddress": "10.8.2.255", + "FirstAddress": "10.8.2.1", + "LastAddress": "10.8.2.254", "Assignment": [ { "Name": "Network", - "IP": "10.71.2.0" + "IP": "10.8.2.0" } ] }, @@ -1681,9 +1681,9 @@ ], "Setting": { "TimeZone": "Pacific Standard Time", - "TimeServer": ["10.10.240.20"], - "SyslogServer": ["10.10.43.111"], - "DNSForwarder": ["10.10.240.23", "10.10.240.24"] + "TimeServer": ["10.100.0.1"], + "SyslogServer": ["10.100.0.2"], + "DNSForwarder": ["10.100.0.3", "10.100.0.4"] } } } diff --git a/tests/test_cases/std_cisco_nxos_fc/expected_bgp.cfg b/tests/test_cases/std_cisco_nxos_fc/expected_bgp.cfg index 3c4499d..a02da4f 100644 --- a/tests/test_cases/std_cisco_nxos_fc/expected_bgp.cfg +++ b/tests/test_cases/std_cisco_nxos_fc/expected_bgp.cfg @@ -1,56 +1,56 @@ ! bgp.j2 router bgp 65242 - router-id 100.71.85.21 + router-id 10.1.1.21 bestpath as-path multipath-relax log-neighbor-changes address-family ipv4 unicast - network 100.71.85.2/30 - network 100.71.85.10/30 - network 100.71.85.21/32 - network 100.69.177.0/24 - network 100.69.178.0/25 - network 100.69.178.128/25 - network 100.69.179.0/28 - network 100.69.179.16/28 - network 100.69.179.32/28 - network 100.69.179.48/28 - network 100.69.179.64/28 - network 100.69.179.80/28 - network 100.69.179.96/28 - network 100.69.179.112/28 - network 100.69.179.128/28 - network 100.69.179.144/28 - network 100.69.179.160/28 - network 100.69.179.176/28 - network 100.69.179.192/28 - network 100.69.179.208/28 - network 100.69.179.224/28 - network 100.69.179.240/28 + network 10.1.1.2/30 + network 10.1.1.10/30 + network 10.1.1.21/32 + network 10.4.1.0/24 + network 10.5.2.0/25 + network 10.5.2.128/25 + network 10.5.1.0/28 + network 10.5.1.16/28 + network 10.5.1.32/28 + network 10.5.1.48/28 + network 10.5.1.64/28 + network 10.5.1.80/28 + network 10.5.1.96/28 + network 10.5.1.112/28 + network 10.5.1.128/28 + network 10.5.1.144/28 + network 10.5.1.160/28 + network 10.5.1.176/28 + network 10.5.1.192/28 + network 10.5.1.208/28 + network 10.5.1.224/28 + network 10.5.1.240/28 maximum-paths 8 maximum-paths ibgp 8 - neighbor 100.71.85.1 + neighbor 10.1.1.1 description TO_Border1 remote-as 64846 address-family ipv4 unicast maximum-prefix 12000 warning-only prefix-list DefaultRoute in - neighbor 100.71.85.9 + neighbor 10.1.1.9 description TO_Border2 remote-as 64846 address-family ipv4 unicast maximum-prefix 12000 warning-only prefix-list DefaultRoute in - neighbor 100.71.85.18 + neighbor 10.1.1.18 description iBGP_PEER remote-as 65242 address-family ipv4 unicast maximum-prefix 12000 warning-only - neighbor 100.71.131.0/25 + neighbor 10.2.1.0/25 description TO_HNVPA remote-as 65112 update-source Loopback0 diff --git a/tests/test_cases/std_cisco_nxos_fc/std_cisco_nxos_fc_input.json b/tests/test_cases/std_cisco_nxos_fc/std_cisco_nxos_fc_input.json index 9750ea9..5cb9556 100644 --- a/tests/test_cases/std_cisco_nxos_fc/std_cisco_nxos_fc_input.json +++ b/tests/test_cases/std_cisco_nxos_fc/std_cisco_nxos_fc_input.json @@ -3,7 +3,7 @@ "make": "cisco", "model": "93180yc-fx3", "type": "TOR1", - "hostname": "s46-r21-93180hl-24-1a", + "hostname": "tor-1a", "version": "10.3(4a)", "firmware": "nxos" }, @@ -17,14 +17,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.71.131.2", + "ip": "10.2.1.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 6, "priority": 150, - "virtual_ip": "100.71.131.1" + "virtual_ip": "10.2.1.1" } } }, @@ -32,14 +32,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.69.176.2", + "ip": "10.3.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 7, "priority": 150, - "virtual_ip": "100.69.176.1" + "virtual_ip": "10.3.1.1" } } }, @@ -51,14 +51,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.85.123", + "ip": "10.1.1.123", "cidr": 26, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 125, "priority": 150, - "virtual_ip": "100.71.85.65" + "virtual_ip": "10.1.1.65" } } }, @@ -66,14 +66,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.69.177.2", + "ip": "10.4.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 201, "priority": 150, - "virtual_ip": "100.69.177.1" + "virtual_ip": "10.4.1.1" } } }, @@ -81,14 +81,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.69.178.2", + "ip": "10.5.2.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 301, "priority": 150, - "virtual_ip": "100.69.178.1" + "virtual_ip": "10.5.2.1" } } }, @@ -96,14 +96,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.69.178.130", + "ip": "10.5.2.130", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 401, "priority": 150, - "virtual_ip": "100.69.178.129" + "virtual_ip": "10.5.2.129" } } }, @@ -111,14 +111,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.69.179.2", + "ip": "10.5.1.2", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 501, "priority": 150, - "virtual_ip": "100.69.179.1" + "virtual_ip": "10.5.1.1" } } }, @@ -126,14 +126,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.69.179.18", + "ip": "10.5.1.18", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 502, "priority": 150, - "virtual_ip": "100.69.179.17" + "virtual_ip": "10.5.1.17" } } }, @@ -141,14 +141,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.69.179.34", + "ip": "10.5.1.34", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 503, "priority": 150, - "virtual_ip": "100.69.179.33" + "virtual_ip": "10.5.1.33" } } }, @@ -156,14 +156,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.69.179.50", + "ip": "10.5.1.50", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 504, "priority": 150, - "virtual_ip": "100.69.179.49" + "virtual_ip": "10.5.1.49" } } }, @@ -171,14 +171,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.69.179.66", + "ip": "10.5.1.66", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 505, "priority": 150, - "virtual_ip": "100.69.179.65" + "virtual_ip": "10.5.1.65" } } }, @@ -186,14 +186,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.69.179.82", + "ip": "10.5.1.82", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 506, "priority": 150, - "virtual_ip": "100.69.179.81" + "virtual_ip": "10.5.1.81" } } }, @@ -201,14 +201,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.69.179.98", + "ip": "10.5.1.98", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 507, "priority": 150, - "virtual_ip": "100.69.179.97" + "virtual_ip": "10.5.1.97" } } }, @@ -216,14 +216,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.69.179.114", + "ip": "10.5.1.114", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 508, "priority": 150, - "virtual_ip": "100.69.179.113" + "virtual_ip": "10.5.1.113" } } }, @@ -231,14 +231,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.69.179.130", + "ip": "10.5.1.130", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 509, "priority": 150, - "virtual_ip": "100.69.179.129" + "virtual_ip": "10.5.1.129" } } }, @@ -246,7 +246,7 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.69.179.145", + "ip": "10.5.1.145", "cidr": 28, "mtu": 9216, "redundancy": { @@ -261,14 +261,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.69.179.162", + "ip": "10.5.1.162", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 511, "priority": 150, - "virtual_ip": "100.69.179.161" + "virtual_ip": "10.5.1.161" } } }, @@ -276,14 +276,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.69.179.178", + "ip": "10.5.1.178", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 512, "priority": 150, - "virtual_ip": "100.69.179.177" + "virtual_ip": "10.5.1.177" } } }, @@ -291,14 +291,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.69.179.194", + "ip": "10.5.1.194", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 513, "priority": 150, - "virtual_ip": "100.69.179.193" + "virtual_ip": "10.5.1.193" } } }, @@ -306,14 +306,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.69.179.210", + "ip": "10.5.1.210", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 514, "priority": 150, - "virtual_ip": "100.69.179.209" + "virtual_ip": "10.5.1.209" } } }, @@ -321,14 +321,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.69.179.226", + "ip": "10.5.1.226", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 515, "priority": 150, - "virtual_ip": "100.69.179.225" + "virtual_ip": "10.5.1.225" } } }, @@ -336,14 +336,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.69.179.242", + "ip": "10.5.1.242", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 516, "priority": 150, - "virtual_ip": "100.69.179.241" + "virtual_ip": "10.5.1.241" } } }, @@ -372,21 +372,21 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.71.85.21/32" + "ipv4": "10.1.1.21/32" }, { "name": "P2P_Border1", "type": "L3", "intf_type": "Ethernet", "intf": "1/48", - "ipv4": "100.71.85.2/30" + "ipv4": "10.1.1.2/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/47", - "ipv4": "100.71.85.10/30" + "ipv4": "10.1.1.10/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -435,34 +435,34 @@ ], "bgp": { "asn": 65242, - "router_id": "100.71.85.21", + "router_id": "10.1.1.21", "networks": [ - "100.71.85.2/30", - "100.71.85.10/30", - "100.71.85.21/32", - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.1.1.2/30", + "10.1.1.10/30", + "10.1.1.21/32", + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ], "neighbors": [ { - "ip": "100.71.85.1", + "ip": "10.1.1.1", "description": "TO_Border1", "remote_as": 64846, "af_ipv4_unicast": { @@ -470,7 +470,7 @@ } }, { - "ip": "100.71.85.9", + "ip": "10.1.1.9", "description": "TO_Border2", "remote_as": 64846, "af_ipv4_unicast": { @@ -478,13 +478,13 @@ } }, { - "ip": "100.71.85.18", + "ip": "10.1.1.18", "description": "iBGP_PEER", "remote_as": 65242, "af_ipv4_unicast": {} }, { - "ip": "100.71.131.0/25", + "ip": "10.2.1.0/25", "description": "TO_HNVPA", "remote_as": 65112, "update_source": "Loopback0", diff --git a/tests/test_cases/std_cisco_nxos_fc/s46-r21-93180hl-24-1a.config b/tests/test_cases/std_cisco_nxos_fc/tor-1a.config similarity index 91% rename from tests/test_cases/std_cisco_nxos_fc/s46-r21-93180hl-24-1a.config rename to tests/test_cases/std_cisco_nxos_fc/tor-1a.config index ba72e0f..d433f2c 100644 --- a/tests/test_cases/std_cisco_nxos_fc/s46-r21-93180hl-24-1a.config +++ b/tests/test_cases/std_cisco_nxos_fc/tor-1a.config @@ -1,14 +1,14 @@ ! header.go.tmpl-hostname -! Name: s46-r21-93180hl-24-1a +! Name: tor-1a ! Make: Cisco ! Model: 93180YC-FX3 -hostname s46-r21-93180hl-24-1a +hostname tor-1a banner motd # NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE -hostname s46-r21-93180hl-24-1a +hostname tor-1a BuildVersion: 1.2305.01 Unauthorized access and/or use prohibited. All access and/or use subject to monitoring. @@ -171,193 +171,193 @@ interface vlan6 description HNVPA_6 mtu 9216 no shutdown - ip address 100.71.131.2/25 + ip address 10.2.1.2/25 no ip redirects no ipv6 redirects hsrp version 2 hsrp 6 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.71.131.1 + ip 10.2.1.1 interface vlan7 description Infra_7 mtu 9216 no shutdown - ip address 100.69.176.2/24 + ip address 10.3.1.2/24 no ip redirects no ipv6 redirects - ip dhcp relay address 100.71.85.107 - ip dhcp relay address 100.71.85.108 - ip dhcp relay address 100.71.85.109 - ip dhcp relay address 100.71.85.110 + ip dhcp relay address 10.1.1.107 + ip dhcp relay address 10.1.1.108 + ip dhcp relay address 10.1.1.109 + ip dhcp relay address 10.1.1.110 hsrp version 2 hsrp 7 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.176.1 + ip 10.3.1.1 interface vlan125 description BMC_Mgmt_125 mtu 9216 no shutdown - ip address 100.71.85.123/26 + ip address 10.1.1.123/26 no ip redirects no ipv6 redirects hsrp version 2 hsrp 125 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.71.85.65 + ip 10.1.1.65 interface vlan201 description Tenant_201 mtu 9216 no shutdown - ip address 100.69.177.2/24 + ip address 10.4.1.2/24 no ip redirects no ipv6 redirects hsrp version 2 hsrp 201 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.177.1 + ip 10.4.1.1 interface vlan301 description LogicalTenant_301 mtu 9216 no shutdown - ip address 100.69.178.2/25 + ip address 10.5.2.2/25 no ip redirects no ipv6 redirects hsrp version 2 hsrp 301 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.178.1 + ip 10.5.2.1 interface vlan401 description DhcpTenant_401 mtu 9216 no shutdown - ip address 100.69.178.130/25 + ip address 10.5.2.130/25 no ip redirects no ipv6 redirects - ip dhcp relay address 100.71.85.126 + ip dhcp relay address 10.1.1.126 hsrp version 2 hsrp 401 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.178.129 + ip 10.5.2.129 interface vlan501 description L3forward_501 mtu 9216 no shutdown - ip address 100.69.179.2/28 + ip address 10.5.1.2/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 501 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.1 + ip 10.5.1.1 interface vlan502 description L3forward_502 mtu 9216 no shutdown - ip address 100.69.179.18/28 + ip address 10.5.1.18/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 502 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.17 + ip 10.5.1.17 interface vlan503 description L3forward_503 mtu 9216 no shutdown - ip address 100.69.179.34/28 + ip address 10.5.1.34/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 503 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.33 + ip 10.5.1.33 interface vlan504 description L3forward_504 mtu 9216 no shutdown - ip address 100.69.179.50/28 + ip address 10.5.1.50/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 504 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.49 + ip 10.5.1.49 interface vlan505 description L3forward_505 mtu 9216 no shutdown - ip address 100.69.179.66/28 + ip address 10.5.1.66/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 505 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.65 + ip 10.5.1.65 interface vlan506 description L3forward_506 mtu 9216 no shutdown - ip address 100.69.179.82/28 + ip address 10.5.1.82/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 506 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.81 + ip 10.5.1.81 interface vlan507 description L3forward_507 mtu 9216 no shutdown - ip address 100.69.179.98/28 + ip address 10.5.1.98/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 507 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.97 + ip 10.5.1.97 interface vlan508 description L3forward_508 mtu 9216 no shutdown - ip address 100.69.179.114/28 + ip address 10.5.1.114/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 508 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.113 + ip 10.5.1.113 interface vlan509 description L3forward_509 mtu 9216 no shutdown - ip address 100.69.179.130/28 + ip address 10.5.1.130/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 509 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.129 + ip 10.5.1.129 interface vlan510 description L3forward_510 mtu 9216 no shutdown - ip address 100.69.179.145/28 + ip address 10.5.1.145/28 no ip redirects no ipv6 redirects @@ -365,73 +365,73 @@ interface vlan511 description L3forward_511 mtu 9216 no shutdown - ip address 100.69.179.162/28 + ip address 10.5.1.162/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 511 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.161 + ip 10.5.1.161 interface vlan512 description L3forward_512 mtu 9216 no shutdown - ip address 100.69.179.178/28 + ip address 10.5.1.178/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 512 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.177 + ip 10.5.1.177 interface vlan513 description L3forward_513 mtu 9216 no shutdown - ip address 100.69.179.194/28 + ip address 10.5.1.194/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 513 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.193 + ip 10.5.1.193 interface vlan514 description L3forward_514 mtu 9216 no shutdown - ip address 100.69.179.210/28 + ip address 10.5.1.210/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 514 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.209 + ip 10.5.1.209 interface vlan515 description L3forward_515 mtu 9216 no shutdown - ip address 100.69.179.226/28 + ip address 10.5.1.226/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 515 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.225 + ip 10.5.1.225 interface vlan516 description L3forward_516 mtu 9216 no shutdown - ip address 100.69.179.242/28 + ip address 10.5.1.242/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 516 priority 150 forwarding-threshold lower 1 upper 150 - ip 100.69.179.241 + ip 10.5.1.241 @@ -451,7 +451,7 @@ spanning-tree mst configuration vpc domain 1 role priority 1 - peer-keepalive destination 100.71.85.18 source 100.71.85.17 vrf default + peer-keepalive destination 10.1.1.18 source 10.1.1.17 vrf default delay restore 150 peer-gateway auto-recovery @@ -472,7 +472,7 @@ interface port-channel50 description VPC:P2P_IBGP no switchport priority-flow-control mode on - ip address 100.71.85.17/30 + ip address 10.1.1.17/30 logging event port link-status mtu 9216 service-policy type qos input AZS_SERVICES @@ -1022,7 +1022,7 @@ interface Ethernet 1/47 no cdp enable no switchport no ip redirects - ip address 100.71.85.10/30 + ip address 10.1.1.10/30 no ipv6 redirects mtu 9216 no shutdown @@ -1032,7 +1032,7 @@ interface Ethernet 1/48 no cdp enable no switchport no ip redirects - ip address 100.71.85.2/30 + ip address 10.1.1.2/30 no ipv6 redirects mtu 9216 no shutdown @@ -1110,7 +1110,7 @@ interface mgmt0 interface loopback0 description Loopback0_Tor1 - ip address 100.71.85.21/32 + ip address 10.1.1.21/32 ! settings.go.tmpl-set_global cli alias name wr copy running-config startup-config @@ -1148,11 +1148,11 @@ line vty ! settings.go.tmpl-set_ntp clock timezone PST -8 0 clock summer-time PDT 2 Sun Apr 02:00 1 Sun Nov 02:00 60 -ntp server 10.10.240.20 +ntp server 10.100.0.1 ntp source-interface vlan125 ! settings.go.tmpl-set_syslog -logging server 10.10.43.111 7 facility local7 use-vrf default +logging server 10.100.0.2 7 facility local7 use-vrf default logging source-interface vlan125 logging level local7 7 no logging console @@ -1212,40 +1212,40 @@ route-map PREFER-WANSIM permit 10 ! bgp.go.tmpl-bgp router bgp 65242 - router-id 100.71.85.21 + router-id 10.1.1.21 bestpath as-path multipath-relax log-neighbor-changes address-family ipv4 unicast - network 100.71.85.0/30 - network 100.71.85.8/30 - network 100.71.85.16/30 - network 100.71.85.21/32 - network 100.71.85.64/26 - network 100.71.131.0/25 - network 100.69.176.0/24 - network 100.69.177.0/24 - network 100.69.178.0/25 - network 100.69.178.128/25 - network 100.69.179.0/28 - network 100.69.179.16/28 - network 100.69.179.32/28 - network 100.69.179.48/28 - network 100.69.179.64/28 - network 100.69.179.80/28 - network 100.69.179.96/28 - network 100.69.179.112/28 - network 100.69.179.128/28 - network 100.69.179.144/28 - network 100.69.179.160/28 - network 100.69.179.176/28 - network 100.69.179.192/28 - network 100.69.179.208/28 - network 100.69.179.224/28 - network 100.69.179.240/28 + network 10.1.1.0/30 + network 10.1.1.8/30 + network 10.1.1.16/30 + network 10.1.1.21/32 + network 10.1.1.64/26 + network 10.2.1.0/25 + network 10.3.1.0/24 + network 10.4.1.0/24 + network 10.5.2.0/25 + network 10.5.2.128/25 + network 10.5.1.0/28 + network 10.5.1.16/28 + network 10.5.1.32/28 + network 10.5.1.48/28 + network 10.5.1.64/28 + network 10.5.1.80/28 + network 10.5.1.96/28 + network 10.5.1.112/28 + network 10.5.1.128/28 + network 10.5.1.144/28 + network 10.5.1.160/28 + network 10.5.1.176/28 + network 10.5.1.192/28 + network 10.5.1.208/28 + network 10.5.1.224/28 + network 10.5.1.240/28 maximum-paths 8 maximum-paths ibgp 8 - neighbor 100.71.85.1 + neighbor 10.1.1.1 description TO_Border1 remote-as 64846 ! @@ -1255,7 +1255,7 @@ router bgp 65242 prefix-list TO-BORDER out prefix-list FROM-BORDER in - neighbor 100.71.85.9 + neighbor 10.1.1.9 description TO_Border2 remote-as 64846 ! @@ -1265,7 +1265,7 @@ router bgp 65242 prefix-list TO-BORDER out prefix-list FROM-BORDER in - neighbor 100.71.85.18 + neighbor 10.1.1.18 description TO_TOR2 remote-as 65242 ! @@ -1275,7 +1275,7 @@ router bgp 65242 - neighbor 100.71.131.0/25 + neighbor 10.2.1.0/25 description TO_MUX remote-as 65112 update-source Loopback0 diff --git a/tests/test_cases/std_cisco_nxos_switched/expected_bgp.cfg b/tests/test_cases/std_cisco_nxos_switched/expected_bgp.cfg index 3c4499d..a02da4f 100644 --- a/tests/test_cases/std_cisco_nxos_switched/expected_bgp.cfg +++ b/tests/test_cases/std_cisco_nxos_switched/expected_bgp.cfg @@ -1,56 +1,56 @@ ! bgp.j2 router bgp 65242 - router-id 100.71.85.21 + router-id 10.1.1.21 bestpath as-path multipath-relax log-neighbor-changes address-family ipv4 unicast - network 100.71.85.2/30 - network 100.71.85.10/30 - network 100.71.85.21/32 - network 100.69.177.0/24 - network 100.69.178.0/25 - network 100.69.178.128/25 - network 100.69.179.0/28 - network 100.69.179.16/28 - network 100.69.179.32/28 - network 100.69.179.48/28 - network 100.69.179.64/28 - network 100.69.179.80/28 - network 100.69.179.96/28 - network 100.69.179.112/28 - network 100.69.179.128/28 - network 100.69.179.144/28 - network 100.69.179.160/28 - network 100.69.179.176/28 - network 100.69.179.192/28 - network 100.69.179.208/28 - network 100.69.179.224/28 - network 100.69.179.240/28 + network 10.1.1.2/30 + network 10.1.1.10/30 + network 10.1.1.21/32 + network 10.4.1.0/24 + network 10.5.2.0/25 + network 10.5.2.128/25 + network 10.5.1.0/28 + network 10.5.1.16/28 + network 10.5.1.32/28 + network 10.5.1.48/28 + network 10.5.1.64/28 + network 10.5.1.80/28 + network 10.5.1.96/28 + network 10.5.1.112/28 + network 10.5.1.128/28 + network 10.5.1.144/28 + network 10.5.1.160/28 + network 10.5.1.176/28 + network 10.5.1.192/28 + network 10.5.1.208/28 + network 10.5.1.224/28 + network 10.5.1.240/28 maximum-paths 8 maximum-paths ibgp 8 - neighbor 100.71.85.1 + neighbor 10.1.1.1 description TO_Border1 remote-as 64846 address-family ipv4 unicast maximum-prefix 12000 warning-only prefix-list DefaultRoute in - neighbor 100.71.85.9 + neighbor 10.1.1.9 description TO_Border2 remote-as 64846 address-family ipv4 unicast maximum-prefix 12000 warning-only prefix-list DefaultRoute in - neighbor 100.71.85.18 + neighbor 10.1.1.18 description iBGP_PEER remote-as 65242 address-family ipv4 unicast maximum-prefix 12000 warning-only - neighbor 100.71.131.0/25 + neighbor 10.2.1.0/25 description TO_HNVPA remote-as 65112 update-source Loopback0 diff --git a/tests/test_cases/std_cisco_nxos_switched/expected_full_config.cfg b/tests/test_cases/std_cisco_nxos_switched/expected_full_config.cfg index af80c4a..a434411 100644 --- a/tests/test_cases/std_cisco_nxos_switched/expected_full_config.cfg +++ b/tests/test_cases/std_cisco_nxos_switched/expected_full_config.cfg @@ -1,14 +1,14 @@ ! system.j2 -! Name: s46-r21-93180hl-24-1a +! Name: tor-1a ! Make: cisco ! Model: 93180yc-fx -hostname s46-r21-93180hl-24-1a +hostname tor-1a banner motd # NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE -hostname s46-r21-93180hl-24-1a +hostname tor-1a Unauthorized access and/or use prohibited. All access and/or use subject to monitoring. @@ -239,187 +239,187 @@ interface vlan6 description HNVPA_6 mtu 9216 no shutdown - ip address 100.71.131.2/25 + ip address 10.2.1.2/25 no ip redirects no ipv6 redirects hsrp version 2 hsrp 6 priority 150 - ip 100.71.131.1 + ip 10.2.1.1 interface vlan7 description Infra_7 mtu 9216 no shutdown - ip address 100.69.176.2/24 + ip address 10.3.1.2/24 no ip redirects no ipv6 redirects hsrp version 2 hsrp 7 priority 150 - ip 100.69.176.1 + ip 10.3.1.1 interface vlan125 description BMC_Mgmt_125 mtu 9216 no shutdown - ip address 100.71.85.123/26 + ip address 10.1.1.123/26 no ip redirects no ipv6 redirects hsrp version 2 hsrp 125 priority 150 - ip 100.71.85.65 + ip 10.1.1.65 interface vlan201 description Tenant_201 mtu 9216 no shutdown - ip address 100.69.177.2/24 + ip address 10.4.1.2/24 no ip redirects no ipv6 redirects hsrp version 2 hsrp 201 priority 150 - ip 100.69.177.1 + ip 10.4.1.1 interface vlan301 description LogicalTenant_301 mtu 9216 no shutdown - ip address 100.69.178.2/25 + ip address 10.5.2.2/25 no ip redirects no ipv6 redirects hsrp version 2 hsrp 301 priority 150 - ip 100.69.178.1 + ip 10.5.2.1 interface vlan401 description DhcpTenant_401 mtu 9216 no shutdown - ip address 100.69.178.130/25 + ip address 10.5.2.130/25 no ip redirects no ipv6 redirects hsrp version 2 hsrp 401 priority 150 - ip 100.69.178.129 + ip 10.5.2.129 interface vlan501 description L3forward_501 mtu 9216 no shutdown - ip address 100.69.179.2/28 + ip address 10.5.1.2/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 501 priority 150 - ip 100.69.179.1 + ip 10.5.1.1 interface vlan502 description L3forward_502 mtu 9216 no shutdown - ip address 100.69.179.18/28 + ip address 10.5.1.18/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 502 priority 150 - ip 100.69.179.17 + ip 10.5.1.17 interface vlan503 description L3forward_503 mtu 9216 no shutdown - ip address 100.69.179.34/28 + ip address 10.5.1.34/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 503 priority 150 - ip 100.69.179.33 + ip 10.5.1.33 interface vlan504 description L3forward_504 mtu 9216 no shutdown - ip address 100.69.179.50/28 + ip address 10.5.1.50/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 504 priority 150 - ip 100.69.179.49 + ip 10.5.1.49 interface vlan505 description L3forward_505 mtu 9216 no shutdown - ip address 100.69.179.66/28 + ip address 10.5.1.66/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 505 priority 150 - ip 100.69.179.65 + ip 10.5.1.65 interface vlan506 description L3forward_506 mtu 9216 no shutdown - ip address 100.69.179.82/28 + ip address 10.5.1.82/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 506 priority 150 - ip 100.69.179.81 + ip 10.5.1.81 interface vlan507 description L3forward_507 mtu 9216 no shutdown - ip address 100.69.179.98/28 + ip address 10.5.1.98/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 507 priority 150 - ip 100.69.179.97 + ip 10.5.1.97 interface vlan508 description L3forward_508 mtu 9216 no shutdown - ip address 100.69.179.114/28 + ip address 10.5.1.114/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 508 priority 150 - ip 100.69.179.113 + ip 10.5.1.113 interface vlan509 description L3forward_509 mtu 9216 no shutdown - ip address 100.69.179.130/28 + ip address 10.5.1.130/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 509 priority 150 - ip 100.69.179.129 + ip 10.5.1.129 interface vlan510 description L3forward_510 mtu 9216 no shutdown - ip address 100.69.179.145/28 + ip address 10.5.1.145/28 no ip redirects no ipv6 redirects hsrp version 2 @@ -431,73 +431,73 @@ interface vlan511 description L3forward_511 mtu 9216 no shutdown - ip address 100.69.179.162/28 + ip address 10.5.1.162/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 511 priority 150 - ip 100.69.179.161 + ip 10.5.1.161 interface vlan512 description L3forward_512 mtu 9216 no shutdown - ip address 100.69.179.178/28 + ip address 10.5.1.178/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 512 priority 150 - ip 100.69.179.177 + ip 10.5.1.177 interface vlan513 description L3forward_513 mtu 9216 no shutdown - ip address 100.69.179.194/28 + ip address 10.5.1.194/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 513 priority 150 - ip 100.69.179.193 + ip 10.5.1.193 interface vlan514 description L3forward_514 mtu 9216 no shutdown - ip address 100.69.179.210/28 + ip address 10.5.1.210/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 514 priority 150 - ip 100.69.179.209 + ip 10.5.1.209 interface vlan515 description L3forward_515 mtu 9216 no shutdown - ip address 100.69.179.226/28 + ip address 10.5.1.226/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 515 priority 150 - ip 100.69.179.225 + ip 10.5.1.225 interface vlan516 description L3forward_516 mtu 9216 no shutdown - ip address 100.69.179.242/28 + ip address 10.5.1.242/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 516 priority 150 - ip 100.69.179.241 + ip 10.5.1.241 @@ -560,7 +560,7 @@ interface Ethernet 1/48 description P2P_Border1 no cdp enable no switchport - ip address 100.71.85.2/30 + ip address 10.1.1.2/30 no ip redirects no ipv6 redirects mtu 9216 @@ -570,7 +570,7 @@ interface Ethernet 1/47 description P2P_Border2 no cdp enable no switchport - ip address 100.71.85.10/30 + ip address 10.1.1.10/30 no ip redirects no ipv6 redirects mtu 9216 @@ -579,7 +579,7 @@ interface Ethernet 1/47 interface loopbackloopback0 description Loopback0 - ip address 100.71.85.21/32 + ip address 10.1.1.21/32 mtu 9216 no shutdown @@ -591,7 +591,7 @@ interface loopbackloopback0 interface port-channel50 description P2P_IBGP no switchport - ip address 100.71.85.17 + ip address 10.1.1.17 logging event port link-status mtu 9216 no shutdown @@ -675,56 +675,56 @@ ip prefix-list DefaultRoute seq 50 deny 0.0.0.0/0 le 32 ! bgp.j2 router bgp 65242 - router-id 100.71.85.21 + router-id 10.1.1.21 bestpath as-path multipath-relax log-neighbor-changes address-family ipv4 unicast - network 100.71.85.2/30 - network 100.71.85.10/30 - network 100.71.85.21/32 - network 100.69.177.0/24 - network 100.69.178.0/25 - network 100.69.178.128/25 - network 100.69.179.0/28 - network 100.69.179.16/28 - network 100.69.179.32/28 - network 100.69.179.48/28 - network 100.69.179.64/28 - network 100.69.179.80/28 - network 100.69.179.96/28 - network 100.69.179.112/28 - network 100.69.179.128/28 - network 100.69.179.144/28 - network 100.69.179.160/28 - network 100.69.179.176/28 - network 100.69.179.192/28 - network 100.69.179.208/28 - network 100.69.179.224/28 - network 100.69.179.240/28 + network 10.1.1.2/30 + network 10.1.1.10/30 + network 10.1.1.21/32 + network 10.4.1.0/24 + network 10.5.2.0/25 + network 10.5.2.128/25 + network 10.5.1.0/28 + network 10.5.1.16/28 + network 10.5.1.32/28 + network 10.5.1.48/28 + network 10.5.1.64/28 + network 10.5.1.80/28 + network 10.5.1.96/28 + network 10.5.1.112/28 + network 10.5.1.128/28 + network 10.5.1.144/28 + network 10.5.1.160/28 + network 10.5.1.176/28 + network 10.5.1.192/28 + network 10.5.1.208/28 + network 10.5.1.224/28 + network 10.5.1.240/28 maximum-paths 8 maximum-paths ibgp 8 - neighbor 100.71.85.1 + neighbor 10.1.1.1 description TO_Border1 remote-as 64846 address-family ipv4 unicast maximum-prefix 12000 warning-only prefix-list DefaultRoute in - neighbor 100.71.85.9 + neighbor 10.1.1.9 description TO_Border2 remote-as 64846 address-family ipv4 unicast maximum-prefix 12000 warning-only prefix-list DefaultRoute in - neighbor 100.71.85.18 + neighbor 10.1.1.18 description iBGP_PEER remote-as 65242 address-family ipv4 unicast maximum-prefix 12000 warning-only - neighbor 100.71.131.0/25 + neighbor 10.2.1.0/25 description TO_HNVPA remote-as 65112 update-source Loopback0 diff --git a/tests/test_cases/std_cisco_nxos_switched/expected_interface.cfg b/tests/test_cases/std_cisco_nxos_switched/expected_interface.cfg index 4446c0d..f35977c 100644 --- a/tests/test_cases/std_cisco_nxos_switched/expected_interface.cfg +++ b/tests/test_cases/std_cisco_nxos_switched/expected_interface.cfg @@ -57,7 +57,7 @@ interface Ethernet 1/48 description P2P_Border1 no cdp enable no switchport - ip address 100.71.85.2/30 + ip address 10.1.1.2/30 no ip redirects no ipv6 redirects mtu 9216 @@ -67,7 +67,7 @@ interface Ethernet 1/47 description P2P_Border2 no cdp enable no switchport - ip address 100.71.85.10/30 + ip address 10.1.1.10/30 no ip redirects no ipv6 redirects mtu 9216 @@ -76,7 +76,7 @@ interface Ethernet 1/47 interface loopbackloopback0 description Loopback0 - ip address 100.71.85.21/32 + ip address 10.1.1.21/32 mtu 9216 no shutdown diff --git a/tests/test_cases/std_cisco_nxos_switched/expected_port_channel.cfg b/tests/test_cases/std_cisco_nxos_switched/expected_port_channel.cfg index 8e7caed..f2a9208 100644 --- a/tests/test_cases/std_cisco_nxos_switched/expected_port_channel.cfg +++ b/tests/test_cases/std_cisco_nxos_switched/expected_port_channel.cfg @@ -4,7 +4,7 @@ interface port-channel50 description P2P_IBGP no switchport - ip address 100.71.85.17 + ip address 10.1.1.17 logging event port link-status mtu 9216 no shutdown diff --git a/tests/test_cases/std_cisco_nxos_switched/expected_system.cfg b/tests/test_cases/std_cisco_nxos_switched/expected_system.cfg index 37cade1..cc3eb8f 100644 --- a/tests/test_cases/std_cisco_nxos_switched/expected_system.cfg +++ b/tests/test_cases/std_cisco_nxos_switched/expected_system.cfg @@ -1,14 +1,14 @@ ! system.j2 -! Name: s46-r21-93180hl-24-1a +! Name: tor-1a ! Make: cisco ! Model: 93180yc-fx -hostname s46-r21-93180hl-24-1a +hostname tor-1a banner motd # NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE -hostname s46-r21-93180hl-24-1a +hostname tor-1a Unauthorized access and/or use prohibited. All access and/or use subject to monitoring. diff --git a/tests/test_cases/std_cisco_nxos_switched/expected_vlan.cfg b/tests/test_cases/std_cisco_nxos_switched/expected_vlan.cfg index 3458aba..efbc69f 100644 --- a/tests/test_cases/std_cisco_nxos_switched/expected_vlan.cfg +++ b/tests/test_cases/std_cisco_nxos_switched/expected_vlan.cfg @@ -84,187 +84,187 @@ interface vlan6 description HNVPA_6 mtu 9216 no shutdown - ip address 100.71.131.2/25 + ip address 10.2.1.2/25 no ip redirects no ipv6 redirects hsrp version 2 hsrp 6 priority 150 - ip 100.71.131.1 + ip 10.2.1.1 interface vlan7 description Infra_7 mtu 9216 no shutdown - ip address 100.69.176.2/24 + ip address 10.3.1.2/24 no ip redirects no ipv6 redirects hsrp version 2 hsrp 7 priority 150 - ip 100.69.176.1 + ip 10.3.1.1 interface vlan125 description BMC_Mgmt_125 mtu 9216 no shutdown - ip address 100.71.85.123/26 + ip address 10.1.1.123/26 no ip redirects no ipv6 redirects hsrp version 2 hsrp 125 priority 150 - ip 100.71.85.65 + ip 10.1.1.65 interface vlan201 description Tenant_201 mtu 9216 no shutdown - ip address 100.69.177.2/24 + ip address 10.4.1.2/24 no ip redirects no ipv6 redirects hsrp version 2 hsrp 201 priority 150 - ip 100.69.177.1 + ip 10.4.1.1 interface vlan301 description LogicalTenant_301 mtu 9216 no shutdown - ip address 100.69.178.2/25 + ip address 10.5.2.2/25 no ip redirects no ipv6 redirects hsrp version 2 hsrp 301 priority 150 - ip 100.69.178.1 + ip 10.5.2.1 interface vlan401 description DhcpTenant_401 mtu 9216 no shutdown - ip address 100.69.178.130/25 + ip address 10.5.2.130/25 no ip redirects no ipv6 redirects hsrp version 2 hsrp 401 priority 150 - ip 100.69.178.129 + ip 10.5.2.129 interface vlan501 description L3forward_501 mtu 9216 no shutdown - ip address 100.69.179.2/28 + ip address 10.5.1.2/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 501 priority 150 - ip 100.69.179.1 + ip 10.5.1.1 interface vlan502 description L3forward_502 mtu 9216 no shutdown - ip address 100.69.179.18/28 + ip address 10.5.1.18/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 502 priority 150 - ip 100.69.179.17 + ip 10.5.1.17 interface vlan503 description L3forward_503 mtu 9216 no shutdown - ip address 100.69.179.34/28 + ip address 10.5.1.34/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 503 priority 150 - ip 100.69.179.33 + ip 10.5.1.33 interface vlan504 description L3forward_504 mtu 9216 no shutdown - ip address 100.69.179.50/28 + ip address 10.5.1.50/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 504 priority 150 - ip 100.69.179.49 + ip 10.5.1.49 interface vlan505 description L3forward_505 mtu 9216 no shutdown - ip address 100.69.179.66/28 + ip address 10.5.1.66/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 505 priority 150 - ip 100.69.179.65 + ip 10.5.1.65 interface vlan506 description L3forward_506 mtu 9216 no shutdown - ip address 100.69.179.82/28 + ip address 10.5.1.82/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 506 priority 150 - ip 100.69.179.81 + ip 10.5.1.81 interface vlan507 description L3forward_507 mtu 9216 no shutdown - ip address 100.69.179.98/28 + ip address 10.5.1.98/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 507 priority 150 - ip 100.69.179.97 + ip 10.5.1.97 interface vlan508 description L3forward_508 mtu 9216 no shutdown - ip address 100.69.179.114/28 + ip address 10.5.1.114/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 508 priority 150 - ip 100.69.179.113 + ip 10.5.1.113 interface vlan509 description L3forward_509 mtu 9216 no shutdown - ip address 100.69.179.130/28 + ip address 10.5.1.130/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 509 priority 150 - ip 100.69.179.129 + ip 10.5.1.129 interface vlan510 description L3forward_510 mtu 9216 no shutdown - ip address 100.69.179.145/28 + ip address 10.5.1.145/28 no ip redirects no ipv6 redirects hsrp version 2 @@ -276,71 +276,71 @@ interface vlan511 description L3forward_511 mtu 9216 no shutdown - ip address 100.69.179.162/28 + ip address 10.5.1.162/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 511 priority 150 - ip 100.69.179.161 + ip 10.5.1.161 interface vlan512 description L3forward_512 mtu 9216 no shutdown - ip address 100.69.179.178/28 + ip address 10.5.1.178/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 512 priority 150 - ip 100.69.179.177 + ip 10.5.1.177 interface vlan513 description L3forward_513 mtu 9216 no shutdown - ip address 100.69.179.194/28 + ip address 10.5.1.194/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 513 priority 150 - ip 100.69.179.193 + ip 10.5.1.193 interface vlan514 description L3forward_514 mtu 9216 no shutdown - ip address 100.69.179.210/28 + ip address 10.5.1.210/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 514 priority 150 - ip 100.69.179.209 + ip 10.5.1.209 interface vlan515 description L3forward_515 mtu 9216 no shutdown - ip address 100.69.179.226/28 + ip address 10.5.1.226/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 515 priority 150 - ip 100.69.179.225 + ip 10.5.1.225 interface vlan516 description L3forward_516 mtu 9216 no shutdown - ip address 100.69.179.242/28 + ip address 10.5.1.242/28 no ip redirects no ipv6 redirects hsrp version 2 hsrp 516 priority 150 - ip 100.69.179.241 + ip 10.5.1.241 diff --git a/tests/test_cases/std_cisco_nxos_switched/std_cisco_nxos_switched_input.json b/tests/test_cases/std_cisco_nxos_switched/std_cisco_nxos_switched_input.json index 719316b..7872976 100644 --- a/tests/test_cases/std_cisco_nxos_switched/std_cisco_nxos_switched_input.json +++ b/tests/test_cases/std_cisco_nxos_switched/std_cisco_nxos_switched_input.json @@ -3,7 +3,7 @@ "make": "cisco", "model": "93180yc-fx", "type": "TOR1", - "hostname": "s46-r21-93180hl-24-1a", + "hostname": "tor-1a", "version": "9.3(11)", "firmware": "nxos" }, @@ -17,14 +17,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.71.131.2", + "ip": "10.2.1.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 6, "priority": 150, - "virtual_ip": "100.71.131.1" + "virtual_ip": "10.2.1.1" } } }, @@ -32,14 +32,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.69.176.2", + "ip": "10.3.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 7, "priority": 150, - "virtual_ip": "100.69.176.1" + "virtual_ip": "10.3.1.1" } } }, @@ -51,14 +51,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.85.123", + "ip": "10.1.1.123", "cidr": 26, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 125, "priority": 150, - "virtual_ip": "100.71.85.65" + "virtual_ip": "10.1.1.65" } } }, @@ -66,14 +66,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.69.177.2", + "ip": "10.4.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 201, "priority": 150, - "virtual_ip": "100.69.177.1" + "virtual_ip": "10.4.1.1" } } }, @@ -81,14 +81,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.69.178.2", + "ip": "10.5.2.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 301, "priority": 150, - "virtual_ip": "100.69.178.1" + "virtual_ip": "10.5.2.1" } } }, @@ -96,14 +96,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.69.178.130", + "ip": "10.5.2.130", "cidr": 25, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 401, "priority": 150, - "virtual_ip": "100.69.178.129" + "virtual_ip": "10.5.2.129" } } }, @@ -111,14 +111,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.69.179.2", + "ip": "10.5.1.2", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 501, "priority": 150, - "virtual_ip": "100.69.179.1" + "virtual_ip": "10.5.1.1" } } }, @@ -126,14 +126,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.69.179.18", + "ip": "10.5.1.18", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 502, "priority": 150, - "virtual_ip": "100.69.179.17" + "virtual_ip": "10.5.1.17" } } }, @@ -141,14 +141,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.69.179.34", + "ip": "10.5.1.34", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 503, "priority": 150, - "virtual_ip": "100.69.179.33" + "virtual_ip": "10.5.1.33" } } }, @@ -156,14 +156,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.69.179.50", + "ip": "10.5.1.50", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 504, "priority": 150, - "virtual_ip": "100.69.179.49" + "virtual_ip": "10.5.1.49" } } }, @@ -171,14 +171,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.69.179.66", + "ip": "10.5.1.66", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 505, "priority": 150, - "virtual_ip": "100.69.179.65" + "virtual_ip": "10.5.1.65" } } }, @@ -186,14 +186,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.69.179.82", + "ip": "10.5.1.82", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 506, "priority": 150, - "virtual_ip": "100.69.179.81" + "virtual_ip": "10.5.1.81" } } }, @@ -201,14 +201,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.69.179.98", + "ip": "10.5.1.98", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 507, "priority": 150, - "virtual_ip": "100.69.179.97" + "virtual_ip": "10.5.1.97" } } }, @@ -216,14 +216,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.69.179.114", + "ip": "10.5.1.114", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 508, "priority": 150, - "virtual_ip": "100.69.179.113" + "virtual_ip": "10.5.1.113" } } }, @@ -231,14 +231,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.69.179.130", + "ip": "10.5.1.130", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 509, "priority": 150, - "virtual_ip": "100.69.179.129" + "virtual_ip": "10.5.1.129" } } }, @@ -246,7 +246,7 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.69.179.145", + "ip": "10.5.1.145", "cidr": 28, "mtu": 9216, "redundancy": { @@ -261,14 +261,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.69.179.162", + "ip": "10.5.1.162", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 511, "priority": 150, - "virtual_ip": "100.69.179.161" + "virtual_ip": "10.5.1.161" } } }, @@ -276,14 +276,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.69.179.178", + "ip": "10.5.1.178", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 512, "priority": 150, - "virtual_ip": "100.69.179.177" + "virtual_ip": "10.5.1.177" } } }, @@ -291,14 +291,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.69.179.194", + "ip": "10.5.1.194", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 513, "priority": 150, - "virtual_ip": "100.69.179.193" + "virtual_ip": "10.5.1.193" } } }, @@ -306,14 +306,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.69.179.210", + "ip": "10.5.1.210", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 514, "priority": 150, - "virtual_ip": "100.69.179.209" + "virtual_ip": "10.5.1.209" } } }, @@ -321,14 +321,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.69.179.226", + "ip": "10.5.1.226", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 515, "priority": 150, - "virtual_ip": "100.69.179.225" + "virtual_ip": "10.5.1.225" } } }, @@ -336,14 +336,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.69.179.242", + "ip": "10.5.1.242", "cidr": 28, "mtu": 9216, "redundancy": { "type": "hsrp", "group": 516, "priority": 150, - "virtual_ip": "100.69.179.241" + "virtual_ip": "10.5.1.241" } } }, @@ -372,21 +372,21 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.71.85.21/32" + "ipv4": "10.1.1.21/32" }, { "name": "P2P_Border1", "type": "L3", "intf_type": "Ethernet", "intf": "1/48", - "ipv4": "100.71.85.2/30" + "ipv4": "10.1.1.2/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/47", - "ipv4": "100.71.85.10/30" + "ipv4": "10.1.1.10/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -423,7 +423,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.71.85.17", + "ipv4": "10.1.1.17", "members": [ "1/41", "1/42" @@ -443,34 +443,34 @@ ], "bgp": { "asn": 65242, - "router_id": "100.71.85.21", + "router_id": "10.1.1.21", "networks": [ - "100.71.85.2/30", - "100.71.85.10/30", - "100.71.85.21/32", - "100.69.177.0/24", - "100.69.178.0/25", - "100.69.178.128/25", - "100.69.179.0/28", - "100.69.179.16/28", - "100.69.179.32/28", - "100.69.179.48/28", - "100.69.179.64/28", - "100.69.179.80/28", - "100.69.179.96/28", - "100.69.179.112/28", - "100.69.179.128/28", - "100.69.179.144/28", - "100.69.179.160/28", - "100.69.179.176/28", - "100.69.179.192/28", - "100.69.179.208/28", - "100.69.179.224/28", - "100.69.179.240/28" + "10.1.1.2/30", + "10.1.1.10/30", + "10.1.1.21/32", + "10.4.1.0/24", + "10.5.2.0/25", + "10.5.2.128/25", + "10.5.1.0/28", + "10.5.1.16/28", + "10.5.1.32/28", + "10.5.1.48/28", + "10.5.1.64/28", + "10.5.1.80/28", + "10.5.1.96/28", + "10.5.1.112/28", + "10.5.1.128/28", + "10.5.1.144/28", + "10.5.1.160/28", + "10.5.1.176/28", + "10.5.1.192/28", + "10.5.1.208/28", + "10.5.1.224/28", + "10.5.1.240/28" ], "neighbors": [ { - "ip": "100.71.85.1", + "ip": "10.1.1.1", "description": "TO_Border1", "remote_as": 64846, "af_ipv4_unicast": { @@ -478,7 +478,7 @@ } }, { - "ip": "100.71.85.9", + "ip": "10.1.1.9", "description": "TO_Border2", "remote_as": 64846, "af_ipv4_unicast": { @@ -486,13 +486,13 @@ } }, { - "ip": "100.71.85.18", + "ip": "10.1.1.18", "description": "iBGP_PEER", "remote_as": 65242, "af_ipv4_unicast": {} }, { - "ip": "100.71.131.0/25", + "ip": "10.2.1.0/25", "description": "TO_HNVPA", "remote_as": 65112, "update_source": "Loopback0", diff --git a/tests/test_cases/std_dell_os10_fc/expected_bgp.cfg b/tests/test_cases/std_dell_os10_fc/expected_bgp.cfg index 42ce0ca..36e0aea 100644 --- a/tests/test_cases/std_dell_os10_fc/expected_bgp.cfg +++ b/tests/test_cases/std_dell_os10_fc/expected_bgp.cfg @@ -1,36 +1,36 @@ ! bgp.j2 router bgp 64556 - router-id 100.71.12.21 + router-id 10.21.1.21 bestpath as-path multipath-relax log-neighbor-changes maximum-paths ibgp 8 maximum-paths ebgp 8 address-family ipv4 unicast - network 100.71.12.2/30 - network 100.71.12.10/30 - network 100.71.12.21/32 - network 100.68.149.0/24 - network 100.68.150.0/25 - network 100.68.150.128/25 - network 100.68.151.0/28 - network 100.68.151.16/28 - network 100.68.151.32/28 - network 100.68.151.48/28 - network 100.68.151.64/28 - network 100.68.151.80/28 - network 100.68.151.96/28 - network 100.68.151.112/28 - network 100.68.151.128/28 - network 100.68.151.144/28 - network 100.68.151.160/28 - network 100.68.151.176/28 - network 100.68.151.192/28 - network 100.68.151.208/28 - network 100.68.151.224/28 - network 100.68.151.240/28 + network 10.21.1.2/30 + network 10.21.1.10/30 + network 10.21.1.21/32 + network 10.24.1.0/24 + network 10.24.150.0/25 + network 10.24.150.128/25 + network 10.25.1.0/28 + network 10.25.1.16/28 + network 10.25.1.32/28 + network 10.25.1.48/28 + network 10.25.1.64/28 + network 10.25.1.80/28 + network 10.25.1.96/28 + network 10.25.1.112/28 + network 10.25.1.128/28 + network 10.25.1.144/28 + network 10.25.1.160/28 + network 10.25.1.176/28 + network 10.25.1.192/28 + network 10.25.1.208/28 + network 10.25.1.224/28 + network 10.25.1.240/28 - neighbor 100.71.12.1 + neighbor 10.21.1.1 description TO_Border1 remote-as 64846 no shutdown @@ -39,7 +39,7 @@ router bgp 64556 prefix-list DefaultRoute in next-hop-self - neighbor 100.71.12.9 + neighbor 10.21.1.9 description TO_Border2 remote-as 64846 no shutdown @@ -48,7 +48,7 @@ router bgp 64556 prefix-list DefaultRoute in next-hop-self - neighbor 100.71.12.18 + neighbor 10.21.1.18 description iBGP_PEER remote-as 64556 no shutdown @@ -58,7 +58,7 @@ router bgp 64556 template TO_TO_HNVPA ebgp-multihop 3 - listen 100.71.143.0/25 limit 5 + listen 10.22.1.0/25 limit 5 remote-as 65018 update-source Loopback0 diff --git a/tests/test_cases/std_dell_os10_fc/expected_full_config.cfg b/tests/test_cases/std_dell_os10_fc/expected_full_config.cfg index 5c6f3fc..87a8dd9 100644 --- a/tests/test_cases/std_dell_os10_fc/expected_full_config.cfg +++ b/tests/test_cases/std_dell_os10_fc/expected_full_config.cfg @@ -1,13 +1,13 @@ ! system.j2 - hostname -! Name: s46-r06-5248hl-6-1a +! Name: tor-1a ! Make: dellemc ! Model: s5248f-on -hostname s46-r06-5248hl-6-1a +hostname tor-1a banner motd # NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE -hostname s46-r06-5248hl-6-1a +hostname tor-1a Unauthorized access and/or use prohibited. All access and/or use subject to monitoring. @@ -156,19 +156,19 @@ interface vlan6 description HNVPA_6 mtu 9216 no shutdown - ip address 100.71.143.2/25 + ip address 10.22.1.2/25 vrrp-group 6 priority 150 - virtual-address 100.71.143.1 + virtual-address 10.22.1.1 no preempt interface vlan7 description Infra_7 mtu 9216 no shutdown - ip address 100.68.148.2/24 + ip address 10.23.1.2/24 vrrp-group 7 priority 150 - virtual-address 100.68.148.1 + virtual-address 10.23.1.1 no preempt interface vlan99 description NativeVlan @@ -177,181 +177,181 @@ interface vlan125 description BMC_Mgmt_125 mtu 9216 no shutdown - ip address 100.71.12.123/26 + ip address 10.21.1.123/26 vrrp-group 125 priority 150 - virtual-address 100.71.12.65 + virtual-address 10.21.1.65 no preempt interface vlan201 description Tenant_201 mtu 9216 no shutdown - ip address 100.68.149.2/24 + ip address 10.24.1.2/24 vrrp-group 201 priority 150 - virtual-address 100.68.149.1 + virtual-address 10.24.1.1 no preempt interface vlan301 description LogicalTenant_301 mtu 9216 no shutdown - ip address 100.68.150.2/25 + ip address 10.24.150.2/25 vrrp-group 301 priority 150 - virtual-address 100.68.150.1 + virtual-address 10.24.150.1 no preempt interface vlan401 description DhcpTenant_401 mtu 9216 no shutdown - ip address 100.68.150.130/25 + ip address 10.24.150.130/25 vrrp-group 401 priority 150 - virtual-address 100.68.150.129 + virtual-address 10.24.150.129 no preempt interface vlan501 description L3forward_501 mtu 9216 no shutdown - ip address 100.68.151.2/28 + ip address 10.25.1.2/28 vrrp-group 501 priority 150 - virtual-address 100.68.151.1 + virtual-address 10.25.1.1 no preempt interface vlan502 description L3forward_502 mtu 9216 no shutdown - ip address 100.68.151.18/28 + ip address 10.25.1.18/28 vrrp-group 502 priority 150 - virtual-address 100.68.151.17 + virtual-address 10.25.1.17 no preempt interface vlan503 description L3forward_503 mtu 9216 no shutdown - ip address 100.68.151.34/28 + ip address 10.25.1.34/28 vrrp-group 503 priority 150 - virtual-address 100.68.151.33 + virtual-address 10.25.1.33 no preempt interface vlan504 description L3forward_504 mtu 9216 no shutdown - ip address 100.68.151.50/28 + ip address 10.25.1.50/28 vrrp-group 504 priority 150 - virtual-address 100.68.151.49 + virtual-address 10.25.1.49 no preempt interface vlan505 description L3forward_505 mtu 9216 no shutdown - ip address 100.68.151.66/28 + ip address 10.25.1.66/28 vrrp-group 505 priority 150 - virtual-address 100.68.151.65 + virtual-address 10.25.1.65 no preempt interface vlan506 description L3forward_506 mtu 9216 no shutdown - ip address 100.68.151.82/28 + ip address 10.25.1.82/28 vrrp-group 506 priority 150 - virtual-address 100.68.151.81 + virtual-address 10.25.1.81 no preempt interface vlan507 description L3forward_507 mtu 9216 no shutdown - ip address 100.68.151.98/28 + ip address 10.25.1.98/28 vrrp-group 507 priority 150 - virtual-address 100.68.151.97 + virtual-address 10.25.1.97 no preempt interface vlan508 description L3forward_508 mtu 9216 no shutdown - ip address 100.68.151.114/28 + ip address 10.25.1.114/28 vrrp-group 508 priority 150 - virtual-address 100.68.151.113 + virtual-address 10.25.1.113 no preempt interface vlan509 description L3forward_509 mtu 9216 no shutdown - ip address 100.68.151.130/28 + ip address 10.25.1.130/28 vrrp-group 509 priority 150 - virtual-address 100.68.151.129 + virtual-address 10.25.1.129 no preempt interface vlan510 description L3forward_510 mtu 9216 no shutdown - ip address 100.68.151.145/28 + ip address 10.25.1.145/28 vrrp-group 510 priority 150 - virtual-address 10.69.179.145 + virtual-address 10.5.1.145 no preempt interface vlan511 description L3forward_511 mtu 9216 no shutdown - ip address 100.68.151.162/28 + ip address 10.25.1.162/28 vrrp-group 511 priority 150 - virtual-address 100.68.151.161 + virtual-address 10.25.1.161 no preempt interface vlan512 description L3forward_512 mtu 9216 no shutdown - ip address 100.68.151.178/28 + ip address 10.25.1.178/28 vrrp-group 512 priority 150 - virtual-address 100.68.151.177 + virtual-address 10.25.1.177 no preempt interface vlan513 description L3forward_513 mtu 9216 no shutdown - ip address 100.68.151.194/28 + ip address 10.25.1.194/28 vrrp-group 513 priority 150 - virtual-address 100.68.151.193 + virtual-address 10.25.1.193 no preempt interface vlan514 description L3forward_514 mtu 9216 no shutdown - ip address 100.68.151.210/28 + ip address 10.25.1.210/28 vrrp-group 514 priority 150 - virtual-address 100.68.151.209 + virtual-address 10.25.1.209 no preempt interface vlan515 description L3forward_515 mtu 9216 no shutdown - ip address 100.68.151.226/28 + ip address 10.25.1.226/28 vrrp-group 515 priority 150 - virtual-address 100.68.151.225 + virtual-address 10.25.1.225 no preempt interface vlan516 description L3forward_516 mtu 9216 no shutdown - ip address 100.68.151.242/28 + ip address 10.25.1.242/28 vrrp-group 516 priority 150 - virtual-address 100.68.151.241 + virtual-address 10.25.1.241 no preempt interface vlan711 description Storage_711_TOR1 @@ -398,21 +398,21 @@ interface range Ethernet 1/1/1-1/1/18 interface Ethernet 1/1/48 description P2P_Border1 no switchport - ip address 100.71.12.2/30 + ip address 10.21.1.2/30 mtu 9216 no shutdown interface Ethernet 1/1/47 description P2P_Border2 no switchport - ip address 100.71.12.10/30 + ip address 10.21.1.10/30 mtu 9216 no shutdown interface loopbackloopback0 description Loopback0 - ip address 100.71.12.21/32 + ip address 10.21.1.21/32 mtu 9216 no shutdown @@ -425,7 +425,7 @@ interface port-channel50 no shutdown no switchport mtu 9216 - ip address 100.71.12.17/30 + ip address 10.21.1.17/30 interface Ethernet 1/1/39 @@ -519,36 +519,36 @@ ip prefix-list DefaultRoute seq 50 deny 0.0.0.0/0 le 32 ! bgp.j2 router bgp 64556 - router-id 100.71.12.21 + router-id 10.21.1.21 bestpath as-path multipath-relax log-neighbor-changes maximum-paths ibgp 8 maximum-paths ebgp 8 address-family ipv4 unicast - network 100.71.12.2/30 - network 100.71.12.10/30 - network 100.71.12.21/32 - network 100.68.149.0/24 - network 100.68.150.0/25 - network 100.68.150.128/25 - network 100.68.151.0/28 - network 100.68.151.16/28 - network 100.68.151.32/28 - network 100.68.151.48/28 - network 100.68.151.64/28 - network 100.68.151.80/28 - network 100.68.151.96/28 - network 100.68.151.112/28 - network 100.68.151.128/28 - network 100.68.151.144/28 - network 100.68.151.160/28 - network 100.68.151.176/28 - network 100.68.151.192/28 - network 100.68.151.208/28 - network 100.68.151.224/28 - network 100.68.151.240/28 + network 10.21.1.2/30 + network 10.21.1.10/30 + network 10.21.1.21/32 + network 10.24.1.0/24 + network 10.24.150.0/25 + network 10.24.150.128/25 + network 10.25.1.0/28 + network 10.25.1.16/28 + network 10.25.1.32/28 + network 10.25.1.48/28 + network 10.25.1.64/28 + network 10.25.1.80/28 + network 10.25.1.96/28 + network 10.25.1.112/28 + network 10.25.1.128/28 + network 10.25.1.144/28 + network 10.25.1.160/28 + network 10.25.1.176/28 + network 10.25.1.192/28 + network 10.25.1.208/28 + network 10.25.1.224/28 + network 10.25.1.240/28 - neighbor 100.71.12.1 + neighbor 10.21.1.1 description TO_Border1 remote-as 64846 no shutdown @@ -557,7 +557,7 @@ router bgp 64556 prefix-list DefaultRoute in next-hop-self - neighbor 100.71.12.9 + neighbor 10.21.1.9 description TO_Border2 remote-as 64846 no shutdown @@ -566,7 +566,7 @@ router bgp 64556 prefix-list DefaultRoute in next-hop-self - neighbor 100.71.12.18 + neighbor 10.21.1.18 description iBGP_PEER remote-as 64556 no shutdown @@ -576,7 +576,7 @@ router bgp 64556 template TO_TO_HNVPA ebgp-multihop 3 - listen 100.71.143.0/25 limit 5 + listen 10.22.1.0/25 limit 5 remote-as 65018 update-source Loopback0 diff --git a/tests/test_cases/std_dell_os10_fc/expected_interface.cfg b/tests/test_cases/std_dell_os10_fc/expected_interface.cfg index 128d2e4..2465172 100644 --- a/tests/test_cases/std_dell_os10_fc/expected_interface.cfg +++ b/tests/test_cases/std_dell_os10_fc/expected_interface.cfg @@ -36,21 +36,21 @@ interface range Ethernet 1/1/1-1/1/18 interface Ethernet 1/1/48 description P2P_Border1 no switchport - ip address 100.71.12.2/30 + ip address 10.21.1.2/30 mtu 9216 no shutdown interface Ethernet 1/1/47 description P2P_Border2 no switchport - ip address 100.71.12.10/30 + ip address 10.21.1.10/30 mtu 9216 no shutdown interface loopbackloopback0 description Loopback0 - ip address 100.71.12.21/32 + ip address 10.21.1.21/32 mtu 9216 no shutdown diff --git a/tests/test_cases/std_dell_os10_fc/expected_port_channel.cfg b/tests/test_cases/std_dell_os10_fc/expected_port_channel.cfg index b6f0ae2..6d16ef7 100644 --- a/tests/test_cases/std_dell_os10_fc/expected_port_channel.cfg +++ b/tests/test_cases/std_dell_os10_fc/expected_port_channel.cfg @@ -5,7 +5,7 @@ interface port-channel50 no shutdown no switchport mtu 9216 - ip address 100.71.12.17/30 + ip address 10.21.1.17/30 interface Ethernet 1/1/39 diff --git a/tests/test_cases/std_dell_os10_fc/expected_system.cfg b/tests/test_cases/std_dell_os10_fc/expected_system.cfg index 681fafe..3d9fae4 100644 --- a/tests/test_cases/std_dell_os10_fc/expected_system.cfg +++ b/tests/test_cases/std_dell_os10_fc/expected_system.cfg @@ -1,13 +1,13 @@ ! system.j2 - hostname -! Name: s46-r06-5248hl-6-1a +! Name: tor-1a ! Make: dellemc ! Model: s5248f-on -hostname s46-r06-5248hl-6-1a +hostname tor-1a banner motd # NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE -hostname s46-r06-5248hl-6-1a +hostname tor-1a Unauthorized access and/or use prohibited. All access and/or use subject to monitoring. diff --git a/tests/test_cases/std_dell_os10_fc/expected_vlan.cfg b/tests/test_cases/std_dell_os10_fc/expected_vlan.cfg index bd54e29..043e4e9 100644 --- a/tests/test_cases/std_dell_os10_fc/expected_vlan.cfg +++ b/tests/test_cases/std_dell_os10_fc/expected_vlan.cfg @@ -6,19 +6,19 @@ interface vlan6 description HNVPA_6 mtu 9216 no shutdown - ip address 100.71.143.2/25 + ip address 10.22.1.2/25 vrrp-group 6 priority 150 - virtual-address 100.71.143.1 + virtual-address 10.22.1.1 no preempt interface vlan7 description Infra_7 mtu 9216 no shutdown - ip address 100.68.148.2/24 + ip address 10.23.1.2/24 vrrp-group 7 priority 150 - virtual-address 100.68.148.1 + virtual-address 10.23.1.1 no preempt interface vlan99 description NativeVlan @@ -27,181 +27,181 @@ interface vlan125 description BMC_Mgmt_125 mtu 9216 no shutdown - ip address 100.71.12.123/26 + ip address 10.21.1.123/26 vrrp-group 125 priority 150 - virtual-address 100.71.12.65 + virtual-address 10.21.1.65 no preempt interface vlan201 description Tenant_201 mtu 9216 no shutdown - ip address 100.68.149.2/24 + ip address 10.24.1.2/24 vrrp-group 201 priority 150 - virtual-address 100.68.149.1 + virtual-address 10.24.1.1 no preempt interface vlan301 description LogicalTenant_301 mtu 9216 no shutdown - ip address 100.68.150.2/25 + ip address 10.24.150.2/25 vrrp-group 301 priority 150 - virtual-address 100.68.150.1 + virtual-address 10.24.150.1 no preempt interface vlan401 description DhcpTenant_401 mtu 9216 no shutdown - ip address 100.68.150.130/25 + ip address 10.24.150.130/25 vrrp-group 401 priority 150 - virtual-address 100.68.150.129 + virtual-address 10.24.150.129 no preempt interface vlan501 description L3forward_501 mtu 9216 no shutdown - ip address 100.68.151.2/28 + ip address 10.25.1.2/28 vrrp-group 501 priority 150 - virtual-address 100.68.151.1 + virtual-address 10.25.1.1 no preempt interface vlan502 description L3forward_502 mtu 9216 no shutdown - ip address 100.68.151.18/28 + ip address 10.25.1.18/28 vrrp-group 502 priority 150 - virtual-address 100.68.151.17 + virtual-address 10.25.1.17 no preempt interface vlan503 description L3forward_503 mtu 9216 no shutdown - ip address 100.68.151.34/28 + ip address 10.25.1.34/28 vrrp-group 503 priority 150 - virtual-address 100.68.151.33 + virtual-address 10.25.1.33 no preempt interface vlan504 description L3forward_504 mtu 9216 no shutdown - ip address 100.68.151.50/28 + ip address 10.25.1.50/28 vrrp-group 504 priority 150 - virtual-address 100.68.151.49 + virtual-address 10.25.1.49 no preempt interface vlan505 description L3forward_505 mtu 9216 no shutdown - ip address 100.68.151.66/28 + ip address 10.25.1.66/28 vrrp-group 505 priority 150 - virtual-address 100.68.151.65 + virtual-address 10.25.1.65 no preempt interface vlan506 description L3forward_506 mtu 9216 no shutdown - ip address 100.68.151.82/28 + ip address 10.25.1.82/28 vrrp-group 506 priority 150 - virtual-address 100.68.151.81 + virtual-address 10.25.1.81 no preempt interface vlan507 description L3forward_507 mtu 9216 no shutdown - ip address 100.68.151.98/28 + ip address 10.25.1.98/28 vrrp-group 507 priority 150 - virtual-address 100.68.151.97 + virtual-address 10.25.1.97 no preempt interface vlan508 description L3forward_508 mtu 9216 no shutdown - ip address 100.68.151.114/28 + ip address 10.25.1.114/28 vrrp-group 508 priority 150 - virtual-address 100.68.151.113 + virtual-address 10.25.1.113 no preempt interface vlan509 description L3forward_509 mtu 9216 no shutdown - ip address 100.68.151.130/28 + ip address 10.25.1.130/28 vrrp-group 509 priority 150 - virtual-address 100.68.151.129 + virtual-address 10.25.1.129 no preempt interface vlan510 description L3forward_510 mtu 9216 no shutdown - ip address 100.68.151.145/28 + ip address 10.25.1.145/28 vrrp-group 510 priority 150 - virtual-address 10.69.179.145 + virtual-address 10.5.1.145 no preempt interface vlan511 description L3forward_511 mtu 9216 no shutdown - ip address 100.68.151.162/28 + ip address 10.25.1.162/28 vrrp-group 511 priority 150 - virtual-address 100.68.151.161 + virtual-address 10.25.1.161 no preempt interface vlan512 description L3forward_512 mtu 9216 no shutdown - ip address 100.68.151.178/28 + ip address 10.25.1.178/28 vrrp-group 512 priority 150 - virtual-address 100.68.151.177 + virtual-address 10.25.1.177 no preempt interface vlan513 description L3forward_513 mtu 9216 no shutdown - ip address 100.68.151.194/28 + ip address 10.25.1.194/28 vrrp-group 513 priority 150 - virtual-address 100.68.151.193 + virtual-address 10.25.1.193 no preempt interface vlan514 description L3forward_514 mtu 9216 no shutdown - ip address 100.68.151.210/28 + ip address 10.25.1.210/28 vrrp-group 514 priority 150 - virtual-address 100.68.151.209 + virtual-address 10.25.1.209 no preempt interface vlan515 description L3forward_515 mtu 9216 no shutdown - ip address 100.68.151.226/28 + ip address 10.25.1.226/28 vrrp-group 515 priority 150 - virtual-address 100.68.151.225 + virtual-address 10.25.1.225 no preempt interface vlan516 description L3forward_516 mtu 9216 no shutdown - ip address 100.68.151.242/28 + ip address 10.25.1.242/28 vrrp-group 516 priority 150 - virtual-address 100.68.151.241 + virtual-address 10.25.1.241 no preempt interface vlan711 description Storage_711_TOR1 diff --git a/tests/test_cases/std_dell_os10_fc/std_dell_os10_fc_input.json b/tests/test_cases/std_dell_os10_fc/std_dell_os10_fc_input.json index 7b5e1bf..c5f74c1 100644 --- a/tests/test_cases/std_dell_os10_fc/std_dell_os10_fc_input.json +++ b/tests/test_cases/std_dell_os10_fc/std_dell_os10_fc_input.json @@ -3,7 +3,7 @@ "make": "dellemc", "model": "s5248f-on", "type": "TOR1", - "hostname": "s46-r06-5248hl-6-1a", + "hostname": "tor-1a", "version": "10.5.5.5", "firmware": "os10" }, @@ -17,14 +17,14 @@ "vlan_id": 6, "name": "HNVPA_6", "interface": { - "ip": "100.71.143.2", + "ip": "10.22.1.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 6, "priority": 150, - "virtual_ip": "100.71.143.1" + "virtual_ip": "10.22.1.1" } } }, @@ -32,14 +32,14 @@ "vlan_id": 7, "name": "Infra_7", "interface": { - "ip": "100.68.148.2", + "ip": "10.23.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 7, "priority": 150, - "virtual_ip": "100.68.148.1" + "virtual_ip": "10.23.1.1" } } }, @@ -51,14 +51,14 @@ "vlan_id": 125, "name": "BMC_Mgmt_125", "interface": { - "ip": "100.71.12.123", + "ip": "10.21.1.123", "cidr": 26, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 125, "priority": 150, - "virtual_ip": "100.71.12.65" + "virtual_ip": "10.21.1.65" } } }, @@ -66,14 +66,14 @@ "vlan_id": 201, "name": "Tenant_201", "interface": { - "ip": "100.68.149.2", + "ip": "10.24.1.2", "cidr": 24, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 201, "priority": 150, - "virtual_ip": "100.68.149.1" + "virtual_ip": "10.24.1.1" } } }, @@ -81,14 +81,14 @@ "vlan_id": 301, "name": "LogicalTenant_301", "interface": { - "ip": "100.68.150.2", + "ip": "10.24.150.2", "cidr": 25, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 301, "priority": 150, - "virtual_ip": "100.68.150.1" + "virtual_ip": "10.24.150.1" } } }, @@ -96,14 +96,14 @@ "vlan_id": 401, "name": "DhcpTenant_401", "interface": { - "ip": "100.68.150.130", + "ip": "10.24.150.130", "cidr": 25, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 401, "priority": 150, - "virtual_ip": "100.68.150.129" + "virtual_ip": "10.24.150.129" } } }, @@ -111,14 +111,14 @@ "vlan_id": 501, "name": "L3forward_501", "interface": { - "ip": "100.68.151.2", + "ip": "10.25.1.2", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 501, "priority": 150, - "virtual_ip": "100.68.151.1" + "virtual_ip": "10.25.1.1" } } }, @@ -126,14 +126,14 @@ "vlan_id": 502, "name": "L3forward_502", "interface": { - "ip": "100.68.151.18", + "ip": "10.25.1.18", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 502, "priority": 150, - "virtual_ip": "100.68.151.17" + "virtual_ip": "10.25.1.17" } } }, @@ -141,14 +141,14 @@ "vlan_id": 503, "name": "L3forward_503", "interface": { - "ip": "100.68.151.34", + "ip": "10.25.1.34", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 503, "priority": 150, - "virtual_ip": "100.68.151.33" + "virtual_ip": "10.25.1.33" } } }, @@ -156,14 +156,14 @@ "vlan_id": 504, "name": "L3forward_504", "interface": { - "ip": "100.68.151.50", + "ip": "10.25.1.50", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 504, "priority": 150, - "virtual_ip": "100.68.151.49" + "virtual_ip": "10.25.1.49" } } }, @@ -171,14 +171,14 @@ "vlan_id": 505, "name": "L3forward_505", "interface": { - "ip": "100.68.151.66", + "ip": "10.25.1.66", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 505, "priority": 150, - "virtual_ip": "100.68.151.65" + "virtual_ip": "10.25.1.65" } } }, @@ -186,14 +186,14 @@ "vlan_id": 506, "name": "L3forward_506", "interface": { - "ip": "100.68.151.82", + "ip": "10.25.1.82", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 506, "priority": 150, - "virtual_ip": "100.68.151.81" + "virtual_ip": "10.25.1.81" } } }, @@ -201,14 +201,14 @@ "vlan_id": 507, "name": "L3forward_507", "interface": { - "ip": "100.68.151.98", + "ip": "10.25.1.98", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 507, "priority": 150, - "virtual_ip": "100.68.151.97" + "virtual_ip": "10.25.1.97" } } }, @@ -216,14 +216,14 @@ "vlan_id": 508, "name": "L3forward_508", "interface": { - "ip": "100.68.151.114", + "ip": "10.25.1.114", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 508, "priority": 150, - "virtual_ip": "100.68.151.113" + "virtual_ip": "10.25.1.113" } } }, @@ -231,14 +231,14 @@ "vlan_id": 509, "name": "L3forward_509", "interface": { - "ip": "100.68.151.130", + "ip": "10.25.1.130", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 509, "priority": 150, - "virtual_ip": "100.68.151.129" + "virtual_ip": "10.25.1.129" } } }, @@ -246,14 +246,14 @@ "vlan_id": 510, "name": "L3forward_510", "interface": { - "ip": "100.68.151.145", + "ip": "10.25.1.145", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 510, "priority": 150, - "virtual_ip": "10.69.179.145" + "virtual_ip": "10.5.1.145" } } }, @@ -261,14 +261,14 @@ "vlan_id": 511, "name": "L3forward_511", "interface": { - "ip": "100.68.151.162", + "ip": "10.25.1.162", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 511, "priority": 150, - "virtual_ip": "100.68.151.161" + "virtual_ip": "10.25.1.161" } } }, @@ -276,14 +276,14 @@ "vlan_id": 512, "name": "L3forward_512", "interface": { - "ip": "100.68.151.178", + "ip": "10.25.1.178", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 512, "priority": 150, - "virtual_ip": "100.68.151.177" + "virtual_ip": "10.25.1.177" } } }, @@ -291,14 +291,14 @@ "vlan_id": 513, "name": "L3forward_513", "interface": { - "ip": "100.68.151.194", + "ip": "10.25.1.194", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 513, "priority": 150, - "virtual_ip": "100.68.151.193" + "virtual_ip": "10.25.1.193" } } }, @@ -306,14 +306,14 @@ "vlan_id": 514, "name": "L3forward_514", "interface": { - "ip": "100.68.151.210", + "ip": "10.25.1.210", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 514, "priority": 150, - "virtual_ip": "100.68.151.209" + "virtual_ip": "10.25.1.209" } } }, @@ -321,14 +321,14 @@ "vlan_id": 515, "name": "L3forward_515", "interface": { - "ip": "100.68.151.226", + "ip": "10.25.1.226", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 515, "priority": 150, - "virtual_ip": "100.68.151.225" + "virtual_ip": "10.25.1.225" } } }, @@ -336,14 +336,14 @@ "vlan_id": 516, "name": "L3forward_516", "interface": { - "ip": "100.68.151.242", + "ip": "10.25.1.242", "cidr": 28, "mtu": 9216, "redundancy": { "type": "vrrp", "group": 516, "priority": 150, - "virtual_ip": "100.68.151.241" + "virtual_ip": "10.25.1.241" } } }, @@ -372,21 +372,21 @@ "type": "L3", "intf_type": "loopback", "intf": "loopback0", - "ipv4": "100.71.12.21/32" + "ipv4": "10.21.1.21/32" }, { "name": "P2P_Border1", "type": "L3", "intf_type": "Ethernet", "intf": "1/1/48", - "ipv4": "100.71.12.2/30" + "ipv4": "10.21.1.2/30" }, { "name": "P2P_Border2", "type": "L3", "intf_type": "Ethernet", "intf": "1/1/47", - "ipv4": "100.71.12.10/30" + "ipv4": "10.21.1.10/30" }, { "name": "Trunk_TO_BMC_SWITCH", @@ -414,7 +414,7 @@ "id": 50, "description": "P2P_IBGP", "type": "L3", - "ipv4": "100.71.12.17", + "ipv4": "10.21.1.17", "members": [ "1/1/39", "1/1/40" @@ -436,34 +436,34 @@ ], "bgp": { "asn": 64556, - "router_id": "100.71.12.21", + "router_id": "10.21.1.21", "networks": [ - "100.71.12.2/30", - "100.71.12.10/30", - "100.71.12.21/32", - "100.68.149.0/24", - "100.68.150.0/25", - "100.68.150.128/25", - "100.68.151.0/28", - "100.68.151.16/28", - "100.68.151.32/28", - "100.68.151.48/28", - "100.68.151.64/28", - "100.68.151.80/28", - "100.68.151.96/28", - "100.68.151.112/28", - "100.68.151.128/28", - "100.68.151.144/28", - "100.68.151.160/28", - "100.68.151.176/28", - "100.68.151.192/28", - "100.68.151.208/28", - "100.68.151.224/28", - "100.68.151.240/28" + "10.21.1.2/30", + "10.21.1.10/30", + "10.21.1.21/32", + "10.24.1.0/24", + "10.24.150.0/25", + "10.24.150.128/25", + "10.25.1.0/28", + "10.25.1.16/28", + "10.25.1.32/28", + "10.25.1.48/28", + "10.25.1.64/28", + "10.25.1.80/28", + "10.25.1.96/28", + "10.25.1.112/28", + "10.25.1.128/28", + "10.25.1.144/28", + "10.25.1.160/28", + "10.25.1.176/28", + "10.25.1.192/28", + "10.25.1.208/28", + "10.25.1.224/28", + "10.25.1.240/28" ], "neighbors": [ { - "ip": "100.71.12.1", + "ip": "10.21.1.1", "description": "TO_Border1", "remote_as": 64846, "af_ipv4_unicast": { @@ -471,7 +471,7 @@ } }, { - "ip": "100.71.12.9", + "ip": "10.21.1.9", "description": "TO_Border2", "remote_as": 64846, "af_ipv4_unicast": { @@ -479,13 +479,13 @@ } }, { - "ip": "100.71.12.18", + "ip": "10.21.1.18", "description": "iBGP_PEER", "remote_as": 64556, "af_ipv4_unicast": {} }, { - "ip": "100.71.143.0/25", + "ip": "10.22.1.0/25", "description": "TO_HNVPA", "remote_as": 65018, "update_source": "Loopback0", diff --git a/tests/test_unit.py b/tests/test_unit.py index 3095e61..148195d 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -1,23 +1,30 @@ -"""Unit tests for src/constants.py, src/utils.py, src/loader.py, and BMC converter.""" +""" +Unit tests for the config-generator core modules. + +Organized by module under test: + 1. Utility functions — infer_firmware, classify_vlan_group + 2. Loader — load_input_json, get_real_path + 3. Constants — sanity checks on shared config values + 4. BMC Converter — switch_info, vlans, interfaces, port_channels, static_routes + +All test data uses generic/sanitized values — no lab-specific identifiers. +""" from __future__ import annotations -import json import sys from pathlib import Path import pytest ROOT_DIR = Path(__file__).resolve().parent.parent -SRC_PATH = ROOT_DIR / "src" if str(ROOT_DIR) not in sys.path: sys.path.insert(0, str(ROOT_DIR)) from src.constants import ( - CISCO, DELL, NXOS, OS10, TOR1, TOR2, BMC, - VLAN_GROUP_MAP, VENDOR_FIRMWARE_MAP, - TOR_SWITCH_TYPES, BMC_HARDCODED_VLANS, BMC_RELEVANT_GROUPS, - JUMBO_MTU, DEFAULT_OUTPUT_DIR, + CISCO, DELL, TOR1, TOR2, + VENDOR_FIRMWARE_MAP, TOR_SWITCH_TYPES, + BMC_HARDCODED_VLANS, JUMBO_MTU, SWITCH_TEMPLATE, SVI_TEMPLATE, VLAN_TEMPLATE, ) from src.utils import infer_firmware, classify_vlan_group @@ -25,295 +32,301 @@ from src.convertors.convertors_bmc_switch_json import BMCSwitchConverter -# ── infer_firmware ──────────────────────────────────────────────────────── +# ═══════════════════════════════════════════════════════════════════════════ +# Fixtures & Factories +# ═══════════════════════════════════════════════════════════════════════════ -class TestInferFirmware: - def test_cisco(self): - assert infer_firmware("cisco") == "nxos" +def _make_bmc_input(*, site="testsite", bmc_make="Cisco", bmc_model="9348GC-FXP", + bmc_hostname="test-bmc-1", bmc_firmware="10.4.5", + bmc_gateway="10.0.0.1", bmc_network="10.0.0.0", bmc_cidr=24, + bmc_vlan_id=125): + """Factory for creating minimal BMC switch input data. - def test_dell(self): - assert infer_firmware("dellemc") == "os10" + All values are generic — override keyword arguments to test specific scenarios. + """ + return { + "InputData": { + "MainEnvData": [{"Site": site}], + "Switches": [ + { + "Make": bmc_make, + "Model": bmc_model, + "Type": "BMC", + "Hostname": bmc_hostname, + "ASN": None, + "Firmware": bmc_firmware, + } + ], + "Supernets": [ + { + "GroupName": "BMC", + "Name": f"BMC_Mgmt_{bmc_vlan_id}", + "VLANID": bmc_vlan_id, + "IPv4": { + "SwitchSVI": True, + "Name": f"BMC_Mgmt_{bmc_vlan_id}", + "VLANID": bmc_vlan_id, + "Cidr": bmc_cidr, + "Network": bmc_network, + "Gateway": bmc_gateway, + }, + }, + { + "GroupName": "UNUSED_VLAN", + "Name": "UNUSED_VLAN", + "IPv4": {"Name": "UNUSED_VLAN", "VLANID": 2}, + }, + { + "GroupName": "NativeVlan", + "Name": "NativeVlan", + "IPv4": {"Name": "NativeVlan", "VLANID": 99}, + }, + ], + } + } - def test_cisco_uppercase(self): - assert infer_firmware("Cisco") == "nxos" - def test_unknown_vendor_passthrough(self): - assert infer_firmware("juniper") == "juniper" +@pytest.fixture +def bmc_converter(tmp_path): + """A BMCSwitchConverter initialised with default test input.""" + return BMCSwitchConverter(_make_bmc_input(), str(tmp_path)) - def test_empty_string(self): - assert infer_firmware("") == "" - def test_whitespace(self): - assert infer_firmware(" cisco ") == "nxos" +@pytest.fixture +def bmc_switch_data(): + """The switch dict from default BMC input (first Switches entry).""" + return _make_bmc_input()["InputData"]["Switches"][0] -# ── classify_vlan_group ────────────────────────────────────────────────── +# ═══════════════════════════════════════════════════════════════════════════ +# 1. Utility Functions +# ═══════════════════════════════════════════════════════════════════════════ -class TestClassifyVlanGroup: - @pytest.mark.parametrize("group_name,expected", [ - ("HNVPA_Pool1", "C"), - ("INFRA_Mgmt", "M"), - ("TENANT_1", "C"), - ("L3FORWARD_1", "C"), - ("STORAGE_A", "S"), - ("UNUSED_1", "UNUSED"), - ("NATIVE_1", "NATIVE"), +class TestInferFirmware: + """Maps vendor Make string to firmware identifier (e.g. 'cisco' -> 'nxos').""" + + @pytest.mark.parametrize("vendor, expected", [ + ("cisco", "nxos"), + ("Cisco", "nxos"), # case-insensitive + (" cisco ", "nxos"), # strips whitespace + ("dellemc", "os10"), ]) - def test_known_groups(self, group_name, expected): - assert classify_vlan_group(group_name) == expected + def test_known_vendors(self, vendor, expected): + assert infer_firmware(vendor) == expected - def test_case_insensitive(self): - assert classify_vlan_group("hnvpa_lower") == "C" + def test_unknown_vendor_returns_lowered(self): + assert infer_firmware("juniper") == "juniper" - def test_unknown_returns_none(self): - assert classify_vlan_group("RANDOM_STUFF") is None + def test_empty_string_returns_empty(self): + assert infer_firmware("") == "" - def test_empty_returns_none(self): - assert classify_vlan_group("") is None +class TestClassifyVlanGroup: + """Maps Supernet GroupName prefix to VLAN set symbol (C, M, S, etc.).""" + + @pytest.mark.parametrize("group_name, expected", [ + ("HNVPA_Pool1", "C"), + ("INFRA_Mgmt", "M"), + ("TENANT_1", "C"), + ("L3FORWARD_1", "C"), + ("STORAGE_A", "S"), + ("UNUSED_1", "UNUSED"), + ("NATIVE_1", "NATIVE"), + ("hnvpa_lower", "C"), # case-insensitive + ]) + def test_known_prefixes(self, group_name, expected): + assert classify_vlan_group(group_name) == expected -# ── load_input_json ────────────────────────────────────────────────────── + @pytest.mark.parametrize("group_name", ["RANDOM_STUFF", ""]) + def test_unknown_or_empty_returns_none(self, group_name): + assert classify_vlan_group(group_name) is None + + +# ═══════════════════════════════════════════════════════════════════════════ +# 2. Loader +# ═══════════════════════════════════════════════════════════════════════════ class TestLoadInputJson: - def test_valid_json(self, tmp_path): + """JSON file loading with validation.""" + + def test_loads_valid_json(self, tmp_path): f = tmp_path / "valid.json" f.write_text('{"a": 1}', encoding="utf-8") assert load_input_json(f) == {"a": 1} - def test_file_not_found(self, tmp_path): + def test_raises_on_missing_file(self, tmp_path): with pytest.raises(FileNotFoundError): load_input_json(tmp_path / "nope.json") - def test_invalid_json(self, tmp_path): + def test_raises_on_malformed_json(self, tmp_path): f = tmp_path / "bad.json" f.write_text("{not json", encoding="utf-8") with pytest.raises(ValueError, match="Failed to parse JSON"): load_input_json(f) -# ── get_real_path ──────────────────────────────────────────────────────── - class TestGetRealPath: - def test_resolves_relative(self): - result = get_real_path(Path("input")) - assert result.is_absolute() + """Path resolution, including PyInstaller frozen mode.""" + + def test_returns_absolute_path(self): + assert get_real_path(Path("input")).is_absolute() - def test_frozen_mode(self, monkeypatch): + def test_uses_meipass_when_frozen(self, monkeypatch): monkeypatch.setattr(sys, "frozen", True, raising=False) monkeypatch.setattr(sys, "_MEIPASS", "/fake/meipass", raising=False) - result = get_real_path(Path("input/templates")) - assert str(result) == "/fake/meipass/input/templates" + assert str(get_real_path(Path("input/templates"))) == "/fake/meipass/input/templates" -# ── constants sanity ───────────────────────────────────────────────────── +# ═══════════════════════════════════════════════════════════════════════════ +# 3. Constants +# ═══════════════════════════════════════════════════════════════════════════ class TestConstants: - def test_tor_switch_types(self): + """Verify constant definitions and template integrity.""" + + def test_tor_switch_types_includes_both(self): assert TOR_SWITCH_TYPES == [TOR1, TOR2] - def test_vendor_firmware_map_complete(self): + def test_vendor_firmware_map_covers_all_vendors(self): assert CISCO in VENDOR_FIRMWARE_MAP assert DELL in VENDOR_FIRMWARE_MAP - def test_bmc_hardcoded_vlans_structure(self): - assert len(BMC_HARDCODED_VLANS) >= 1 + def test_bmc_vlans_have_required_keys(self): for vlan in BMC_HARDCODED_VLANS: assert "vlan_id" in vlan assert "name" in vlan - def test_templates_not_mutated(self): - """Ensure template dicts haven't been accidentally modified.""" + def test_in_code_templates_are_pristine(self): + """Guard against accidental mutation of shared template dicts.""" assert SWITCH_TEMPLATE["make"] == "" assert SVI_TEMPLATE["ip"] == "" assert VLAN_TEMPLATE["vlan_id"] == 0 -# ── BMC converter ──────────────────────────────────────────────────────── - -def _make_bmc_input(*, site="testsite", bmc_make="Cisco", bmc_model="9348GC-FXP", - bmc_hostname="test-bmc-1", bmc_firmware="10.4.5", - bmc_gateway="10.0.0.1", bmc_network="10.0.0.0", bmc_cidr=24, - bmc_vlan_id=125): - """Helper to create a minimal lab input with BMC switch and supernets.""" - return { - "InputData": { - "MainEnvData": [{"Site": site}], - "Switches": [ - { - "Make": bmc_make, - "Model": bmc_model, - "Type": "BMC", - "Hostname": bmc_hostname, - "ASN": None, - "Firmware": bmc_firmware, - } - ], - "Supernets": [ - { - "GroupName": "BMC", - "Name": f"BMC_Mgmt_{bmc_vlan_id}", - "VLANID": bmc_vlan_id, - "IPv4": { - "SwitchSVI": True, - "Name": f"BMC_Mgmt_{bmc_vlan_id}", - "VLANID": bmc_vlan_id, - "Cidr": bmc_cidr, - "Network": bmc_network, - "Gateway": bmc_gateway, - }, - }, - { - "GroupName": "UNUSED_VLAN", - "Name": "UNUSED_VLAN", - "IPv4": {"Name": "UNUSED_VLAN", "VLANID": 2}, - }, - { - "GroupName": "NativeVlan", - "Name": "NativeVlan", - "IPv4": {"Name": "NativeVlan", "VLANID": 99}, - }, - ], - } - } - +# ═══════════════════════════════════════════════════════════════════════════ +# 4. BMC Converter +# ═══════════════════════════════════════════════════════════════════════════ class TestBMCSwitchInfo: - def test_site_from_main_env_data(self, tmp_path): - input_data = _make_bmc_input(site="lab42") - conv = BMCSwitchConverter(input_data, str(tmp_path)) - switch_data = input_data["InputData"]["Switches"][0] - info = conv._build_switch_info(switch_data) - assert info["site"] == "lab42" - - def test_site_empty_when_missing(self, tmp_path): - input_data = _make_bmc_input() - input_data["InputData"]["MainEnvData"] = [] - conv = BMCSwitchConverter(input_data, str(tmp_path)) - switch_data = input_data["InputData"]["Switches"][0] - info = conv._build_switch_info(switch_data) + """BMCSwitchConverter._build_switch_info — switch metadata extraction.""" + + def test_reads_site_from_main_env_data(self, tmp_path): + data = _make_bmc_input(site="site42") + conv = BMCSwitchConverter(data, str(tmp_path)) + info = conv._build_switch_info(data["InputData"]["Switches"][0]) + assert info["site"] == "site42" + + def test_site_defaults_to_empty_when_missing(self, tmp_path): + data = _make_bmc_input() + data["InputData"]["MainEnvData"] = [] + conv = BMCSwitchConverter(data, str(tmp_path)) + info = conv._build_switch_info(data["InputData"]["Switches"][0]) assert info["site"] == "" - def test_firmware_inferred(self, tmp_path): - input_data = _make_bmc_input(bmc_make="Cisco") - conv = BMCSwitchConverter(input_data, str(tmp_path)) - switch_data = input_data["InputData"]["Switches"][0] - info = conv._build_switch_info(switch_data) + def test_infers_firmware_from_make(self, bmc_converter, bmc_switch_data): + info = bmc_converter._build_switch_info(bmc_switch_data) assert info["firmware"] == "nxos" assert info["make"] == "cisco" - def test_hostname_lowered(self, tmp_path): - input_data = _make_bmc_input(bmc_hostname="TEST-BMC-Upper") - conv = BMCSwitchConverter(input_data, str(tmp_path)) - switch_data = input_data["InputData"]["Switches"][0] - info = conv._build_switch_info(switch_data) - assert info["hostname"] == "test-bmc-upper" + def test_lowercases_hostname(self, tmp_path): + data = _make_bmc_input(bmc_hostname="UPPER-BMC-1") + conv = BMCSwitchConverter(data, str(tmp_path)) + info = conv._build_switch_info(data["InputData"]["Switches"][0]) + assert info["hostname"] == "upper-bmc-1" class TestBMCVlans: - def test_hardcoded_vlans_always_present(self, tmp_path): - input_data = _make_bmc_input() - conv = BMCSwitchConverter(input_data, str(tmp_path)) - vlans = conv._build_vlans() - vlan_ids = {v["vlan_id"] for v in vlans} - assert 2 in vlan_ids - assert 99 in vlan_ids - - def test_bmc_vlan_from_supernet(self, tmp_path): - input_data = _make_bmc_input(bmc_vlan_id=125) - conv = BMCSwitchConverter(input_data, str(tmp_path)) - vlans = conv._build_vlans() + """BMCSwitchConverter._build_vlans — VLAN list construction.""" + + def test_always_includes_hardcoded_vlans(self, bmc_converter): + vlan_ids = {v["vlan_id"] for v in bmc_converter._build_vlans()} + assert {2, 99} <= vlan_ids + + def test_adds_bmc_vlan_from_supernet(self, bmc_converter): + vlans = bmc_converter._build_vlans() v125 = next((v for v in vlans if v["vlan_id"] == 125), None) assert v125 is not None assert v125["name"] == "BMC_Mgmt_125" - def test_bmc_svi_populated(self, tmp_path): - input_data = _make_bmc_input(bmc_gateway="10.0.0.1", bmc_network="10.0.0.0", - bmc_cidr=24, bmc_vlan_id=125) - conv = BMCSwitchConverter(input_data, str(tmp_path)) - vlans = conv._build_vlans() - v125 = next(v for v in vlans if v["vlan_id"] == 125) - assert "interface" in v125 + def test_populates_svi_on_bmc_vlan(self, tmp_path): + data = _make_bmc_input(bmc_gateway="10.0.0.1", bmc_network="10.0.0.0", bmc_cidr=24) + conv = BMCSwitchConverter(data, str(tmp_path)) + v125 = next(v for v in conv._build_vlans() if v["vlan_id"] == 125) assert v125["interface"]["cidr"] == 24 assert v125["interface"]["mtu"] == JUMBO_MTU - def test_vlans_sorted_by_id(self, tmp_path): - input_data = _make_bmc_input() - conv = BMCSwitchConverter(input_data, str(tmp_path)) - vlans = conv._build_vlans() - ids = [v["vlan_id"] for v in vlans] + def test_vlans_sorted_by_id(self, bmc_converter): + ids = [v["vlan_id"] for v in bmc_converter._build_vlans()] assert ids == sorted(ids) - def test_hardcoded_vlans_not_mutated(self, tmp_path): - """Calling _build_vlans should not modify BMC_HARDCODED_VLANS.""" + def test_does_not_mutate_global_constant(self, bmc_converter): + """Calling _build_vlans must not alter the shared BMC_HARDCODED_VLANS.""" before = [dict(v) for v in BMC_HARDCODED_VLANS] - input_data = _make_bmc_input() - conv = BMCSwitchConverter(input_data, str(tmp_path)) - conv._build_vlans() - after = [dict(v) for v in BMC_HARDCODED_VLANS] - assert before == after + bmc_converter._build_vlans() + assert [dict(v) for v in BMC_HARDCODED_VLANS] == before class TestBMCPortChannels: - def test_port_channels_from_template(self, tmp_path): - template_data = { - "interface_templates": {"common": [{"name": "test", "type": "Access"}]}, - "port_channels": [ - {"id": 102, "description": "TOR_BMC", "type": "Trunk", - "native_vlan": "99", "tagged_vlans": "125", "members": ["1/51", "1/52"]} - ], - } - pcs = BMCSwitchConverter._build_port_channels(template_data) + """BMCSwitchConverter._build_port_channels — static template extraction.""" + + _SAMPLE_TEMPLATE = { + "interface_templates": {"common": [{"name": "test", "type": "Access"}]}, + "port_channels": [ + {"id": 102, "description": "TOR_BMC", "type": "Trunk", + "native_vlan": "99", "tagged_vlans": "125", "members": ["1/51", "1/52"]}, + ], + } + + def test_extracts_port_channels_from_template(self): + pcs = BMCSwitchConverter._build_port_channels(self._SAMPLE_TEMPLATE) assert len(pcs) == 1 assert pcs[0]["id"] == 102 assert pcs[0]["members"] == ["1/51", "1/52"] - def test_empty_when_no_port_channels(self, tmp_path): - template_data = {"interface_templates": {"common": [{"name": "test"}]}} - pcs = BMCSwitchConverter._build_port_channels(template_data) + def test_returns_empty_when_absent(self): + pcs = BMCSwitchConverter._build_port_channels({"interface_templates": {"common": []}}) assert pcs == [] - def test_deep_copy_prevents_mutation(self, tmp_path): + def test_deep_copies_to_prevent_mutation(self): original = [{"id": 1, "members": ["1/1"]}] - template_data = {"port_channels": original} - pcs = BMCSwitchConverter._build_port_channels(template_data) + pcs = BMCSwitchConverter._build_port_channels({"port_channels": original}) pcs[0]["id"] = 999 assert original[0]["id"] == 1 class TestBMCStaticRoutes: - def test_default_route_from_bmc_gateway(self, tmp_path): - input_data = _make_bmc_input(bmc_gateway="10.0.0.1") - conv = BMCSwitchConverter(input_data, str(tmp_path)) - routes = conv._build_static_routes() + """BMCSwitchConverter._build_static_routes — default route from BMC gateway.""" + + def test_creates_default_route_from_gateway(self, bmc_converter): + routes = bmc_converter._build_static_routes() assert len(routes) == 1 - assert routes[0]["prefix"] == "0.0.0.0/0" - assert routes[0]["next_hop"] == "10.0.0.1" - - def test_no_routes_without_bmc_supernet(self, tmp_path): - input_data = _make_bmc_input() - # Remove BMC supernet - input_data["InputData"]["Supernets"] = [ - s for s in input_data["InputData"]["Supernets"] - if not s.get("GroupName", "").upper().startswith("BMC") + assert routes[0] == { + "prefix": "0.0.0.0/0", + "next_hop": "10.0.0.1", + "description": "BMC default gateway", + } + + def test_no_routes_when_bmc_supernet_missing(self, tmp_path): + data = _make_bmc_input() + data["InputData"]["Supernets"] = [ + s for s in data["InputData"]["Supernets"] + if not s["GroupName"].upper().startswith("BMC") ] - conv = BMCSwitchConverter(input_data, str(tmp_path)) - routes = conv._build_static_routes() - assert routes == [] - - def test_no_routes_without_gateway(self, tmp_path): - input_data = _make_bmc_input() - # Remove gateway - for s in input_data["InputData"]["Supernets"]: - if s.get("GroupName", "").upper().startswith("BMC"): + assert BMCSwitchConverter(data, str(tmp_path))._build_static_routes() == [] + + def test_no_routes_when_gateway_empty(self, tmp_path): + data = _make_bmc_input() + for s in data["InputData"]["Supernets"]: + if s["GroupName"].upper().startswith("BMC"): s["IPv4"]["Gateway"] = "" - conv = BMCSwitchConverter(input_data, str(tmp_path)) - routes = conv._build_static_routes() - assert routes == [] + assert BMCSwitchConverter(data, str(tmp_path))._build_static_routes() == [] class TestBMCInterfaces: - def test_interfaces_from_template(self, tmp_path): - template_data = { + """BMCSwitchConverter._build_interfaces — static template extraction.""" + + def test_extracts_common_interfaces(self): + template = { "interface_templates": { "common": [ {"name": "Unused", "type": "Access", "access_vlan": "2"}, @@ -321,12 +334,10 @@ def test_interfaces_from_template(self, tmp_path): ] } } - intfs = BMCSwitchConverter._build_interfaces(template_data) + intfs = BMCSwitchConverter._build_interfaces(template) assert len(intfs) == 2 - assert intfs[0]["name"] == "Unused" - assert intfs[1]["name"] == "Host_BMC" + assert [i["name"] for i in intfs] == ["Unused", "Host_BMC"] - def test_raises_on_empty_common(self, tmp_path): - template_data = {"interface_templates": {"common": []}} + def test_raises_when_no_common_interfaces(self): with pytest.raises(ValueError, match="No common interfaces"): - BMCSwitchConverter._build_interfaces(template_data) + BMCSwitchConverter._build_interfaces({"interface_templates": {"common": []}}) From f1ef69da2c405e568aa28a9e916587bf0e8b0e7c Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Sat, 7 Feb 2026 06:06:31 +0000 Subject: [PATCH 05/11] test & docs: add test cases, fix generator tests, consolidate docs Test improvements: - Add 2 new converter test cases: switched_nobmc (93108TC-FX3P, no BMC) and switched_20node (93180YC-FX3, 20-node with BMC) - Add 43 StandardJSONBuilder unit tests covering build_switch, build_vlans, resolve_interface_vlans, build_bgp, build_prefix_lists, build_qos, deployment_pattern, and build_ip_mapping - Fix test_generator.py: move generation from collection-time to test-time with tmp_path isolation, remove silent except:pass - Add 8 missing expected .cfg files for std_cisco_nxos_fc - Clean up stale generated_*.cfg from test case folders - Total: 103 tests passing (85 unit + 12 converter + 6 generator) Documentation consolidation: - Remove QUICK_START.md (merged into README), COPILOT_AGENT_GUIDE.md (2177 lines of generic boilerplate), SWITCH_INTERFACE_TEMPLATE.md (merged into TEMPLATE_GUIDE) - Consolidate 7 files / 4179 lines -> 4 files / 659 lines (84% reduction) - Update README with quick start, Python usage, accurate directory tree - Deduplicate JSON schema references, remove Go-era content --- README.md | 308 +-- docs/CONVERTOR_GUIDE.md | 285 +-- docs/COPILOT_AGENT_GUIDE.md | 2177 ----------------- docs/QUICK_START.md | 78 - docs/SWITCH_INTERFACE_TEMPLATE.md | 241 -- docs/TEMPLATE_GUIDE.md | 693 +----- docs/TROUBLESHOOTING.md | 546 +---- .../expected_outputs/bmc-3.json | 98 + .../expected_outputs/tor-3a.json | 527 ++++ .../expected_outputs/tor-3b.json | 527 ++++ .../lab_cisco_nxos_switch_input.json | 1973 +++++++++++++++ .../expected_outputs/tor-2a.json | 528 ++++ .../expected_outputs/tor-2b.json | 528 ++++ .../lab_cisco_nxos_switch_input.json | 1697 +++++++++++++ .../expected_full_config.cfg | 727 ++++++ .../std_cisco_nxos_fc/expected_interface.cfg | 69 + .../std_cisco_nxos_fc/expected_login.cfg | 41 + .../expected_port_channel.cfg | 82 + .../expected_prefix_list.cfg | 5 + .../std_cisco_nxos_fc/expected_qos.cfg | 37 + .../std_cisco_nxos_fc/expected_system.cfg | 74 + .../std_cisco_nxos_fc/expected_vlan.cfg | 346 +++ tests/test_generator.py | 119 +- tests/test_unit.py | 502 ++++ 24 files changed, 8225 insertions(+), 3983 deletions(-) delete mode 100644 docs/COPILOT_AGENT_GUIDE.md delete mode 100644 docs/QUICK_START.md delete mode 100644 docs/SWITCH_INTERFACE_TEMPLATE.md create mode 100644 tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/bmc-3.json create mode 100644 tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/tor-3a.json create mode 100644 tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/tor-3b.json create mode 100644 tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/lab_cisco_nxos_switch_input.json create mode 100644 tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/expected_outputs/tor-2a.json create mode 100644 tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/expected_outputs/tor-2b.json create mode 100644 tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/lab_cisco_nxos_switch_input.json create mode 100644 tests/test_cases/std_cisco_nxos_fc/expected_full_config.cfg create mode 100644 tests/test_cases/std_cisco_nxos_fc/expected_interface.cfg create mode 100644 tests/test_cases/std_cisco_nxos_fc/expected_login.cfg create mode 100644 tests/test_cases/std_cisco_nxos_fc/expected_port_channel.cfg create mode 100644 tests/test_cases/std_cisco_nxos_fc/expected_prefix_list.cfg create mode 100644 tests/test_cases/std_cisco_nxos_fc/expected_qos.cfg create mode 100644 tests/test_cases/std_cisco_nxos_fc/expected_system.cfg create mode 100644 tests/test_cases/std_cisco_nxos_fc/expected_vlan.cfg diff --git a/README.md b/README.md index fb7a3ed..37e1569 100644 --- a/README.md +++ b/README.md @@ -1,213 +1,150 @@ # Network Configuration Generation Tool -- [Network Configuration Generation Tool](#network-configuration-generation-tool) - - [Overview](#overview) - - [Quick Navigation](#quick-navigation) - - [Goals](#goals) - - [Design Architecture](#design-architecture) - - [Overall Flow](#overall-flow) - - [Other User-Defined Input Support](#other-user-defined-input-support) - - [Workflow Detail](#workflow-detail) - - [Directory Structure](#directory-structure) - - [Input \& Output Examples](#input--output-examples) - - [Sample Input JSON](#sample-input-json) - - [Sample Template (Jinja2)](#sample-template-jinja2) - - [Quick Start](#quick-start) - - [What's Improved in This Version](#whats-improved-in-this-version) - - [Key Enhancements](#key-enhancements) - ## Overview -This tool generates vendor-specific network switch configurations (e.g., Cisco NX-OS, Dell OS10) using JSON input and Jinja2 templates. It supports both source code usage and standalone executables for environments without Python. - -## Quick Navigation +This tool generates vendor-specific network switch configurations (e.g., Cisco NX-OS, Dell OS10) using JSON input and Jinja2 templates. It supports both Python source usage and standalone executables. -**First time here?** Choose your path: +**Documentation:** -- **Just want to use it?** → [`docs/QUICK_START.md`](docs/QUICK_START.md) -- **Need to convert your data format?** → [`docs/CONVERTOR_GUIDE.md`](docs/CONVERTOR_GUIDE.md) -- **Want to customize templates?** → [`docs/TEMPLATE_GUIDE.md`](docs/TEMPLATE_GUIDE.md) -- **Need to create/modify switch templates?** → [`docs/SWITCH_INTERFACE_TEMPLATE.md`](docs/SWITCH_INTERFACE_TEMPLATE.md) -- **Having issues?** → [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) +- [Template Guide](docs/TEMPLATE_GUIDE.md) — Jinja2 templates and switch interface templates +- [Converter Guide](docs/CONVERTOR_GUIDE.md) — Writing custom input format converters +- [Troubleshooting](docs/TROUBLESHOOTING.md) — Common issues and solutions --- -## Goals +## Quick Start -- Support configuration generation for **multiple switch vendors** -- Allow users to define **input variables** in a structured JSON format -- Output readable **vendor-specific configuration files** -- Support both **source-code use and standalone executable** -- Ensure clean project structure and developer scalability +### Option A: Standalone Executable (No Python Required) ---- +Download from [Releases](../../releases), then: -## Design Architecture +```bash +# See all options +./network_config_generator -h -### Overall Flow -```mermaid -flowchart LR - A["Standard Input JSON
(Network Variables)"] - C["Jinja2 Template
(Config Templates)"] - E("Config Generation Tool
(Python Script)") - G(Generated Configuration) - - A -->|Load Variables| E - C -->|Provide Templates| E - E -->|Render Template with Variables| G - - subgraph User Input - direction TB - A - C - end +# Generate configs from standard-format JSON +./network_config_generator --input_json input/standard_input.json --output_folder output/ + +# Generate from lab-format JSON (auto-converts) +./network_config_generator --input_json my_lab_input.json --output_folder configs/ --convertor lab ``` -> [!NOTE] -> The structure and format of the **JSON input file must remain fixed** to match the variables used in the Jinja2 templates, but you can safely update **values** as needed, either manually or programmatically. +### Option B: Python Source + +```bash +# Install dependencies +pip install -r requirements.txt + +# Generate from standard-format JSON +python src/main.py --input_json input/standard_input.json --output_folder output/ + +# Generate from lab-format JSON with auto-conversion +python src/main.py --input_json my_lab_input.json --output_folder configs/ --convertor lab + +# Run tests +python -m pytest tests/ -v +``` -### Other User-Defined Input Support +### Output -To support a wide range of input data formats, the system allows users to define their own converters. These converters transform any non-standard input into a unified JSON structure. Sample converters are provided in the repository as references to help users get started. +The tool produces individual section configs plus a merged full config: + +``` +output/ +├── generated_system.cfg +├── generated_vlan.cfg +├── generated_interface.cfg +├── generated_port_channel.cfg +├── generated_bgp.cfg +├── generated_prefix_list.cfg +├── generated_qos.cfg +├── generated_login.cfg +└── generated_full_config.cfg +``` + +--- + +## Architecture + +### Pipeline ```mermaid flowchart LR - U1["Non-Standard JSON Input"] - U2["CSV Input"] - U3["YAML Input"] - U4["Other Format Input"] - S1["Standard Input JSON"] - - U1 -->|convertor1.py| S1 - U2 -->|convertor2.py| S1 - U3 -->|convertor3.py| S1 - U4 -->|convertorx.py| S1 - - subgraph "User-Defined Input Types" - direction TB - U1 - U2 - U3 - U4 - end + A["Standard Input JSON"] -->|Load Variables| E("Config Generator") + C["Jinja2 Templates"] -->|Provide Templates| E + E -->|Render| G["Generated .cfg Files"] ``` -Each input type should be handled by a user-defined converter script (e.g., convertor1.py). These scripts are responsible for converting the input into the standardized JSON format. Example converter scripts are included in the repo to illustrate expected structure and behavior. +### Converter Support + +Non-standard inputs (lab JSON, CSV, YAML, etc.) are transformed to standard format via pluggable converters: -### Workflow Detail ```mermaid flowchart LR - A["Standard Input JSON"] - B["Config Generation Tool"] - T1["vlan.j2 Template"] - T2["bgp.j2 Template"] - T3["interface.j2 Template"] - Tn["xxx.j2 Templates"] - O1["VLAN Config"] - O2["BGP Config"] - O3["Interface Config"] - O4["xxx Config"] - OC["Combined Full Config"] - - A --> T1 - A --> T2 - A --> T3 - A --> Tn - T1 --> B - T2 --> B - T3 --> B - Tn --> B - B --> O1 - B --> O2 - B --> O3 - B --> O4 - B --> OC - - subgraph "Jinja2 Templates" - direction TB - T1 - T2 - T3 - Tn - end - - subgraph "Dedicated Config Output" - direction TB - O1 - O2 - O3 - O4 - end - - subgraph "Full Config Output" - direction TB - OC - end + U1["Lab JSON"] -->|convertors_lab_switch_json.py| S1["Standard JSON"] + U2["BMC JSON"] -->|convertors_bmc_switch_json.py| S1 + U3["Custom Format"] -->|your_converter.py| S1 + S1 --> G["Generator + Templates → .cfg"] ``` +> [!NOTE] +> The standard JSON format must match the variables used in Jinja2 templates. You can safely update values but the structure must stay fixed. + +--- + ## Directory Structure -```plaintext -root/ -├── .devcontainer/ # Development container configuration -├── .github/ # GitHub Actions workflows -├── build/ # Build artifacts and executables -├── docs/ # Documentation files -│ ├── CONVERTOR_GUIDE.md # Guide for creating custom convertors -│ ├── QUICK_START.md # Quick start and executable usage guide -│ ├── SWITCH_INTERFACE_TEMPLATE.md # Switch interface template guide -│ ├── TEMPLATE_GUIDE.md # Jinja2 template development guide -│ └── TROUBLESHOOTING.md # Common issues and solutions -├── input/ # Input files and templates -│ ├── standard_input.json # Standard format input example -│ ├── jinja2_templates/ # Jinja2 template files -│ │ ├── cisco/ -│ │ │ └── nxos/ # Cisco NX-OS templates -│ │ │ ├── bgp.j2 # BGP configuration template -│ │ │ ├── full_config.j2 # Combined full configuration template -│ │ │ ├── interface.j2 # Interface configuration template -│ │ │ ├── login.j2 # Login/user configuration template -│ │ │ ├── port_channel.j2 # Port channel configuration template -│ │ │ ├── prefix_list.j2 # Prefix list configuration template -│ │ │ ├── qos.j2 # QoS configuration template -│ │ │ ├── system.j2 # System configuration template -│ │ │ └── vlan.j2 # VLAN configuration template -│ │ └── dellemc/ # Dell EMC templates (vendor-specific) -│ └── switch_interface_templates/ # Switch interface template configurations -│ ├── cisco/ -│ └── dellemc/ -├── src/ # Source code -│ ├── __init__.py # Package initialization -│ ├── main.py # Entry point for the tool -│ ├── generator.py # Main generation logic -│ ├── loader.py # Input file loading and parsing -│ └── convertors/ # Input format converters -│ ├── __init__.py # Convertor registry -│ ├── convertors_lab_switch_json.py # Lab format converter -│ └── convertors_bmc_switch_json.py # BMC switch converter -├── tests/ # Test files -│ ├── test_generator.py # Unit tests for generator logic -│ ├── test_convertors.py # Unit tests for input conversion -│ └── test_cases/ # Test case data files -├── requirements.txt # Python dependencies -├── network_config_generator.spec # PyInstaller build specification -└── _old/ # Legacy Go implementation (archived) +``` +├── docs/ # Documentation +│ ├── TEMPLATE_GUIDE.md # Jinja2 + switch interface template guide +│ ├── CONVERTOR_GUIDE.md # Custom converter guide +│ └── TROUBLESHOOTING.md # Common issues and solutions +├── input/ +│ ├── standard_input.json # Standard format example +│ ├── jinja2_templates/ # Jinja2 config templates +│ │ ├── cisco/nxos/ # 10 templates (bgp, vlan, interface, …) +│ │ └── dellemc/os10/ # 11 templates (+ vlt.j2) +│ └── switch_interface_templates/ # Switch model definitions +│ ├── cisco/ # 93108TC-FX3P, 93180YC-FX, 93180YC-FX3, +│ │ # 9348GC-FXP (BMC), 9348GC-FX3 (BMC) +│ └── dellemc/ # N3248TE-ON (BMC), S5248F-ON +├── src/ +│ ├── main.py # CLI entry point +│ ├── generator.py # Jinja2 rendering engine +│ ├── loader.py # Input file loading and parsing +│ ├── constants.py # Shared constants (VLAN maps, templates) +│ ├── utils.py # Helpers (infer_firmware, classify_vlan) +│ └── convertors/ +│ ├── convertors_lab_switch_json.py # Lab → Standard JSON (TOR switches) +│ └── convertors_bmc_switch_json.py # Lab → Standard JSON (BMC switches) +├── tests/ +│ ├── conftest.py # Shared fixtures and helpers +│ ├── test_unit.py # Unit tests (StandardJSONBuilder, utils, etc.) +│ ├── test_convertors.py # Golden-file tests for converters +│ ├── test_generator.py # Golden-file tests for Jinja2 generation +│ └── test_cases/ # Test data (6 converter + 3 generator cases) +├── tools/ # Utility scripts (IP mgmt, port mapping) +└── requirements.txt # Python dependencies ``` --- ## Input & Output Examples -### Sample Input JSON +### Standard Input JSON ```json { - "hostname": "tor-switch-1", + "switch": { + "hostname": "tor-switch-1", + "make": "cisco", + "firmware": "nxos" + }, + "vlans": [ + { "vlan_id": 711, "name": "Compute" } + ], "interfaces": [ { "name": "Ethernet1/1", "vlan": 711, "description": "Compute1" } ], - "vlans": [ - { "id": 711, "name": "Compute" } - ], "bgp": { "asn": 65001, "router_id": "192.168.0.1" @@ -221,33 +158,4 @@ router bgp {{ bgp.asn }} router-id {{ bgp.router_id }} ``` -> [!NOTE] -> **Need more details?** See [`docs/TEMPLATE_GUIDE.md`](docs/TEMPLATE_GUIDE.md) for complete examples and template development guide. - ---- - -## Quick Start - -For detailed usage instructions, examples, and setup steps, see [`docs/QUICK_START.md`](docs/QUICK_START.md). - ---- - -## What's Improved in This Version - -We've significantly redesigned the tool architecture to make it more modular, maintainable, and user-friendly. While the original version used **Go templates**, the new version is built with **Python + Jinja2** and brings several key improvements: - -### Key Enhancements - -- **Modular Output Generation** - Instead of producing a single full configuration, the tool now supports generating individual configuration sections (e.g., VLANs, interfaces, BGP) based on your input needs—making review, debugging, and reuse much easier. - -- **No Rebuild Required for Changes** - All logic is now in editable Python and Jinja2 templates—no compilation needed. You can easily update the templates or logic without rebuilding any binary. - -- **Cleaner and More Flexible Logic** - We've removed hardcoded rules and added more structured parsing logic, which makes the tool easier to extend, test, and adapt to different network designs or vendors. - -- **Open to Contributions** - The new structure makes it easy for contributors to add new templates or enhance existing ones. If you support a new vendor or configuration style, you can simply submit a template pull request. - -This upgrade is not just a technology shift—it's a foundation for faster iteration, better collaboration, and easier maintenance. +See [docs/TEMPLATE_GUIDE.md](docs/TEMPLATE_GUIDE.md) for complete template reference. diff --git a/docs/CONVERTOR_GUIDE.md b/docs/CONVERTOR_GUIDE.md index f2a2a44..ada79f9 100644 --- a/docs/CONVERTOR_GUIDE.md +++ b/docs/CONVERTOR_GUIDE.md @@ -1,256 +1,133 @@ -# Converting Your Data Format +# Converter Guide -## 🤔 Do I Need This? +## When You Need a Converter -**You need a converter if:** -- Your switch data is in a different format than the tool expects -- You get an error like "conversion required" -- Your JSON structure looks different from the examples +You need a converter if your input data is **not** in the standard JSON format expected by the generator. The converter transforms your format into standard JSON, which the templates can render. -**You DON'T need this if:** -- Your data already works with the tool -- You're using the provided example files +You **don't** need this if your data already works with the tool or you're using the provided example files. -## � Simple Example +--- -Let's say your data looks like this: +## How It Works -**Your Format:** -```json -{ - "devices": [ - { - "name": "switch-01", - "type": "cisco", - "vlans": "100,200,300", - "ports": "1-48" - } - ] -} ``` - -**Tool Needs:** -```json -{ - "switch": { - "hostname": "switch-01", - "make": "cisco", - "firmware": "nxos" - }, - "vlans": [ - {"vlan_id": 100, "name": "VLAN_100"}, - {"vlan_id": 200, "name": "VLAN_200"}, - {"vlan_id": 300, "name": "VLAN_300"} - ], - "interfaces": [], - "port_channels": [], - "bgp": {} -} +Your Format → Converter → Standard JSON → Generator + Templates → .cfg files ``` -## �️ Create Your Converter (4 Steps) +The tool ships with two converters: +- `convertors_lab_switch_json.py` — Converts lab-format JSON (TOR switches) +- `convertors_bmc_switch_json.py` — Converts lab-format JSON (BMC switches) + +--- + +## Creating a Converter ### Step 1: Create the File -Create: `src/convertors/my_converter.py` -### Step 2: Write the Function +Create `src/convertors/my_converter.py` + +### Step 2: Implement the Function + +Your converter must export a function named `convert_switch_input_json`: + ```python +import json +import os + def convert_switch_input_json(input_data, output_directory): - """ - Convert your format to standard format - + """Convert custom format to standard format. + Args: input_data: Your JSON data (as Python dict) - output_directory: Where to save converted files + output_directory: Where to save converted JSON files """ - - # Example: Convert each device for device in input_data["devices"]: - - # Build standard format - standard_data = { + standard = { "switch": { "hostname": device["name"], "make": device["type"], - "firmware": "nxos" # or detect from your data + "firmware": "nxos", }, "vlans": [], "interfaces": [], "port_channels": [], - "bgp": {} + "bgp": {}, } - - # Convert VLANs (example: "100,200,300" → list) - if device.get("vlans"): - vlan_ids = device["vlans"].split(",") - for vlan_id in vlan_ids: - standard_data["vlans"].append({ - "vlan_id": int(vlan_id), - "name": f"VLAN_{vlan_id}" + + # Convert VLANs + for vid in device.get("vlans", "").split(","): + if vid.strip(): + standard["vlans"].append({ + "vlan_id": int(vid), + "name": f"VLAN_{vid}", }) - - # Save file for this switch - import json - import os - filename = f"{device['name']}.json" - filepath = os.path.join(output_directory, filename) - - with open(filepath, 'w') as f: - json.dump(standard_data, f, indent=2) + + # Write one file per switch + filepath = os.path.join(output_directory, f"{device['name']}.json") + with open(filepath, "w") as f: + json.dump(standard, f, indent=2) ``` -### Step 3: Test It +### Step 3: Run It + ```bash python src/main.py --input_json your_data.json --convertor my_converter ``` ### Step 4: Check Results -Look in your output folder for: -- `switch-01/` (folder with generated configs) -- `std_switch-01.json` (converted data for troubleshooting) -## 📋 Standard Format Reference +The converter writes standard JSON files to the output directory. The generator then renders each one against the Jinja2 templates. -Your converter must create JSON with these sections: +--- -### Required: Switch Info -```json -{ - "switch": { - "hostname": "switch-name", - "make": "cisco", // cisco, dellemc, etc. - "firmware": "nxos" // nxos, os10, etc. - } -} -``` +## Standard JSON Format -### Optional: VLANs -```json -{ - "vlans": [ - { - "vlan_id": 100, - "name": "VLAN_100", - "description": "Server VLAN" - } - ] -} -``` +Your converter must produce JSON with this structure. Only `switch` is required; all other sections are optional. -### Optional: Interfaces ```json { - "interfaces": [ - { - "name": "Ethernet1/1", - "vlan": 100, - "description": "Server port", - "type": "access" // access, trunk, etc. - } - ] -} -``` - -### Optional: BGP, Port Channels, etc. -```json -{ - "bgp": {}, - "port_channels": [], - "prefix_lists": [], - "qos": {} -} -``` - -## 🆘 Common Issues - -**Error: "Module not found"** -- Make sure file is in `src/convertors/` -- Use dots in path: `convertors.my_converter` - -**Error: "Function not found"** -- Function must be named exactly: `convert_switch_input_json` - -**No output files** -- Check file permissions in output directory -- Add print statements to debug your converter - -## 💡 Tips - -- **Start simple**: Convert just the basic switch info first -- **Use print()**: Add debug prints to see what's happening -- **Check examples**: Look at existing converters in `src/convertors/` -- **Test incrementally**: Add one section at a time (VLANs, then interfaces, etc.) + "switch": { + "hostname": "switch-01", + "make": "cisco", + "firmware": "nxos", + "model": "93180YC-FX" + }, "vlans": [ - { - "vlan_id": 100, // VLAN number - "name": "Production" // VLAN name - } - ] -} -``` - -### Optional: Interfaces -```json -{ + { "vlan_id": 100, "name": "VLAN_100", "description": "Server VLAN" } + ], "interfaces": [ - { - "name": "Ethernet1/1", // Interface name - "mode": "access", // access or trunk - "vlan": 100 // VLAN for access ports - } - ] -} -``` - -## 🎯 Complete Working Example - -Let's say you have this input: -```json -{ - "datacenter": { - "leaf_switches": [ - { - "hostname": "leaf-01", - "brand": "cisco", - "software": "nxos", - "access_vlans": [100, 200] - } + { "name": "Ethernet1/1", "type": "access", "vlan": 100, "description": "Server port" } + ], + "port_channels": [ + { "id": 50, "type": "L3", "members": ["Ethernet1/41", "Ethernet1/42"] } + ], + "bgp": { + "asn": 65001, + "router_id": "10.0.0.1", + "neighbors": [ + { "ip": "10.0.0.2", "remote_as": 65100, "description": "Border1" } ] - } + }, + "prefix_lists": [], + "qos": {} } ``` -Your convertor (`convertors/datacenter_convertor.py`) would: - -1. **Extract switch data** from `datacenter.leaf_switches` -2. **Map fields**: `brand` → `make`, `software` → `firmware` -3. **Transform VLANs**: Convert `access_vlans` array to VLAN objects -4. **Save file**: Create `leaf-01.json` with standard format - -## 🚀 Using Your Convertor - -```bash -# Use your custom convertor -./network-config-generator --input_json datacenter.json --convertor datacenter_convertor - -# Tool will: -# 1. Load your datacenter.json -# 2. Run datacenter_convertor to transform it -# 3. Generate switch configs using templates -``` +--- -## 💡 Tips +## Common Issues -- **Start Simple**: Begin with just switch info and VLANs -- **Test Often**: Check that your output works with the tool -- **Use Examples**: Look at existing convertors for reference -- **One File Per Switch**: Each switch gets its own JSON file -- **Validate Data**: Check for required fields before processing +| Problem | Solution | +|---------|----------| +| `Module not found` | File must be in `src/convertors/`. Use dot notation: `--convertor my_converter` | +| `Function not found` | Must be named exactly `convert_switch_input_json` | +| No output files | Check file permissions; add `print()` statements for debugging | -## 📚 Need Help? +--- -- Look at `convertors/convertors_lab_switch_json.py` for a real example -- Check `tests/test_cases/` for sample inputs and outputs -- The tool will show errors if your format doesn't match +## Tips -That's it! Convertors are just simple data transformers - nothing complex needed! +- Start simple — convert just `switch` info first, then add sections incrementally +- Look at the existing converters in `src/convertors/` for real-world examples +- Check `tests/test_cases/` for sample inputs and expected outputs +- Each switch should produce its own JSON file diff --git a/docs/COPILOT_AGENT_GUIDE.md b/docs/COPILOT_AGENT_GUIDE.md deleted file mode 100644 index f02a156..0000000 --- a/docs/COPILOT_AGENT_GUIDE.md +++ /dev/null @@ -1,2177 +0,0 @@ -# 🤖 GitHub Copilot Agent Development Guide - -[![PowerShell](https://img.shields.io/badge/PowerShell-Best%20Practices-blue?logo=powershell)](https://docs.microsoft.com/en-us/powershell/) -[![Python](https://img.shields.io/badge/Python-3.7%2B-blue?logo=python)](https://docs.python.org/) -[![Security](https://img.shields.io/badge/Security-Hardened-red?logo=security)](https://docs.microsoft.com/en-us/security/) -[![GitHub](https://img.shields.io/badge/Markdown-GitHub%20Standards-green?logo=github)](https://docs.github.com/en/get-started/writing-on-github) -[![Testing](https://img.shields.io/badge/Testing-Comprehensive-success?logo=checkmarx)](https://pester.dev/) -[![Jinja2](https://img.shields.io/badge/Templates-Jinja2-orange?logo=jinja)](https://jinja.palletsprojects.com/) - -## 📋 Table of Contents - -- [🤖 GitHub Copilot Agent Development Guide](#-github-copilot-agent-development-guide) - - [📋 Table of Contents](#-table-of-contents) - - [📖 Overview](#-overview) - - [🏗️ Project Architecture](#️-project-architecture) - - [🔐 PowerShell Security Best Practices](#-powershell-security-best-practices) - - [⚡ Core Security Principles](#-core-security-principles) - - [1. **Principle of Least Privilege**](#1-principle-of-least-privilege) - - [2. **Input Validation First**](#2-input-validation-first) - - [3. **Secure File Operations**](#3-secure-file-operations) - - [🛡️ Input Validation \& Sanitization](#️-input-validation--sanitization) - - [🔒 Credential Management](#-credential-management) - - [📝 Logging \& Auditing](#-logging--auditing) - - [💻 PowerShell Development Best Practices](#-powershell-development-best-practices) - - [🏗️ Code Structure \& Organization](#️-code-structure--organization) - - [**Function Design Principles**](#function-design-principles) - - [📚 Documentation Standards](#-documentation-standards) - - [**Comment-Based Help Requirements**](#comment-based-help-requirements) - - [🔧 Error Handling](#-error-handling) - - [**Comprehensive Error Management**](#comprehensive-error-management) - - [⚡ Performance Guidelines](#-performance-guidelines) - - [� Python Development Best Practices](#-python-development-best-practices) - - [🔐 Python Security Best Practices](#-python-security-best-practices) - - [**Input Validation \& Sanitization**](#input-validation--sanitization) - - [**Secure File Operations**](#secure-file-operations) - - [🏗️ Code Structure \& Organization](#️-code-structure--organization-1) - - [**Module Design Principles**](#module-design-principles) - - [🧪 Python Testing Framework](#-python-testing-framework) - - [**pytest Configuration**](#pytest-configuration) - - [**Comprehensive Test Suite**](#comprehensive-test-suite) - - [📦 Python Dependency Management](#-python-dependency-management) - - [**requirements.txt Best Practices**](#requirementstxt-best-practices) - - [**Setup Configuration (setup.py or pyproject.toml)**](#setup-configuration-setuppy-or-pyprojecttoml) - - [📖 GitHub Markdown Best Practices](#-github-markdown-best-practices) - - [📊 Document Structure](#-document-structure) - - [**Standardized README Structure**](#standardized-readme-structure) - - [🎨 Visual Elements](#-visual-elements) - - [**Strategic Emoji Usage**](#strategic-emoji-usage) - - [**Enhanced Code Blocks**](#enhanced-code-blocks) - - [**Callout Boxes**](#callout-boxes) - - [🔗 Linking \& Navigation](#-linking--navigation) - - [**Internal Linking Best Practices**](#internal-linking-best-practices) - - [📱 GitHub-Specific Features](#-github-specific-features) - - [**Collapsible Sections**](#collapsible-sections) - - [**Mermaid Diagrams**](#mermaid-diagrams) - - [**Task Lists**](#task-lists) - - [**Tables with Alignment**](#tables-with-alignment) - - [🧪 Unit Testing Framework](#-unit-testing-framework) - - [🎯 Testing Strategy](#-testing-strategy) - - [**Test Pyramid Architecture**](#test-pyramid-architecture) - - [🔬 Test Implementation](#-test-implementation) - - [**Comprehensive Test Structure**](#comprehensive-test-structure) - - [📊 Coverage Requirements](#-coverage-requirements) - - [**Test Coverage Standards**](#test-coverage-standards) - - [🚀 Continuous Integration](#-continuous-integration) - - [**GitHub Actions Integration**](#github-actions-integration) - - [📚 Documentation Maintenance](#-documentation-maintenance) - - [🔄 Change Management Process](#-change-management-process) - - [**Documentation Update Workflow**](#documentation-update-workflow) - - [📝 Documentation Standards](#-documentation-standards-1) - - [**Automated Documentation Validation**](#automated-documentation-validation) - - [🔍 Review Guidelines](#-review-guidelines) - - [**Documentation Review Checklist**](#documentation-review-checklist) - - [🤖 Automation](#-automation) - - [**Documentation Update Scripts**](#documentation-update-scripts) - - [🛠️ Tool-Specific Guidelines](#️-tool-specific-guidelines) - - [**PortMap Tool Maintenance**](#portmap-tool-maintenance) - - [**Input Format Changes**](#input-format-changes) - - [**Output Format Changes**](#output-format-changes) - - [**Feature Additions**](#feature-additions) - - [**Breaking Changes**](#breaking-changes) - - [**Python Core Generator Maintenance**](#python-core-generator-maintenance) - - [**Input Schema Changes**](#input-schema-changes) - - [**Template Changes**](#template-changes) - - [**Switch Configuration Output Changes**](#switch-configuration-output-changes) - - [**Dependency Updates**](#dependency-updates) - - [**API Changes**](#api-changes) - - [**Performance Optimizations**](#performance-optimizations) - - [**Cross-Language Integration**](#cross-language-integration) - - [**Data Format Compatibility**](#data-format-compatibility) - - [**Documentation Synchronization**](#documentation-synchronization) - - [📞 Support \& Resources](#-support--resources) - - [**Documentation Resources**](#documentation-resources) - - [**Internal Resources**](#internal-resources) - - [**Community \& Support**](#community--support) - -## 📖 Overview - -This guide provides comprehensive best practices for developing and maintaining **multi-language tools** with GitHub Copilot agents, focusing on the **AzureStack Network Switch Config Generator** project ecosystem. The project consists of both **Python core components** (network configuration generation) and **PowerShell utilities** (network documentation and tooling). It covers security, development standards, documentation practices, and maintenance procedures for both languages. - -> 🎯 **Goal**: Ensure consistent, secure, and well-documented Python and PowerShell tools that integrate seamlessly with GitHub workflows and maintain high quality standards. - -### 🏗️ Project Architecture - -```mermaid -graph TD - A[JSON Input] --> B[Python Core - src/] - B --> C[Jinja2 Templates] - C --> D[Switch Configurations] - - A --> E[PowerShell Tools - tools/] - E --> F[Port Documentation] - E --> G[IP Management] - E --> H[Environment Assignment] - - style B fill:#3776ab - style E fill:#012456 -``` - -| Component | Language | Purpose | Location | -| --------------------- | ------------- | --------------------------------------- | ------------------------------------ | -| **Core Generator** | 🐍 Python | Network switch configuration generation | `src/` | -| **PortMap Tool** | 💻 PowerShell | Physical port documentation | `tools/PortMap/` | -| **IP Management** | 💻 PowerShell | IP address assignment | `tools/IPAssignment/` | -| **Environment Tools** | 💻 PowerShell | Environment configuration | `tools/EnvironmentDetailAssignment/` | - -## 🔐 PowerShell Security Best Practices - -### ⚡ Core Security Principles - -#### 1. **Principle of Least Privilege** - -```powershell -# ✅ Good: Specific permissions -#Requires -Version 5.1 -#Requires -Modules @{ ModuleName="Microsoft.PowerShell.Utility"; ModuleVersion="3.1.0.0" } - -# ❌ Avoid: Excessive permissions -# #Requires -RunAsAdministrator (unless truly necessary) -``` - -#### 2. **Input Validation First** - -```powershell -function Test-NetworkConfiguration { - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [ValidateScript({ - if (-not (Test-Path $_)) { - throw "Configuration file not found: $_" - } - if ($_ -notmatch '\.json$') { - throw "Only JSON files are supported" - } - return $true - })] - [string]$ConfigPath - ) - - # Additional runtime validation - try { - $config = Get-Content $ConfigPath -Raw | ConvertFrom-Json -ErrorAction Stop - } - catch { - throw "Invalid JSON format in configuration file: $_" - } -} -``` - -#### 3. **Secure File Operations** - -```powershell -# ✅ Good: Safe path construction -$safePath = Join-Path -Path $env:TEMP -ChildPath "network-config-$(Get-Date -Format 'yyyyMMdd-HHmmss').json" - -# ✅ Good: Validate output directory -$outputDir = Split-Path $OutputFile -Parent -if (-not (Test-Path $outputDir)) { - New-Item -Path $outputDir -ItemType Directory -Force | Out-Null -} - -# ❌ Avoid: Path injection vulnerabilities -# $outputPath = "$basePath\$userInput.json" # Dangerous! -``` - -### 🛡️ Input Validation & Sanitization - -
-🔍 Comprehensive Input Validation Patterns - -```powershell -function Confirm-InputParameters { - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [ValidateLength(1, 260)] # Windows path length limit - [string]$FilePath, - - [Parameter(Mandatory = $true)] - [ValidateSet("Markdown", "CSV", "JSON", IgnoreCase = $true)] - [string]$OutputFormat, - - [Parameter(Mandatory = $false)] - [ValidateRange(1, 65535)] - [int]$Port = 443, - - [Parameter(Mandatory = $false)] - [ValidatePattern('^[a-zA-Z0-9\-._]+$')] - [string[]]$DeviceNames - ) - - # Runtime validation - if ($FilePath -match '[<>:"|?*]') { - throw "Invalid characters in file path" - } - - # File existence and readability - if (-not (Test-Path $FilePath -PathType Leaf)) { - throw "File not found or not accessible: $FilePath" - } - - # JSON structure validation - try { - $jsonContent = Get-Content $FilePath -Raw | ConvertFrom-Json - if (-not $jsonContent.devices) { - throw "Required 'devices' property not found in JSON" - } - } - catch { - throw "JSON validation failed: $($_.Exception.Message)" - } -} -``` - -
- -### 🔒 Credential Management - -```powershell -# ✅ Good: Secure credential handling -function Get-SecureCredential { - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [string]$CredentialName - ) - - # Use Windows Credential Manager or Azure Key Vault - try { - $credential = Get-StoredCredential -Target $CredentialName - if (-not $credential) { - $credential = Get-Credential -Message "Enter credentials for $CredentialName" - } - return $credential - } - catch { - Write-Error "Failed to retrieve credentials: $_" - return $null - } -} - -# ❌ Never do this -# $password = "hardcoded-password" # Security violation! -# $apiKey = Read-Host "Enter API key" # Logged in console history -``` - -### 📝 Logging & Auditing - -```powershell -function Write-AuditLog { - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [ValidateSet("Info", "Warning", "Error", "Security")] - [string]$Level, - - [Parameter(Mandatory = $true)] - [string]$Message, - - [Parameter(Mandatory = $false)] - [string]$Component = $MyInvocation.ScriptName - ) - - $logEntry = [PSCustomObject]@{ - Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" - Level = $Level - Component = (Split-Path $Component -Leaf) - User = $env:USERNAME - Computer = $env:COMPUTERNAME - Message = $Message - ProcessId = $PID - } - - # Write to Windows Event Log for security events - if ($Level -eq "Security") { - Write-EventLog -LogName "Application" -Source "NetworkTools" -EntryType Warning -EventId 1001 -Message $Message - } - - # Also log to file with rotation - $logPath = Join-Path $env:TEMP "network-tools-$(Get-Date -Format 'yyyy-MM').log" - $logEntry | ConvertTo-Json -Compress | Add-Content $logPath -} -``` - -## 💻 PowerShell Development Best Practices - -### 🏗️ Code Structure & Organization - -#### **Function Design Principles** - -```powershell -function Expand-NetworkPortRange { - <# - .SYNOPSIS - Expands port range strings into individual port arrays with support for breakout interfaces. - - .DESCRIPTION - Converts port range specifications (e.g., "1-24", "25.1-25.4") into arrays of individual - port identifiers. Handles both standard integer ports and QSFP breakout sub-interfaces. - - .PARAMETER PortRange - The port range string to expand. Supports formats: - - "1-24" (standard range) - - "25.1-25.4" (breakout range) - - "26.1" (single breakout interface) - - .EXAMPLE - Expand-NetworkPortRange -PortRange "1-5" - Returns: @(1, 2, 3, 4, 5) - - .EXAMPLE - Expand-NetworkPortRange -PortRange "25.1-25.4" - Returns: @("25.1", "25.2", "25.3", "25.4") - - .OUTPUTS - [Object[]] Array of port identifiers (integers for standard ports, strings for breakout) - - .NOTES - Uses Write-Output -NoEnumerate to prevent PowerShell array enumeration issues - with single-element arrays. - #> - [CmdletBinding()] - [OutputType([Object[]])] - param( - [Parameter(Mandatory = $true, ValueFromPipeline = $true)] - [ValidateNotNullOrEmpty()] - [string]$PortRange - ) - - begin { - Write-Verbose "Starting port range expansion" - } - - process { - try { - Write-Verbose "Processing range: $PortRange" - - # Handle breakout interface ranges (e.g., "25.1-25.4") - if ($PortRange -match '^(\d+)\.(\d+)-(\d+)\.(\d+)$') { - $startPort = [int]$Matches[1] - $startSub = [int]$Matches[2] - $endPort = [int]$Matches[3] - $endSub = [int]$Matches[4] - - # Validate range consistency - if ($startPort -ne $endPort) { - throw "Breakout ranges must use the same primary interface: $PortRange" - } - - $result = @() - for ($sub = $startSub; $sub -le $endSub; $sub++) { - $result += "$startPort.$sub" - } - - Write-Verbose "Expanded breakout range to $($result.Count) interfaces" - Write-Output -NoEnumerate $result - return - } - - # Handle single breakout interface (e.g., "26.1") - if ($PortRange -match '^\d+\.\d+$') { - Write-Verbose "Single breakout interface: $PortRange" - Write-Output -NoEnumerate @($PortRange) - return - } - - # Handle standard port ranges (e.g., "1-24") - if ($PortRange -match '^(\d+)-(\d+)$') { - $start = [int]$Matches[1] - $end = [int]$Matches[2] - - if ($start -gt $end) { - throw "Invalid range: start port ($start) greater than end port ($end)" - } - - $result = @($start..$end) - Write-Verbose "Expanded standard range to $($result.Count) ports" - Write-Output -NoEnumerate $result - return - } - - # Handle single standard port - if ($PortRange -match '^\d+$') { - $port = [int]$PortRange - Write-Verbose "Single standard port: $port" - Write-Output -NoEnumerate @($port) - return - } - - throw "Invalid port range format: $PortRange" - } - catch { - Write-Error "Failed to expand port range '$PortRange': $($_.Exception.Message)" - throw - } - } - - end { - Write-Verbose "Port range expansion completed" - } -} -``` - -### 📚 Documentation Standards - -#### **Comment-Based Help Requirements** - -Every function must include: - -```powershell -<# -.SYNOPSIS - Brief one-line description of what the function does. - -.DESCRIPTION - Detailed explanation of the function's purpose, behavior, and any important - implementation details. Include algorithm explanations if complex. - -.PARAMETER ParameterName - Description of each parameter, including valid values, formats, and examples. - -.EXAMPLE - Provide multiple realistic examples showing different use cases. - -.EXAMPLE - Include edge cases and error scenarios where helpful. - -.INPUTS - What can be piped to this function. - -.OUTPUTS - What the function returns, including data types. - -.NOTES - Version information, author, change history, dependencies, or special considerations. - -.LINK - References to related functions, documentation, or external resources. -#> -``` - -### 🔧 Error Handling - -#### **Comprehensive Error Management** - -```powershell -function Import-NetworkConfiguration { - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [string]$ConfigPath - ) - - # Use try/catch with specific error handling - try { - # Validate file existence - if (-not (Test-Path $ConfigPath)) { - throw [System.IO.FileNotFoundException]::new("Configuration file not found: $ConfigPath") - } - - # Attempt JSON parsing with detailed error context - $jsonContent = Get-Content $ConfigPath -Raw -ErrorAction Stop - $config = $jsonContent | ConvertFrom-Json -ErrorAction Stop - - # Business logic validation - if (-not $config.devices -or $config.devices.Count -eq 0) { - throw [System.ArgumentException]::new("Configuration must contain at least one device") - } - - foreach ($device in $config.devices) { - if (-not $device.deviceName) { - throw [System.ArgumentException]::new("All devices must have a 'deviceName' property") - } - } - - Write-Verbose "Successfully imported configuration with $($config.devices.Count) devices" - return $config - } - catch [System.IO.FileNotFoundException] { - Write-Error "File access error: $($_.Exception.Message)" -Category ObjectNotFound - throw - } - catch [System.ArgumentException] { - Write-Error "Configuration validation error: $($_.Exception.Message)" -Category InvalidArgument - throw - } - catch { - # Generic JSON parsing errors - if ($_.Exception.Message -like "*JSON*") { - Write-Error "JSON parsing failed in '$ConfigPath'. Please verify file format and syntax." -Category InvalidData - } - else { - Write-Error "Unexpected error importing configuration: $($_.Exception.Message)" -Category NotSpecified - } - throw - } -} -``` - -### ⚡ Performance Guidelines - -
-🚀 Performance Optimization Patterns - -```powershell -# ✅ Good: Use efficient collections -$deviceList = [System.Collections.Generic.List[PSObject]]::new() -$connectionMap = [System.Collections.Hashtable]::new() - -# ✅ Good: Minimize object creation in loops -foreach ($device in $devices) { - $deviceList.Add([PSCustomObject]@{ - Name = $device.deviceName - Ports = $device.portRanges | ForEach-Object { Expand-PortRange $_.range } - }) -} - -# ❌ Avoid: Inefficient array operations -# $results = @() -# foreach ($item in $largeCollection) { -# $results += $item # Creates new array each time! -# } - -# ✅ Good: Use pipeline efficiently -$processedDevices = $devices | - Where-Object { $_.deviceType -eq 'Switch' } | - ForEach-Object { - [PSCustomObject]@{ - Name = $_.deviceName - PortCount = ($_.portRanges | Measure-Object).Count - } - } - -# ✅ Good: Parallel processing for independent operations -$results = $devices | ForEach-Object -Parallel { - param($device) - Process-DeviceConfiguration -Device $device -} -ThrottleLimit 10 -``` - -
- -## � Python Development Best Practices - -### 🔐 Python Security Best Practices - -#### **Input Validation & Sanitization** - -```python -import json -import os -from pathlib import Path -from typing import Dict, Any, Optional -import logging - -def validate_input_json(filepath: Path) -> Dict[str, Any]: - """ - Safely load and validate JSON configuration files. - - Args: - filepath: Path to JSON configuration file - - Returns: - Validated configuration dictionary - - Raises: - FileNotFoundError: If configuration file doesn't exist - ValueError: If JSON is invalid or missing required fields - PermissionError: If file cannot be read - """ - # Validate file exists and is readable - if not filepath.exists(): - raise FileNotFoundError(f"Configuration file not found: {filepath}") - - if not filepath.is_file(): - raise ValueError(f"Path is not a file: {filepath}") - - # Check file permissions - if not os.access(filepath, os.R_OK): - raise PermissionError(f"Cannot read file: {filepath}") - - # Validate file size (prevent DoS attacks) - file_size = filepath.stat().st_size - if file_size > 50 * 1024 * 1024: # 50MB limit - raise ValueError(f"Configuration file too large: {file_size} bytes") - - try: - with open(filepath, 'r', encoding='utf-8') as file: - data = json.load(file) - except json.JSONDecodeError as e: - raise ValueError(f"Invalid JSON format: {e}") - except UnicodeDecodeError as e: - raise ValueError(f"File encoding error: {e}") - - # Validate required structure - required_fields = ['switch'] - for field in required_fields: - if field not in data: - raise ValueError(f"Missing required field: {field}") - - # Validate switch metadata - switch_data = data['switch'] - switch_required = ['make', 'firmware'] - for field in switch_required: - if field not in switch_data: - raise ValueError(f"Missing required switch field: {field}") - if not isinstance(switch_data[field], str) or not switch_data[field].strip(): - raise ValueError(f"Switch field '{field}' must be non-empty string") - - logging.info(f"Successfully validated configuration: {filepath}") - return data - -def sanitize_path_component(component: str) -> str: - """ - Sanitize string for use in file paths. - - Args: - component: String to sanitize - - Returns: - Sanitized string safe for file paths - """ - # Remove dangerous characters - safe_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_." - sanitized = ''.join(c for c in component if c in safe_chars) - - # Prevent directory traversal - if sanitized in ('..', '.'): - sanitized = '_' - - # Ensure not empty - if not sanitized: - sanitized = 'default' - - return sanitized[:255] # Limit length -``` - -#### **Secure File Operations** - -```python -from pathlib import Path -import tempfile -import shutil -from contextlib import contextmanager - -@contextmanager -def secure_temp_dir(): - """ - Create a secure temporary directory with proper cleanup. - """ - temp_dir = None - try: - temp_dir = Path(tempfile.mkdtemp(prefix='netconfig_')) - # Set restrictive permissions (owner only) - temp_dir.chmod(0o700) - yield temp_dir - finally: - if temp_dir and temp_dir.exists(): - shutil.rmtree(temp_dir, ignore_errors=True) - -def safe_write_config(content: str, output_path: Path) -> None: - """ - Safely write configuration content to file. - - Args: - content: Configuration content to write - output_path: Destination file path - """ - # Validate output directory - output_dir = output_path.parent - if not output_dir.exists(): - output_dir.mkdir(parents=True, mode=0o755) - - # Use atomic write with temporary file - temp_path = output_path.with_suffix(output_path.suffix + '.tmp') - - try: - with open(temp_path, 'w', encoding='utf-8') as temp_file: - temp_file.write(content) - temp_file.flush() - os.fsync(temp_file.fileno()) # Force write to disk - - # Atomic move - temp_path.replace(output_path) - - # Set appropriate permissions - output_path.chmod(0o644) - - logging.info(f"Successfully wrote configuration to: {output_path}") - - except Exception as e: - # Cleanup on failure - if temp_path.exists(): - temp_path.unlink() - raise -``` - -### 🏗️ Code Structure & Organization - -#### **Module Design Principles** - -```python -""" -Network Configuration Generator Module - -This module provides functionality for generating network switch configurations -from standardized JSON input using Jinja2 templates. - -Example: - Basic usage of the configuration generator: - - from generator import generate_config - - generate_config( - input_std_json="config.json", - template_folder="templates/", - output_folder="output/" - ) - -Attributes: - __version__ (str): The current version of this module - __author__ (str): Module author information -""" - -__version__ = "1.0.0" -__author__ = "Network Engineering Team" - -import logging -from pathlib import Path -from typing import Dict, Any, Optional -from jinja2 import Environment, FileSystemLoader, select_autoescape - -# Configure module-level logging -logger = logging.getLogger(__name__) - -class ConfigurationError(Exception): - """Custom exception for configuration-related errors.""" - pass - -class TemplateError(Exception): - """Custom exception for template-related errors.""" - pass - -class NetworkConfigGenerator: - """ - Main class for generating network switch configurations. - - This class handles the entire configuration generation pipeline from - input validation through template rendering to output file creation. - - Attributes: - template_env: Jinja2 environment for template rendering - output_directory: Path where generated configurations are written - """ - - def __init__(self, template_directory: Path, output_directory: Path): - """ - Initialize the configuration generator. - - Args: - template_directory: Path to Jinja2 templates - output_directory: Path for output configurations - - Raises: - FileNotFoundError: If template directory doesn't exist - PermissionError: If directories aren't accessible - """ - self.template_directory = Path(template_directory) - self.output_directory = Path(output_directory) - - # Validate directories - if not self.template_directory.exists(): - raise FileNotFoundError(f"Template directory not found: {template_directory}") - - if not self.template_directory.is_dir(): - raise ValueError(f"Template path is not a directory: {template_directory}") - - # Create output directory if it doesn't exist - self.output_directory.mkdir(parents=True, exist_ok=True) - - # Initialize Jinja2 environment with security settings - self.template_env = Environment( - loader=FileSystemLoader(str(self.template_directory)), - autoescape=select_autoescape(['html', 'xml']), - trim_blocks=True, - lstrip_blocks=True - ) - - logger.info(f"Initialized generator with templates: {template_directory}") - - def generate_configuration( - self, - config_data: Dict[str, Any], - device_name: str - ) -> Path: - """ - Generate configuration for a single network device. - - Args: - config_data: Validated configuration data dictionary - device_name: Name of the target device - - Returns: - Path to generated configuration file - - Raises: - ConfigurationError: If configuration generation fails - TemplateError: If template rendering fails - """ - try: - # Extract device metadata - switch_data = config_data['switch'] - make = sanitize_path_component(switch_data['make'].lower()) - firmware = sanitize_path_component(switch_data['firmware'].lower()) - - # Find appropriate template - template_path = self._find_template(make, firmware) - template = self.template_env.get_template(str(template_path)) - - # Render configuration - rendered_config = template.render( - switch=switch_data, - device_name=device_name, - **config_data - ) - - # Generate output filename - output_filename = f"{sanitize_path_component(device_name)}.cfg" - output_path = self.output_directory / output_filename - - # Write configuration file - safe_write_config(rendered_config, output_path) - - return output_path - - except Exception as e: - logger.error(f"Failed to generate configuration for {device_name}: {e}") - raise ConfigurationError(f"Configuration generation failed: {e}") - - def _find_template(self, make: str, firmware: str) -> Path: - """ - Locate the appropriate template file for device make/firmware. - - Args: - make: Device manufacturer (e.g., 'cisco', 'dell') - firmware: Device firmware (e.g., 'nxos', 'os10') - - Returns: - Path to template file - - Raises: - TemplateError: If template cannot be found - """ - # Try specific template first - specific_template = self.template_directory / make / firmware / "full_config.j2" - if specific_template.exists(): - return Path(make) / firmware / "full_config.j2" - - # Try generic template - generic_template = self.template_directory / "generic" / "full_config.j2" - if generic_template.exists(): - logger.warning(f"Using generic template for {make}/{firmware}") - return Path("generic") / "full_config.j2" - - raise TemplateError(f"No template found for {make}/{firmware}") -``` - -### 🧪 Python Testing Framework - -#### **pytest Configuration** - -```python -# conftest.py - pytest configuration and fixtures -import pytest -from pathlib import Path -import tempfile -import shutil -import json -from typing import Dict, Any - -@pytest.fixture -def temp_directory(): - """Create a temporary directory for test files.""" - temp_dir = Path(tempfile.mkdtemp()) - yield temp_dir - shutil.rmtree(temp_dir, ignore_errors=True) - -@pytest.fixture -def sample_config() -> Dict[str, Any]: - """Provide sample configuration data for tests.""" - return { - "switch": { - "make": "cisco", - "firmware": "nxos", - "version": "9.3.8" - }, - "interfaces": [ - { - "name": "Ethernet1/1", - "type": "access", - "vlan": 100 - } - ] - } - -@pytest.fixture -def sample_config_file(temp_directory, sample_config): - """Create a sample JSON configuration file.""" - config_file = temp_directory / "test_config.json" - with open(config_file, 'w') as f: - json.dump(sample_config, f, indent=2) - return config_file - -@pytest.fixture -def template_directory(temp_directory): - """Create a sample template directory structure.""" - template_dir = temp_directory / "templates" - cisco_dir = template_dir / "cisco" / "nxos" - cisco_dir.mkdir(parents=True) - - # Create sample template - template_content = """ -hostname {{ device_name }} -! -{% for interface in interfaces %} -interface {{ interface.name }} - switchport mode {{ interface.type }} - {% if interface.vlan %} - switchport access vlan {{ interface.vlan }} - {% endif %} -! -{% endfor %} -""" - - template_file = cisco_dir / "full_config.j2" - template_file.write_text(template_content) - - return template_dir -``` - -#### **Comprehensive Test Suite** - -```python -# test_generator.py - Main generator testing -import pytest -from pathlib import Path -from generator import NetworkConfigGenerator, ConfigurationError, TemplateError -from loader import validate_input_json - -class TestNetworkConfigGenerator: - """Test suite for NetworkConfigGenerator class.""" - - def test_generator_initialization(self, template_directory, temp_directory): - """Test proper generator initialization.""" - output_dir = temp_directory / "output" - generator = NetworkConfigGenerator(template_directory, output_dir) - - assert generator.template_directory == template_directory - assert generator.output_directory == output_dir - assert output_dir.exists() # Should be created automatically - - def test_generator_invalid_template_directory(self, temp_directory): - """Test initialization with invalid template directory.""" - invalid_template_dir = temp_directory / "nonexistent" - output_dir = temp_directory / "output" - - with pytest.raises(FileNotFoundError): - NetworkConfigGenerator(invalid_template_dir, output_dir) - - def test_generate_configuration_success( - self, - template_directory, - temp_directory, - sample_config - ): - """Test successful configuration generation.""" - output_dir = temp_directory / "output" - generator = NetworkConfigGenerator(template_directory, output_dir) - - result_path = generator.generate_configuration(sample_config, "switch01") - - assert result_path.exists() - assert result_path.name == "switch01.cfg" - - # Verify content - content = result_path.read_text() - assert "hostname switch01" in content - assert "interface Ethernet1/1" in content - assert "switchport access vlan 100" in content - - def test_generate_configuration_missing_template( - self, - temp_directory, - sample_config - ): - """Test configuration generation with missing template.""" - # Create empty template directory - template_dir = temp_directory / "templates" - template_dir.mkdir() - output_dir = temp_directory / "output" - - generator = NetworkConfigGenerator(template_dir, output_dir) - - with pytest.raises(ConfigurationError): - generator.generate_configuration(sample_config, "switch01") - - def test_path_sanitization(self, template_directory, temp_directory, sample_config): - """Test that device names are properly sanitized for file paths.""" - output_dir = temp_directory / "output" - generator = NetworkConfigGenerator(template_directory, output_dir) - - # Test with potentially dangerous device name - dangerous_name = "../../../etc/passwd" - result_path = generator.generate_configuration(sample_config, dangerous_name) - - # Should be sanitized to safe filename - assert result_path.parent == output_dir - assert ".." not in str(result_path) - assert "passwd" not in str(result_path) - -class TestInputValidation: - """Test suite for input validation functions.""" - - def test_validate_valid_config(self, sample_config_file): - """Test validation of valid configuration file.""" - result = validate_input_json(sample_config_file) - - assert isinstance(result, dict) - assert "switch" in result - assert result["switch"]["make"] == "cisco" - - def test_validate_nonexistent_file(self, temp_directory): - """Test validation of nonexistent file.""" - nonexistent_file = temp_directory / "nonexistent.json" - - with pytest.raises(FileNotFoundError): - validate_input_json(nonexistent_file) - - def test_validate_invalid_json(self, temp_directory): - """Test validation of invalid JSON file.""" - invalid_file = temp_directory / "invalid.json" - invalid_file.write_text("{ invalid json content") - - with pytest.raises(ValueError, match="Invalid JSON format"): - validate_input_json(invalid_file) - - def test_validate_missing_required_fields(self, temp_directory): - """Test validation of JSON missing required fields.""" - incomplete_config = {"incomplete": "config"} - config_file = temp_directory / "incomplete.json" - - with open(config_file, 'w') as f: - json.dump(incomplete_config, f) - - with pytest.raises(ValueError, match="Missing required field"): - validate_input_json(config_file) - - @pytest.mark.parametrize("file_size", [0, 1024, 50 * 1024 * 1024 + 1]) - def test_validate_file_size_limits(self, temp_directory, file_size): - """Test file size validation.""" - large_file = temp_directory / "large.json" - - # Create file of specified size - with open(large_file, 'wb') as f: - if file_size > 0: - f.write(b'x' * file_size) - - if file_size > 50 * 1024 * 1024: # Over 50MB limit - with pytest.raises(ValueError, match="Configuration file too large"): - validate_input_json(large_file) - elif file_size == 0: - with pytest.raises(ValueError, match="Invalid JSON format"): - validate_input_json(large_file) - else: - # Should handle normal sized files (will fail JSON parsing but not size check) - with pytest.raises(ValueError): - validate_input_json(large_file) - -# Integration tests -class TestEndToEndGeneration: - """End-to-end integration tests.""" - - def test_full_generation_pipeline( - self, - template_directory, - temp_directory, - sample_config_file - ): - """Test complete generation pipeline from file to output.""" - output_dir = temp_directory / "output" - - # Load and validate configuration - config_data = validate_input_json(sample_config_file) - - # Generate configuration - generator = NetworkConfigGenerator(template_directory, output_dir) - result_path = generator.generate_configuration(config_data, "test-switch") - - # Verify results - assert result_path.exists() - content = result_path.read_text() - assert "hostname test-switch" in content - - # Verify file permissions - assert oct(result_path.stat().st_mode)[-3:] == '644' -``` - -### 📦 Python Dependency Management - -#### **requirements.txt Best Practices** - -```plaintext -# Core dependencies with version pinning -jinja2>=3.1.0,<4.0.0 -pytest>=7.0.0,<8.0.0 - -# Development dependencies -pytest-cov>=4.0.0,<5.0.0 -black>=22.0.0,<24.0.0 -flake8>=5.0.0,<6.0.0 -mypy>=1.0.0,<2.0.0 -isort>=5.0.0,<6.0.0 - -# Security scanning -bandit>=1.7.0,<2.0.0 -safety>=2.0.0,<3.0.0 -``` - -#### **Setup Configuration (setup.py or pyproject.toml)** - -```toml -# pyproject.toml - Modern Python project configuration -[build-system] -requires = ["setuptools>=45", "wheel", "setuptools_scm>=6.2"] -build-backend = "setuptools.build_meta" - -[project] -name = "azurestack-network-config-generator" -description = "Network switch configuration generator for AzureStack environments" -readme = "README.md" -authors = [{name = "Network Engineering Team"}] -license = {text = "MIT"} -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: System Administrators", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", -] -requires-python = ">=3.7" -dependencies = [ - "jinja2>=3.1.0,<4.0.0", -] -dynamic = ["version"] - -[project.optional-dependencies] -dev = [ - "pytest>=7.0.0,<8.0.0", - "pytest-cov>=4.0.0,<5.0.0", - "black>=22.0.0,<24.0.0", - "flake8>=5.0.0,<6.0.0", - "mypy>=1.0.0,<2.0.0", - "isort>=5.0.0,<6.0.0", - "bandit>=1.7.0,<2.0.0", - "safety>=2.0.0,<3.0.0", -] - -[project.scripts] -netconfig = "src.main:main" - -[tool.setuptools_scm] -write_to = "src/_version.py" - -[tool.black] -line-length = 88 -target-version = ['py37', 'py38', 'py39', 'py310', 'py311'] -include = '\.pyi?$' -extend-exclude = ''' -/( - # directories - \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | build - | dist -)/ -''' - -[tool.isort] -profile = "black" -multi_line_output = 3 -line_length = 88 -known_first_party = ["src"] - -[tool.mypy] -python_version = "3.7" -warn_return_any = true -warn_unused_configs = true -disallow_untyped_defs = true -disallow_incomplete_defs = true -check_untyped_defs = true -disallow_untyped_decorators = true -no_implicit_optional = true -warn_redundant_casts = true -warn_unused_ignores = true -warn_no_return = true -warn_unreachable = true -strict_equality = true - -[tool.pytest.ini_options] -testpaths = ["tests"] -python_files = ["test_*.py"] -python_classes = ["Test*"] -python_functions = ["test_*"] -addopts = [ - "--verbose", - "--cov=src", - "--cov-report=html", - "--cov-report=term-missing", - "--cov-fail-under=85", -] - -[tool.coverage.run] -source = ["src"] -omit = [ - "*/tests/*", - "*/test_*.py", - "setup.py", -] - -[tool.coverage.report] -exclude_lines = [ - "pragma: no cover", - "def __repr__", - "if self.debug:", - "if settings.DEBUG", - "raise AssertionError", - "raise NotImplementedError", - "if 0:", - "if __name__ == .__main__.:", -] -``` - -## 📖 GitHub Markdown Best Practices - -### 📊 Document Structure - -#### **Standardized README Structure** - -```markdown -# 🛠️ Tool Name - -[![Badges](shields.io-badges)] - -> Brief compelling description with key value proposition - -## 📋 Table of Contents - -[Auto-generated navigation] - -## 📖 Overview - -[Detailed description] - -## ⚡ Quick Start - -[Immediate usage examples] - -## ✨ Features - -[Key capabilities with visual hierarchy] - -## 📝 Input Requirements - -[Configuration specs] - -## ⚙️ Installation & Dependencies - -[Setup instructions] - -## 🚀 Usage - -[Comprehensive examples] - -## 📊 Output Examples - -[Sample outputs] - -## 🧪 Testing & Validation - -[Test procedures] - -## 🤝 Contributing - -[Contribution guidelines] - -## 📞 Support - -[Help resources] - -## 📚 Version History - -[Change log] -``` - -### 🎨 Visual Elements - -#### **Strategic Emoji Usage** - -| Category | Emojis | Usage | -| --------------- | ----------- | ----------------------------------------- | -| **Actions** | ⚡ 🚀 🔧 🛠️ | Commands, tools, operations | -| **Information** | 📖 📝 📋 📊 | Documentation, data | -| **Status** | ✅ ❌ ⚠️ 🎯 | Success, failure, warnings, goals | -| **Categories** | 🔐 💻 🧪 🤝 | Security, development, testing, community | -| **Navigation** | 📋 🔗 📞 📚 | TOC, links, support, resources | - -#### **Enhanced Code Blocks** - -````markdown -```powershell -# 🎯 Example: Generate network documentation -.\PortMap.ps1 -InputFile "config.json" -OutputFormat Markdown - -# 📊 Result: Professional documentation generated -# ✅ Output: network-config-Cisco-Dell-3dev-portmap.md -``` -```` - -#### **Callout Boxes** - -```markdown -> 💡 **Pro Tip**: Use `-ShowUnused` to see all ports in sequential order - -> ⚠️ **Warning**: CSV format creates individual files per device - -> 📋 **Prerequisites**: PowerShell 5.1+ and valid JSON configuration - -> 🎯 **Goal**: Comprehensive network documentation with breakout cable support -``` - -### 🔗 Linking & Navigation - -#### **Internal Linking Best Practices** - -```markdown - - -Check the [troubleshooting guide](../docs/TROUBLESHOOTING.md) for common issues. - - - -See the [PowerShell documentation][ps-docs] for cmdlet details. - -[ps-docs]: https://docs.microsoft.com/en-us/powershell/ - - - -[![Tests](https://img.shields.io/badge/Tests-Comprehensive-success)](README.MD#testing--validation) -``` - -### 📱 GitHub-Specific Features - -
-🔧 Advanced GitHub Markdown Features - -#### **Collapsible Sections** - -```markdown -
-📝 Command Line Parameters - -| Parameter | Type | Required | Description | -| ------------ | ------ | -------- | -------------------------- | -| `-InputFile` | String | ✅ | Path to JSON configuration | - -
-``` - -#### **Mermaid Diagrams** - -````markdown -```mermaid -graph TD - A[JSON Config] --> B[PortMap Tool] - B --> C[Markdown Docs] - B --> D[CSV Reports] - B --> E[JSON Data] -``` -```` - -#### **Task Lists** - -```markdown -- [x] Implement breakout cable support -- [x] Add comprehensive unit tests -- [ ] Add GUI interface -- [ ] Implement REST API -``` - -#### **Tables with Alignment** - -```markdown -| Feature | Status | Version | -| :-------------- | :--------: | ------: | -| Breakout Cables | ✅ Active | v1.0+ | -| CSV Output | ✅ Active | v1.0+ | -| GUI Interface | 🚧 Planned | v2.0 | -``` - -
- -## 🧪 Unit Testing Framework - -### 🎯 Testing Strategy - -#### **Test Pyramid Architecture** - -```mermaid -graph TD - A[Unit Tests - 70%] --> B[Integration Tests - 20%] - B --> C[End-to-End Tests - 10%] - - A --> A1[Function Logic] - A --> A2[Input Validation] - A --> A3[Error Handling] - - B --> B1[File Operations] - B --> B2[Output Formats] - B --> B3[Configuration Loading] - - C --> C1[Complete Workflows] - C --> C2[User Scenarios] -``` - -### 🔬 Test Implementation - -#### **Comprehensive Test Structure** - -```powershell -#Requires -Version 5.1 - -<# -.SYNOPSIS - Comprehensive test suite for network configuration tools. - -.DESCRIPTION - Implements multi-layered testing approach with unit tests, integration tests, - and end-to-end validation scenarios. -#> - -[CmdletBinding()] -param( - [Parameter(Mandatory = $false)] - [string]$TestDataPath = ".\test-configurations", - - [Parameter(Mandatory = $false)] - [ValidateSet("Unit", "Integration", "E2E", "All")] - [string]$TestType = "All", - - [Parameter(Mandatory = $false)] - [switch]$GenerateReport -) - -# Test framework configuration -$Script:TestResults = [System.Collections.Generic.List[object]]::new() -$Script:TestsPassed = 0 -$Script:TestsFailed = 0 -$Script:TestsSkipped = 0 - -function Write-TestResult { - <# - .SYNOPSIS - Records and displays test results with standardized formatting. - #> - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [string]$TestName, - - [Parameter(Mandatory = $true)] - [ValidateSet("Pass", "Fail", "Skip")] - [string]$Result, - - [Parameter(Mandatory = $false)] - [string]$Message = "", - - [Parameter(Mandatory = $false)] - [string]$Category = "General", - - [Parameter(Mandatory = $false)] - [timespan]$Duration = [timespan]::Zero - ) - - $testResult = [PSCustomObject]@{ - TestName = $TestName - Category = $Category - Result = $Result - Message = $Message - Duration = $Duration - Timestamp = Get-Date - Computer = $env:COMPUTERNAME - User = $env:USERNAME - } - - $Script:TestResults.Add($testResult) - - switch ($Result) { - "Pass" { - Write-Host "✅ PASS: $TestName" -ForegroundColor Green - if ($Message) { Write-Host " 💡 $Message" -ForegroundColor Gray } - $Script:TestsPassed++ - } - "Fail" { - Write-Host "❌ FAIL: $TestName" -ForegroundColor Red - if ($Message) { Write-Host " 🚫 $Message" -ForegroundColor Red } - $Script:TestsFailed++ - } - "Skip" { - Write-Host "⏭️ SKIP: $TestName" -ForegroundColor Yellow - if ($Message) { Write-Host " ⚠️ $Message" -ForegroundColor Yellow } - $Script:TestsSkipped++ - } - } -} - -function Test-PortRangeExpansion { - <# - .SYNOPSIS - Unit tests for port range expansion functionality. - #> - [CmdletBinding()] - param() - - Write-Host "`n🔬 Unit Tests: Port Range Expansion" -ForegroundColor Cyan - - # Test 1: Standard range expansion - $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - try { - $result = Expand-NetworkPortRange -PortRange "1-5" - $expected = @(1, 2, 3, 4, 5) - - if (Compare-Object $result $expected) { - Write-TestResult "Standard Range (1-5)" "Fail" "Expected @(1,2,3,4,5), got $($result -join ',')" "Unit" $stopwatch.Elapsed - } - else { - Write-TestResult "Standard Range (1-5)" "Pass" "Correctly expanded to 5 ports" "Unit" $stopwatch.Elapsed - } - } - catch { - Write-TestResult "Standard Range (1-5)" "Fail" $_.Exception.Message "Unit" $stopwatch.Elapsed - } - finally { - $stopwatch.Stop() - } - - # Test 2: Breakout range expansion - $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - try { - $result = Expand-NetworkPortRange -PortRange "25.1-25.4" - $expected = @("25.1", "25.2", "25.3", "25.4") - - if (Compare-Object $result $expected) { - Write-TestResult "Breakout Range (25.1-25.4)" "Fail" "Expected @('25.1','25.2','25.3','25.4'), got $($result -join ',')" "Unit" $stopwatch.Elapsed - } - else { - Write-TestResult "Breakout Range (25.1-25.4)" "Pass" "Correctly expanded breakout interfaces" "Unit" $stopwatch.Elapsed - } - } - catch { - Write-TestResult "Breakout Range (25.1-25.4)" "Fail" $_.Exception.Message "Unit" $stopwatch.Elapsed - } - finally { - $stopwatch.Stop() - } - - # Test 3: Single breakout interface - $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - try { - $result = Expand-NetworkPortRange -PortRange "26.1" - $expected = @("26.1") - - if ($result.Count -ne 1 -or $result[0] -ne "26.1") { - Write-TestResult "Single Breakout (26.1)" "Fail" "Expected @('26.1'), got $($result -join ',')" "Unit" $stopwatch.Elapsed - } - else { - Write-TestResult "Single Breakout (26.1)" "Pass" "Single breakout interface handled correctly" "Unit" $stopwatch.Elapsed - } - } - catch { - Write-TestResult "Single Breakout (26.1)" "Fail" $_.Exception.Message "Unit" $stopwatch.Elapsed - } - finally { - $stopwatch.Stop() - } - - # Test 4: Error handling for invalid ranges - $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - try { - $result = Expand-NetworkPortRange -PortRange "invalid-range" -ErrorAction Stop - Write-TestResult "Invalid Range Handling" "Fail" "Should have thrown an error for invalid range" "Unit" $stopwatch.Elapsed - } - catch { - Write-TestResult "Invalid Range Handling" "Pass" "Correctly rejected invalid range format" "Unit" $stopwatch.Elapsed - } - finally { - $stopwatch.Stop() - } -} - -function Test-ConfigurationValidation { - <# - .SYNOPSIS - Integration tests for configuration file processing. - #> - [CmdletBinding()] - param() - - Write-Host "`n🔧 Integration Tests: Configuration Processing" -ForegroundColor Cyan - - # Test valid configuration - $testConfig = Join-Path $TestDataPath "valid-config.json" - if (Test-Path $testConfig) { - $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - try { - $config = Import-NetworkConfiguration -ConfigPath $testConfig - if ($config.devices -and $config.devices.Count -gt 0) { - Write-TestResult "Valid Configuration Loading" "Pass" "Loaded $($config.devices.Count) devices" "Integration" $stopwatch.Elapsed - } - else { - Write-TestResult "Valid Configuration Loading" "Fail" "No devices found in configuration" "Integration" $stopwatch.Elapsed - } - } - catch { - Write-TestResult "Valid Configuration Loading" "Fail" $_.Exception.Message "Integration" $stopwatch.Elapsed - } - finally { - $stopwatch.Stop() - } - } - else { - Write-TestResult "Valid Configuration Loading" "Skip" "Test configuration file not found" "Integration" - } -} - -function Show-TestReport { - <# - .SYNOPSIS - Generates comprehensive test report with statistics and details. - #> - [CmdletBinding()] - param() - - $totalTests = $Script:TestsPassed + $Script:TestsFailed + $Script:TestsSkipped - $successRate = if ($totalTests -gt 0) { [math]::Round(($Script:TestsPassed / $totalTests) * 100, 2) } else { 0 } - - Write-Host "`n📊 Test Report Summary" -ForegroundColor Magenta - Write-Host "=" * 50 -ForegroundColor Magenta - Write-Host "Total Tests: $totalTests" -ForegroundColor White - Write-Host "✅ Passed: $Script:TestsPassed" -ForegroundColor Green - Write-Host "❌ Failed: $Script:TestsFailed" -ForegroundColor Red - Write-Host "⏭️ Skipped: $Script:TestsSkipped" -ForegroundColor Yellow - Write-Host "📈 Success Rate: $successRate%" -ForegroundColor $(if ($successRate -eq 100) { "Green" } elseif ($successRate -ge 80) { "Yellow" } else { "Red" }) - - # Category breakdown - $categories = $Script:TestResults | Group-Object Category - if ($categories) { - Write-Host "`n📋 Results by Category:" -ForegroundColor Cyan - foreach ($category in $categories) { - $categoryPassed = ($category.Group | Where-Object Result -eq "Pass").Count - $categoryTotal = $category.Count - $categoryRate = [math]::Round(($categoryPassed / $categoryTotal) * 100, 1) - Write-Host " $($category.Name): $categoryPassed/$categoryTotal ($categoryRate%)" -ForegroundColor White - } - } - - # Failed tests details - $failedTests = $Script:TestResults | Where-Object Result -eq "Fail" - if ($failedTests) { - Write-Host "`n❌ Failed Tests:" -ForegroundColor Red - foreach ($test in $failedTests) { - Write-Host " • $($test.TestName): $($test.Message)" -ForegroundColor Red - } - } - - # Performance analysis - $testsWithDuration = $Script:TestResults | Where-Object { $_.Duration.TotalMilliseconds -gt 0 } - if ($testsWithDuration) { - $avgDuration = ($testsWithDuration | Measure-Object -Property Duration -Average).Average.TotalMilliseconds - $slowTests = $testsWithDuration | Where-Object { $_.Duration.TotalMilliseconds -gt ($avgDuration * 2) } - - Write-Host "`n⏱️ Performance Analysis:" -ForegroundColor Cyan - Write-Host " Average Test Duration: $([math]::Round($avgDuration, 2))ms" -ForegroundColor White - - if ($slowTests) { - Write-Host " 🐌 Slow Tests (>2x average):" -ForegroundColor Yellow - foreach ($test in $slowTests) { - Write-Host " • $($test.TestName): $([math]::Round($test.Duration.TotalMilliseconds, 2))ms" -ForegroundColor Yellow - } - } - } - - # Generate report file if requested - if ($GenerateReport) { - $reportPath = "test-report-$(Get-Date -Format 'yyyyMMdd-HHmmss').json" - $reportData = @{ - Summary = @{ - TotalTests = $totalTests - Passed = $Script:TestsPassed - Failed = $Script:TestsFailed - Skipped = $Script:TestsSkipped - SuccessRate = $successRate - } - TestResults = $Script:TestResults - GeneratedAt = Get-Date - Environment = @{ - Computer = $env:COMPUTERNAME - User = $env:USERNAME - PowerShellVersion = $PSVersionTable.PSVersion.ToString() - OS = $PSVersionTable.OS - } - } - - $reportData | ConvertTo-Json -Depth 10 | Out-File $reportPath - Write-Host "`n📄 Detailed report saved to: $reportPath" -ForegroundColor Green - } -} -``` - -### 📊 Coverage Requirements - -#### **Test Coverage Standards** - -| Component | Unit Tests | Integration Tests | E2E Tests | Target Coverage | -| --------------------- | ----------- | ----------------- | ----------- | --------------- | -| **Core Functions** | ✅ Required | ✅ Required | ⚠️ Selected | 95%+ | -| **Input Validation** | ✅ Required | ✅ Required | ✅ Required | 100% | -| **Error Handling** | ✅ Required | ✅ Required | ⚠️ Selected | 90%+ | -| **Output Generation** | ⚠️ Selected | ✅ Required | ✅ Required | 85%+ | -| **Configuration** | ⚠️ Selected | ✅ Required | ✅ Required | 80%+ | - -### 🚀 Continuous Integration - -#### **GitHub Actions Integration** - -```yaml -name: PowerShell Tests - -on: - push: - branches: [main, develop] - pull_request: - branches: [main] - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [windows-latest, ubuntu-latest, macos-latest] - powershell-version: ["5.1", "7.0", "7.1", "7.2"] - - steps: - - uses: actions/checkout@v3 - - - name: Setup PowerShell - uses: microsoft/setup-powershell@v1 - with: - powershell-version: ${{ matrix.powershell-version }} - - - name: Run Tests - run: | - .\tools\PortMap\Test-PortMap.ps1 -GenerateReport - shell: pwsh - - - name: Upload Test Results - uses: actions/upload-artifact@v3 - if: always() - with: - name: test-results-${{ matrix.os }}-ps${{ matrix.powershell-version }} - path: test-report-*.json -``` - -## 📚 Documentation Maintenance - -### 🔄 Change Management Process - -#### **Documentation Update Workflow** - -```mermaid -flowchart TD - A[Code Change] --> B{Input/Output Modified?} - B -->|Yes| C[Update README] - B -->|No| D[Review Tests] - - C --> E[Update Examples] - E --> F[Update Parameter Docs] - F --> G[Update Output Samples] - G --> H[Validate Links] - H --> I[Update Version History] - - D --> J[Run Test Suite] - J --> K{Tests Pass?} - K -->|No| L[Fix Issues] - K -->|Yes| M[Update Test Docs] - - L --> J - I --> N[Commit Changes] - M --> N - N --> O[Create PR] - O --> P[Documentation Review] - P --> Q[Merge] -``` - -### 📝 Documentation Standards - -#### **Automated Documentation Validation** - -````powershell -function Test-DocumentationIntegrity { - <# - .SYNOPSIS - Validates documentation consistency with code implementation. - #> - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [string]$ProjectPath - ) - - $results = @() - - # Check README examples against actual tool parameters - $readmePath = Join-Path $ProjectPath "README.md" - if (Test-Path $readmePath) { - $readmeContent = Get-Content $readmePath -Raw - - # Extract PowerShell examples from README - $examples = [regex]::Matches($readmeContent, '```powershell\s*\n(.*?)\n```', [System.Text.RegularExpressions.RegexOptions]::Singleline) - - foreach ($example in $examples) { - $code = $example.Groups[1].Value - - # Validate that examples use correct parameter names - $paramMatches = [regex]::Matches($code, '-(\w+)') - foreach ($paramMatch in $paramMatches) { - $paramName = $paramMatch.Groups[1].Value - - # Check if parameter exists in actual tool - try { - $help = Get-Help ".\PortMap.ps1" -Parameter $paramName -ErrorAction SilentlyContinue - if (-not $help) { - $results += [PSCustomObject]@{ - Type = "InvalidParameter" - Location = "README Example" - Issue = "Parameter '-$paramName' not found in tool" - Severity = "Error" - } - } - } - catch { - $results += [PSCustomObject]@{ - Type = "ValidationError" - Location = "README Example" - Issue = "Could not validate parameter '-$paramName': $($_.Exception.Message)" - Severity = "Warning" - } - } - } - } - } - - # Check that all tool parameters are documented - try { - $toolHelp = Get-Help ".\PortMap.ps1" -Full - $toolParameters = $toolHelp.parameters.parameter - - foreach ($param in $toolParameters) { - $paramName = $param.name - if ($readmeContent -notmatch "-$paramName\b") { - $results += [PSCustomObject]@{ - Type = "MissingDocumentation" - Location = "README Parameters" - Issue = "Parameter '-$paramName' not documented in README" - Severity = "Warning" - } - } - } - } - catch { - $results += [PSCustomObject]@{ - Type = "ToolAnalysisError" - Location = "Tool Help" - Issue = "Could not analyze tool parameters: $($_.Exception.Message)" - Severity = "Error" - } - } - - # Validate internal links - $linkMatches = [regex]::Matches($readmeContent, '\[([^\]]+)\]\(([^)]+)\)') - foreach ($link in $linkMatches) { - $linkText = $link.Groups[1].Value - $linkTarget = $link.Groups[2].Value - - # Check relative file links - if ($linkTarget -match '^[^#].*\.md$') { - $targetPath = Join-Path $ProjectPath $linkTarget - if (-not (Test-Path $targetPath)) { - $results += [PSCustomObject]@{ - Type = "BrokenLink" - Location = "README Links" - Issue = "Link target not found: $linkTarget" - Severity = "Error" - } - } - } - - # Check anchor links - if ($linkTarget -match '^#(.+)$') { - $anchor = $linkTarget.Substring(1).ToLower() - $headings = [regex]::Matches($readmeContent, '^#+\s*(.+)$', [System.Text.RegularExpressions.RegexOptions]::Multiline) - $validAnchors = $headings | ForEach-Object { - $heading = $_.Groups[1].Value - # Convert to GitHub anchor format - $heading.ToLower() -replace '[^\w\s-]', '' -replace '\s+', '-' - } - - if ($anchor -notin $validAnchors) { - $results += [PSCustomObject]@{ - Type = "BrokenAnchor" - Location = "README Anchors" - Issue = "Anchor not found: #$anchor" - Severity = "Warning" - } - } - } - } - - return $results -} -```` - -### 🔍 Review Guidelines - -#### **Documentation Review Checklist** - -- [ ] **✅ Accuracy**: All examples work with current tool version -- [ ] **📝 Completeness**: All parameters and features documented -- [ ] **🔗 Links**: All internal and external links functional -- [ ] **📊 Examples**: Output samples match current format -- [ ] **🎯 Consistency**: Terminology and formatting consistent -- [ ] **📱 GitHub Features**: Proper use of badges, TOC, collapsible sections -- [ ] **🔍 SEO**: Good use of headings and keywords for discoverability -- [ ] **👥 Accessibility**: Clear structure and alternative text for images - -### 🤖 Automation - -#### **Documentation Update Scripts** - -```powershell -function Update-ToolDocumentation { - <# - .SYNOPSIS - Automatically updates tool documentation when interface changes. - #> - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [string]$ToolPath, - - [Parameter(Mandatory = $true)] - [string]$ReadmePath, - - [Parameter(Mandatory = $false)] - [switch]$UpdateExamples - ) - - # Generate current parameter documentation - $help = Get-Help $ToolPath -Full - $parametersSection = Generate-ParameterDocumentation -Help $help - - # Update README parameter section - $readme = Get-Content $ReadmePath -Raw - $updatedReadme = Update-ReadmeSection -Content $readme -Section "Parameters" -NewContent $parametersSection - - # Update examples if requested - if ($UpdateExamples) { - $examples = Generate-UsageExamples -ToolPath $ToolPath - $updatedReadme = Update-ReadmeSection -Content $updatedReadme -Section "Usage" -NewContent $examples - } - - # Update version history - $version = Get-ToolVersion -ToolPath $ToolPath - $versionEntry = Generate-VersionEntry -Version $version -Changes $Changes - $updatedReadme = Update-ReadmeSection -Content $updatedReadme -Section "Version History" -NewContent $versionEntry -Prepend - - # Write updated content - Set-Content $ReadmePath -Value $updatedReadme -Encoding UTF8 - - Write-Host "✅ Documentation updated successfully" -ForegroundColor Green -} -``` - -## 🛠️ Tool-Specific Guidelines - -### **PortMap Tool Maintenance** - -When modifying the PortMap tool, ensure these documentation elements stay current: - -#### **Input Format Changes** - -- [ ] Update JSON schema examples in README -- [ ] Refresh sample configuration files -- [ ] Update input validation test cases -- [ ] Verify parameter documentation accuracy - -#### **Output Format Changes** - -- [ ] Regenerate all sample outputs (Markdown, CSV, JSON) -- [ ] Update output format comparison tables -- [ ] Refresh screenshots if applicable -- [ ] Update integration examples - -#### **Feature Additions** - -- [ ] Add feature to features list with emoji -- [ ] Include usage examples -- [ ] Add unit tests for new functionality -- [ ] Update version history -- [ ] Consider updating badges if significant - -#### **Breaking Changes** - -- [ ] Update major version number -- [ ] Document migration path -- [ ] Update all examples -- [ ] Add compatibility notes -- [ ] Consider deprecation warnings - -### **Python Core Generator Maintenance** - -When modifying the Python core components (`src/` directory), ensure these elements are maintained: - -#### **Input Schema Changes** - -- [ ] Update JSON schema validation in `loader.py` -- [ ] Refresh sample input configurations -- [ ] Update pytest test fixtures with new schema -- [ ] Verify input validation error messages -- [ ] Update type hints and docstrings -- [ ] Run `mypy` type checking validation - -#### **Template Changes** - -- [ ] Update Jinja2 templates in `input/jinja2_templates/` -- [ ] Verify template syntax and variable usage -- [ ] Test templates with sample data -- [ ] Update template documentation comments -- [ ] Consider backward compatibility for existing configurations - -#### **Switch Configuration Output Changes** - -- [ ] Regenerate sample switch configurations -- [ ] Update output validation in tests -- [ ] Verify configuration syntax for target devices -- [ ] Update integration test expectations -- [ ] Document new output format features - -#### **Dependency Updates** - -- [ ] Update `requirements.txt` with version constraints -- [ ] Run security scanning with `bandit` and `safety` -- [ ] Update CI/CD pipeline for new dependencies -- [ ] Test compatibility across Python versions (3.7+) -- [ ] Update `pyproject.toml` configuration if needed - -#### **API Changes** - -- [ ] Update function signatures and type hints -- [ ] Maintain backward compatibility where possible -- [ ] Update docstrings and examples -- [ ] Add deprecation warnings for removed features -- [ ] Update integration tests for API changes -- [ ] Consider semantic versioning implications - -#### **Performance Optimizations** - -- [ ] Run performance benchmarks before/after changes -- [ ] Update memory usage tests if applicable -- [ ] Consider impact on large configuration files -- [ ] Profile code with `cProfile` for complex changes -- [ ] Document performance characteristics - -### **Cross-Language Integration** - -When changes affect both Python and PowerShell components: - -#### **Data Format Compatibility** - -- [ ] Ensure JSON output from Python is compatible with PowerShell tools -- [ ] Verify file naming conventions are consistent -- [ ] Test end-to-end workflows with both components -- [ ] Update integration documentation -- [ ] Consider version compatibility matrices - -#### **Documentation Synchronization** - -- [ ] Update README files for both components -- [ ] Synchronize version numbers across tools -- [ ] Update main project documentation -- [ ] Ensure consistent terminology and examples -- [ ] Update architecture diagrams and workflows - -## 📞 Support & Resources - -### **Documentation Resources** - -| Resource | Description | Link | -| ----------------------------- | ----------------------------- | ----------------------------------------------------------------------- | -| **PowerShell Best Practices** | Official Microsoft guidelines | [PowerShell Docs](https://docs.microsoft.com/en-us/powershell/) | -| **GitHub Markdown Guide** | Official GitHub documentation | [GitHub Docs](https://docs.github.com/en/get-started/writing-on-github) | -| **Pester Testing** | PowerShell testing framework | [Pester.dev](https://pester.dev/) | -| **Shields.io** | Badge generation service | [Shields.io](https://shields.io/) | -| **Mermaid Diagrams** | Diagram syntax for GitHub | [Mermaid.js](https://mermaid-js.github.io/) | - -### **Internal Resources** - -- 📋 [Project Contributing Guidelines](../CONTRIBUTING.md) -- 🔐 [Security Policy](../SECURITY.md) -- 🆘 [Support Documentation](../SUPPORT.md) -- 📚 [Troubleshooting Guide](TROUBLESHOOTING.md) -- 🧪 [Testing Documentation](TESTING.md) - -### **Community & Support** - -- 💬 [Project Discussions](../../discussions) -- 🐛 [Issue Tracking](../../issues) -- 📝 [Feature Requests](../../issues/new?template=feature_request.md) -- 🔄 [Pull Requests](../../pulls) - ---- - -> 📝 **Document Version**: 1.0 -> 🗓️ **Last Updated**: September 25, 2025 -> ✍️ **Maintained by**: Network Engineering Team -> 🔄 **Review Schedule**: Quarterly or with major releases - -**This document is a living guide - please contribute improvements and updates as the project evolves!** 🚀 diff --git a/docs/QUICK_START.md b/docs/QUICK_START.md deleted file mode 100644 index e3c084a..0000000 --- a/docs/QUICK_START.md +++ /dev/null @@ -1,78 +0,0 @@ -# Using the Standalone Executable - -## 📦 No Python Required! - -The easiest way to use this tool is with our pre-built executables. No need to install Python or any dependencies! - -## ⬇️ Download - -1. Go to [Releases](../../releases) page -2. Download for your operating system: - - **Windows**: `network_config_generator.exe` - - **Linux**: `network_config_generator` - -## 🚀 Quick Start - - -To see all available options and usage details, run the executable with the `-h` or `--help` flag: - -```powershell -# Windows -.\network_config_generator.exe -h - -# Linux -./network_config_generator -h -``` - -This will display a summary of command-line arguments, default values, and workflow steps. -```powershell -> .\network_config_generator.exe -h -usage: network_config_generator.exe [-h] --input_json INPUT_JSON [--template_folder TEMPLATE_FOLDER] - [--output_folder OUTPUT_FOLDER] [--convertor CONVERTOR] - -options: - -h, --help show this help message and exit - --input_json INPUT_JSON - Path to input JSON file (lab or standard format) - --template_folder TEMPLATE_FOLDER - Folder containing Jinja2 templates (default: input/jinja2_templates) - --output_folder OUTPUT_FOLDER - Directory to save generated configs (default: same directory as input file) - --convertor CONVERTOR - Convertor to use for non-standard input formats (default: - convertors.convertors_lab_switch_json) - -Examples: - network_config_generator.exe --input_json input/standard_input.json --output_folder output/ - network_config_generator.exe --input_json my_lab_input.json --output_folder configs/ --convertor lab -``` - -![Network Config Generator Demo](./media/network-config-generator01.gif) - - -## 📋 What You Get - -After running, if successful, you'll see: -- Individual feature configs (e.g., interfaces, VLANs, BGP) -- Merged full config (all switch features combined into one configuration file) -- Standard switch JSON (for debugging): Contains the normalized switch data used to generate configs, useful for troubleshooting or verifying input conversion. - -``` -configs/ -├── switch-01/ -│ ├── generated_interfaces -│ ├── generated_vlans -│ ├── generated_bgp -│ └── generated_full_config -│ └── std_switch_json -└── switch-02/ - ├── generated_interfaces - └── ... (same files) -``` - - -## 🆘 Need Help? - -- **Issues?** → See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) -- **Custom data format?** → See [CONVERTOR_GUIDE.md](CONVERTOR_GUIDE.md) -- **Modify templates?** → See [TEMPLATE_GUIDE.md](TEMPLATE_GUIDE.md) diff --git a/docs/SWITCH_INTERFACE_TEMPLATE.md b/docs/SWITCH_INTERFACE_TEMPLATE.md deleted file mode 100644 index d71c819..0000000 --- a/docs/SWITCH_INTERFACE_TEMPLATE.md +++ /dev/null @@ -1,241 +0,0 @@ -# Switch Interface Template Guide - -This guide shows you how to quickly create or modify switch interface templates for the Azure Stack Network Configuration Generator. **No programming experience is required** - just follow the examples below. - -## Quick Start: Common Use Cases - -### Use Case 1: I Have a New Switch Model -**Goal:** Create a template for a switch model that doesn't exist yet. - -**Steps:** -1. **Find the template folder:** `input/switch_interface_templates/` - - Look for existing templates in `cisco/` or `dellemc/` folders. - - If your switch is from another vendor, create a new folder (e.g., `juniper/`). -2. **Copy a similar template:** Pick an existing `.json` file closest to your switch -3. **Rename the file:** Change filename to your exact switch model (e.g., `9336C-FX2.json`) -4. **Update 3 key things:** - - Switch model name - - Interface ranges (port counts) - - Uplink port numbers - -**Example:** Creating template for Cisco 9336C-FX2: -```bash -Copy: cisco/93180YC-FX.json → cisco/9336C-FX2.json -``` - -Then edit these parts: -```json -"model": "9336C-FX2", // Change model name -"end_intf": "1/32", // Change port count -"intf": "1/35" // Change uplink ports -``` - -### Use Case 2: Change Host Connection Ports -**Goal:** Servers connect to different ports than the template shows. - -**Find this section in the file:** -```json -"start_intf": "1/1", // Change start port -"end_intf": "1/16" // Change end port -``` - -**Change to your ports:** -```json -"start_intf": "1/5", // Servers start at port 5 -"end_intf": "1/24" // Servers end at port 24 -``` - -### Use Case 3: Change Uplink Ports -**Goal:** Your uplink connections are on different ports. - -**Find these sections:** -```json -"name": "P2P_Border1", -"intf": "1/48" // Change this port - -"name": "P2P_Border2", -"intf": "1/47" // Change this port -``` - -**Change to your uplink ports:** -```json -"intf": "1/52" // New uplink port -"intf": "1/51" // New uplink port -``` - -### Use Case 4: Add or Change VLANs -**Goal:** Use different VLAN numbers or add more VLANs. - -**Find VLAN settings:** -```json -"native_vlan": "99", // Untagged VLAN -"tagged_vlans": "M,C,S" // Tagged VLANs -``` - -**Recommendation:** Use actual VLAN numbers instead of letters: -```json -"native_vlan": "100", // Your management VLAN -"tagged_vlans": "200,300,400" // Your VLANs -``` - -> **Note:** M=Management, C=Compute, S=Storage. Using numbers is easier. - -### Use Case 5: Change Port Channel Members -**Goal:** Different interfaces for link aggregation. - -**Find port channel section:** -```json -"port_channels": [ - { - "id": 50, - "members": ["1/41", "1/42"] // Change these interfaces - } -] -``` - -**Change to your interfaces:** -```json -"members": ["1/49", "1/50", "1/51"] // Your link aggregation ports -``` - -## Interface Naming by Vendor - -**Cisco:** `1/48` (slot/port) -**Dell EMC:** `1/1/48` (unit/slot/port) - -Make sure you use the right format for your switch brand! - -## Quick Validation - -After making changes, check these basics: - -### 1. File Syntax -- Every `{` has a matching `}` -- Every `[` has a matching `]` -- Commas `,` between items (except the last item) -- Text values in quotes `"like this"` - -### 2. Interface Numbers -- Verify interface numbers exist on your switch -- Use correct format: Cisco `1/48` vs Dell `1/1/48` -- No interface used in multiple places - -### 3. Test Your Changes -1. Save your template file -2. Run the configuration generator -3. Check output files in `test_output` folder - -## Quick Troubleshooting - -**Problem:** Generator shows errors -**Solution:** Check JSON syntax using VS Code or online JSON validator - -**Problem:** Wrong interface configuration generated -**Solution:** Verify interface names match your switch documentation - -**Problem:** Overlapping configurations -**Solution:** Ensure same interface isn't configured in multiple places - ---- - -## Detailed Reference (Advanced Users) - -### Template File Structure - -Templates are stored in JSON format in this directory structure: - -``` -input/switch_interface_templates/ -├── cisco/ -│ ├── 93108TC-FX3P.json -│ ├── 93180YC-FX.json -│ └── 93180YC-FX3.json -└── dellemc/ - └── S5248F-ON.json -``` - -### Complete Template Sections - -Each template file contains these main sections: - -#### 1. Switch Information -```json -{ - "make": "Cisco", // Manufacturer name - "model": "93180YC-FX", // Exact switch model - "type": "TOR", // Switch type (Top of Rack) -``` - -#### 2. Interface Templates -Organized by deployment scenarios: - -```json -"interface_templates": { - "common": [...], // Interfaces used in all scenarios - "fully_converged": [...], // Hyper-converged infrastructure - "switched": [...], // Traditional switched network - "switchless": [...] // Switchless configuration -} -``` - -#### 3. Port Channels -```json -"port_channels": [...] // Link aggregation groups -``` - -### Complete Interface Properties - -| Property | Description | Example Values | -|----------|-------------|----------------| -| `name` | Descriptive name | `"HyperConverged_To_Host"` | -| `type` | Interface type | `"Access"`, `"Trunk"`, `"L3"` | -| `description` | Interface description | `"Connection to compute host"` | -| `intf_type` | Physical interface type | `"Ethernet"`, `"loopback"` | -| `intf` | Single interface | `"1/48"` | -| `start_intf` | Range start | `"1/1"` | -| `end_intf` | Range end | `"1/16"` | -| `access_vlan` | Access port VLAN | `"100"` | -| `native_vlan` | Trunk native VLAN | `"99"` | -| `tagged_vlans` | Trunk tagged VLANs | `"100,200,300"` | -| `shutdown` | Disable interface | `true` or `false` | -| `ipv4` | IP address | `""` (empty for dynamic) | -| `service_policy` | QoS policy | `{"qos_input": "AZLOCAL-QOS-MAP"}` | - -### Deployment Scenarios Explained - -#### Common Interfaces -Used in all deployment types: -- **Unused**: Shutdown all interfaces initially -- **Loopback0**: Management loopback interface -- **P2P_Border1/Border2**: Uplink connections -- **Trunk_TO_BMC_SWITCH**: BMC management connection - -#### Fully Converged -- **HyperConverged_To_Host**: Trunk carrying management (M), compute (C), and storage (S) traffic - -#### Switched -- **Switched_Compute_To_Host**: Trunk for compute traffic -- **Switched_Storage_To_Host**: Trunk for storage traffic - -#### Switchless -- **Switchless_Compute_To_Host**: Simplified trunk configuration - -### Port Channel Details - -Port channels (link aggregation) configuration: - -```json -{ - "id": 50, // Channel group number - "description": "P2P_IBGP", // Description - "type": "L3", // "L3" or "Trunk" - "ipv4": "", // IP address (empty for dynamic) - "members": ["1/41", "1/42"] // Physical interfaces in the group -} -``` - -For trunk port channels, add: -```json -"native_vlan": "99", // Untagged VLAN -"tagged_vlans": "100,200" // Tagged VLANs -``` diff --git a/docs/TEMPLATE_GUIDE.md b/docs/TEMPLATE_GUIDE.md index ac326d1..0f4516f 100644 --- a/docs/TEMPLATE_GUIDE.md +++ b/docs/TEMPLATE_GUIDE.md @@ -1,643 +1,220 @@ -# Customizing Configuration Templates +# Template Guide -## 🤔 Do I Need This? +This guide covers both **Jinja2 config templates** (which render `.cfg` outputs) and **switch interface templates** (JSON files that define port layouts per switch model). -**You need to read this if:** -- You want to support a new switch vendor -- You need to modify the generated configuration format -- You want to add new configuration sections -- You're getting errors about missing templates +--- -**You DON'T need this if:** -- You're happy with Cisco NX-OS or Dell OS10 templates -- You just want to generate configs with existing templates +## Jinja2 Config Templates -## 📁 How Templates Work +### How They Work Templates are organized by vendor and firmware: ``` input/jinja2_templates/ -├── cisco/ -│ └── nxos/ ← Your switch's "make" and "firmware" -│ ├── bgp.j2 ← Generates BGP configuration -│ ├── interface.j2 ← Generates interface configuration -│ ├── vlan.j2 ← Generates VLAN configuration -│ └── full_config.j2 ← Combines everything -└── dellemc/ - └── os10/ - ├── bgp.j2 - └── vlan.j2 -``` - -**How the tool picks templates:** -1. Looks at your switch data: `"make": "cisco", "firmware": "nxos"` -2. Finds folder: `input/jinja2_templates/cisco/nxos/` -3. Uses all `.j2` files in that folder - -## 📝 Simple Example - -Let's create a basic VLAN template: - -**Your data:** +├── cisco/nxos/ ← make=cisco, firmware=nxos +│ ├── bgp.j2 +│ ├── full_config.j2 +│ ├── interface.j2 +│ ├── login.j2 +│ ├── port_channel.j2 +│ ├── prefix_list.j2 +│ ├── qos.j2 +│ ├── static_route.j2 +│ ├── system.j2 +│ └── vlan.j2 +└── dellemc/os10/ ← make=dellemc, firmware=os10 + ├── (same sections) + └── vlt.j2 ← Dell-specific +``` + +The generator reads your switch's `make` and `firmware` from the input JSON, finds the matching template folder, and renders every `.j2` file in it. + +### Simple Example + +**Input data:** ```json -{ - "vlans": [ - {"vlan_id": 100, "name": "Servers"}, - {"vlan_id": 200, "name": "Storage"} - ] -} +{ "vlans": [{"vlan_id": 100, "name": "Servers"}, {"vlan_id": 200, "name": "Storage"}] } ``` -**Template (`vlans.j2`):** +**Template (`vlan.j2`):** ```jinja2 -! VLAN Configuration {% for vlan in vlans %} vlan {{ vlan.vlan_id }} name {{ vlan.name }} {% endfor %} ``` -**Generated output:** +**Output:** ``` -! VLAN Configuration vlan 100 name Servers vlan 200 name Storage ``` -## 🛠️ Creating Your First Template - -### Step 1: Choose Your Vendor Folder -```bash -# For a new vendor, create: -mkdir -p input/jinja2_templates/your_vendor/your_firmware/ +### Available Data in Templates -# For existing vendor with new firmware: -mkdir -p input/jinja2_templates/cisco/your_new_firmware/ -``` - -### Step 2: Create a Simple Template -Create `input/jinja2_templates/your_vendor/your_firmware/vlan.j2`: +All fields from the standard JSON are available: ```jinja2 -{# This is a comment - won't appear in output #} -! Generated VLAN Configuration -! Switch: {{ switch.hostname }} +{{ switch.hostname }} {# Switch name #} +{{ switch.make }} {# cisco, dellemc #} +{{ switch.firmware }} {# nxos, os10 #} -{% if vlans %} {% for vlan in vlans %} -vlan {{ vlan.vlan_id }} - name {{ vlan.name }} - {% if vlan.description %} - description {{ vlan.description }} - {% endif %} + {{ vlan.vlan_id }} {{ vlan.name }} {% endfor %} -{% else %} -! No VLANs configured -{% endif %} -``` - -### Step 3: Test It -```bash -# Make sure your switch data has: -# "make": "your_vendor", "firmware": "your_firmware" -./network_config_generator --input_json your_data.json --output_folder test/ -``` - -### Step 4: Check the Output -Look for `test/your_switch/generated_vlan` file. -## 📋 Available Data in Templates - -Your templates can access all data from your input JSON: - -### Switch Information -```jinja2 -{{ switch.hostname }} # Switch name -{{ switch.make }} # cisco, dellemc, etc. -{{ switch.firmware }} # nxos, os10, etc. -{{ switch.model }} # Optional: switch model -``` - -### VLANs -```jinja2 -{% for vlan in vlans %} -{{ vlan.vlan_id }} # VLAN number -{{ vlan.name }} # VLAN name -{{ vlan.description }} # Optional description -{% endfor %} -``` - -### Interfaces -```jinja2 -{% for interface in interfaces %} -{{ interface.name }} # Ethernet1/1, etc. -{{ interface.vlan }} # VLAN assignment -{{ interface.description }} # Port description -{{ interface.type }} # access, trunk, etc. +{% for iface in interfaces %} + {{ iface.name }} {{ iface.description }} {{ iface.type }} {% endfor %} -``` -### BGP (if configured) -```jinja2 -{{ bgp.asn }} # AS number -{{ bgp.router_id }} # Router ID -{% for neighbor in bgp.neighbors %} -{{ neighbor.ip }} # Neighbor IP -{{ neighbor.remote_as }} # Neighbor AS +{{ bgp.asn }} {{ bgp.router_id }} +{% for n in bgp.neighbors %} + {{ n.ip }} {{ n.remote_as }} {% endfor %} ``` -## 💡 Template Tips - -### 1. Use Comments -```jinja2 -{# This comment explains what this section does #} -! This comment appears in the generated config -``` +### Adding a New Vendor -### 2. Handle Missing Data -```jinja2 -{% if vlans %} - {# Generate VLAN config #} -{% else %} - ! No VLANs to configure -{% endif %} -``` +1. Create the folder: `input/jinja2_templates///` +2. Add `.j2` template files (one per config section) +3. Ensure your input JSON has `"make": "", "firmware": ""` -### 3. Format Numbers -```jinja2 -interface Ethernet1/{{ "%02d"|format(interface.number) }} -{# Formats 1 as "01", 2 as "02", etc. #} -``` +### Jinja2 Tips -### 4. Default Values ```jinja2 -{{ interface.description | default("No description") }} -``` - -## 🆘 Common Issues - -**"Template not found"** -- Check folder structure matches your switch's `make` and `firmware` -- Verify `.j2` file extension +{# Comments — not in output #} +! Config comments — appears in output -**"Variable not found"** -- Check your input JSON has the expected data structure -- Use `{% if variable %}` to handle optional data - -**"Syntax error"** -- Check Jinja2 syntax: `{{ }}` for variables, `{% %}` for logic -- Make sure all `{% if %}` have matching `{% endif %}` - -## � Advanced Features +{# Handle missing data #} +{% if interface.mtu is defined %} + mtu {{ interface.mtu }} +{% endif %} -### Include Other Templates -```jinja2 -{# Include common header in all templates #} -{% include 'header.j2' %} -``` +{# Default values #} +mtu {{ interface.mtu | default(1500) }} -### Loops with Conditions -```jinja2 -{% for interface in interfaces if interface.type == "trunk" %} -interface {{ interface.name }} +{# Filter loops #} +{% for iface in interfaces if iface.type == "Trunk" %} switchport mode trunk {% endfor %} -``` -### Macros for Repeated Code -```jinja2 -{% macro interface_config(iface) %} -interface {{ iface.name }} - description {{ iface.description }} - switchport access vlan {{ iface.vlan }} -{% endmacro %} - -{% for interface in interfaces %} -{{ interface_config(interface) }} -{% endfor %} -``` - -```jinja2 -{# vlans.j2 - Generate VLAN configuration #} -{% for vlan in vlans %} +{# Macros for reuse #} +{% macro vlan_config(vlan) %} vlan {{ vlan.vlan_id }} name {{ vlan.name }} -{% if vlan.interface is defined %} - -interface vlan{{ vlan.vlan_id }} - description {{ vlan.name }} - ip address {{ vlan.interface.ip }}/{{ vlan.interface.cidr }} -{% if vlan.interface.mtu is defined %} - mtu {{ vlan.interface.mtu }} -{% endif %} -{% if vlan.interface.redundancy is defined %} - {{ vlan.interface.redundancy.type }} {{ vlan.interface.redundancy.group }} - {{ vlan.interface.redundancy.type }} {{ vlan.interface.redundancy.group }} priority {{ vlan.interface.redundancy.priority }} - {{ vlan.interface.redundancy.type }} {{ vlan.interface.redundancy.group }} ip {{ vlan.interface.redundancy.virtual_ip }} -{% endif %} -{% endif %} - -{% endfor %} -``` - -### Output Example -``` -vlan 100 - name Management - -interface vlan100 - description Management - ip address 192.168.1.1/24 - mtu 1500 - hsrp 100 - hsrp 100 priority 110 - hsrp 100 ip 192.168.1.254 - -vlan 200 - name Storage - -interface vlan200 - description Storage - ip address 10.0.0.1/24 - mtu 9000 -``` - -## 🔧 Advanced Template Techniques - -### 1. **Conditional Logic** - -```jinja2 -{# Interface configuration with conditions #} -{% for interface in interfaces %} -interface {{ interface.name }} -{% if interface.description is defined %} - description {{ interface.description }} -{% endif %} -{% if interface.type == "Trunk" %} - switchport mode trunk -{% if interface.native_vlan is defined %} - switchport trunk native vlan {{ interface.native_vlan }} -{% endif %} -{% if interface.tagged_vlans is defined %} - switchport trunk allowed vlan {{ interface.tagged_vlans }} -{% endif %} -{% elif interface.type == "Access" %} - switchport mode access - switchport access vlan {{ interface.vlan }} -{% elif interface.type == "L3" %} - no switchport -{% if interface.ipv4 is defined and interface.ipv4 %} - ip address {{ interface.ipv4 }} -{% endif %} -{% endif %} - -{% endfor %} -``` - -### 2. **Loops and Filters** - -```jinja2 -{# BGP configuration with loops and filters #} -router bgp {{ bgp.asn }} - router-id {{ bgp.router_id }} - - {# Advertise networks #} -{% for network in bgp.networks %} -{% if network %} - network {{ network }} -{% endif %} -{% endfor %} - - {# Configure neighbors #} -{% for neighbor in bgp.neighbors %} - neighbor {{ neighbor.ip }} - remote-as {{ neighbor.remote_as }} - description {{ neighbor.description }} -{% if neighbor.update_source is defined %} - update-source {{ neighbor.update_source }} -{% endif %} -{% if neighbor.ebgp_multihop is defined %} - ebgp-multihop {{ neighbor.ebgp_multihop }} -{% endif %} - address-family ipv4 unicast -{% if neighbor.af_ipv4_unicast.prefix_list_in is defined %} - prefix-list {{ neighbor.af_ipv4_unicast.prefix_list_in }} in -{% endif %} -{% if neighbor.af_ipv4_unicast.prefix_list_out is defined %} - prefix-list {{ neighbor.af_ipv4_unicast.prefix_list_out }} out -{% endif %} - -{% endfor %} -``` - -### 3. **Template Macros for Reusability** - -```jinja2 -{# macros.j2 - Reusable template components #} - -{# Macro for interface common configuration #} -{% macro interface_common(interface) %} -interface {{ interface.name }} -{% if interface.description is defined %} - description {{ interface.description }} -{% endif %} -{% if interface.mtu is defined %} - mtu {{ interface.mtu }} -{% endif %} -{% endmacro %} - -{# Macro for HSRP/VRRP configuration #} -{% macro redundancy_config(redundancy) %} -{% if redundancy.type == "hsrp" %} - hsrp {{ redundancy.group }} - hsrp {{ redundancy.group }} priority {{ redundancy.priority }} - hsrp {{ redundancy.group }} ip {{ redundancy.virtual_ip }} -{% elif redundancy.type == "vrrp" %} - vrrp {{ redundancy.group }} - vrrp {{ redundancy.group }} priority {{ redundancy.priority }} - vrrp {{ redundancy.group }} ip {{ redundancy.virtual_ip }} -{% endif %} {% endmacro %} - -{# Usage in main template #} -{% from 'macros.j2' import interface_common, redundancy_config %} - -{% for vlan in vlans %} -{% if vlan.interface is defined %} -{{ interface_common(vlan.interface) }} - ip address {{ vlan.interface.ip }}/{{ vlan.interface.cidr }} -{% if vlan.interface.redundancy is defined %} -{{ redundancy_config(vlan.interface.redundancy) }} -{% endif %} -{% endif %} -{% endfor %} ``` -## 🏢 Vendor-Specific Customizations - -### Cisco NX-OS Example +--- -```jinja2 -{# cisco/nxos/system.j2 #} -hostname {{ switch.hostname }} +## Switch Interface Templates -feature bgp -feature interface-vlan -feature hsrp -feature lacp +Switch interface templates are JSON files that define the physical port layout and logical interface assignments for each switch model. The converter uses these to build the standard JSON. -ip domain-lookup -vdc {{ switch.hostname }} id 1 +### File Location -{# NX-OS specific features #} -feature nxapi -feature bash-shell -feature scp-server -``` - -### Dell EMC OS10 Example - -```jinja2 -{# dellemc/os10/system.j2 #} -hostname {{ switch.hostname }} - -{# OS10 specific configuration #} -system-user linuxadmin password $6$rounds=656000$... role sysadmin -aaa authorization exec default local - -{# Enable required features #} -router bgp -interface vlan -``` - -## 🔄 Template Inheritance - -Create base templates and extend them for specific vendors: - -### Base Template (`base/interfaces.j2`) - -```jinja2 -{# Base interface template #} -{% for interface in interfaces %} -{% block interface_header %} -interface {{ interface.name }} -{% endblock %} - -{% block interface_description %} -{% if interface.description is defined %} - description {{ interface.description }} -{% endif %} -{% endblock %} - -{% block interface_specific %} -{# Override in vendor-specific templates #} -{% endblock %} - -{% block interface_footer %} -{# Common footer configuration #} -{% endblock %} - -{% endfor %} -``` - -### Vendor-Specific Extension (`cisco/nxos/interfaces.j2`) - -```jinja2 -{# Cisco NX-OS specific interface template #} -{% extends "base/interfaces.j2" %} - -{% block interface_specific %} -{% if interface.type == "Trunk" %} - switchport mode trunk -{% if interface.native_vlan is defined %} - switchport trunk native vlan {{ interface.native_vlan }} -{% endif %} -{% if interface.tagged_vlans is defined %} - switchport trunk allowed vlan {{ interface.tagged_vlans }} -{% endif %} -{% elif interface.type == "Access" %} - switchport mode access - switchport access vlan {{ interface.vlan }} -{% elif interface.type == "L3" %} - no switchport -{% if interface.ipv4 is defined and interface.ipv4 %} - ip address {{ interface.ipv4 }} -{% endif %} - no shutdown -{% endif %} -{% endblock %} ``` - -## 📊 Data Access Patterns - -### Accessing Switch Data - -```jinja2 -{# Switch information #} -Hostname: {{ switch.hostname }} -Make: {{ switch.make }} -Model: {{ switch.model }} -Firmware: {{ switch.firmware }} -Version: {{ switch.version }} +input/switch_interface_templates/ +├── cisco/ +│ ├── 93108TC-FX3P.json # TOR (16-port) +│ ├── 93180YC-FX.json # TOR (16-port) +│ ├── 93180YC-FX3.json # TOR (20-port) +│ ├── 9348GC-FXP.json # BMC (16-node) +│ └── 9348GC-FX3.json # BMC (20-node) +└── dellemc/ + ├── s5248f-on.json # TOR + └── N3248TE-ON.json # BMC ``` -### Working with Arrays +### Template Structure -```jinja2 -{# Loop through VLANs #} -{% for vlan in vlans %} -VLAN {{ vlan.vlan_id }}: {{ vlan.name }} -{% endfor %} +Each file contains: -{# Filter arrays #} -{% for vlan in vlans if vlan.vlan_id > 100 %} -High VLAN: {{ vlan.vlan_id }} -{% endfor %} -``` - -### Nested Data Access - -```jinja2 -{# Access nested BGP data #} -BGP ASN: {{ bgp.asn }} -Router ID: {{ bgp.router_id }} - -{% for neighbor in bgp.neighbors %} -Neighbor {{ neighbor.ip }}: - AS: {{ neighbor.remote_as }} - Description: {{ neighbor.description }} -{% if neighbor.af_ipv4_unicast is defined %} - IPv4 Unicast: -{% for key, value in neighbor.af_ipv4_unicast.items() %} - {{ key }}: {{ value }} -{% endfor %} -{% endif %} -{% endfor %} +```json +{ + "make": "Cisco", + "model": "93180YC-FX", + "type": "TOR", + "interface_templates": { + "common": [...], // All deployment patterns + "fully_converged": [...], // HyperConverged + "switched": [...], // Switched + "switchless": [...] // Switchless + }, + "port_channels": [...] +} ``` -## 🧪 Testing Templates +### Interface Properties -### Template Testing Approach +| Property | Description | Example | +|----------|-------------|---------| +| `name` | Descriptive name | `"HyperConverged_To_Host"` | +| `type` | Mode | `"Access"`, `"Trunk"`, `"L3"` | +| `intf_type` | Physical type | `"Ethernet"`, `"loopback"` | +| `intf` | Single port | `"1/48"` | +| `start_intf` / `end_intf` | Port range | `"1/1"` / `"1/16"` | +| `native_vlan` | Trunk native VLAN | `"99"` | +| `tagged_vlans` | Trunk tagged VLANs | `"M,C,S"` or `"100,200"` | +| `access_vlan` | Access port VLAN | `"100"` | +| `shutdown` | Disable interface | `true` / `false` | +| `ipv4` | IP address | `""` (empty = filled by converter) | -1. **Create test standard JSON files** -2. **Generate configs using your templates** -3. **Validate the output** +**VLAN symbols:** `M` = Management/INFRA, `C` = Compute, `S` = Storage. You can also use literal VLAN IDs. -### Example Test Structure +### Common Use Cases -``` -tests/template_tests/ -├── my_vendor_test/ -│ ├── input/ -│ │ └── test_standard_input.json -│ ├── templates/ -│ │ └── my_vendor/ -│ │ └── my_firmware/ -│ │ ├── interfaces.j2 -│ │ └── vlans.j2 -│ └── expected_output/ -│ ├── expected_interfaces.cfg -│ └── expected_vlans.cfg -``` +**New switch model:** +1. Copy the closest existing template +2. Rename to your model: e.g., `9336C-FX2.json` +3. Update `model`, port ranges, and uplink ports -### Template Testing Command - -```bash -# Test your custom templates -python src/main.py \ - --input_json tests/template_tests/my_vendor_test/input/test_standard_input.json \ - --template_folder tests/template_tests/my_vendor_test/templates \ - --output_folder test_output/ -``` - -## 🚀 Best Practices - -### 1. **Use Meaningful Comments** -```jinja2 -{# This section configures BGP neighbors for eBGP peering #} -{% for neighbor in bgp.neighbors if neighbor.remote_as != bgp.asn %} -``` - -### 2. **Handle Missing Data Gracefully** -```jinja2 -{% if interface.mtu is defined and interface.mtu != 1500 %} - mtu {{ interface.mtu }} -{% endif %} +**Change host ports:** +```json +"start_intf": "1/5", // was 1/1 +"end_intf": "1/24" // was 1/16 ``` -### 3. **Use Consistent Formatting** -```jinja2 -{# Good: Consistent indentation and spacing #} -interface {{ interface.name }} - description {{ interface.description }} - switchport mode {{ interface.mode }} - -{# Bad: Inconsistent formatting #} -interface {{interface.name}} -description {{interface.description}} - switchport mode {{interface.mode}} +**Change uplink ports:** +```json +"name": "P2P_Border1", +"intf": "1/52" // was 1/48 ``` -### 4. **Leverage Jinja2 Filters** -```jinja2 -{# String manipulation #} -hostname {{ switch.hostname | upper }} - -{# List manipulation #} -{% for vlan in vlans | sort(attribute='vlan_id') %} - -{# Default values #} -mtu {{ interface.mtu | default(1500) }} +**Change port channel members:** +```json +"port_channels": [{ + "id": 50, + "members": ["1/49", "1/50"] // your LAG ports +}] ``` -### 5. **Modular Template Design** -Break large templates into smaller, manageable pieces: - -```jinja2 -{# main_config.j2 #} -{% include 'system.j2' %} -{% include 'interfaces.j2' %} -{% include 'vlans.j2' %} -{% include 'bgp.j2' %} -``` +### Interface Naming by Vendor -## 🔧 Troubleshooting Templates +- **Cisco:** `1/48` (slot/port) +- **Dell EMC:** `1/1/48` (unit/slot/port) -### Common Issues +### Deployment Patterns -1. **Template Not Found** - - Check template path: `input/jinja2_templates/{make}/{firmware}/` - - Verify file extension: `.j2` +| Pattern | Description | Host Interfaces | +|---------|-------------|-----------------| +| `fully_converged` | HCI — all traffic on one trunk | M+C+S tagged | +| `switched` | Separate compute and storage trunks | C trunk + S trunk | +| `switchless` | Storage direct-attached | C trunk only | -2. **Variable Not Defined Errors** - ```jinja2 - {# Safe access with default #} - {{ interface.mtu | default(1500) }} - - {# Check if defined #} - {% if interface.mtu is defined %} - ``` +The `common` section defines interfaces shared across all patterns (loopbacks, uplinks, unused ports, BMC trunk). -3. **Unexpected Output** - - Use `{{ variable | pprint }}` for debugging - - Check data types and structure +--- -### Template Debugging +## Troubleshooting Templates -```jinja2 -{# Debug template - shows all available data #} - -{{ switch | pprint }} +**Template not found?** Check that your `make`/`firmware` values match the folder path under `input/jinja2_templates/`. - -{{ vlans | pprint }} +**Wrong interface config?** Verify interface names match your switch docs. Cisco uses `1/48`, Dell uses `1/1/48`. - -{{ interfaces | pprint }} -``` +**JSON syntax error in switch template?** Validate with `python -m json.tool your_template.json`. -This template system provides powerful flexibility while maintaining simplicity. Start with basic templates and gradually add more sophisticated features as needed! +**Undefined variable in Jinja2?** Use `{% if var is defined %}` guards or `{{ var | default("") }}` filters. diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index 557d75d..15b4c22 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -1,531 +1,145 @@ -# Troubleshooting Guide +# Troubleshooting -## � Quick Fixes +## Quick Fixes -### ❌ "Input is in lab format - conversion required" +### "Input is in lab format — conversion required" -**What it means:** Your data format is different from what the tool expects. +Your data isn't in standard format. The tool can auto-convert if you specify a converter: -**Quick fix:** ```bash -# Just run it anyway - tool will auto-convert -./network_config_generator --input_json your_file.json --output_folder configs/ +python src/main.py --input_json your_file.json --convertor lab ``` -**If that doesn't work:** -1. Check if your JSON has keys like `Version`, `Description`, `InputData` -2. Try using a custom converter: `--convertor your.custom.converter` +If that doesn't work, check whether your JSON has `Version`/`InputData` keys (lab format) vs `switch`/`vlans` keys (standard format). --- -### ❌ "Failed to convert to standard format" +### "Template folder not found" -**What it means:** The converter couldn't understand your data format. +The tool can't find templates that match your switch's `make`/`firmware`. -**Step-by-step fix:** - -1. **Check your input file is valid JSON:** - ```bash - # Test if JSON is valid - python -m json.tool your_file.json - ``` - -2. **Look at your data structure:** - - Does it have the expected format for your converter? - - Are all required fields present? - -3. **Try the default path first:** - ```bash - # Don't specify a converter - let tool auto-detect - ./network_config_generator --input_json your_file.json --output_folder configs/ +1. Check you're running from the project root +2. Verify the folder exists: `input/jinja2_templates///` +3. Check your JSON has matching values: + ```json + { "switch": { "make": "cisco", "firmware": "nxos" } } ``` -4. **If using custom converter, check it exists:** - - File should be in: `src/convertors/your_converter.py` - - Should have function: `convert_switch_input_json()` - --- -### ❌ "Template folder not found" - -**What it means:** Tool can't find the configuration templates. +### "No configs generated" or empty output -**Quick fix:** -```bash -# Make sure you're running from the right directory -cd path/to/AzureStack_Network_Switch_Config_Generator -./network_config_generator --input_json your_file.json --output_folder configs/ -``` - -**If still not working:** -- Check that `input/jinja2_templates/` folder exists -- Verify it has subfolders like `cisco/nxos/` or `dellemc/os10/` +1. **Vendor/firmware mismatch** — `make` and `firmware` must match a template folder name +2. **Empty data** — if no VLANs in input, no VLAN config is generated +3. **Missing templates** — check that the folder contains `.j2` files --- -### ❌ "No configs generated" or Empty output - -**Possible causes:** +### "Failed to parse JSON" -1. **Wrong switch vendor/firmware in your data:** - ```json - { - "switch": { - "make": "cisco", // Must match template folder name - "firmware": "nxos" // Must match template subfolder - } - } - ``` +Common JSON syntax errors: -2. **Missing template files:** - - Check `input/jinja2_templates/cisco/nxos/` has `.j2` files - - Try with a known working vendor (cisco/nxos) +``` +Missing commas: {"key1": "v1" "key2": "v2"} ← needs comma +Trailing commas: {"key": "value",} ← remove trailing comma +Single quotes: {'key': 'value'} ← use double quotes +Comments: {"key": "value" // note} ← JSON doesn't allow comments +``` -3. **Empty data sections:** - - If no VLANs in your data, no VLAN config will be generated - - Check that your input has data in the sections you expect +Validate with: `python -m json.tool your_file.json` --- -### ❌ Permission errors - -**Windows:** -```cmd -# Run as Administrator, or move to a folder you own -mkdir C:\MyConfigs -.\network_config_generator.exe --input_json data.json --output_folder C:\MyConfigs\ -``` +### Permission errors -**Linux:** ```bash -# Make sure output folder is writable -mkdir ~/configs -./network_config_generator --input_json data.json --output_folder ~/configs/ +# Linux — ensure output folder is writable +mkdir -p output/ && chmod 755 output/ + +# Windows — run from a folder you own, or as Administrator ``` --- -## 🔧 Debug Steps +## Debug Steps -### 1. Start with a simple test -```bash -# Use the provided example file first -./network_config_generator --input_json input/standard_input.json --output_folder test_output/ -``` +### 1. Test with the included example -### 2. Check what files were created ```bash -# Look for these in your output folder: -ls -la your_output_folder/ -# Should see: switch folders + JSON files +python src/main.py --input_json input/standard_input.json --output_folder test_output/ ``` -### 3. Examine the converted JSON files -```bash -# Look at the std_*.json files in each switch folder -cat output_folder/switch-01/std_switch-01.json -``` +### 2. Check generated files -### 4. Verify your input format -```json -# Standard format should look like: -{ - "switch": { "hostname": "...", "make": "...", "firmware": "..." }, - "vlans": [...], - "interfaces": [...], - "bgp": {...} -} - -# Lab format typically looks like: -{ - "Version": "1.0", - "Description": "...", - "InputData": { - "Switches": [...], - "Supernets": [...] - } -} +```bash +ls -la test_output/ +# Should see: generated_*.cfg files ``` -## 📞 Still Need Help? +### 3. Examine the standard JSON -1. **Check examples:** Look at files in `input/` folder -2. **Read other guides:** - - [CONVERTOR_GUIDE.md](CONVERTOR_GUIDE.md) - For custom data formats - - [TEMPLATE_GUIDE.md](TEMPLATE_GUIDE.md) - For template issues -3. **Create an issue** on GitHub with: - - Your input file (remove sensitive data) - - Full error message - - What you expected to happen +If using a converter, look at the intermediate `std_*.json` files to verify the conversion. -### Template Issues +### 4. Enable debug logging -#### **Error: "Template path not found"** -**Problem**: The tool cannot find templates for your switch type. - -**Solution**: Check template directory structure: ```bash -ls -la input/jinja2_templates/{make}/{firmware}/ -# Example: input/jinja2_templates/cisco/nxos/ +python src/main.py --input_json data.json --output_folder out/ --debug ``` -**Expected structure**: -``` -input/jinja2_templates/ -├── cisco/ -│ └── nxos/ -│ ├── interfaces.j2 -│ ├── vlans.j2 -│ └── bgp.j2 -└── dellemc/ - └── os10/ - └── *.j2 -``` +### 5. Run tests -**Fix**: Create the missing template directory or check your switch metadata: -```json -{ - "switch": { - "make": "cisco", // Must match folder name - "firmware": "nxos" // Must match subfolder name - } -} +```bash +python -m pytest tests/ -v ``` --- -#### **Error: "No templates found in template directory"** -**Problem**: Template directory exists but contains no `.j2` files. - -**Solutions**: -1. **Check file extensions**: Templates must end with `.j2` -2. **Verify file permissions**: Ensure files are readable -3. **Check template content**: Ensure templates are valid Jinja2 - ---- - -#### **Error: Template rendering failed** -**Problem**: Jinja2 template has syntax errors or undefined variables. - -**Debugging steps**: -1. **Check template syntax**: - ```jinja2 - {# Good #} - {% for vlan in vlans %} - vlan {{ vlan.vlan_id }} - {% endfor %} - - {# Bad - missing endfor #} - {% for vlan in vlans %} - vlan {{ vlan.vlan_id }} - ``` - -2. **Check variable names**: - ```jinja2 - {# Safe access #} - {{ interface.mtu | default(1500) }} - - {# Check if defined #} - {% if interface.mtu is defined %} - mtu {{ interface.mtu }} - {% endif %} - ``` - -3. **Add debug output to templates**: - ```jinja2 - {# Debug: Show available data #} - - {{ vlans | pprint }} - ``` - ---- - -### File Permission Issues - -#### **Error: Permission denied when writing files** -**Problem**: Output directory is not writable. - -**Solutions**: -1. **Check directory permissions**: - ```bash - ls -ld output_folder/ - ``` - -2. **Create directory with proper permissions**: - ```bash - mkdir -p output_folder/ - chmod 755 output_folder/ - ``` - -3. **Run with appropriate user permissions** - ---- - -### Executable Issues (Binary Distributions) - -#### **Error: "network-config-generator: command not found"** -**Problem**: Executable not in PATH or not executable. - -**Solutions**: -1. **Make executable** (Linux): - ```bash - chmod +x network-config-generator-linux-amd64 - ``` - -2. **Use full path**: - ```bash - ./network-config-generator-linux-amd64 --help - ``` - -3. **Add to PATH**: - ```bash - export PATH=$PATH:/path/to/executable - ``` - ---- - -#### **Windows: "The system cannot execute the specified program"** -**Problem**: Windows security or missing dependencies. - -**Solutions**: -1. **Unblock the file**: - - Right-click executable → Properties → General → Unblock - -2. **Run as Administrator** if needed - -3. **Check Windows Defender** - ensure file isn't quarantined - -4. **Use PowerShell**: - ```powershell - .\network-config-generator-windows-amd64.exe --help - ``` - ---- - -### JSON Format Issues +## Template Rendering Errors -#### **Error: "Failed to parse JSON"** -**Problem**: Input JSON file has syntax errors. +**Undefined variable:** +```jinja2 +{# Use safe access #} +{{ interface.mtu | default(1500) }} -**Solutions**: -1. **Validate JSON syntax**: - ```bash - python -m json.tool your_input.json - ``` - -2. **Check for common JSON errors**: - - Missing commas: `{"key1": "value1" "key2": "value2"}` ❌ - - Trailing commas: `{"key": "value",}` ❌ - - Single quotes: `{'key': 'value'}` ❌ - - Comments: `{"key": "value", // comment}` ❌ - -3. **Use a JSON validator** online or in your editor - ---- - -#### **Error: "Input JSON was empty or failed to parse"** -**Problem**: JSON file is empty, corrupted, or has encoding issues. - -**Solutions**: -1. **Check file size and content**: - ```bash - ls -l your_input.json - head your_input.json - ``` - -2. **Check file encoding**: - ```bash - file your_input.json - ``` - -3. **Fix encoding if needed**: - ```bash - iconv -f windows-1252 -t utf-8 input.json > input_utf8.json - ``` - ---- - -### Performance Issues - -#### **Problem: Generation takes too long** -**Solutions**: - -1. **Reduce template complexity**: - - Avoid complex loops in templates - - Use simpler Jinja2 expressions - -2. **Check input data size**: - - Large VLAN lists or interface configurations can slow processing - -3. **Optimize templates**: - ```jinja2 - {# Inefficient #} - {% for interface in interfaces %} - {% for vlan in vlans %} - {# Complex nested logic #} - {% endfor %} - {% endfor %} - - {# Better #} - {% for interface in interfaces %} - {# Simple operations #} - {% endfor %} - ``` - ---- - -#### **Problem: Large output files** -**Solutions**: - -1. **Remove debug output** from templates -2. **Optimize template whitespace**: - ```jinja2 - {# Control whitespace #} - interface {{ interface.name }} - {%- if interface.description is defined %} - description {{ interface.description }} - {%- endif %} - ``` - ---- - -### Multi-Switch Issues - -#### **Problem: Only one switch config generated** -**Cause**: Input contains multiple switches but convertor only processes one. - -**Solutions**: -1. **Check convertor implementation** - ensure it processes all switches -2. **Verify input format** - ensure all switches are properly defined -3. **Check output directory** - files might be overwriting each other - ---- +{% if interface.mtu is defined %} + mtu {{ interface.mtu }} +{% endif %} +``` -#### **Problem: Switch configs overwriting each other** -**Cause**: Multiple switches have the same hostname. +**Missing `endfor`/`endif`:** +Every `{% for %}` needs `{% endfor %}`, every `{% if %}` needs `{% endif %}`. -**Solutions**: -1. **Ensure unique hostnames** in input data -2. **Check convertor logic** for hostname generation -3. **Use switch type/role in filename** if hostnames conflict +**Debug data in templates:** +```jinja2 + +{{ vlans | pprint }} +``` --- -## 🔧 Debugging Techniques - -### Enable Verbose Output - -1. **Check tool output**: Run the tool with verbose logging to see processing steps - -2. **Add debug to templates**: - ```jinja2 - {# Show all available data #} - - {{ data | pprint }} - - ``` - -### Check Intermediate Files - -1. **Examine standard format JSON**: - ```bash - # After conversion, check the generated standard files - cat temp_converted/*.json | jq '.' - ``` - -2. **Verify template discovery**: - ```bash - ls -la input/jinja2_templates/{make}/{firmware}/ - ``` - -### Test Components Separately - -1. **Test convertor only**: Run conversion in isolation to check output format - -2. **Test generator only**: Use pre-converted standard format files with the tool: - ```bash - ./network-config-generator --input_json standard_format.json --output_folder test/ - ``` - -### Validate Generated Configs - -1. **Check config syntax** (vendor-specific): - ```bash - # Cisco NX-OS - nxos-syntax-check generated_config.cfg - - # Dell OS10 - os10-syntax-check generated_config.cfg - ``` - -2. **Compare with expected output**: - ```bash - diff expected_config.cfg generated_config.cfg - ``` - -## 📞 Getting Help - -### Before Reporting Issues - -1. **Check this troubleshooting guide** -2. **Verify your input format** matches expected structure -3. **Test with sample data** from the repository -4. **Check template syntax** if using custom templates - -### When Reporting Issues - -Include the following information: - -1. **Command used**: - ```bash - ./network-config-generator --input_json input.json --output_folder output/ - ``` - -2. **Error message** (full text) - -3. **Input file structure** (sanitized): - ```json - { - "switch": { - "make": "cisco", - "firmware": "nxos" - } - } - ``` - -4. **Environment details**: - - OS: Windows/Linux - - Python version (if using Python) - - Tool version - -5. **Expected vs actual behavior** - -### Useful Debug Commands +## Executable Issues +**Linux — "command not found":** ```bash -# Check tool version and help -./network-config-generator --help - -# Test with minimal input -echo '{"switch":{"make":"cisco","firmware":"nxos","hostname":"test"},"vlans":[],"interfaces":[]}' > minimal.json -./network-config-generator --input_json minimal.json --output_folder debug/ - -# Validate JSON syntax -./network-config-generator --input_json your_input.json --output_folder debug/ --dry-run +chmod +x ./network_config_generator +./network_config_generator --help +``` -# Check template structure -find input/jinja2_templates -name "*.j2" -type f +**Windows — "cannot execute":** +1. Right-click → Properties → General → Unblock +2. Run from PowerShell: `.\network_config_generator.exe --help` -# Test with minimal input -echo '{"switch":{"make":"cisco","firmware":"nxos","hostname":"test"},"vlans":[],"interfaces":[]}' > minimal.json -./network-config-generator --input_json minimal.json --output_folder debug/ -``` +--- -### Community Resources +## Getting Help -- **GitHub Issues**: Report bugs and feature requests -- **GitHub Discussions**: Ask questions and share solutions -- **Documentation**: Check the `docs/` folder for detailed guides -- **Examples**: Look at `tests/test_cases/` for working examples +Before reporting an issue: +1. Check this guide and test with sample data +2. Validate your JSON syntax +3. Verify template folder structure -Remember: Most issues are related to input format, template paths, or JSON syntax. Double-check these areas first! +When reporting, include: +- Command used and full error message +- Input file structure (sanitized) +- OS and Python version +- Expected vs actual behavior diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/bmc-3.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/bmc-3.json new file mode 100644 index 0000000..218f740 --- /dev/null +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/bmc-3.json @@ -0,0 +1,98 @@ +{ + "switch": { + "make": "cisco", + "model": "9348gc-fx3", + "type": "BMC", + "hostname": "bmc-3", + "version": "10.3(4a)", + "firmware": "nxos", + "site": "site3" + }, + "vlans": [ + { + "vlan_id": 2, + "name": "UNUSED_VLAN", + "shutdown": true + }, + { + "vlan_id": 99, + "name": "NATIVE_VLAN" + }, + { + "vlan_id": 125, + "name": "BMC_Mgmt_125", + "interface": { + "ip": "10.71.32.254", + "cidr": 26, + "mtu": 9216 + } + } + ], + "interfaces": [ + { + "name": "Unused", + "type": "Access", + "description": "initial unused for all interfaces then config as defined", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/54", + "access_vlan": "2", + "shutdown": true + }, + { + "name": "Host_BMC", + "type": "Access", + "description": "Host BMC Connection", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/20", + "access_vlan": "125" + }, + { + "name": "HLH_BMC", + "type": "Access", + "description": "HLH BMC Connection", + "intf_type": "Ethernet", + "intf": "1/46", + "access_vlan": "125" + }, + { + "name": "HLH_OS", + "type": "Access", + "description": "HLH OS Connection", + "intf_type": "Ethernet", + "start_intf": "1/49", + "end_intf": "1/50", + "access_vlan": "125" + }, + { + "name": "To_TORs", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/51", + "end_intf": "1/52", + "native_vlan": "99", + "tagged_vlans": "125" + } + ], + "port_channels": [ + { + "id": 102, + "description": "TOR_BMC", + "type": "Trunk", + "native_vlan": "99", + "tagged_vlans": "125", + "members": [ + "1/51", + "1/52" + ] + } + ], + "static_routes": [ + { + "prefix": "0.0.0.0/0", + "next_hop": "10.71.32.193", + "description": "BMC default gateway" + } + ] +} \ No newline at end of file diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/tor-3a.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/tor-3a.json new file mode 100644 index 0000000..67d46c7 --- /dev/null +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/tor-3a.json @@ -0,0 +1,527 @@ +{ + "switch": { + "make": "cisco", + "model": "93180yc-fx3", + "type": "TOR1", + "hostname": "tor-3a", + "version": "10.3(4a)", + "firmware": "nxos", + "site": "site3" + }, + "vlans": [ + { + "vlan_id": 2, + "name": "UNUSED_VLAN", + "shutdown": true + }, + { + "vlan_id": 6, + "name": "HNVPA_6", + "interface": { + "ip": "10.71.180.2", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 6, + "priority": 150, + "virtual_ip": "10.71.180.1" + } + } + }, + { + "vlan_id": 7, + "name": "Infra_7", + "interface": { + "ip": "10.68.230.2", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 7, + "priority": 150, + "virtual_ip": "10.68.230.1" + } + } + }, + { + "vlan_id": 99, + "name": "NativeVlan" + }, + { + "vlan_id": 125, + "name": "BMC_Mgmt_125", + "interface": { + "ip": "10.71.32.251", + "cidr": 26, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 125, + "priority": 150, + "virtual_ip": "10.71.32.193" + } + } + }, + { + "vlan_id": 201, + "name": "Tenant_201", + "interface": { + "ip": "10.78.36.2", + "cidr": 23, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 201, + "priority": 150, + "virtual_ip": "10.78.36.1" + } + } + }, + { + "vlan_id": 301, + "name": "LogicalTenant_301", + "interface": { + "ip": "10.78.38.2", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 301, + "priority": 150, + "virtual_ip": "10.78.38.1" + } + } + }, + { + "vlan_id": 401, + "name": "DhcpTenant_401", + "interface": { + "ip": "10.78.39.2", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 401, + "priority": 150, + "virtual_ip": "10.78.39.1" + } + } + }, + { + "vlan_id": 501, + "name": "L3forward_501", + "interface": { + "ip": "10.68.229.2", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 501, + "priority": 150, + "virtual_ip": "10.68.229.1" + } + } + }, + { + "vlan_id": 502, + "name": "L3forward_502", + "interface": { + "ip": "10.68.229.18", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 502, + "priority": 150, + "virtual_ip": "10.68.229.17" + } + } + }, + { + "vlan_id": 503, + "name": "L3forward_503", + "interface": { + "ip": "10.68.229.34", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 503, + "priority": 150, + "virtual_ip": "10.68.229.33" + } + } + }, + { + "vlan_id": 504, + "name": "L3forward_504", + "interface": { + "ip": "10.68.229.50", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 504, + "priority": 150, + "virtual_ip": "10.68.229.49" + } + } + }, + { + "vlan_id": 505, + "name": "L3forward_505", + "interface": { + "ip": "10.68.229.66", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 505, + "priority": 150, + "virtual_ip": "10.68.229.65" + } + } + }, + { + "vlan_id": 506, + "name": "L3forward_506", + "interface": { + "ip": "10.68.229.82", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 506, + "priority": 150, + "virtual_ip": "10.68.229.81" + } + } + }, + { + "vlan_id": 507, + "name": "L3forward_507", + "interface": { + "ip": "10.68.229.98", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 507, + "priority": 150, + "virtual_ip": "10.68.229.97" + } + } + }, + { + "vlan_id": 508, + "name": "L3forward_508", + "interface": { + "ip": "10.68.229.114", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 508, + "priority": 150, + "virtual_ip": "10.68.229.113" + } + } + }, + { + "vlan_id": 509, + "name": "L3forward_509", + "interface": { + "ip": "10.68.229.130", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 509, + "priority": 150, + "virtual_ip": "10.68.229.129" + } + } + }, + { + "vlan_id": 510, + "name": "L3forward_510", + "interface": { + "ip": "10.68.229.146", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 510, + "priority": 150, + "virtual_ip": "10.68.229.145" + } + } + }, + { + "vlan_id": 511, + "name": "L3forward_511", + "interface": { + "ip": "10.68.229.162", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 511, + "priority": 150, + "virtual_ip": "10.68.229.161" + } + } + }, + { + "vlan_id": 512, + "name": "L3forward_512", + "interface": { + "ip": "10.68.229.178", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 512, + "priority": 150, + "virtual_ip": "10.68.229.177" + } + } + }, + { + "vlan_id": 513, + "name": "L3forward_513", + "interface": { + "ip": "10.68.229.194", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 513, + "priority": 150, + "virtual_ip": "10.68.229.193" + } + } + }, + { + "vlan_id": 514, + "name": "L3forward_514", + "interface": { + "ip": "10.68.229.210", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 514, + "priority": 150, + "virtual_ip": "10.68.229.209" + } + } + }, + { + "vlan_id": 515, + "name": "L3forward_515", + "interface": { + "ip": "10.68.229.226", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 515, + "priority": 150, + "virtual_ip": "10.68.229.225" + } + } + }, + { + "vlan_id": 516, + "name": "L3forward_516", + "interface": { + "ip": "10.68.229.242", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 516, + "priority": 150, + "virtual_ip": "10.68.229.241" + } + } + }, + { + "vlan_id": 711, + "name": "Storage_711_TOR1" + }, + { + "vlan_id": 712, + "name": "Storage_712_TOR2" + } + ], + "interfaces": [ + { + "name": "Unused", + "type": "Access", + "description": "initial unused for all interfaces then config as defined", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/54", + "access_vlan": "2", + "shutdown": true + }, + { + "name": "Loopback0", + "type": "L3", + "intf_type": "loopback", + "intf": "loopback0", + "ipv4": "10.71.32.149/32" + }, + { + "name": "P2P_Border1", + "type": "L3", + "intf_type": "Ethernet", + "intf": "1/48", + "ipv4": "10.71.32.130/30" + }, + { + "name": "P2P_Border2", + "type": "L3", + "intf_type": "Ethernet", + "intf": "1/47", + "ipv4": "10.71.32.138/30" + }, + { + "name": "Trunk_TO_BMC_SWITCH", + "type": "Trunk", + "intf_type": "Ethernet", + "intf": "1/49", + "native_vlan": "99", + "tagged_vlans": "125" + }, + { + "name": "Switched_Compute_To_Host", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/16", + "native_vlan": "7", + "tagged_vlans": "7,6,201,301,401,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516" + }, + { + "name": "Switched_Storage_To_Host", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/17", + "end_intf": "1/32", + "native_vlan": "99", + "tagged_vlans": "711", + "service_policy": { + "qos_input": "AZLOCAL-QOS-MAP" + } + } + ], + "port_channels": [ + { + "id": 50, + "description": "P2P_IBGP", + "type": "L3", + "ipv4": "10.71.32.145", + "members": [ + "1/41", + "1/42" + ] + }, + { + "id": 101, + "description": "ToR_Peer_Link", + "type": "Trunk", + "native_vlan": "99", + "members": [ + "1/49", + "1/50", + "1/51" + ] + } + ], + "bgp": { + "asn": 64797, + "router_id": "10.71.32.149", + "networks": [ + "10.71.32.130/30", + "10.71.32.138/30", + "10.71.32.149/32", + "10.71.32.144/30", + "10.71.180.0/24", + "10.68.230.0/24", + "10.71.32.192/26", + "10.78.36.0/23", + "10.78.38.0/24", + "10.78.39.0/24", + "10.68.229.0/28", + "10.68.229.16/28", + "10.68.229.32/28", + "10.68.229.48/28", + "10.68.229.64/28", + "10.68.229.80/28", + "10.68.229.96/28", + "10.68.229.112/28", + "10.68.229.128/28", + "10.68.229.144/28", + "10.68.229.160/28", + "10.68.229.176/28", + "10.68.229.192/28", + "10.68.229.208/28", + "10.68.229.224/28", + "10.68.229.240/28" + ], + "neighbors": [ + { + "ip": "10.71.32.129", + "description": "TO_Border1", + "remote_as": 64841, + "af_ipv4_unicast": { + "prefix_list_in": "DefaultRoute" + } + }, + { + "ip": "10.71.32.137", + "description": "TO_Border2", + "remote_as": 64841, + "af_ipv4_unicast": { + "prefix_list_in": "DefaultRoute" + } + }, + { + "ip": "10.71.32.146", + "description": "iBGP_PEER", + "remote_as": 64797, + "af_ipv4_unicast": {} + }, + { + "ip": "10.71.180.0/24", + "description": "TO_HNVPA", + "remote_as": 64686, + "update_source": "Loopback0", + "ebgp_multihop": 3, + "af_ipv4_unicast": { + "prefix_list_out": "DefaultRoute" + } + } + ] + }, + "prefix_lists": { + "DefaultRoute": [ + { + "seq": 10, + "action": "permit", + "prefix": "0.0.0.0/0" + }, + { + "seq": 50, + "action": "deny", + "prefix": "0.0.0.0/0", + "prefix_filter": "le 32" + } + ] + }, + "qos": true +} \ No newline at end of file diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/tor-3b.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/tor-3b.json new file mode 100644 index 0000000..a0422b2 --- /dev/null +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/expected_outputs/tor-3b.json @@ -0,0 +1,527 @@ +{ + "switch": { + "make": "cisco", + "model": "93180yc-fx3", + "type": "TOR2", + "hostname": "tor-3b", + "version": "10.3(4a)", + "firmware": "nxos", + "site": "site3" + }, + "vlans": [ + { + "vlan_id": 2, + "name": "UNUSED_VLAN", + "shutdown": true + }, + { + "vlan_id": 6, + "name": "HNVPA_6", + "interface": { + "ip": "10.71.180.3", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 6, + "priority": 140, + "virtual_ip": "10.71.180.1" + } + } + }, + { + "vlan_id": 7, + "name": "Infra_7", + "interface": { + "ip": "10.68.230.3", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 7, + "priority": 140, + "virtual_ip": "10.68.230.1" + } + } + }, + { + "vlan_id": 99, + "name": "NativeVlan" + }, + { + "vlan_id": 125, + "name": "BMC_Mgmt_125", + "interface": { + "ip": "10.71.32.252", + "cidr": 26, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 125, + "priority": 140, + "virtual_ip": "10.71.32.193" + } + } + }, + { + "vlan_id": 201, + "name": "Tenant_201", + "interface": { + "ip": "10.78.36.3", + "cidr": 23, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 201, + "priority": 140, + "virtual_ip": "10.78.36.1" + } + } + }, + { + "vlan_id": 301, + "name": "LogicalTenant_301", + "interface": { + "ip": "10.78.38.3", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 301, + "priority": 140, + "virtual_ip": "10.78.38.1" + } + } + }, + { + "vlan_id": 401, + "name": "DhcpTenant_401", + "interface": { + "ip": "10.78.39.3", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 401, + "priority": 140, + "virtual_ip": "10.78.39.1" + } + } + }, + { + "vlan_id": 501, + "name": "L3forward_501", + "interface": { + "ip": "10.68.229.3", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 501, + "priority": 140, + "virtual_ip": "10.68.229.1" + } + } + }, + { + "vlan_id": 502, + "name": "L3forward_502", + "interface": { + "ip": "10.68.229.19", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 502, + "priority": 140, + "virtual_ip": "10.68.229.17" + } + } + }, + { + "vlan_id": 503, + "name": "L3forward_503", + "interface": { + "ip": "10.68.229.35", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 503, + "priority": 140, + "virtual_ip": "10.68.229.33" + } + } + }, + { + "vlan_id": 504, + "name": "L3forward_504", + "interface": { + "ip": "10.68.229.51", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 504, + "priority": 140, + "virtual_ip": "10.68.229.49" + } + } + }, + { + "vlan_id": 505, + "name": "L3forward_505", + "interface": { + "ip": "10.68.229.67", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 505, + "priority": 140, + "virtual_ip": "10.68.229.65" + } + } + }, + { + "vlan_id": 506, + "name": "L3forward_506", + "interface": { + "ip": "10.68.229.83", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 506, + "priority": 140, + "virtual_ip": "10.68.229.81" + } + } + }, + { + "vlan_id": 507, + "name": "L3forward_507", + "interface": { + "ip": "10.68.229.99", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 507, + "priority": 140, + "virtual_ip": "10.68.229.97" + } + } + }, + { + "vlan_id": 508, + "name": "L3forward_508", + "interface": { + "ip": "10.68.229.115", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 508, + "priority": 140, + "virtual_ip": "10.68.229.113" + } + } + }, + { + "vlan_id": 509, + "name": "L3forward_509", + "interface": { + "ip": "10.68.229.131", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 509, + "priority": 140, + "virtual_ip": "10.68.229.129" + } + } + }, + { + "vlan_id": 510, + "name": "L3forward_510", + "interface": { + "ip": "10.68.229.147", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 510, + "priority": 140, + "virtual_ip": "10.68.229.145" + } + } + }, + { + "vlan_id": 511, + "name": "L3forward_511", + "interface": { + "ip": "10.68.229.163", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 511, + "priority": 140, + "virtual_ip": "10.68.229.161" + } + } + }, + { + "vlan_id": 512, + "name": "L3forward_512", + "interface": { + "ip": "10.68.229.179", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 512, + "priority": 140, + "virtual_ip": "10.68.229.177" + } + } + }, + { + "vlan_id": 513, + "name": "L3forward_513", + "interface": { + "ip": "10.68.229.195", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 513, + "priority": 140, + "virtual_ip": "10.68.229.193" + } + } + }, + { + "vlan_id": 514, + "name": "L3forward_514", + "interface": { + "ip": "10.68.229.211", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 514, + "priority": 140, + "virtual_ip": "10.68.229.209" + } + } + }, + { + "vlan_id": 515, + "name": "L3forward_515", + "interface": { + "ip": "10.68.229.227", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 515, + "priority": 140, + "virtual_ip": "10.68.229.225" + } + } + }, + { + "vlan_id": 516, + "name": "L3forward_516", + "interface": { + "ip": "10.68.229.243", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 516, + "priority": 140, + "virtual_ip": "10.68.229.241" + } + } + }, + { + "vlan_id": 711, + "name": "Storage_711_TOR1" + }, + { + "vlan_id": 712, + "name": "Storage_712_TOR2" + } + ], + "interfaces": [ + { + "name": "Unused", + "type": "Access", + "description": "initial unused for all interfaces then config as defined", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/54", + "access_vlan": "2", + "shutdown": true + }, + { + "name": "Loopback0", + "type": "L3", + "intf_type": "loopback", + "intf": "loopback0", + "ipv4": "10.71.32.150/32" + }, + { + "name": "P2P_Border1", + "type": "L3", + "intf_type": "Ethernet", + "intf": "1/48", + "ipv4": "10.71.32.134/30" + }, + { + "name": "P2P_Border2", + "type": "L3", + "intf_type": "Ethernet", + "intf": "1/47", + "ipv4": "10.71.32.142/30" + }, + { + "name": "Trunk_TO_BMC_SWITCH", + "type": "Trunk", + "intf_type": "Ethernet", + "intf": "1/49", + "native_vlan": "99", + "tagged_vlans": "125" + }, + { + "name": "Switched_Compute_To_Host", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/16", + "native_vlan": "7", + "tagged_vlans": "7,6,201,301,401,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516" + }, + { + "name": "Switched_Storage_To_Host", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/17", + "end_intf": "1/32", + "native_vlan": "99", + "tagged_vlans": "712", + "service_policy": { + "qos_input": "AZLOCAL-QOS-MAP" + } + } + ], + "port_channels": [ + { + "id": 50, + "description": "P2P_IBGP", + "type": "L3", + "ipv4": "10.71.32.146", + "members": [ + "1/41", + "1/42" + ] + }, + { + "id": 101, + "description": "ToR_Peer_Link", + "type": "Trunk", + "native_vlan": "99", + "members": [ + "1/49", + "1/50", + "1/51" + ] + } + ], + "bgp": { + "asn": 64797, + "router_id": "10.71.32.150", + "networks": [ + "10.71.32.134/30", + "10.71.32.142/30", + "10.71.32.150/32", + "10.71.32.144/30", + "10.71.180.0/24", + "10.68.230.0/24", + "10.71.32.192/26", + "10.78.36.0/23", + "10.78.38.0/24", + "10.78.39.0/24", + "10.68.229.0/28", + "10.68.229.16/28", + "10.68.229.32/28", + "10.68.229.48/28", + "10.68.229.64/28", + "10.68.229.80/28", + "10.68.229.96/28", + "10.68.229.112/28", + "10.68.229.128/28", + "10.68.229.144/28", + "10.68.229.160/28", + "10.68.229.176/28", + "10.68.229.192/28", + "10.68.229.208/28", + "10.68.229.224/28", + "10.68.229.240/28" + ], + "neighbors": [ + { + "ip": "10.71.32.133", + "description": "TO_Border1", + "remote_as": 64841, + "af_ipv4_unicast": { + "prefix_list_in": "DefaultRoute" + } + }, + { + "ip": "10.71.32.141", + "description": "TO_Border2", + "remote_as": 64841, + "af_ipv4_unicast": { + "prefix_list_in": "DefaultRoute" + } + }, + { + "ip": "10.71.32.145", + "description": "iBGP_PEER", + "remote_as": 64797, + "af_ipv4_unicast": {} + }, + { + "ip": "10.71.180.0/24", + "description": "TO_HNVPA", + "remote_as": 64686, + "update_source": "Loopback0", + "ebgp_multihop": 3, + "af_ipv4_unicast": { + "prefix_list_out": "DefaultRoute" + } + } + ] + }, + "prefix_lists": { + "DefaultRoute": [ + { + "seq": 10, + "action": "permit", + "prefix": "0.0.0.0/0" + }, + { + "seq": 50, + "action": "deny", + "prefix": "0.0.0.0/0", + "prefix_filter": "le 32" + } + ] + }, + "qos": true +} \ No newline at end of file diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/lab_cisco_nxos_switch_input.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/lab_cisco_nxos_switch_input.json new file mode 100644 index 0000000..c84b5e8 --- /dev/null +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_20node/lab_cisco_nxos_switch_input.json @@ -0,0 +1,1973 @@ +{ + "Version": "1.0.0", + "Description": "Template for ASZ Rack", + "InputData": { + "MainEnvData": [ + { + "Id": "Env01", + "Site": "site3", + "RackName": "rack03", + "NodeCount": 20, + "ConnectType": "connected", + "CiEnabled": "yes", + "ClusterUnits": [ + { + "Name": "Cl01", + "NodeCount": 1, + "RackId": "Rack01", + "NamingPrefix": "rack0301", + "PhysicalNamingPrefix": "rack0301", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rack0301.test.example.com", + "ExternalDomainFQDN": "ext-rack0301.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl02", + "NodeCount": 1, + "RackId": "Rack01", + "NamingPrefix": "rack0302", + "PhysicalNamingPrefix": "rack0302", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rack0302.test.example.com", + "ExternalDomainFQDN": "ext-rack0302.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl03", + "NodeCount": 1, + "RackId": "Rack01", + "NamingPrefix": "rack0303", + "PhysicalNamingPrefix": "rack0303", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rack0303.test.example.com", + "ExternalDomainFQDN": "ext-rack0303.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl04", + "NodeCount": 4, + "RackId": "Rack01", + "NamingPrefix": "rack0304", + "PhysicalNamingPrefix": "rack0304", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rack0304.test.example.com", + "ExternalDomainFQDN": "ext-rack0304.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl05", + "NodeCount": 4, + "RackId": "Rack01", + "NamingPrefix": "rack0305", + "PhysicalNamingPrefix": "rack0305", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rack0305.test.example.com", + "ExternalDomainFQDN": "ext-rack0305.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl06", + "NodeCount": 4, + "RackId": "Rack01", + "NamingPrefix": "rack0306", + "PhysicalNamingPrefix": "rack0306", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rack0306.test.example.com", + "ExternalDomainFQDN": "ext-rack0306.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl07", + "NodeCount": 4, + "RackId": "Rack01", + "NamingPrefix": "rack0307", + "PhysicalNamingPrefix": "rack0307", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rack0307.test.example.com", + "ExternalDomainFQDN": "ext-rack0307.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl08", + "NodeCount": 1, + "RackId": "Rack01", + "NamingPrefix": "rack0308", + "PhysicalNamingPrefix": "rack0308", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rack0308.test.example.com", + "ExternalDomainFQDN": "ext-rack0308.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + } + ] + } + ], + "Switches": [ + { + "Make": "Cisco", + "Model": "C9336C-FX2", + "Hostname": "border-3a", + "Type": "Border1", + "ASN": 64841 + }, + { + "Make": "Cisco", + "Model": "C9336C-FX2", + "Hostname": "border-3b", + "Type": "Border2", + "ASN": 64841 + }, + { + "Make": "Cisco", + "Model": "93180YC-FX3", + "Type": "TOR1", + "Hostname": "tor-3a", + "ASN": 64797, + "Firmware": "10.3(4a)" + }, + { + "Make": "Cisco", + "Model": "93180YC-FX3", + "Type": "TOR2", + "Hostname": "tor-3b", + "ASN": 64797, + "Firmware": "10.3(4a)" + }, + { + "Make": "Cisco", + "Model": "9348GC-FX3", + "Type": "BMC", + "Hostname": "bmc-3", + "ASN": null, + "Firmware": "10.3(4a)" + }, + { + "Make": "Microsoft", + "Model": null, + "Type": "MUX", + "Hostname": "mux-3", + "ASN": 64686, + "Firmware": null + } + ], + "DeploymentPattern": "Switched", + "SwitchUplink": "BGP", + "HostConnectivity": "BGP", + "Supernets": [ + { + "GroupName": "P2P_Border", + "Name": "P2P_Border1_Tor1", + "VlanId": 0, + "Description": "Uplink to Border1, P2P_{$Type}_{$Type}", + "IPv4": { + "Name": "P2P_Border1_Tor1", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.71.32.128/30", + "Network": "10.71.32.128", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.71.32.131", + "FirstAddress": "10.71.32.129", + "LastAddress": "10.71.32.130", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.32.128" + }, + { + "Name": "Border1", + "IP": "10.71.32.129" + }, + { + "Name": "TOR1", + "IP": "10.71.32.130" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "P2P_Border", + "Name": "P2P_Border1_Tor2", + "VlanId": 0, + "Description": "Uplink to Border2, P2P_{$Type}_{$Type}", + "IPv4": { + "Name": "P2P_Border1_Tor2", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.71.32.132/30", + "Network": "10.71.32.132", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.71.32.135", + "FirstAddress": "10.71.32.133", + "LastAddress": "10.71.32.134", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.32.132" + }, + { + "Name": "Border1", + "IP": "10.71.32.133" + }, + { + "Name": "TOR2", + "IP": "10.71.32.134" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "P2P_Border", + "Name": "P2P_Border2_Tor1", + "VlanId": 0, + "Description": "Uplink to Border2, naming convention P2P_{$Type}_{$Type}", + "IPv4": { + "Name": "P2P_Border2_Tor1", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.71.32.136/30", + "Network": "10.71.32.136", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.71.32.139", + "FirstAddress": "10.71.32.137", + "LastAddress": "10.71.32.138", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.32.136" + }, + { + "Name": "Border2", + "IP": "10.71.32.137" + }, + { + "Name": "TOR1", + "IP": "10.71.32.138" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "P2P_Border", + "Name": "P2P_Border2_Tor2", + "VlanId": 0, + "Description": "Uplink to Border2, naming convention P2P_{$Type}_{$Type}", + "IPv4": { + "Name": "P2P_Border2_Tor2", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.71.32.140/30", + "Network": "10.71.32.140", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.71.32.143", + "FirstAddress": "10.71.32.141", + "LastAddress": "10.71.32.142", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.32.140" + }, + { + "Name": "Border2", + "IP": "10.71.32.141" + }, + { + "Name": "TOR2", + "IP": "10.71.32.142" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "P2P_IBGP", + "Name": "P2P_iBGP", + "VlanId": 0, + "Description": "IBGP Peer Link", + "IPv4": { + "Name": "P2P_iBGP", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.71.32.144/30", + "Network": "10.71.32.144", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.71.32.147", + "FirstAddress": "10.71.32.145", + "LastAddress": "10.71.32.146", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.32.144" + }, + { + "Name": "TOR1", + "IP": "10.71.32.145" + }, + { + "Name": "TOR2", + "IP": "10.71.32.146" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Loopback0", + "Name": "Loopback0_Tor1", + "VlanId": 0, + "Description": "Switch Loopback assignment", + "IPv4": { + "Name": "Loopback0_Tor1", + "VlanId": 0, + "Cidr": 32, + "TORGroup": "", + "NetworkType": "Loopback", + "Subnet": "10.71.32.149/32", + "Network": "10.71.32.149", + "Netmask": "255.255.255.255", + "Gateway": "", + "BroadcastAddress": "", + "FirstAddress": "", + "LastAddress": "", + "Assignment": [ + { + "Name": "TOR1", + "IP": "10.71.32.149" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Loopback0", + "Name": "Loopback0_Tor2", + "VlanId": 0, + "Description": "Switch Loopback assignment", + "IPv4": { + "Name": "Loopback0_Tor2", + "VlanId": 0, + "Cidr": 32, + "TORGroup": "", + "NetworkType": "Loopback", + "Subnet": "10.71.32.150/32", + "Network": "10.71.32.150", + "Netmask": "255.255.255.255", + "Gateway": "", + "BroadcastAddress": "", + "FirstAddress": "", + "LastAddress": "", + "Assignment": [ + { + "Name": "TOR2", + "IP": "10.71.32.150" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "BMC", + "Name": "BMC_Mgmt_125", + "VLANID": 125, + "Description": "BMC Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "BMC_Mgmt_125", + "VLANID": 125, + "Cidr": 26, + "TORGroup": "", + "NetworkType": "Infrastructure", + "Subnet": "10.71.32.192/26", + "Network": "10.71.32.192", + "Netmask": "255.255.255.192", + "Gateway": "10.71.32.193", + "BroadcastAddress": "10.71.32.255", + "FirstAddress": "10.71.32.193", + "LastAddress": "10.71.32.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.32.192", + "ClusterID": null + }, + { + "Name": "Gateway", + "IP": "10.71.32.193", + "ClusterID": null + }, + { + "Name": "HLH-BMC", + "IP": "10.71.32.194", + "ClusterID": null + }, + { + "Name": "CL01-N01", + "IP": "10.71.32.195", + "ClusterID": "CL01" + }, + { + "Name": "CL02-N01", + "IP": "10.71.32.196", + "ClusterID": "CL02" + }, + { + "Name": "CL03-N01", + "IP": "10.71.32.197", + "ClusterID": "CL03" + }, + { + "Name": "CL04-N01", + "IP": "10.71.32.198", + "ClusterID": "CL04" + }, + { + "Name": "CL04-N02", + "IP": "10.71.32.199", + "ClusterID": "CL04" + }, + { + "Name": "CL04-N03", + "IP": "10.71.32.200", + "ClusterID": "CL04" + }, + { + "Name": "CL04-N04", + "IP": "10.71.32.201", + "ClusterID": "CL04" + }, + { + "Name": "CL05-N01", + "IP": "10.71.32.202", + "ClusterID": "CL05" + }, + { + "Name": "CL05-N02", + "IP": "10.71.32.203", + "ClusterID": "CL05" + }, + { + "Name": "CL05-N03", + "IP": "10.71.32.204", + "ClusterID": "CL05" + }, + { + "Name": "CL05-N04", + "IP": "10.71.32.205", + "ClusterID": "CL05" + }, + { + "Name": "CL06-N01", + "IP": "10.71.32.206", + "ClusterID": "CL06" + }, + { + "Name": "CL06-N02", + "IP": "10.71.32.207", + "ClusterID": "CL06" + }, + { + "Name": "CL06-N03", + "IP": "10.71.32.208", + "ClusterID": "CL06" + }, + { + "Name": "CL06-N04", + "IP": "10.71.32.209", + "ClusterID": "CL06" + }, + { + "Name": "CL07-N01", + "IP": "10.71.32.210", + "ClusterID": "CL07" + }, + { + "Name": "CL07-N02", + "IP": "10.71.32.211", + "ClusterID": "CL07" + }, + { + "Name": "CL07-N03", + "IP": "10.71.32.212", + "ClusterID": "CL07" + }, + { + "Name": "CL07-N04", + "IP": "10.71.32.213", + "ClusterID": "CL07" + }, + { + "Name": "CL08-N01", + "IP": "10.71.32.214", + "ClusterID": "CL08" + }, + { + "Name": "CL01-HLH-DVM01", + "IP": "10.71.32.235", + "ClusterID": "CL01" + }, + { + "Name": "CL02-HLH-DVM02", + "IP": "10.71.32.236", + "ClusterID": "CL02" + }, + { + "Name": "CL03-HLH-DVM03", + "IP": "10.71.32.237", + "ClusterID": "CL03" + }, + { + "Name": "CL04-HLH-DVM04", + "IP": "10.71.32.238", + "ClusterID": "CL04" + }, + { + "Name": "CL05-HLH-DVM05", + "IP": "10.71.32.239", + "ClusterID": "CL05" + }, + { + "Name": "CL06-HLH-DVM06", + "IP": "10.71.32.240", + "ClusterID": "CL06" + }, + { + "Name": "CL07-HLH-DVM07", + "IP": "10.71.32.241", + "ClusterID": "CL07" + }, + { + "Name": "CL08-HLH-DVM08", + "IP": "10.71.32.242", + "ClusterID": "CL08" + }, + { + "Name": "Tor1-Mgmt", + "IP": "10.71.32.251", + "ClusterID": null + }, + { + "Name": "Tor2-Mgmt", + "IP": "10.71.32.252", + "ClusterID": null + }, + { + "Name": "BMC-Mgmt", + "IP": "10.71.32.253", + "ClusterID": null + }, + { + "Name": "HLH-OS", + "IP": "10.71.32.254", + "ClusterID": null + }, + { + "Name": "Broadcast", + "IP": "10.71.32.255", + "ClusterID": null + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "HNVPA", + "Name": "HNVPA_6", + "VLANID": 6, + "Description": "HNVPA Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "HNVPA_6", + "VLANID": 6, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "PA", + "Subnet": "10.71.180.0/24", + "Network": "10.71.180.0", + "Netmask": "255.255.255.0", + "Gateway": "10.71.180.1", + "BroadcastAddress": "10.71.180.255", + "FirstAddress": "10.71.180.1", + "LastAddress": "10.71.180.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.180.0" + }, + { + "Name": "Gateway", + "IP": "10.71.180.1" + }, + { + "Name": "TOR1", + "IP": "10.71.180.2" + }, + { + "Name": "TOR2", + "IP": "10.71.180.3" + } + ], + "IPPools": [ + { + "Name": "CL01", + "StartingAddress": "10.71.180.4", + "EndingAddress": "10.71.180.19" + }, + { + "Name": "CL02", + "StartingAddress": "10.71.180.20", + "EndingAddress": "10.71.180.35" + }, + { + "Name": "CL03", + "StartingAddress": "10.71.180.36", + "EndingAddress": "10.71.180.51" + }, + { + "Name": "CL04", + "StartingAddress": "10.71.180.52", + "EndingAddress": "10.71.180.83" + }, + { + "Name": "CL05", + "StartingAddress": "10.71.180.84", + "EndingAddress": "10.71.180.115" + }, + { + "Name": "CL06", + "StartingAddress": "10.71.180.116", + "EndingAddress": "10.71.180.147" + }, + { + "Name": "CL07", + "StartingAddress": "10.71.180.148", + "EndingAddress": "10.71.180.179" + }, + { + "Name": "CL08", + "StartingAddress": "10.71.180.180", + "EndingAddress": "10.71.180.195" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Infrastructure", + "Name": "Infra_7", + "VLANID": 7, + "Description": "Infrastructure Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "Infra_7", + "VLANID": 7, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Infrastructure", + "Subnet": "10.68.230.0/24", + "Network": "10.68.230.0", + "Netmask": "255.255.255.0", + "Gateway": "10.68.230.1", + "BroadcastAddress": "10.68.230.255", + "FirstAddress": "10.68.230.1", + "LastAddress": "10.68.230.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.230.0" + }, + { + "Name": "Gateway", + "IP": "10.68.230.1" + }, + { + "Name": "TOR1", + "IP": "10.68.230.2" + }, + { + "Name": "TOR2", + "IP": "10.68.230.3" + }, + { + "Name": "CL01-N01", + "IP": "10.68.230.4" + }, + { + "Name": "CL02-N01", + "IP": "10.68.230.32" + }, + { + "Name": "CL03-N01", + "IP": "10.68.230.64" + }, + { + "Name": "CL04-N01", + "IP": "10.68.230.96" + }, + { + "Name": "CL04-N02", + "IP": "10.68.230.97" + }, + { + "Name": "CL04-N03", + "IP": "10.68.230.98" + }, + { + "Name": "CL04-N04", + "IP": "10.68.230.99" + }, + { + "Name": "CL05-N01", + "IP": "10.68.230.128" + }, + { + "Name": "CL05-N02", + "IP": "10.68.230.129" + }, + { + "Name": "CL05-N03", + "IP": "10.68.230.130" + }, + { + "Name": "CL05-N04", + "IP": "10.68.230.131" + }, + { + "Name": "CL06-N01", + "IP": "10.68.230.160" + }, + { + "Name": "CL06-N02", + "IP": "10.68.230.161" + }, + { + "Name": "CL06-N03", + "IP": "10.68.230.162" + }, + { + "Name": "CL06-N04", + "IP": "10.68.230.163" + }, + { + "Name": "CL07-N01", + "IP": "10.68.230.192" + }, + { + "Name": "CL07-N02", + "IP": "10.68.230.193" + }, + { + "Name": "CL07-N03", + "IP": "10.68.230.194" + }, + { + "Name": "CL07-N04", + "IP": "10.68.230.195" + }, + { + "Name": "CL08-N01", + "IP": "10.68.230.224" + } + ], + "IPPools": [ + { + "Name": "CL01", + "StartingAddress": "10.68.230.5", + "EndingAddress": "10.68.230.31" + }, + { + "Name": "CL02", + "StartingAddress": "10.68.230.33", + "EndingAddress": "10.68.230.63" + }, + { + "Name": "CL03", + "StartingAddress": "10.68.230.65", + "EndingAddress": "10.68.230.95" + }, + { + "Name": "CL04", + "StartingAddress": "10.68.230.100", + "EndingAddress": "10.68.230.127" + }, + { + "Name": "CL05", + "StartingAddress": "10.68.230.132", + "EndingAddress": "10.68.230.159" + }, + { + "Name": "CL06", + "StartingAddress": "10.68.230.164", + "EndingAddress": "10.68.230.191" + }, + { + "Name": "CL07", + "StartingAddress": "10.68.230.196", + "EndingAddress": "10.68.230.223" + }, + { + "Name": "CL08", + "StartingAddress": "10.68.230.225", + "EndingAddress": "10.68.230.254" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "TENANT", + "Name": "Tenant_201", + "VLANID": 201, + "Description": "TENANT Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "Tenant_201", + "VLANID": 201, + "Cidr": 23, + "TORGroup": "", + "NetworkType": "Tenant", + "Subnet": "10.78.36.0/23", + "Network": "10.78.36.0", + "Netmask": "255.255.254.0", + "Gateway": "10.78.36.1", + "BroadcastAddress": "10.78.37.255", + "FirstAddress": "10.78.36.1", + "LastAddress": "10.78.37.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.78.36.0" + }, + { + "Name": "Gateway", + "IP": "10.78.36.1" + }, + { + "Name": "TOR1", + "IP": "10.78.36.2" + }, + { + "Name": "TOR2", + "IP": "10.78.36.3" + } + ], + "IPPools": [ + { + "Name": "CL01", + "StartingAddress": "10.78.36.4", + "EndingAddress": "10.78.36.35" + }, + { + "Name": "CL02", + "StartingAddress": "10.78.36.36", + "EndingAddress": "10.78.36.67" + }, + { + "Name": "CL03", + "StartingAddress": "10.78.36.68", + "EndingAddress": "10.78.36.99" + }, + { + "Name": "CL04", + "StartingAddress": "10.78.36.100", + "EndingAddress": "10.78.36.163" + }, + { + "Name": "CL05", + "StartingAddress": "10.78.36.164", + "EndingAddress": "10.78.36.227" + }, + { + "Name": "CL06", + "StartingAddress": "10.78.36.228", + "EndingAddress": "10.78.37.35" + }, + { + "Name": "CL07", + "StartingAddress": "10.78.37.36", + "EndingAddress": "10.78.37.99" + }, + { + "Name": "CL08", + "StartingAddress": "10.78.37.100", + "EndingAddress": "10.78.37.131" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "TENANT", + "Name": "LogicalTenant_301", + "VLANID": 301, + "Description": "TENANT Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "LogicalTenant_301", + "VLANID": 301, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Tenant", + "Subnet": "10.78.38.0/24", + "Network": "10.78.38.0", + "Netmask": "255.255.255.0", + "Gateway": "10.78.38.1", + "BroadcastAddress": "10.78.38.255", + "FirstAddress": "10.78.38.1", + "LastAddress": "10.78.38.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.78.38.0" + }, + { + "Name": "Gateway", + "IP": "10.78.38.1" + }, + { + "Name": "TOR1", + "IP": "10.78.38.2" + }, + { + "Name": "TOR2", + "IP": "10.78.38.3" + } + ], + "IPPools": [ + { + "Name": "CL01", + "StartingAddress": "10.78.38.4", + "EndingAddress": "10.78.38.19" + }, + { + "Name": "CL02", + "StartingAddress": "10.78.38.20", + "EndingAddress": "10.78.38.35" + }, + { + "Name": "CL03", + "StartingAddress": "10.78.38.36", + "EndingAddress": "10.78.38.51" + }, + { + "Name": "CL04", + "StartingAddress": "10.78.38.52", + "EndingAddress": "10.78.38.83" + }, + { + "Name": "CL05", + "StartingAddress": "10.78.38.84", + "EndingAddress": "10.78.38.115" + }, + { + "Name": "CL06", + "StartingAddress": "10.78.38.116", + "EndingAddress": "10.78.38.147" + }, + { + "Name": "CL07", + "StartingAddress": "10.78.38.148", + "EndingAddress": "10.78.38.179" + }, + { + "Name": "CL08", + "StartingAddress": "10.78.38.180", + "EndingAddress": "10.78.38.195" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "TENANT", + "Name": "DhcpTenant_401", + "VLANID": 401, + "Description": "TENANT Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "DhcpTenant_401", + "VLANID": 401, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Tenant", + "Subnet": "10.78.39.0/24", + "Network": "10.78.39.0", + "Netmask": "255.255.255.0", + "Gateway": "10.78.39.1", + "BroadcastAddress": "10.78.39.255", + "FirstAddress": "10.78.39.1", + "LastAddress": "10.78.39.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.78.39.0" + }, + { + "Name": "Gateway", + "IP": "10.78.39.1" + }, + { + "Name": "TOR1", + "IP": "10.78.39.2" + }, + { + "Name": "TOR2", + "IP": "10.78.39.3" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_501", + "VLANID": 501, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_501", + "VLANID": 501, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.0/28", + "Network": "10.68.229.0", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.1", + "BroadcastAddress": "10.68.229.15", + "FirstAddress": "10.68.229.1", + "LastAddress": "10.68.229.14", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.0" + }, + { + "Name": "Gateway", + "IP": "10.68.229.1" + }, + { + "Name": "TOR1", + "IP": "10.68.229.2" + }, + { + "Name": "TOR2", + "IP": "10.68.229.3" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_502", + "VLANID": 502, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_502", + "VLANID": 502, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.16/28", + "Network": "10.68.229.16", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.17", + "BroadcastAddress": "10.68.229.31", + "FirstAddress": "10.68.229.17", + "LastAddress": "10.68.229.30", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.16" + }, + { + "Name": "Gateway", + "IP": "10.68.229.17" + }, + { + "Name": "TOR1", + "IP": "10.68.229.18" + }, + { + "Name": "TOR2", + "IP": "10.68.229.19" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_503", + "VLANID": 503, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_503", + "VLANID": 503, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.32/28", + "Network": "10.68.229.32", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.33", + "BroadcastAddress": "10.68.229.47", + "FirstAddress": "10.68.229.33", + "LastAddress": "10.68.229.46", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.32" + }, + { + "Name": "Gateway", + "IP": "10.68.229.33" + }, + { + "Name": "TOR1", + "IP": "10.68.229.34" + }, + { + "Name": "TOR2", + "IP": "10.68.229.35" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_504", + "VLANID": 504, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_504", + "VLANID": 504, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.48/28", + "Network": "10.68.229.48", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.49", + "BroadcastAddress": "10.68.229.63", + "FirstAddress": "10.68.229.49", + "LastAddress": "10.68.229.62", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.48" + }, + { + "Name": "Gateway", + "IP": "10.68.229.49" + }, + { + "Name": "TOR1", + "IP": "10.68.229.50" + }, + { + "Name": "TOR2", + "IP": "10.68.229.51" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_505", + "VLANID": 505, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_505", + "VLANID": 505, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.64/28", + "Network": "10.68.229.64", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.65", + "BroadcastAddress": "10.68.229.79", + "FirstAddress": "10.68.229.65", + "LastAddress": "10.68.229.78", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.64" + }, + { + "Name": "Gateway", + "IP": "10.68.229.65" + }, + { + "Name": "TOR1", + "IP": "10.68.229.66" + }, + { + "Name": "TOR2", + "IP": "10.68.229.67" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_506", + "VLANID": 506, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_506", + "VLANID": 506, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.80/28", + "Network": "10.68.229.80", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.81", + "BroadcastAddress": "10.68.229.95", + "FirstAddress": "10.68.229.81", + "LastAddress": "10.68.229.94", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.80" + }, + { + "Name": "Gateway", + "IP": "10.68.229.81" + }, + { + "Name": "TOR1", + "IP": "10.68.229.82" + }, + { + "Name": "TOR2", + "IP": "10.68.229.83" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_507", + "VLANID": 507, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_507", + "VLANID": 507, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.96/28", + "Network": "10.68.229.96", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.97", + "BroadcastAddress": "10.68.229.111", + "FirstAddress": "10.68.229.97", + "LastAddress": "10.68.229.110", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.96" + }, + { + "Name": "Gateway", + "IP": "10.68.229.97" + }, + { + "Name": "TOR1", + "IP": "10.68.229.98" + }, + { + "Name": "TOR2", + "IP": "10.68.229.99" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_508", + "VLANID": 508, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_508", + "VLANID": 508, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.112/28", + "Network": "10.68.229.112", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.113", + "BroadcastAddress": "10.68.229.127", + "FirstAddress": "10.68.229.113", + "LastAddress": "10.68.229.126", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.112" + }, + { + "Name": "Gateway", + "IP": "10.68.229.113" + }, + { + "Name": "TOR1", + "IP": "10.68.229.114" + }, + { + "Name": "TOR2", + "IP": "10.68.229.115" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_509", + "VLANID": 509, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_509", + "VLANID": 509, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.128/28", + "Network": "10.68.229.128", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.129", + "BroadcastAddress": "10.68.229.143", + "FirstAddress": "10.68.229.129", + "LastAddress": "10.68.229.142", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.128" + }, + { + "Name": "Gateway", + "IP": "10.68.229.129" + }, + { + "Name": "TOR1", + "IP": "10.68.229.130" + }, + { + "Name": "TOR2", + "IP": "10.68.229.131" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_510", + "VLANID": 510, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_510", + "VLANID": 510, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.144/28", + "Network": "10.68.229.144", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.145", + "BroadcastAddress": "10.68.229.159", + "FirstAddress": "10.68.229.145", + "LastAddress": "10.68.229.158", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.144" + }, + { + "Name": "Gateway", + "IP": "10.68.229.145" + }, + { + "Name": "TOR1", + "IP": "10.68.229.146" + }, + { + "Name": "TOR2", + "IP": "10.68.229.147" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_511", + "VLANID": 511, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_511", + "VLANID": 511, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.160/28", + "Network": "10.68.229.160", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.161", + "BroadcastAddress": "10.68.229.175", + "FirstAddress": "10.68.229.161", + "LastAddress": "10.68.229.174", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.160" + }, + { + "Name": "Gateway", + "IP": "10.68.229.161" + }, + { + "Name": "TOR1", + "IP": "10.68.229.162" + }, + { + "Name": "TOR2", + "IP": "10.68.229.163" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_512", + "VLANID": 512, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_512", + "VLANID": 512, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.176/28", + "Network": "10.68.229.176", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.177", + "BroadcastAddress": "10.68.229.191", + "FirstAddress": "10.68.229.177", + "LastAddress": "10.68.229.190", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.176" + }, + { + "Name": "Gateway", + "IP": "10.68.229.177" + }, + { + "Name": "TOR1", + "IP": "10.68.229.178" + }, + { + "Name": "TOR2", + "IP": "10.68.229.179" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_513", + "VLANID": 513, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_513", + "VLANID": 513, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.192/28", + "Network": "10.68.229.192", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.193", + "BroadcastAddress": "10.68.229.207", + "FirstAddress": "10.68.229.193", + "LastAddress": "10.68.229.206", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.192" + }, + { + "Name": "Gateway", + "IP": "10.68.229.193" + }, + { + "Name": "TOR1", + "IP": "10.68.229.194" + }, + { + "Name": "TOR2", + "IP": "10.68.229.195" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_514", + "VLANID": 514, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_514", + "VLANID": 514, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.208/28", + "Network": "10.68.229.208", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.209", + "BroadcastAddress": "10.68.229.223", + "FirstAddress": "10.68.229.209", + "LastAddress": "10.68.229.222", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.208" + }, + { + "Name": "Gateway", + "IP": "10.68.229.209" + }, + { + "Name": "TOR1", + "IP": "10.68.229.210" + }, + { + "Name": "TOR2", + "IP": "10.68.229.211" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_515", + "VLANID": 515, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_515", + "VLANID": 515, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.224/28", + "Network": "10.68.229.224", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.225", + "BroadcastAddress": "10.68.229.239", + "FirstAddress": "10.68.229.225", + "LastAddress": "10.68.229.238", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.224" + }, + { + "Name": "Gateway", + "IP": "10.68.229.225" + }, + { + "Name": "TOR1", + "IP": "10.68.229.226" + }, + { + "Name": "TOR2", + "IP": "10.68.229.227" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_516", + "VLANID": 516, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_516", + "VLANID": 516, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.68.229.240/28", + "Network": "10.68.229.240", + "Netmask": "255.255.255.240", + "Gateway": "10.68.229.241", + "BroadcastAddress": "10.68.229.255", + "FirstAddress": "10.68.229.241", + "LastAddress": "10.68.229.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.68.229.240" + }, + { + "Name": "Gateway", + "IP": "10.68.229.241" + }, + { + "Name": "TOR1", + "IP": "10.68.229.242" + }, + { + "Name": "TOR2", + "IP": "10.68.229.243" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "ExternalIP", + "Name": "PublicVIP", + "VLANID": 0, + "Description": "ExternalIP Network, no config on switch. GroupName is unique key.", + "IPv4": { + "SwitchSVI": false, + "Name": "PublicVIP", + "VLANID": 0, + "Cidr": 23, + "TORGroup": "", + "NetworkType": "ExternalIP", + "Subnet": "10.65.182.0/23", + "Network": "10.65.182.0", + "Netmask": "255.255.254.0", + "Gateway": null, + "BroadcastAddress": "10.65.183.255", + "FirstAddress": "10.65.182.1", + "LastAddress": "10.65.183.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.65.182.0" + } + ], + "IPPools": [ + { + "Name": "CL01", + "Subnet": "10.65.182.0/26" + }, + { + "Name": "CL02", + "Subnet": "10.65.182.64/26" + }, + { + "Name": "CL03", + "Subnet": "10.65.182.128/26" + }, + { + "Name": "CL04", + "Subnet": "10.65.182.192/26" + }, + { + "Name": "CL05", + "Subnet": "10.65.183.0/26" + }, + { + "Name": "CL06", + "Subnet": "10.65.183.64/26" + }, + { + "Name": "CL07", + "Subnet": "10.65.183.128/26" + }, + { + "Name": "CL08", + "Subnet": "10.65.183.192/26" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "ExternalIP", + "Name": "GRE", + "VLANID": 0, + "Description": "ExternalIP Network, no config on switch. GroupName is unique key.", + "IPv4": { + "SwitchSVI": false, + "Name": "GRE", + "VLANID": 0, + "Cidr": 25, + "TORGroup": "", + "NetworkType": "ExternalIP", + "Subnet": "10.76.26.128/25", + "Network": "10.76.26.128", + "Netmask": "255.255.255.128", + "Gateway": null, + "BroadcastAddress": "10.76.26.255", + "FirstAddress": "10.76.26.129", + "LastAddress": "10.76.26.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.76.26.128" + } + ], + "IPPools": [ + { + "Name": "CL01", + "Subnet": "10.76.26.128/28" + }, + { + "Name": "CL02", + "Subnet": "10.76.26.144/28" + }, + { + "Name": "CL03", + "Subnet": "10.76.26.160/28" + }, + { + "Name": "CL04", + "Subnet": "10.76.26.176/28" + }, + { + "Name": "CL05", + "Subnet": "10.76.26.192/28" + }, + { + "Name": "CL06", + "Subnet": "10.76.26.208/28" + }, + { + "Name": "CL07", + "Subnet": "10.76.26.224/28" + }, + { + "Name": "CL08", + "Subnet": "10.76.26.240/28" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Storage", + "Name": "Storage_711_TOR1", + "VLANID": 711, + "Description": "Storage Network, no config on switch. GroupName is unique key.", + "IPv4": { + "SwitchSVI": false, + "Name": "Storage_711_TOR1", + "VLANID": 711, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Storage", + "Subnet": "10.71.1.0/24", + "Network": "10.71.1.0", + "Netmask": "255.255.255.0", + "Gateway": "10.71.1.1", + "BroadcastAddress": "10.71.1.255", + "FirstAddress": "10.71.1.1", + "LastAddress": "10.71.1.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.1.0" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Storage", + "Name": "Storage_712_TOR2", + "VLANID": 712, + "Description": "Storage Network, no config on switch. GroupName is unique key.", + "IPv4": { + "SwitchSVI": false, + "Name": "Storage_712_TOR2", + "VLANID": 712, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Storage", + "Subnet": "10.71.2.0/24", + "Network": "10.71.2.0", + "Netmask": "255.255.255.0", + "Gateway": "10.71.2.1", + "BroadcastAddress": "10.71.2.255", + "FirstAddress": "10.71.2.1", + "LastAddress": "10.71.2.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.2.0" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "UNUSED_VLAN", + "Name": "UNUSED_VLAN", + "VLANID": 2, + "Description": "UNUSED_VLAN", + "IPv4": { + "SwitchSVI": false, + "Name": "UNUSED_VLAN", + "VLANID": 2, + "NetworkType": "UNUSED_VLAN" + } + }, + { + "GroupName": "NativeVlan", + "Name": "NativeVlan", + "VLANID": 99, + "Description": "NativeVlan", + "IPv4": { + "SwitchSVI": false, + "Name": "NativeVlan", + "VLANID": 99, + "NetworkType": "NativeVlan" + } + } + ], + "Setting": { + "TimeZone": "Pacific Standard Time", + "TimeServer": [ + "10.10.240.20" + ], + "SyslogServer": [ + "10.10.43.111" + ], + "DNSForwarder": [ + "10.10.240.23", + "10.10.240.24" + ] + }, + "WANSIM": { + "Hostname": "wansim-3", + "Loopback": { + "IP": "10.10.35.42", + "IPNetwork": "10.10.35.42/32", + "Subnet": "10.10.35.0/25" + }, + "GRE1": { + "Name": "TOR1", + "LocalIP": "2.1.1.0", + "RemoteIP": "2.1.1.1", + "IPNetwork": "2.1.1.0/31" + }, + "GRE2": { + "Name": "TOR2", + "LocalIP": "2.1.1.2", + "RemoteIP": "2.1.1.3", + "IPNetwork": "2.1.1.2/31" + }, + "BGP": { + "LocalASN": 64897, + "IPv4Nbr": [ + { + "NeighborAsn": 64816, + "NeighborIPAddress": "10.10.36.2", + "Description": "To_Uplink1", + "EbgpMultiHop": 8, + "UpdateSource": "eth0" + }, + { + "NeighborAsn": 64816, + "NeighborIPAddress": "10.10.36.3", + "Description": "To_Uplink2", + "EbgpMultiHop": 8, + "UpdateSource": "eth0" + } + ] + }, + "RerouteNetworks": [ + "Infrastructure", + "TENANT", + "L3FORWARD" + ], + "NetworkProfile": { + "UploadBW": "1Gbit", + "UploadDelay": "0ms", + "UploadLoss": "0%", + "DownloadBW": "1Gbit", + "DownloadDelay": "0ms", + "DownloadLoss": "0%" + } + } + } +} diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/expected_outputs/tor-2a.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/expected_outputs/tor-2a.json new file mode 100644 index 0000000..4536aa4 --- /dev/null +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/expected_outputs/tor-2a.json @@ -0,0 +1,528 @@ +{ + "switch": { + "make": "cisco", + "model": "93108tc-fx3p", + "type": "TOR1", + "hostname": "tor-2a", + "version": "10.3(4a)", + "firmware": "nxos", + "site": "site2" + }, + "vlans": [ + { + "vlan_id": 2, + "name": "UNUSED_VLAN", + "shutdown": true + }, + { + "vlan_id": 6, + "name": "HNVPA_6", + "interface": { + "ip": "10.100.166.130", + "cidr": 25, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 6, + "priority": 150, + "virtual_ip": "10.100.166.129" + } + } + }, + { + "vlan_id": 7, + "name": "Infra_7", + "interface": { + "ip": "10.103.112.2", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 7, + "priority": 150, + "virtual_ip": "10.103.112.1" + } + } + }, + { + "vlan_id": 99, + "name": "NativeVlan" + }, + { + "vlan_id": 125, + "name": "BMC_Mgmt_125", + "interface": { + "ip": "10.100.73.123", + "cidr": 26, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 125, + "priority": 150, + "virtual_ip": "10.100.73.65" + } + } + }, + { + "vlan_id": 201, + "name": "Tenant_201", + "interface": { + "ip": "10.99.52.2", + "cidr": 23, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 201, + "priority": 150, + "virtual_ip": "10.99.52.1" + } + } + }, + { + "vlan_id": 301, + "name": "LogicalTenant_301", + "interface": { + "ip": "10.99.54.2", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 301, + "priority": 150, + "virtual_ip": "10.99.54.1" + } + } + }, + { + "vlan_id": 401, + "name": "DhcpTenant_401", + "interface": { + "ip": "10.99.55.2", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 401, + "priority": 150, + "virtual_ip": "10.99.55.1" + } + } + }, + { + "vlan_id": 501, + "name": "L3forward_501", + "interface": { + "ip": "10.103.113.2", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 501, + "priority": 150, + "virtual_ip": "10.103.113.1" + } + } + }, + { + "vlan_id": 502, + "name": "L3forward_502", + "interface": { + "ip": "10.103.113.18", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 502, + "priority": 150, + "virtual_ip": "10.103.113.17" + } + } + }, + { + "vlan_id": 503, + "name": "L3forward_503", + "interface": { + "ip": "10.103.113.34", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 503, + "priority": 150, + "virtual_ip": "10.103.113.33" + } + } + }, + { + "vlan_id": 504, + "name": "L3forward_504", + "interface": { + "ip": "10.103.113.50", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 504, + "priority": 150, + "virtual_ip": "10.103.113.49" + } + } + }, + { + "vlan_id": 505, + "name": "L3forward_505", + "interface": { + "ip": "10.103.113.66", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 505, + "priority": 150, + "virtual_ip": "10.103.113.65" + } + } + }, + { + "vlan_id": 506, + "name": "L3forward_506", + "interface": { + "ip": "10.103.113.82", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 506, + "priority": 150, + "virtual_ip": "10.103.113.81" + } + } + }, + { + "vlan_id": 507, + "name": "L3forward_507", + "interface": { + "ip": "10.103.113.98", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 507, + "priority": 150, + "virtual_ip": "10.103.113.97" + } + } + }, + { + "vlan_id": 508, + "name": "L3forward_508", + "interface": { + "ip": "10.103.113.114", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 508, + "priority": 150, + "virtual_ip": "10.103.113.113" + } + } + }, + { + "vlan_id": 509, + "name": "L3forward_509", + "interface": { + "ip": "10.103.113.130", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 509, + "priority": 150, + "virtual_ip": "10.103.113.129" + } + } + }, + { + "vlan_id": 510, + "name": "L3forward_510", + "interface": { + "ip": "10.103.113.146", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 510, + "priority": 150, + "virtual_ip": "10.103.113.145" + } + } + }, + { + "vlan_id": 511, + "name": "L3forward_511", + "interface": { + "ip": "10.103.113.162", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 511, + "priority": 150, + "virtual_ip": "10.103.113.161" + } + } + }, + { + "vlan_id": 512, + "name": "L3forward_512", + "interface": { + "ip": "10.103.113.178", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 512, + "priority": 150, + "virtual_ip": "10.103.113.177" + } + } + }, + { + "vlan_id": 513, + "name": "L3forward_513", + "interface": { + "ip": "10.103.113.194", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 513, + "priority": 150, + "virtual_ip": "10.103.113.193" + } + } + }, + { + "vlan_id": 514, + "name": "L3forward_514", + "interface": { + "ip": "10.103.113.210", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 514, + "priority": 150, + "virtual_ip": "10.103.113.209" + } + } + }, + { + "vlan_id": 515, + "name": "L3forward_515", + "interface": { + "ip": "10.103.113.226", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 515, + "priority": 150, + "virtual_ip": "10.103.113.225" + } + } + }, + { + "vlan_id": 516, + "name": "L3forward_516", + "interface": { + "ip": "10.103.113.242", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 516, + "priority": 150, + "virtual_ip": "10.103.113.241" + } + } + }, + { + "vlan_id": 711, + "name": "Storage_711_TOR1" + }, + { + "vlan_id": 712, + "name": "Storage_712_TOR2" + } + ], + "interfaces": [ + { + "name": "Unused", + "type": "Access", + "description": "initial unused for all interfaces then config as defined", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/54", + "access_vlan": "2", + "shutdown": true + }, + { + "name": "Loopback0", + "type": "L3", + "intf_type": "loopback", + "intf": "loopback0", + "ipv4": "10.100.73.21/32" + }, + { + "name": "P2P_Border1", + "type": "L3", + "intf_type": "Ethernet", + "intf": "1/48", + "ipv4": "10.100.73.2/30" + }, + { + "name": "P2P_Border2", + "type": "L3", + "intf_type": "Ethernet", + "intf": "1/47", + "ipv4": "10.100.73.10/30" + }, + { + "name": "Trunk_TO_BMC_SWITCH", + "type": "Trunk", + "intf_type": "Ethernet", + "intf": "1/49", + "native_vlan": "99", + "tagged_vlans": "125" + }, + { + "name": "Switched_Compute_To_Host", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/16", + "native_vlan": "7", + "tagged_vlans": "7,6,201,301,401,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516" + }, + { + "name": "Switched_Storage_To_Host", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/17", + "end_intf": "1/32", + "native_vlan": "99", + "tagged_vlans": "711", + "service_policy": { + "qos_input": "AZLOCAL-QOS-MAP" + } + } + ], + "port_channels": [ + { + "id": 50, + "description": "P2P_IBGP", + "type": "L3", + "ipv4": "10.100.73.17", + "members": [ + "1/41", + "1/42" + ] + }, + { + "id": 101, + "description": "ToR_Peer_Link", + "type": "Trunk", + "native_vlan": "99", + "tagged_vlans": "", + "members": [ + "1/49", + "1/50", + "1/51" + ] + } + ], + "bgp": { + "asn": 64584, + "router_id": "10.100.73.21", + "networks": [ + "10.100.73.2/30", + "10.100.73.10/30", + "10.100.73.21/32", + "10.100.73.16/30", + "10.100.166.128/25", + "10.103.112.0/24", + "10.100.73.64/26", + "10.99.52.0/23", + "10.99.54.0/24", + "10.99.55.0/24", + "10.103.113.0/28", + "10.103.113.16/28", + "10.103.113.32/28", + "10.103.113.48/28", + "10.103.113.64/28", + "10.103.113.80/28", + "10.103.113.96/28", + "10.103.113.112/28", + "10.103.113.128/28", + "10.103.113.144/28", + "10.103.113.160/28", + "10.103.113.176/28", + "10.103.113.192/28", + "10.103.113.208/28", + "10.103.113.224/28", + "10.103.113.240/28" + ], + "neighbors": [ + { + "ip": "10.100.73.1", + "description": "TO_Border1", + "remote_as": 64809, + "af_ipv4_unicast": { + "prefix_list_in": "DefaultRoute" + } + }, + { + "ip": "10.100.73.9", + "description": "TO_Border2", + "remote_as": 64809, + "af_ipv4_unicast": { + "prefix_list_in": "DefaultRoute" + } + }, + { + "ip": "10.100.73.18", + "description": "iBGP_PEER", + "remote_as": 64584, + "af_ipv4_unicast": {} + }, + { + "ip": "10.100.166.128/25", + "description": "TO_HNVPA", + "remote_as": 65052, + "update_source": "Loopback0", + "ebgp_multihop": 3, + "af_ipv4_unicast": { + "prefix_list_out": "DefaultRoute" + } + } + ] + }, + "prefix_lists": { + "DefaultRoute": [ + { + "seq": 10, + "action": "permit", + "prefix": "0.0.0.0/0" + }, + { + "seq": 50, + "action": "deny", + "prefix": "0.0.0.0/0", + "prefix_filter": "le 32" + } + ] + }, + "qos": true +} \ No newline at end of file diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/expected_outputs/tor-2b.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/expected_outputs/tor-2b.json new file mode 100644 index 0000000..9f23c7e --- /dev/null +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/expected_outputs/tor-2b.json @@ -0,0 +1,528 @@ +{ + "switch": { + "make": "cisco", + "model": "93108tc-fx3p", + "type": "TOR2", + "hostname": "tor-2b", + "version": "10.3(4a)", + "firmware": "nxos", + "site": "site2" + }, + "vlans": [ + { + "vlan_id": 2, + "name": "UNUSED_VLAN", + "shutdown": true + }, + { + "vlan_id": 6, + "name": "HNVPA_6", + "interface": { + "ip": "10.100.166.131", + "cidr": 25, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 6, + "priority": 140, + "virtual_ip": "10.100.166.129" + } + } + }, + { + "vlan_id": 7, + "name": "Infra_7", + "interface": { + "ip": "10.103.112.3", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 7, + "priority": 140, + "virtual_ip": "10.103.112.1" + } + } + }, + { + "vlan_id": 99, + "name": "NativeVlan" + }, + { + "vlan_id": 125, + "name": "BMC_Mgmt_125", + "interface": { + "ip": "10.100.73.124", + "cidr": 26, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 125, + "priority": 140, + "virtual_ip": "10.100.73.65" + } + } + }, + { + "vlan_id": 201, + "name": "Tenant_201", + "interface": { + "ip": "10.99.52.3", + "cidr": 23, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 201, + "priority": 140, + "virtual_ip": "10.99.52.1" + } + } + }, + { + "vlan_id": 301, + "name": "LogicalTenant_301", + "interface": { + "ip": "10.99.54.3", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 301, + "priority": 140, + "virtual_ip": "10.99.54.1" + } + } + }, + { + "vlan_id": 401, + "name": "DhcpTenant_401", + "interface": { + "ip": "10.99.55.3", + "cidr": 24, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 401, + "priority": 140, + "virtual_ip": "10.99.55.1" + } + } + }, + { + "vlan_id": 501, + "name": "L3forward_501", + "interface": { + "ip": "10.103.113.3", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 501, + "priority": 140, + "virtual_ip": "10.103.113.1" + } + } + }, + { + "vlan_id": 502, + "name": "L3forward_502", + "interface": { + "ip": "10.103.113.19", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 502, + "priority": 140, + "virtual_ip": "10.103.113.17" + } + } + }, + { + "vlan_id": 503, + "name": "L3forward_503", + "interface": { + "ip": "10.103.113.35", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 503, + "priority": 140, + "virtual_ip": "10.103.113.33" + } + } + }, + { + "vlan_id": 504, + "name": "L3forward_504", + "interface": { + "ip": "10.103.113.51", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 504, + "priority": 140, + "virtual_ip": "10.103.113.49" + } + } + }, + { + "vlan_id": 505, + "name": "L3forward_505", + "interface": { + "ip": "10.103.113.67", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 505, + "priority": 140, + "virtual_ip": "10.103.113.65" + } + } + }, + { + "vlan_id": 506, + "name": "L3forward_506", + "interface": { + "ip": "10.103.113.83", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 506, + "priority": 140, + "virtual_ip": "10.103.113.81" + } + } + }, + { + "vlan_id": 507, + "name": "L3forward_507", + "interface": { + "ip": "10.103.113.99", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 507, + "priority": 140, + "virtual_ip": "10.103.113.97" + } + } + }, + { + "vlan_id": 508, + "name": "L3forward_508", + "interface": { + "ip": "10.103.113.115", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 508, + "priority": 140, + "virtual_ip": "10.103.113.113" + } + } + }, + { + "vlan_id": 509, + "name": "L3forward_509", + "interface": { + "ip": "10.103.113.131", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 509, + "priority": 140, + "virtual_ip": "10.103.113.129" + } + } + }, + { + "vlan_id": 510, + "name": "L3forward_510", + "interface": { + "ip": "10.103.113.147", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 510, + "priority": 140, + "virtual_ip": "10.103.113.145" + } + } + }, + { + "vlan_id": 511, + "name": "L3forward_511", + "interface": { + "ip": "10.103.113.163", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 511, + "priority": 140, + "virtual_ip": "10.103.113.161" + } + } + }, + { + "vlan_id": 512, + "name": "L3forward_512", + "interface": { + "ip": "10.103.113.179", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 512, + "priority": 140, + "virtual_ip": "10.103.113.177" + } + } + }, + { + "vlan_id": 513, + "name": "L3forward_513", + "interface": { + "ip": "10.103.113.195", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 513, + "priority": 140, + "virtual_ip": "10.103.113.193" + } + } + }, + { + "vlan_id": 514, + "name": "L3forward_514", + "interface": { + "ip": "10.103.113.211", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 514, + "priority": 140, + "virtual_ip": "10.103.113.209" + } + } + }, + { + "vlan_id": 515, + "name": "L3forward_515", + "interface": { + "ip": "10.103.113.227", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 515, + "priority": 140, + "virtual_ip": "10.103.113.225" + } + } + }, + { + "vlan_id": 516, + "name": "L3forward_516", + "interface": { + "ip": "10.103.113.243", + "cidr": 28, + "mtu": 9216, + "redundancy": { + "type": "hsrp", + "group": 516, + "priority": 140, + "virtual_ip": "10.103.113.241" + } + } + }, + { + "vlan_id": 711, + "name": "Storage_711_TOR1" + }, + { + "vlan_id": 712, + "name": "Storage_712_TOR2" + } + ], + "interfaces": [ + { + "name": "Unused", + "type": "Access", + "description": "initial unused for all interfaces then config as defined", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/54", + "access_vlan": "2", + "shutdown": true + }, + { + "name": "Loopback0", + "type": "L3", + "intf_type": "loopback", + "intf": "loopback0", + "ipv4": "10.100.73.22/32" + }, + { + "name": "P2P_Border1", + "type": "L3", + "intf_type": "Ethernet", + "intf": "1/48", + "ipv4": "10.100.73.6/30" + }, + { + "name": "P2P_Border2", + "type": "L3", + "intf_type": "Ethernet", + "intf": "1/47", + "ipv4": "10.100.73.14/30" + }, + { + "name": "Trunk_TO_BMC_SWITCH", + "type": "Trunk", + "intf_type": "Ethernet", + "intf": "1/49", + "native_vlan": "99", + "tagged_vlans": "125" + }, + { + "name": "Switched_Compute_To_Host", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/1", + "end_intf": "1/16", + "native_vlan": "7", + "tagged_vlans": "7,6,201,301,401,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516" + }, + { + "name": "Switched_Storage_To_Host", + "type": "Trunk", + "intf_type": "Ethernet", + "start_intf": "1/17", + "end_intf": "1/32", + "native_vlan": "99", + "tagged_vlans": "712", + "service_policy": { + "qos_input": "AZLOCAL-QOS-MAP" + } + } + ], + "port_channels": [ + { + "id": 50, + "description": "P2P_IBGP", + "type": "L3", + "ipv4": "10.100.73.18", + "members": [ + "1/41", + "1/42" + ] + }, + { + "id": 101, + "description": "ToR_Peer_Link", + "type": "Trunk", + "native_vlan": "99", + "tagged_vlans": "", + "members": [ + "1/49", + "1/50", + "1/51" + ] + } + ], + "bgp": { + "asn": 64584, + "router_id": "10.100.73.22", + "networks": [ + "10.100.73.6/30", + "10.100.73.14/30", + "10.100.73.22/32", + "10.100.73.16/30", + "10.100.166.128/25", + "10.103.112.0/24", + "10.100.73.64/26", + "10.99.52.0/23", + "10.99.54.0/24", + "10.99.55.0/24", + "10.103.113.0/28", + "10.103.113.16/28", + "10.103.113.32/28", + "10.103.113.48/28", + "10.103.113.64/28", + "10.103.113.80/28", + "10.103.113.96/28", + "10.103.113.112/28", + "10.103.113.128/28", + "10.103.113.144/28", + "10.103.113.160/28", + "10.103.113.176/28", + "10.103.113.192/28", + "10.103.113.208/28", + "10.103.113.224/28", + "10.103.113.240/28" + ], + "neighbors": [ + { + "ip": "10.100.73.5", + "description": "TO_Border1", + "remote_as": 64809, + "af_ipv4_unicast": { + "prefix_list_in": "DefaultRoute" + } + }, + { + "ip": "10.100.73.13", + "description": "TO_Border2", + "remote_as": 64809, + "af_ipv4_unicast": { + "prefix_list_in": "DefaultRoute" + } + }, + { + "ip": "10.100.73.17", + "description": "iBGP_PEER", + "remote_as": 64584, + "af_ipv4_unicast": {} + }, + { + "ip": "10.100.166.128/25", + "description": "TO_HNVPA", + "remote_as": 65052, + "update_source": "Loopback0", + "ebgp_multihop": 3, + "af_ipv4_unicast": { + "prefix_list_out": "DefaultRoute" + } + } + ] + }, + "prefix_lists": { + "DefaultRoute": [ + { + "seq": 10, + "action": "permit", + "prefix": "0.0.0.0/0" + }, + { + "seq": 50, + "action": "deny", + "prefix": "0.0.0.0/0", + "prefix_filter": "le 32" + } + ] + }, + "qos": true +} \ No newline at end of file diff --git a/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/lab_cisco_nxos_switch_input.json b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/lab_cisco_nxos_switch_input.json new file mode 100644 index 0000000..306a515 --- /dev/null +++ b/tests/test_cases/convert_lab_switch_input_json_cisco_nxos_switched_nobmc/lab_cisco_nxos_switch_input.json @@ -0,0 +1,1697 @@ +{ + "Version": "1.0.0", + "Description": "Template for ASZ Rack", + "InputData": { + "MainEnvData": [ + { + "Id": "Env01", + "Site": "site2", + "RackName": "rack02", + "NodeCount": 16, + "ConnectType": "connected", + "CiEnabled": "yes", + "ClusterUnits": [ + { + "Name": "Cl01", + "NodeCount": 4, + "RackId": "Rack01", + "NamingPrefix": "rb2001", + "PhysicalNamingPrefix": "rb2001", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rb2001.test.example.com", + "ExternalDomainFQDN": "ext-rb2001.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl02", + "NodeCount": 4, + "RackId": "Rack01", + "NamingPrefix": "rb2002", + "PhysicalNamingPrefix": "rb2002", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rb2002.test.example.com", + "ExternalDomainFQDN": "ext-rb2002.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl03", + "NodeCount": 4, + "RackId": "Rack01", + "NamingPrefix": "rb2003", + "PhysicalNamingPrefix": "rb2003", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rb2003.test.example.com", + "ExternalDomainFQDN": "ext-rb2003.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + }, + { + "Name": "Cl04", + "NodeCount": 4, + "RackId": "Rack01", + "NamingPrefix": "rb2004", + "PhysicalNamingPrefix": "rb2004", + "Topology": "Switched", + "CompanyName": "Microsoft", + "RegionName": "Redmond", + "DomainFQDN": "rb2004.test.example.com", + "ExternalDomainFQDN": "ext-rb2004.test.example.com", + "InfraAzureEnvironment": "AzureCloud", + "InfraAzureDirectoryTenantName": "msazurestack.example.com" + } + ] + } + ], + "Switches": [ + { + "Make": "Cisco", + "Model": "C9336C-FX2", + "Hostname": "border-2a", + "Type": "Border1", + "ASN": 64809 + }, + { + "Make": "Cisco", + "Model": "C9336C-FX2", + "Hostname": "border-2b", + "Type": "Border2", + "ASN": 64809 + }, + { + "Make": "Cisco", + "Model": "93108TC-FX3P", + "Type": "TOR1", + "Hostname": "tor-2a", + "ASN": 64584, + "Firmware": "10.3(4a)" + }, + { + "Make": "Cisco", + "Model": "93108TC-FX3P", + "Type": "TOR2", + "Hostname": "tor-2b", + "ASN": 64584, + "Firmware": "10.3(4a)" + }, + { + "Make": "None", + "Model": "None", + "Type": "None", + "Hostname": "None", + "ASN": null, + "Firmware": "None" + }, + { + "Make": "Microsoft", + "Model": null, + "Type": "MUX", + "Hostname": "mux-2", + "ASN": 65052, + "Firmware": null + } + ], + "DeploymentPattern": "Switched", + "SwitchUplink": "BGP", + "HostConnectivity": "BGP", + "Supernets": [ + { + "GroupName": "P2P_Border", + "Name": "P2P_Border1_Tor1", + "VlanId": 0, + "Description": "Uplink to Border1, P2P_{$Type}_{$Type}", + "IPv4": { + "Name": "P2P_Border1_Tor1", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.100.73.0/30", + "Network": "10.100.73.0", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.100.73.3", + "FirstAddress": "10.100.73.1", + "LastAddress": "10.100.73.2", + "Assignment": [ + { + "Name": "Network", + "IP": "10.100.73.0" + }, + { + "Name": "Border1", + "IP": "10.100.73.1" + }, + { + "Name": "TOR1", + "IP": "10.100.73.2" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "P2P_Border", + "Name": "P2P_Border1_Tor2", + "VlanId": 0, + "Description": "Uplink to Border2, P2P_{$Type}_{$Type}", + "IPv4": { + "Name": "P2P_Border1_Tor2", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.100.73.4/30", + "Network": "10.100.73.4", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.100.73.7", + "FirstAddress": "10.100.73.5", + "LastAddress": "10.100.73.6", + "Assignment": [ + { + "Name": "Network", + "IP": "10.100.73.4" + }, + { + "Name": "Border1", + "IP": "10.100.73.5" + }, + { + "Name": "TOR2", + "IP": "10.100.73.6" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "P2P_Border", + "Name": "P2P_Border2_Tor1", + "VlanId": 0, + "Description": "Uplink to Border2, naming convention P2P_{$Type}_{$Type}", + "IPv4": { + "Name": "P2P_Border2_Tor1", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.100.73.8/30", + "Network": "10.100.73.8", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.100.73.11", + "FirstAddress": "10.100.73.9", + "LastAddress": "10.100.73.10", + "Assignment": [ + { + "Name": "Network", + "IP": "10.100.73.8" + }, + { + "Name": "Border2", + "IP": "10.100.73.9" + }, + { + "Name": "TOR1", + "IP": "10.100.73.10" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "P2P_Border", + "Name": "P2P_Border2_Tor2", + "VlanId": 0, + "Description": "Uplink to Border2, naming convention P2P_{$Type}_{$Type}", + "IPv4": { + "Name": "P2P_Border2_Tor2", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.100.73.12/30", + "Network": "10.100.73.12", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.100.73.15", + "FirstAddress": "10.100.73.13", + "LastAddress": "10.100.73.14", + "Assignment": [ + { + "Name": "Network", + "IP": "10.100.73.12" + }, + { + "Name": "Border2", + "IP": "10.100.73.13" + }, + { + "Name": "TOR2", + "IP": "10.100.73.14" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "P2P_IBGP", + "Name": "P2P_iBGP", + "VlanId": 0, + "Description": "IBGP Peer Link", + "IPv4": { + "Name": "P2P_iBGP", + "VlanId": 0, + "Cidr": 30, + "TORGroup": "", + "NetworkType": "P2P Link", + "Subnet": "10.100.73.16/30", + "Network": "10.100.73.16", + "Netmask": "255.255.255.252", + "Gateway": "", + "BroadcastAddress": "10.100.73.19", + "FirstAddress": "10.100.73.17", + "LastAddress": "10.100.73.18", + "Assignment": [ + { + "Name": "Network", + "IP": "10.100.73.16" + }, + { + "Name": "TOR1", + "IP": "10.100.73.17" + }, + { + "Name": "TOR2", + "IP": "10.100.73.18" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Loopback0", + "Name": "Loopback0_Tor1", + "VlanId": 0, + "Description": "Switch Loopback assignment", + "IPv4": { + "Name": "Loopback0_Tor1", + "VlanId": 0, + "Cidr": 32, + "TORGroup": "", + "NetworkType": "Loopback", + "Subnet": "10.100.73.21/32", + "Network": "10.100.73.21", + "Netmask": "255.255.255.255", + "Gateway": "", + "BroadcastAddress": "", + "FirstAddress": "", + "LastAddress": "", + "Assignment": [ + { + "Name": "TOR1", + "IP": "10.100.73.21" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Loopback0", + "Name": "Loopback0_Tor2", + "VlanId": 0, + "Description": "Switch Loopback assignment", + "IPv4": { + "Name": "Loopback0_Tor2", + "VlanId": 0, + "Cidr": 32, + "TORGroup": "", + "NetworkType": "Loopback", + "Subnet": "10.100.73.22/32", + "Network": "10.100.73.22", + "Netmask": "255.255.255.255", + "Gateway": "", + "BroadcastAddress": "", + "FirstAddress": "", + "LastAddress": "", + "Assignment": [ + { + "Name": "TOR2", + "IP": "10.100.73.22" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "BMC", + "Name": "BMC_Mgmt_125", + "VLANID": 125, + "Description": "BMC Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "BMC_Mgmt_125", + "VLANID": 125, + "Cidr": 26, + "TORGroup": "", + "NetworkType": "Infrastructure", + "Subnet": "10.100.73.64/26", + "Network": "10.100.73.64", + "Netmask": "255.255.255.192", + "Gateway": "10.100.73.65", + "BroadcastAddress": "10.100.73.127", + "FirstAddress": "10.100.73.65", + "LastAddress": "10.100.73.126", + "Assignment": [ + { + "Name": "Network", + "IP": "10.100.73.64", + "ClusterID": null + }, + { + "Name": "Gateway", + "IP": "10.100.73.65", + "ClusterID": null + }, + { + "Name": "HLH-BMC", + "IP": "10.100.73.66", + "ClusterID": null + }, + { + "Name": "CL01-N01", + "IP": "10.100.73.67", + "ClusterID": "CL01" + }, + { + "Name": "CL01-N02", + "IP": "10.100.73.68", + "ClusterID": "CL01" + }, + { + "Name": "CL01-N03", + "IP": "10.100.73.69", + "ClusterID": "CL01" + }, + { + "Name": "CL01-N04", + "IP": "10.100.73.70", + "ClusterID": "CL01" + }, + { + "Name": "CL02-N01", + "IP": "10.100.73.71", + "ClusterID": "CL02" + }, + { + "Name": "CL02-N02", + "IP": "10.100.73.72", + "ClusterID": "CL02" + }, + { + "Name": "CL02-N03", + "IP": "10.100.73.73", + "ClusterID": "CL02" + }, + { + "Name": "CL02-N04", + "IP": "10.100.73.74", + "ClusterID": "CL02" + }, + { + "Name": "CL03-N01", + "IP": "10.100.73.75", + "ClusterID": "CL03" + }, + { + "Name": "CL03-N02", + "IP": "10.100.73.76", + "ClusterID": "CL03" + }, + { + "Name": "CL03-N03", + "IP": "10.100.73.77", + "ClusterID": "CL03" + }, + { + "Name": "CL03-N04", + "IP": "10.100.73.78", + "ClusterID": "CL03" + }, + { + "Name": "CL04-N01", + "IP": "10.100.73.79", + "ClusterID": "CL04" + }, + { + "Name": "CL04-N02", + "IP": "10.100.73.80", + "ClusterID": "CL04" + }, + { + "Name": "CL04-N03", + "IP": "10.100.73.81", + "ClusterID": "CL04" + }, + { + "Name": "CL04-N04", + "IP": "10.100.73.82", + "ClusterID": "CL04" + }, + { + "Name": "CL01-HLH-DVM01", + "IP": "10.100.73.107", + "ClusterID": "CL01" + }, + { + "Name": "CL02-HLH-DVM02", + "IP": "10.100.73.108", + "ClusterID": "CL02" + }, + { + "Name": "CL03-HLH-DVM03", + "IP": "10.100.73.109", + "ClusterID": "CL03" + }, + { + "Name": "CL04-HLH-DVM04", + "IP": "10.100.73.110", + "ClusterID": "CL04" + }, + { + "Name": "Tor1-Mgmt", + "IP": "10.100.73.123", + "ClusterID": null + }, + { + "Name": "Tor2-Mgmt", + "IP": "10.100.73.124", + "ClusterID": null + }, + { + "Name": "BMC-Mgmt", + "IP": "10.100.73.125", + "ClusterID": null + }, + { + "Name": "HLH-OS", + "IP": "10.100.73.126", + "ClusterID": null + }, + { + "Name": "Broadcast", + "IP": "10.100.73.127", + "ClusterID": null + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "HNVPA", + "Name": "HNVPA_6", + "VLANID": 6, + "Description": "HNVPA Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "HNVPA_6", + "VLANID": 6, + "Cidr": 25, + "TORGroup": "", + "NetworkType": "PA", + "Subnet": "10.100.166.128/25", + "Network": "10.100.166.128", + "Netmask": "255.255.255.128", + "Gateway": "10.100.166.129", + "BroadcastAddress": "10.100.166.255", + "FirstAddress": "10.100.166.129", + "LastAddress": "10.100.166.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.100.166.128" + }, + { + "Name": "Gateway", + "IP": "10.100.166.129" + }, + { + "Name": "TOR1", + "IP": "10.100.166.130" + }, + { + "Name": "TOR2", + "IP": "10.100.166.131" + } + ], + "IPPools": [ + { + "Name": "CL01", + "StartingAddress": "10.100.166.132", + "EndingAddress": "10.100.166.159" + }, + { + "Name": "CL02", + "StartingAddress": "10.100.166.160", + "EndingAddress": "10.100.166.191" + }, + { + "Name": "CL03", + "StartingAddress": "10.100.166.192", + "EndingAddress": "10.100.166.223" + }, + { + "Name": "CL04", + "StartingAddress": "10.100.166.224", + "EndingAddress": "10.100.166.254" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Infrastructure", + "Name": "Infra_7", + "VLANID": 7, + "Description": "Infrastructure Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "Infra_7", + "VLANID": 7, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Infrastructure", + "Subnet": "10.103.112.0/24", + "Network": "10.103.112.0", + "Netmask": "255.255.255.0", + "Gateway": "10.103.112.1", + "BroadcastAddress": "10.103.112.255", + "FirstAddress": "10.103.112.1", + "LastAddress": "10.103.112.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.112.0" + }, + { + "Name": "Gateway", + "IP": "10.103.112.1" + }, + { + "Name": "TOR1", + "IP": "10.103.112.2" + }, + { + "Name": "TOR2", + "IP": "10.103.112.3" + }, + { + "Name": "CL01-N01", + "IP": "10.103.112.4" + }, + { + "Name": "CL01-N02", + "IP": "10.103.112.5" + }, + { + "Name": "CL01-N03", + "IP": "10.103.112.6" + }, + { + "Name": "CL01-N04", + "IP": "10.103.112.7" + }, + { + "Name": "CL02-N01", + "IP": "10.103.112.64" + }, + { + "Name": "CL02-N02", + "IP": "10.103.112.65" + }, + { + "Name": "CL02-N03", + "IP": "10.103.112.66" + }, + { + "Name": "CL02-N04", + "IP": "10.103.112.67" + }, + { + "Name": "CL03-N01", + "IP": "10.103.112.128" + }, + { + "Name": "CL03-N02", + "IP": "10.103.112.129" + }, + { + "Name": "CL03-N03", + "IP": "10.103.112.130" + }, + { + "Name": "CL03-N04", + "IP": "10.103.112.131" + }, + { + "Name": "CL04-N01", + "IP": "10.103.112.192" + }, + { + "Name": "CL04-N02", + "IP": "10.103.112.193" + }, + { + "Name": "CL04-N03", + "IP": "10.103.112.194" + }, + { + "Name": "CL04-N04", + "IP": "10.103.112.195" + } + ], + "IPPools": [ + { + "Name": "CL01", + "StartingAddress": "10.103.112.8", + "EndingAddress": "10.103.112.63" + }, + { + "Name": "CL02", + "StartingAddress": "10.103.112.68", + "EndingAddress": "10.103.112.127" + }, + { + "Name": "CL03", + "StartingAddress": "10.103.112.132", + "EndingAddress": "10.103.112.191" + }, + { + "Name": "CL04", + "StartingAddress": "10.103.112.196", + "EndingAddress": "10.103.112.254" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "TENANT", + "Name": "Tenant_201", + "VLANID": 201, + "Description": "TENANT Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "Tenant_201", + "VLANID": 201, + "Cidr": 23, + "TORGroup": "", + "NetworkType": "Tenant", + "Subnet": "10.99.52.0/23", + "Network": "10.99.52.0", + "Netmask": "255.255.254.0", + "Gateway": "10.99.52.1", + "BroadcastAddress": "10.99.53.255", + "FirstAddress": "10.99.52.1", + "LastAddress": "10.99.53.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.99.52.0" + }, + { + "Name": "Gateway", + "IP": "10.99.52.1" + }, + { + "Name": "TOR1", + "IP": "10.99.52.2" + }, + { + "Name": "TOR2", + "IP": "10.99.52.3" + } + ], + "IPPools": [ + { + "Name": "CL01", + "StartingAddress": "10.99.52.4", + "EndingAddress": "10.99.52.127" + }, + { + "Name": "CL02", + "StartingAddress": "10.99.52.128", + "EndingAddress": "10.99.52.255" + }, + { + "Name": "CL03", + "StartingAddress": "10.99.53.0", + "EndingAddress": "10.99.53.127" + }, + { + "Name": "CL04", + "StartingAddress": "10.99.53.128", + "EndingAddress": "10.99.53.254" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "TENANT", + "Name": "LogicalTenant_301", + "VLANID": 301, + "Description": "TENANT Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "LogicalTenant_301", + "VLANID": 301, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Tenant", + "Subnet": "10.99.54.0/24", + "Network": "10.99.54.0", + "Netmask": "255.255.255.0", + "Gateway": "10.99.54.1", + "BroadcastAddress": "10.99.54.255", + "FirstAddress": "10.99.54.1", + "LastAddress": "10.99.54.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.99.54.0" + }, + { + "Name": "Gateway", + "IP": "10.99.54.1" + }, + { + "Name": "TOR1", + "IP": "10.99.54.2" + }, + { + "Name": "TOR2", + "IP": "10.99.54.3" + } + ], + "IPPools": [ + { + "Name": "CL01", + "StartingAddress": "10.99.54.4", + "EndingAddress": "10.99.54.63" + }, + { + "Name": "CL02", + "StartingAddress": "10.99.54.64", + "EndingAddress": "10.99.54.127" + }, + { + "Name": "CL03", + "StartingAddress": "10.99.54.128", + "EndingAddress": "10.99.54.191" + }, + { + "Name": "CL04", + "StartingAddress": "10.99.54.192", + "EndingAddress": "10.99.54.254" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "TENANT", + "Name": "DhcpTenant_401", + "VLANID": 401, + "Description": "TENANT Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "DhcpTenant_401", + "VLANID": 401, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Tenant", + "Subnet": "10.99.55.0/24", + "Network": "10.99.55.0", + "Netmask": "255.255.255.0", + "Gateway": "10.99.55.1", + "BroadcastAddress": "10.99.55.255", + "FirstAddress": "10.99.55.1", + "LastAddress": "10.99.55.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.99.55.0" + }, + { + "Name": "Gateway", + "IP": "10.99.55.1" + }, + { + "Name": "TOR1", + "IP": "10.99.55.2" + }, + { + "Name": "TOR2", + "IP": "10.99.55.3" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_501", + "VLANID": 501, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_501", + "VLANID": 501, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.0/28", + "Network": "10.103.113.0", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.1", + "BroadcastAddress": "10.103.113.15", + "FirstAddress": "10.103.113.1", + "LastAddress": "10.103.113.14", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.0" + }, + { + "Name": "Gateway", + "IP": "10.103.113.1" + }, + { + "Name": "TOR1", + "IP": "10.103.113.2" + }, + { + "Name": "TOR2", + "IP": "10.103.113.3" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_502", + "VLANID": 502, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_502", + "VLANID": 502, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.16/28", + "Network": "10.103.113.16", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.17", + "BroadcastAddress": "10.103.113.31", + "FirstAddress": "10.103.113.17", + "LastAddress": "10.103.113.30", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.16" + }, + { + "Name": "Gateway", + "IP": "10.103.113.17" + }, + { + "Name": "TOR1", + "IP": "10.103.113.18" + }, + { + "Name": "TOR2", + "IP": "10.103.113.19" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_503", + "VLANID": 503, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_503", + "VLANID": 503, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.32/28", + "Network": "10.103.113.32", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.33", + "BroadcastAddress": "10.103.113.47", + "FirstAddress": "10.103.113.33", + "LastAddress": "10.103.113.46", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.32" + }, + { + "Name": "Gateway", + "IP": "10.103.113.33" + }, + { + "Name": "TOR1", + "IP": "10.103.113.34" + }, + { + "Name": "TOR2", + "IP": "10.103.113.35" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_504", + "VLANID": 504, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_504", + "VLANID": 504, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.48/28", + "Network": "10.103.113.48", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.49", + "BroadcastAddress": "10.103.113.63", + "FirstAddress": "10.103.113.49", + "LastAddress": "10.103.113.62", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.48" + }, + { + "Name": "Gateway", + "IP": "10.103.113.49" + }, + { + "Name": "TOR1", + "IP": "10.103.113.50" + }, + { + "Name": "TOR2", + "IP": "10.103.113.51" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_505", + "VLANID": 505, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_505", + "VLANID": 505, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.64/28", + "Network": "10.103.113.64", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.65", + "BroadcastAddress": "10.103.113.79", + "FirstAddress": "10.103.113.65", + "LastAddress": "10.103.113.78", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.64" + }, + { + "Name": "Gateway", + "IP": "10.103.113.65" + }, + { + "Name": "TOR1", + "IP": "10.103.113.66" + }, + { + "Name": "TOR2", + "IP": "10.103.113.67" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_506", + "VLANID": 506, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_506", + "VLANID": 506, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.80/28", + "Network": "10.103.113.80", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.81", + "BroadcastAddress": "10.103.113.95", + "FirstAddress": "10.103.113.81", + "LastAddress": "10.103.113.94", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.80" + }, + { + "Name": "Gateway", + "IP": "10.103.113.81" + }, + { + "Name": "TOR1", + "IP": "10.103.113.82" + }, + { + "Name": "TOR2", + "IP": "10.103.113.83" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_507", + "VLANID": 507, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_507", + "VLANID": 507, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.96/28", + "Network": "10.103.113.96", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.97", + "BroadcastAddress": "10.103.113.111", + "FirstAddress": "10.103.113.97", + "LastAddress": "10.103.113.110", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.96" + }, + { + "Name": "Gateway", + "IP": "10.103.113.97" + }, + { + "Name": "TOR1", + "IP": "10.103.113.98" + }, + { + "Name": "TOR2", + "IP": "10.103.113.99" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_508", + "VLANID": 508, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_508", + "VLANID": 508, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.112/28", + "Network": "10.103.113.112", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.113", + "BroadcastAddress": "10.103.113.127", + "FirstAddress": "10.103.113.113", + "LastAddress": "10.103.113.126", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.112" + }, + { + "Name": "Gateway", + "IP": "10.103.113.113" + }, + { + "Name": "TOR1", + "IP": "10.103.113.114" + }, + { + "Name": "TOR2", + "IP": "10.103.113.115" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_509", + "VLANID": 509, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_509", + "VLANID": 509, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.128/28", + "Network": "10.103.113.128", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.129", + "BroadcastAddress": "10.103.113.143", + "FirstAddress": "10.103.113.129", + "LastAddress": "10.103.113.142", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.128" + }, + { + "Name": "Gateway", + "IP": "10.103.113.129" + }, + { + "Name": "TOR1", + "IP": "10.103.113.130" + }, + { + "Name": "TOR2", + "IP": "10.103.113.131" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_510", + "VLANID": 510, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_510", + "VLANID": 510, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.144/28", + "Network": "10.103.113.144", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.145", + "BroadcastAddress": "10.103.113.159", + "FirstAddress": "10.103.113.145", + "LastAddress": "10.103.113.158", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.144" + }, + { + "Name": "Gateway", + "IP": "10.103.113.145" + }, + { + "Name": "TOR1", + "IP": "10.103.113.146" + }, + { + "Name": "TOR2", + "IP": "10.103.113.147" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_511", + "VLANID": 511, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_511", + "VLANID": 511, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.160/28", + "Network": "10.103.113.160", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.161", + "BroadcastAddress": "10.103.113.175", + "FirstAddress": "10.103.113.161", + "LastAddress": "10.103.113.174", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.160" + }, + { + "Name": "Gateway", + "IP": "10.103.113.161" + }, + { + "Name": "TOR1", + "IP": "10.103.113.162" + }, + { + "Name": "TOR2", + "IP": "10.103.113.163" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_512", + "VLANID": 512, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_512", + "VLANID": 512, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.176/28", + "Network": "10.103.113.176", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.177", + "BroadcastAddress": "10.103.113.191", + "FirstAddress": "10.103.113.177", + "LastAddress": "10.103.113.190", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.176" + }, + { + "Name": "Gateway", + "IP": "10.103.113.177" + }, + { + "Name": "TOR1", + "IP": "10.103.113.178" + }, + { + "Name": "TOR2", + "IP": "10.103.113.179" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_513", + "VLANID": 513, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_513", + "VLANID": 513, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.192/28", + "Network": "10.103.113.192", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.193", + "BroadcastAddress": "10.103.113.207", + "FirstAddress": "10.103.113.193", + "LastAddress": "10.103.113.206", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.192" + }, + { + "Name": "Gateway", + "IP": "10.103.113.193" + }, + { + "Name": "TOR1", + "IP": "10.103.113.194" + }, + { + "Name": "TOR2", + "IP": "10.103.113.195" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_514", + "VLANID": 514, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_514", + "VLANID": 514, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.208/28", + "Network": "10.103.113.208", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.209", + "BroadcastAddress": "10.103.113.223", + "FirstAddress": "10.103.113.209", + "LastAddress": "10.103.113.222", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.208" + }, + { + "Name": "Gateway", + "IP": "10.103.113.209" + }, + { + "Name": "TOR1", + "IP": "10.103.113.210" + }, + { + "Name": "TOR2", + "IP": "10.103.113.211" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_515", + "VLANID": 515, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_515", + "VLANID": 515, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.224/28", + "Network": "10.103.113.224", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.225", + "BroadcastAddress": "10.103.113.239", + "FirstAddress": "10.103.113.225", + "LastAddress": "10.103.113.238", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.224" + }, + { + "Name": "Gateway", + "IP": "10.103.113.225" + }, + { + "Name": "TOR1", + "IP": "10.103.113.226" + }, + { + "Name": "TOR2", + "IP": "10.103.113.227" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "L3FORWARD", + "Name": "L3forward_516", + "VLANID": 516, + "Description": "L3forward Network. GroupName is unique key.", + "IPv4": { + "SwitchSVI": true, + "Name": "L3forward_516", + "VLANID": 516, + "Cidr": 28, + "TORGroup": "", + "NetworkType": "L3forward", + "Subnet": "10.103.113.240/28", + "Network": "10.103.113.240", + "Netmask": "255.255.255.240", + "Gateway": "10.103.113.241", + "BroadcastAddress": "10.103.113.255", + "FirstAddress": "10.103.113.241", + "LastAddress": "10.103.113.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.103.113.240" + }, + { + "Name": "Gateway", + "IP": "10.103.113.241" + }, + { + "Name": "TOR1", + "IP": "10.103.113.242" + }, + { + "Name": "TOR2", + "IP": "10.103.113.243" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "ExternalIP", + "Name": "PublicVIP", + "VLANID": 0, + "Description": "ExternalIP Network, no config on switch. GroupName is unique key.", + "IPv4": { + "SwitchSVI": false, + "Name": "PublicVIP", + "VLANID": 0, + "Cidr": 23, + "TORGroup": "", + "NetworkType": "ExternalIP", + "Subnet": "10.97.168.0/23", + "Network": "10.97.168.0", + "Netmask": "255.255.254.0", + "Gateway": null, + "BroadcastAddress": "10.97.169.255", + "FirstAddress": "10.97.168.1", + "LastAddress": "10.97.169.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.97.168.0" + } + ], + "IPPools": [ + { + "Name": "CL01", + "Subnet": "10.97.168.0/25" + }, + { + "Name": "CL02", + "Subnet": "10.97.168.128/25" + }, + { + "Name": "CL03", + "Subnet": "10.97.169.0/25" + }, + { + "Name": "CL04", + "Subnet": "10.97.169.128/25" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "ExternalIP", + "Name": "GRE", + "VLANID": 0, + "Description": "ExternalIP Network, no config on switch. GroupName is unique key.", + "IPv4": { + "SwitchSVI": false, + "Name": "GRE", + "VLANID": 0, + "Cidr": 25, + "TORGroup": "", + "NetworkType": "ExternalIP", + "Subnet": "10.102.23.0/25", + "Network": "10.102.23.0", + "Netmask": "255.255.255.128", + "Gateway": null, + "BroadcastAddress": "10.102.23.127", + "FirstAddress": "10.102.23.1", + "LastAddress": "10.102.23.126", + "Assignment": [ + { + "Name": "Network", + "IP": "10.102.23.0" + } + ], + "IPPools": [ + { + "Name": "CL01", + "Subnet": "10.102.23.0/27" + }, + { + "Name": "CL02", + "Subnet": "10.102.23.32/27" + }, + { + "Name": "CL03", + "Subnet": "10.102.23.64/27" + }, + { + "Name": "CL04", + "Subnet": "10.102.23.96/27" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Storage", + "Name": "Storage_711_TOR1", + "VLANID": 711, + "Description": "Storage Network, no config on switch. GroupName is unique key.", + "IPv4": { + "SwitchSVI": false, + "Name": "Storage_711_TOR1", + "VLANID": 711, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Storage", + "Subnet": "10.71.1.0/24", + "Network": "10.71.1.0", + "Netmask": "255.255.255.0", + "Gateway": "10.71.1.1", + "BroadcastAddress": "10.71.1.255", + "FirstAddress": "10.71.1.1", + "LastAddress": "10.71.1.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.1.0" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "Storage", + "Name": "Storage_712_TOR2", + "VLANID": 712, + "Description": "Storage Network, no config on switch. GroupName is unique key.", + "IPv4": { + "SwitchSVI": false, + "Name": "Storage_712_TOR2", + "VLANID": 712, + "Cidr": 24, + "TORGroup": "", + "NetworkType": "Storage", + "Subnet": "10.71.2.0/24", + "Network": "10.71.2.0", + "Netmask": "255.255.255.0", + "Gateway": "10.71.2.1", + "BroadcastAddress": "10.71.2.255", + "FirstAddress": "10.71.2.1", + "LastAddress": "10.71.2.254", + "Assignment": [ + { + "Name": "Network", + "IP": "10.71.2.0" + } + ] + }, + "IPv6": {} + }, + { + "GroupName": "UNUSED_VLAN", + "Name": "UNUSED_VLAN", + "VLANID": 2, + "Description": "UNUSED_VLAN", + "IPv4": { + "SwitchSVI": false, + "Name": "UNUSED_VLAN", + "VLANID": 2, + "NetworkType": "UNUSED_VLAN" + } + }, + { + "GroupName": "NativeVlan", + "Name": "NativeVlan", + "VLANID": 99, + "Description": "NativeVlan", + "IPv4": { + "SwitchSVI": false, + "Name": "NativeVlan", + "VLANID": 99, + "NetworkType": "NativeVlan" + } + } + ], + "Setting": { + "TimeZone": "Pacific Standard Time", + "TimeServer": [ + "10.10.240.20" + ], + "SyslogServer": [ + "10.10.43.111" + ], + "DNSForwarder": [ + "10.10.240.23", + "10.10.240.24" + ] + } + } +} diff --git a/tests/test_cases/std_cisco_nxos_fc/expected_full_config.cfg b/tests/test_cases/std_cisco_nxos_fc/expected_full_config.cfg new file mode 100644 index 0000000..cd1df9b --- /dev/null +++ b/tests/test_cases/std_cisco_nxos_fc/expected_full_config.cfg @@ -0,0 +1,727 @@ +! system.j2 + +! Name: tor-1a +! Make: cisco +! Model: 93180yc-fx3 +hostname tor-1a + +banner motd # +NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE + +hostname tor-1a +Unauthorized access and/or use prohibited. +All access and/or use subject to monitoring. + +NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + + +no feature telnet +feature scp-server +feature bgp +feature interface-vlan +feature lldp +feature dhcp +feature vpc +feature hsrp +feature lacp +feature ssh +feature tacacs+ + + +clock timezone PST -8 0 +clock summer-time PDT 2 Sun Apr 02:00 1 Sun Nov 02:00 60 +ntp server [NTP_SERVER_IP] +ntp source-interface [MGMT_VLAN] + + +logging server [LOG_SERVER_IP] 7 facility local7 use-vrf default +logging source-interface [MGMT_VLAN] +logging level local7 7 +no logging console +login on-success log +logging origin-id hostname + +logging level acllog 7 +logging level aclmgr 7 +logging level eth_port_channel 7 +logging level hsrp 7 +logging level icam 7 +logging level interface-vlan 7 +logging level ipqosmgr 7 +logging level vlan_mgr 7 +logging level vpc 7 +logging level netstack 7 +logging level bgp 7 + + +no cdp enable +lldp tlv-select dcbxp egress-queuing + +service dhcp +ip dhcp relay + +ip load-sharing address source-destination port source-destination + +ip icmp-errors source-interface [MGMT_VLAN] + +cli alias name wr copy running-config startup-config + + +snmp-server community [PLACEHOLDER] ro +snmp-server community [PLACEHOLDER] rW +snmp-server contact "Contact Support" +snmp-server location + +! login.j2 + +fips mode enable +user max-logins 1 +password prompt username +userpassphrase min-length 15 max-length 80 +username admin password 0 $CREDENTIAL_PLACEHOLDER$ role network-admin +username $CREDENTIAL_PLACEHOLDER$ password 0 $CREDENTIAL_PLACEHOLDER$ role network-admin + + +no feature ssh +no ssh key ecdsa +no ssh key rsa +ssh key rsa 2048 force +ssh key ecdsa 256 force +feature ssh + + +line console + exec-timeout 10 +line vty + exec-timeout 10 + session-limit 3 + + +! Replace [TACACS_SERVER_IP], [TACACS_KEY], [TACACS_GROUP],[MGMT_VLAN] with actual values. +tacacs-server key [TACACS_KEY] +tacacs-server timeout 2 +ip tacacs source-interface [MGMT_VLAN] + +tacacs-server host [TACACS_SERVER_IP] +tacacs-server host [TACACS_SERVER_IP] + +aaa group server tacacs+ [TACACS_GROUP] + server [TACACS_SERVER_IP] + server [TACACS_SERVER_IP] + source-interface [MGMT_VLAN] + +aaa authentication login default group [TACACS_GROUP] +aaa authentication login console group [TACACS_GROUP] +aaa accounting default group [TACACS_GROUP] + +! qos.j2 + +policy-map type network-qos AZLOCAL-NWQOS + class type network-qos AZLOCAL-NWQOS-RDMA + pause pfc-cos 3 + mtu 9216 + class type network-qos AZLOCAL-NWQOS-DEFAULT + mtu 9216 + class type network-qos AZLOCAL-NWQOS-CLUSTER + mtu 9216 + + +class-map type qos match-all AZLOCAL-QOS-RDMA + match cos 3 +class-map type qos match-all AZLOCAL-QOS-CLUSTER + match cos 7 + +policy-map type qos AZLOCAL-QOS-MAP + class AZLOCAL-QOS-RDMA + set qos-group 3 + class AZLOCAL-QOS-CLUSTER + set qos-group 7 + + +policy-map type queuing AZLOCAL-QUEUE-OUT + class type queuing c-out-8q-q3 + bandwidth remaining percent 50 + random-detect minimum-threshold 300 kbytes maximum-threshold 300 kbytes drop-probability 100 weight 0 ecn + class type queuing c-out-8q-q-default + bandwidth remaining percent 48 + class type queuing c-out-8q-q7 + bandwidth percent 2 + + +system qos + service-policy type network-qos AZLOCAL-NWQOS + service-policy type queuing output AZLOCAL-QUEUE-OUT + +! vlan.j2 + +vlan 2 + name UNUSED_VLAN + shutdown +vlan 6 + name HNVPA_6 + +vlan 7 + name Infra_7 + +vlan 99 + name NativeVlan + +vlan 125 + name BMC_Mgmt_125 + +vlan 201 + name Tenant_201 + +vlan 301 + name LogicalTenant_301 + +vlan 401 + name DhcpTenant_401 + +vlan 501 + name L3forward_501 + +vlan 502 + name L3forward_502 + +vlan 503 + name L3forward_503 + +vlan 504 + name L3forward_504 + +vlan 505 + name L3forward_505 + +vlan 506 + name L3forward_506 + +vlan 507 + name L3forward_507 + +vlan 508 + name L3forward_508 + +vlan 509 + name L3forward_509 + +vlan 510 + name L3forward_510 + +vlan 511 + name L3forward_511 + +vlan 512 + name L3forward_512 + +vlan 513 + name L3forward_513 + +vlan 514 + name L3forward_514 + +vlan 515 + name L3forward_515 + +vlan 516 + name L3forward_516 + +vlan 711 + name Storage_711_TOR1 + +vlan 712 + name Storage_712_TOR2 + + + +interface vlan6 + description HNVPA_6 + mtu 9216 + no shutdown + ip address 10.2.1.2/25 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 6 + priority 150 + ip 10.2.1.1 + +interface vlan7 + description Infra_7 + mtu 9216 + no shutdown + ip address 10.3.1.2/24 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 7 + priority 150 + ip 10.3.1.1 + +interface vlan125 + description BMC_Mgmt_125 + mtu 9216 + no shutdown + ip address 10.1.1.123/26 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 125 + priority 150 + ip 10.1.1.65 + +interface vlan201 + description Tenant_201 + mtu 9216 + no shutdown + ip address 10.4.1.2/24 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 201 + priority 150 + ip 10.4.1.1 + +interface vlan301 + description LogicalTenant_301 + mtu 9216 + no shutdown + ip address 10.5.2.2/25 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 301 + priority 150 + ip 10.5.2.1 + +interface vlan401 + description DhcpTenant_401 + mtu 9216 + no shutdown + ip address 10.5.2.130/25 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 401 + priority 150 + ip 10.5.2.129 + +interface vlan501 + description L3forward_501 + mtu 9216 + no shutdown + ip address 10.5.1.2/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 501 + priority 150 + ip 10.5.1.1 + +interface vlan502 + description L3forward_502 + mtu 9216 + no shutdown + ip address 10.5.1.18/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 502 + priority 150 + ip 10.5.1.17 + +interface vlan503 + description L3forward_503 + mtu 9216 + no shutdown + ip address 10.5.1.34/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 503 + priority 150 + ip 10.5.1.33 + +interface vlan504 + description L3forward_504 + mtu 9216 + no shutdown + ip address 10.5.1.50/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 504 + priority 150 + ip 10.5.1.49 + +interface vlan505 + description L3forward_505 + mtu 9216 + no shutdown + ip address 10.5.1.66/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 505 + priority 150 + ip 10.5.1.65 + +interface vlan506 + description L3forward_506 + mtu 9216 + no shutdown + ip address 10.5.1.82/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 506 + priority 150 + ip 10.5.1.81 + +interface vlan507 + description L3forward_507 + mtu 9216 + no shutdown + ip address 10.5.1.98/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 507 + priority 150 + ip 10.5.1.97 + +interface vlan508 + description L3forward_508 + mtu 9216 + no shutdown + ip address 10.5.1.114/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 508 + priority 150 + ip 10.5.1.113 + +interface vlan509 + description L3forward_509 + mtu 9216 + no shutdown + ip address 10.5.1.130/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 509 + priority 150 + ip 10.5.1.129 + +interface vlan510 + description L3forward_510 + mtu 9216 + no shutdown + ip address 10.5.1.145/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 510 + priority 150 + ip + +interface vlan511 + description L3forward_511 + mtu 9216 + no shutdown + ip address 10.5.1.162/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 511 + priority 150 + ip 10.5.1.161 + +interface vlan512 + description L3forward_512 + mtu 9216 + no shutdown + ip address 10.5.1.178/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 512 + priority 150 + ip 10.5.1.177 + +interface vlan513 + description L3forward_513 + mtu 9216 + no shutdown + ip address 10.5.1.194/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 513 + priority 150 + ip 10.5.1.193 + +interface vlan514 + description L3forward_514 + mtu 9216 + no shutdown + ip address 10.5.1.210/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 514 + priority 150 + ip 10.5.1.209 + +interface vlan515 + description L3forward_515 + mtu 9216 + no shutdown + ip address 10.5.1.226/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 515 + priority 150 + ip 10.5.1.225 + +interface vlan516 + description L3forward_516 + mtu 9216 + no shutdown + ip address 10.5.1.242/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 516 + priority 150 + ip 10.5.1.241 + + + +! interface.j2 + +interface Ethernet 1/1-1/54 + description Unused + no cdp enable + switchport + switchport mode access + switchport access vlan 2 + spanning-tree port type edge + no logging event port link-status + mtu 9216 + shutdown + + +interface Ethernet 1/49 + description Trunk_TO_BMC_SWITCH + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan 125 + priority-flow-control mode on send-tlv + spanning-tree port type edge trunk + no logging event port link-status + mtu 9216 + no shutdown + +interface Ethernet 1/1-1/16 + description HyperConverged_To_Host + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 7 + switchport trunk allowed vlan 7,6,201,301,401,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,711 + priority-flow-control mode on send-tlv + spanning-tree port type edge trunk + no logging event port link-status + mtu 9216 + service-policy type qos input AZLOCAL-QOS-MAP + no shutdown + + +interface Ethernet 1/48 + description P2P_Border1 + no cdp enable + no switchport + ip address 10.1.1.2/30 + no ip redirects + no ipv6 redirects + mtu 9216 + no shutdown + +interface Ethernet 1/47 + description P2P_Border2 + no cdp enable + no switchport + ip address 10.1.1.10/30 + no ip redirects + no ipv6 redirects + mtu 9216 + no shutdown + + +interface loopbackloopback0 + description Loopback0 + ip address 10.1.1.21/32 + mtu 9216 + no shutdown + + + +! port-channel.j2 + + +interface port-channel50 + description iBGP_Peer + no switchport + ip address + logging event port link-status + mtu 9216 + no shutdown + + +interface Ethernet 1/41 + description iBGP_Peer + no cdp enable + logging event port link-status + mtu 9216 + channel-group 50 mode active + no shutdown + +interface Ethernet 1/42 + description iBGP_Peer + no cdp enable + logging event port link-status + mtu 9216 + channel-group 50 mode active + no shutdown + + + +interface port-channel101 + description ToR_Peer_Link + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan + spanning-tree port type network + logging event port link-status + mtu 9216 + no shutdown + + +interface Ethernet 1/49 + description ToR_Peer_Link + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan + spanning-tree port type network + logging event port link-status + mtu 9216 + channel-group 101 mode active + no shutdown + +interface Ethernet 1/50 + description ToR_Peer_Link + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan + spanning-tree port type network + logging event port link-status + mtu 9216 + channel-group 101 mode active + no shutdown + +interface Ethernet 1/51 + description ToR_Peer_Link + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan + spanning-tree port type network + logging event port link-status + mtu 9216 + channel-group 101 mode active + no shutdown + + + + + +! prefix_list.j2 +ip prefix-list DefaultRoute seq 10 permit 0.0.0.0/0 +ip prefix-list DefaultRoute seq 50 deny 0.0.0.0/0 le 32 + + + + +! bgp.j2 +router bgp 65242 + router-id 10.1.1.21 + bestpath as-path multipath-relax + log-neighbor-changes + address-family ipv4 unicast + network 10.1.1.2/30 + network 10.1.1.10/30 + network 10.1.1.21/32 + network 10.4.1.0/24 + network 10.5.2.0/25 + network 10.5.2.128/25 + network 10.5.1.0/28 + network 10.5.1.16/28 + network 10.5.1.32/28 + network 10.5.1.48/28 + network 10.5.1.64/28 + network 10.5.1.80/28 + network 10.5.1.96/28 + network 10.5.1.112/28 + network 10.5.1.128/28 + network 10.5.1.144/28 + network 10.5.1.160/28 + network 10.5.1.176/28 + network 10.5.1.192/28 + network 10.5.1.208/28 + network 10.5.1.224/28 + network 10.5.1.240/28 + maximum-paths 8 + maximum-paths ibgp 8 + + neighbor 10.1.1.1 + description TO_Border1 + remote-as 64846 + address-family ipv4 unicast + maximum-prefix 12000 warning-only + prefix-list DefaultRoute in + + neighbor 10.1.1.9 + description TO_Border2 + remote-as 64846 + address-family ipv4 unicast + maximum-prefix 12000 warning-only + prefix-list DefaultRoute in + + neighbor 10.1.1.18 + description iBGP_PEER + remote-as 65242 + address-family ipv4 unicast + maximum-prefix 12000 warning-only + + neighbor 10.2.1.0/25 + description TO_HNVPA + remote-as 65112 + update-source Loopback0 + ebgp-multihop 3 + address-family ipv4 unicast + maximum-prefix 12000 warning-only + prefix-list DefaultRoute out + + diff --git a/tests/test_cases/std_cisco_nxos_fc/expected_interface.cfg b/tests/test_cases/std_cisco_nxos_fc/expected_interface.cfg new file mode 100644 index 0000000..ee089a4 --- /dev/null +++ b/tests/test_cases/std_cisco_nxos_fc/expected_interface.cfg @@ -0,0 +1,69 @@ +! interface.j2 + +interface Ethernet 1/1-1/54 + description Unused + no cdp enable + switchport + switchport mode access + switchport access vlan 2 + spanning-tree port type edge + no logging event port link-status + mtu 9216 + shutdown + + +interface Ethernet 1/49 + description Trunk_TO_BMC_SWITCH + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan 125 + priority-flow-control mode on send-tlv + spanning-tree port type edge trunk + no logging event port link-status + mtu 9216 + no shutdown + +interface Ethernet 1/1-1/16 + description HyperConverged_To_Host + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 7 + switchport trunk allowed vlan 7,6,201,301,401,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,711 + priority-flow-control mode on send-tlv + spanning-tree port type edge trunk + no logging event port link-status + mtu 9216 + service-policy type qos input AZLOCAL-QOS-MAP + no shutdown + + +interface Ethernet 1/48 + description P2P_Border1 + no cdp enable + no switchport + ip address 10.1.1.2/30 + no ip redirects + no ipv6 redirects + mtu 9216 + no shutdown + +interface Ethernet 1/47 + description P2P_Border2 + no cdp enable + no switchport + ip address 10.1.1.10/30 + no ip redirects + no ipv6 redirects + mtu 9216 + no shutdown + + +interface loopbackloopback0 + description Loopback0 + ip address 10.1.1.21/32 + mtu 9216 + no shutdown + diff --git a/tests/test_cases/std_cisco_nxos_fc/expected_login.cfg b/tests/test_cases/std_cisco_nxos_fc/expected_login.cfg new file mode 100644 index 0000000..21fb6d9 --- /dev/null +++ b/tests/test_cases/std_cisco_nxos_fc/expected_login.cfg @@ -0,0 +1,41 @@ +! login.j2 + +fips mode enable +user max-logins 1 +password prompt username +userpassphrase min-length 15 max-length 80 +username admin password 0 $CREDENTIAL_PLACEHOLDER$ role network-admin +username $CREDENTIAL_PLACEHOLDER$ password 0 $CREDENTIAL_PLACEHOLDER$ role network-admin + + +no feature ssh +no ssh key ecdsa +no ssh key rsa +ssh key rsa 2048 force +ssh key ecdsa 256 force +feature ssh + + +line console + exec-timeout 10 +line vty + exec-timeout 10 + session-limit 3 + + +! Replace [TACACS_SERVER_IP], [TACACS_KEY], [TACACS_GROUP],[MGMT_VLAN] with actual values. +tacacs-server key [TACACS_KEY] +tacacs-server timeout 2 +ip tacacs source-interface [MGMT_VLAN] + +tacacs-server host [TACACS_SERVER_IP] +tacacs-server host [TACACS_SERVER_IP] + +aaa group server tacacs+ [TACACS_GROUP] + server [TACACS_SERVER_IP] + server [TACACS_SERVER_IP] + source-interface [MGMT_VLAN] + +aaa authentication login default group [TACACS_GROUP] +aaa authentication login console group [TACACS_GROUP] +aaa accounting default group [TACACS_GROUP] \ No newline at end of file diff --git a/tests/test_cases/std_cisco_nxos_fc/expected_port_channel.cfg b/tests/test_cases/std_cisco_nxos_fc/expected_port_channel.cfg new file mode 100644 index 0000000..74c9bd6 --- /dev/null +++ b/tests/test_cases/std_cisco_nxos_fc/expected_port_channel.cfg @@ -0,0 +1,82 @@ +! port-channel.j2 + + +interface port-channel50 + description iBGP_Peer + no switchport + ip address + logging event port link-status + mtu 9216 + no shutdown + + +interface Ethernet 1/41 + description iBGP_Peer + no cdp enable + logging event port link-status + mtu 9216 + channel-group 50 mode active + no shutdown + +interface Ethernet 1/42 + description iBGP_Peer + no cdp enable + logging event port link-status + mtu 9216 + channel-group 50 mode active + no shutdown + + + +interface port-channel101 + description ToR_Peer_Link + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan + spanning-tree port type network + logging event port link-status + mtu 9216 + no shutdown + + +interface Ethernet 1/49 + description ToR_Peer_Link + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan + spanning-tree port type network + logging event port link-status + mtu 9216 + channel-group 101 mode active + no shutdown + +interface Ethernet 1/50 + description ToR_Peer_Link + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan + spanning-tree port type network + logging event port link-status + mtu 9216 + channel-group 101 mode active + no shutdown + +interface Ethernet 1/51 + description ToR_Peer_Link + no cdp enable + switchport + switchport mode trunk + switchport trunk native vlan 99 + switchport trunk allowed vlan + spanning-tree port type network + logging event port link-status + mtu 9216 + channel-group 101 mode active + no shutdown + + diff --git a/tests/test_cases/std_cisco_nxos_fc/expected_prefix_list.cfg b/tests/test_cases/std_cisco_nxos_fc/expected_prefix_list.cfg new file mode 100644 index 0000000..480b5ca --- /dev/null +++ b/tests/test_cases/std_cisco_nxos_fc/expected_prefix_list.cfg @@ -0,0 +1,5 @@ + +! prefix_list.j2 +ip prefix-list DefaultRoute seq 10 permit 0.0.0.0/0 +ip prefix-list DefaultRoute seq 50 deny 0.0.0.0/0 le 32 + diff --git a/tests/test_cases/std_cisco_nxos_fc/expected_qos.cfg b/tests/test_cases/std_cisco_nxos_fc/expected_qos.cfg new file mode 100644 index 0000000..d1da3ff --- /dev/null +++ b/tests/test_cases/std_cisco_nxos_fc/expected_qos.cfg @@ -0,0 +1,37 @@ +! qos.j2 + +policy-map type network-qos AZLOCAL-NWQOS + class type network-qos AZLOCAL-NWQOS-RDMA + pause pfc-cos 3 + mtu 9216 + class type network-qos AZLOCAL-NWQOS-DEFAULT + mtu 9216 + class type network-qos AZLOCAL-NWQOS-CLUSTER + mtu 9216 + + +class-map type qos match-all AZLOCAL-QOS-RDMA + match cos 3 +class-map type qos match-all AZLOCAL-QOS-CLUSTER + match cos 7 + +policy-map type qos AZLOCAL-QOS-MAP + class AZLOCAL-QOS-RDMA + set qos-group 3 + class AZLOCAL-QOS-CLUSTER + set qos-group 7 + + +policy-map type queuing AZLOCAL-QUEUE-OUT + class type queuing c-out-8q-q3 + bandwidth remaining percent 50 + random-detect minimum-threshold 300 kbytes maximum-threshold 300 kbytes drop-probability 100 weight 0 ecn + class type queuing c-out-8q-q-default + bandwidth remaining percent 48 + class type queuing c-out-8q-q7 + bandwidth percent 2 + + +system qos + service-policy type network-qos AZLOCAL-NWQOS + service-policy type queuing output AZLOCAL-QUEUE-OUT \ No newline at end of file diff --git a/tests/test_cases/std_cisco_nxos_fc/expected_system.cfg b/tests/test_cases/std_cisco_nxos_fc/expected_system.cfg new file mode 100644 index 0000000..fc56b75 --- /dev/null +++ b/tests/test_cases/std_cisco_nxos_fc/expected_system.cfg @@ -0,0 +1,74 @@ +! system.j2 + +! Name: tor-1a +! Make: cisco +! Model: 93180yc-fx3 +hostname tor-1a + +banner motd # +NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE + +hostname tor-1a +Unauthorized access and/or use prohibited. +All access and/or use subject to monitoring. + +NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + + +no feature telnet +feature scp-server +feature bgp +feature interface-vlan +feature lldp +feature dhcp +feature vpc +feature hsrp +feature lacp +feature ssh +feature tacacs+ + + +clock timezone PST -8 0 +clock summer-time PDT 2 Sun Apr 02:00 1 Sun Nov 02:00 60 +ntp server [NTP_SERVER_IP] +ntp source-interface [MGMT_VLAN] + + +logging server [LOG_SERVER_IP] 7 facility local7 use-vrf default +logging source-interface [MGMT_VLAN] +logging level local7 7 +no logging console +login on-success log +logging origin-id hostname + +logging level acllog 7 +logging level aclmgr 7 +logging level eth_port_channel 7 +logging level hsrp 7 +logging level icam 7 +logging level interface-vlan 7 +logging level ipqosmgr 7 +logging level vlan_mgr 7 +logging level vpc 7 +logging level netstack 7 +logging level bgp 7 + + +no cdp enable +lldp tlv-select dcbxp egress-queuing + +service dhcp +ip dhcp relay + +ip load-sharing address source-destination port source-destination + +ip icmp-errors source-interface [MGMT_VLAN] + +cli alias name wr copy running-config startup-config + + +snmp-server community [PLACEHOLDER] ro +snmp-server community [PLACEHOLDER] rW +snmp-server contact "Contact Support" +snmp-server location \ No newline at end of file diff --git a/tests/test_cases/std_cisco_nxos_fc/expected_vlan.cfg b/tests/test_cases/std_cisco_nxos_fc/expected_vlan.cfg new file mode 100644 index 0000000..efbc69f --- /dev/null +++ b/tests/test_cases/std_cisco_nxos_fc/expected_vlan.cfg @@ -0,0 +1,346 @@ +! vlan.j2 + +vlan 2 + name UNUSED_VLAN + shutdown +vlan 6 + name HNVPA_6 + +vlan 7 + name Infra_7 + +vlan 99 + name NativeVlan + +vlan 125 + name BMC_Mgmt_125 + +vlan 201 + name Tenant_201 + +vlan 301 + name LogicalTenant_301 + +vlan 401 + name DhcpTenant_401 + +vlan 501 + name L3forward_501 + +vlan 502 + name L3forward_502 + +vlan 503 + name L3forward_503 + +vlan 504 + name L3forward_504 + +vlan 505 + name L3forward_505 + +vlan 506 + name L3forward_506 + +vlan 507 + name L3forward_507 + +vlan 508 + name L3forward_508 + +vlan 509 + name L3forward_509 + +vlan 510 + name L3forward_510 + +vlan 511 + name L3forward_511 + +vlan 512 + name L3forward_512 + +vlan 513 + name L3forward_513 + +vlan 514 + name L3forward_514 + +vlan 515 + name L3forward_515 + +vlan 516 + name L3forward_516 + +vlan 711 + name Storage_711_TOR1 + +vlan 712 + name Storage_712_TOR2 + + + +interface vlan6 + description HNVPA_6 + mtu 9216 + no shutdown + ip address 10.2.1.2/25 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 6 + priority 150 + ip 10.2.1.1 + +interface vlan7 + description Infra_7 + mtu 9216 + no shutdown + ip address 10.3.1.2/24 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 7 + priority 150 + ip 10.3.1.1 + +interface vlan125 + description BMC_Mgmt_125 + mtu 9216 + no shutdown + ip address 10.1.1.123/26 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 125 + priority 150 + ip 10.1.1.65 + +interface vlan201 + description Tenant_201 + mtu 9216 + no shutdown + ip address 10.4.1.2/24 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 201 + priority 150 + ip 10.4.1.1 + +interface vlan301 + description LogicalTenant_301 + mtu 9216 + no shutdown + ip address 10.5.2.2/25 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 301 + priority 150 + ip 10.5.2.1 + +interface vlan401 + description DhcpTenant_401 + mtu 9216 + no shutdown + ip address 10.5.2.130/25 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 401 + priority 150 + ip 10.5.2.129 + +interface vlan501 + description L3forward_501 + mtu 9216 + no shutdown + ip address 10.5.1.2/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 501 + priority 150 + ip 10.5.1.1 + +interface vlan502 + description L3forward_502 + mtu 9216 + no shutdown + ip address 10.5.1.18/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 502 + priority 150 + ip 10.5.1.17 + +interface vlan503 + description L3forward_503 + mtu 9216 + no shutdown + ip address 10.5.1.34/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 503 + priority 150 + ip 10.5.1.33 + +interface vlan504 + description L3forward_504 + mtu 9216 + no shutdown + ip address 10.5.1.50/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 504 + priority 150 + ip 10.5.1.49 + +interface vlan505 + description L3forward_505 + mtu 9216 + no shutdown + ip address 10.5.1.66/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 505 + priority 150 + ip 10.5.1.65 + +interface vlan506 + description L3forward_506 + mtu 9216 + no shutdown + ip address 10.5.1.82/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 506 + priority 150 + ip 10.5.1.81 + +interface vlan507 + description L3forward_507 + mtu 9216 + no shutdown + ip address 10.5.1.98/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 507 + priority 150 + ip 10.5.1.97 + +interface vlan508 + description L3forward_508 + mtu 9216 + no shutdown + ip address 10.5.1.114/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 508 + priority 150 + ip 10.5.1.113 + +interface vlan509 + description L3forward_509 + mtu 9216 + no shutdown + ip address 10.5.1.130/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 509 + priority 150 + ip 10.5.1.129 + +interface vlan510 + description L3forward_510 + mtu 9216 + no shutdown + ip address 10.5.1.145/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 510 + priority 150 + ip + +interface vlan511 + description L3forward_511 + mtu 9216 + no shutdown + ip address 10.5.1.162/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 511 + priority 150 + ip 10.5.1.161 + +interface vlan512 + description L3forward_512 + mtu 9216 + no shutdown + ip address 10.5.1.178/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 512 + priority 150 + ip 10.5.1.177 + +interface vlan513 + description L3forward_513 + mtu 9216 + no shutdown + ip address 10.5.1.194/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 513 + priority 150 + ip 10.5.1.193 + +interface vlan514 + description L3forward_514 + mtu 9216 + no shutdown + ip address 10.5.1.210/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 514 + priority 150 + ip 10.5.1.209 + +interface vlan515 + description L3forward_515 + mtu 9216 + no shutdown + ip address 10.5.1.226/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 515 + priority 150 + ip 10.5.1.225 + +interface vlan516 + description L3forward_516 + mtu 9216 + no shutdown + ip address 10.5.1.242/28 + no ip redirects + no ipv6 redirects + hsrp version 2 + hsrp 516 + priority 150 + ip 10.5.1.241 + diff --git a/tests/test_generator.py b/tests/test_generator.py index d791471..fc4ff09 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -4,26 +4,26 @@ Each test case lives in a folder under ``tests/test_cases/std_*``. The folder contains: - A ``*_input.json`` file (standard format) - - ``expected_
.cfg`` files for comparison + - ``expected_
.cfg`` golden files for comparison + +Generation runs at test-time into ``tmp_path`` for isolation — +no files are written into the source tree. """ from __future__ import annotations -import io -import sys from pathlib import Path import pytest from conftest import TEST_CASES_ROOT, TEMPLATE_ROOT, find_text_differences - -# ── import generator ────────────────────────────────────────────────────── from src.generator import generate_config -# ── discover test cases ─────────────────────────────────────────────────── +# ── discover test cases (no side effects) ───────────────────────────────── def _find_std_cases() -> list[tuple[str, Path]]: + """Return (folder_name, input_json_path) for every std_* test case.""" cases = [] for folder in sorted(TEST_CASES_ROOT.iterdir()): if not folder.is_dir() or not folder.name.startswith("std_"): @@ -33,64 +33,65 @@ def _find_std_cases() -> list[tuple[str, Path]]: return cases -def _discover_generated_pairs() -> list[tuple[str, str, Path, Path]]: - """Generate configs into tmp dirs and return (folder, section, gen, exp) tuples.""" - pairs: list[tuple[str, str, Path, Path]] = [] - - for folder_name, input_file in _find_std_cases(): - folder_path = TEST_CASES_ROOT / folder_name +_STD_CASES = _find_std_cases() - # Generate into the test-case folder (idempotent) - old = sys.stdout - sys.stdout = io.StringIO() - try: - generate_config( - input_std_json=str(input_file), - template_folder=str(TEMPLATE_ROOT), - output_folder=str(folder_path), - ) - except Exception: - pass # template-path issues are expected for some vendors - finally: - sys.stdout = old - for gen_file in sorted(folder_path.glob("generated_*.cfg")): - section = gen_file.stem.replace("generated_", "") - exp_file = folder_path / f"expected_{section}.cfg" - pairs.append((folder_name, section, gen_file, exp_file)) +# ── tests ───────────────────────────────────────────────────────────────── - return pairs +@pytest.mark.parametrize( + "folder_name, input_file", + _STD_CASES, + ids=[c[0] for c in _STD_CASES], +) +def test_generation_succeeds(folder_name, input_file, tmp_path): + """Generator runs without error and produces at least one .cfg file.""" + generate_config( + input_std_json=str(input_file), + template_folder=str(TEMPLATE_ROOT), + output_folder=str(tmp_path), + ) + generated = list(tmp_path.glob("generated_*.cfg")) + assert generated, f"No .cfg files generated for {folder_name}" -_ALL_PAIRS = _discover_generated_pairs() -_ALL_STD_CASES = _find_std_cases() +@pytest.mark.parametrize( + "folder_name, input_file", + _STD_CASES, + ids=[c[0] for c in _STD_CASES], +) +def test_golden_file_comparison(folder_name, input_file, tmp_path): + """Compare every expected_
.cfg against its generated output.""" + generate_config( + input_std_json=str(input_file), + template_folder=str(TEMPLATE_ROOT), + output_folder=str(tmp_path), + ) + + case_dir = TEST_CASES_ROOT / folder_name + expected_files = sorted(case_dir.glob("expected_*.cfg")) + + if not expected_files: + pytest.skip(f"No expected golden files in {folder_name}") + + errors = [] + for exp_file in expected_files: + section = exp_file.stem.replace("expected_", "") + gen_file = tmp_path / f"generated_{section}.cfg" + + if not gen_file.exists(): + errors.append(f"Section '{section}': generated file missing") + continue + expected_text = exp_file.read_text("utf-8").strip() + generated_text = gen_file.read_text("utf-8").strip() -# ── parametrised tests ──────────────────────────────────────────────────── + if expected_text != generated_text: + diffs = find_text_differences(expected_text, generated_text) + errors.append( + f"Section '{section}' differs:\n" + + "\n".join(f" {d}" for d in diffs[:5]) + ) -@pytest.mark.parametrize( - "folder_name, section, gen_path, exp_path", - _ALL_PAIRS, - ids=[f"{folder}-{section}" for folder, section, _, _ in _ALL_PAIRS], -) -def test_generated_config(folder_name, section, gen_path, exp_path): - """Compare a single generated .cfg against its expected golden file.""" - if not exp_path.exists(): - pytest.skip(f"No expected file: {exp_path.name}") - - generated = gen_path.read_text("utf-8").strip() - expected = exp_path.read_text("utf-8").strip() - - if expected != generated: - diffs = find_text_differences(expected, generated) - msg = f"{folder_name}/{section} differs:\n" + "\n".join(f" - {d}" for d in diffs[:5]) - pytest.fail(msg, pytrace=False) - - -@pytest.mark.parametrize("case", _ALL_STD_CASES, ids=lambda c: f"has_output_{c[0]}") -def test_output_files_generated(case): - """At least one .cfg file should be generated for each test case.""" - folder_name, _ = case - folder_path = TEST_CASES_ROOT / folder_name - generated = list(folder_path.glob("generated_*.cfg")) - assert generated, f"No generated .cfg files for {folder_name}" \ No newline at end of file + assert not errors, ( + f"{folder_name} golden file mismatches:\n" + "\n".join(errors) + ) \ No newline at end of file diff --git a/tests/test_unit.py b/tests/test_unit.py index 148195d..8a88c66 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -6,6 +6,8 @@ 2. Loader — load_input_json, get_real_path 3. Constants — sanity checks on shared config values 4. BMC Converter — switch_info, vlans, interfaces, port_channels, static_routes + 5. TOR Converter (StandardJSONBuilder) — build_switch, build_vlans, + _resolve_interface_vlans, build_bgp, build_prefix_lists, build_qos All test data uses generic/sanitized values — no lab-specific identifiers. """ @@ -30,6 +32,7 @@ from src.utils import infer_firmware, classify_vlan_group from src.loader import load_input_json, get_real_path from src.convertors.convertors_bmc_switch_json import BMCSwitchConverter +from src.convertors.convertors_lab_switch_json import StandardJSONBuilder # ═══════════════════════════════════════════════════════════════════════════ @@ -341,3 +344,502 @@ def test_extracts_common_interfaces(self): def test_raises_when_no_common_interfaces(self): with pytest.raises(ValueError, match="No common interfaces"): BMCSwitchConverter._build_interfaces({"interface_templates": {"common": []}}) + + +# ═══════════════════════════════════════════════════════════════════════════ +# 5. TOR Converter — StandardJSONBuilder +# ═══════════════════════════════════════════════════════════════════════════ + + +def _make_tor_input(*, site="site1", deployment_pattern="Switched", node_count=16, + tor_make="Cisco", tor_model="93180YC-FX", tor_firmware="10.3(4a)", + tor1_hostname="tor-1a", tor2_hostname="tor-1b", + tor_asn=65242, border_asn=64846, mux_asn=65112, + extra_supernets=None): + """Factory for creating minimal TOR converter input data. + + Provides a realistic input structure with Switches, Supernets, and + ClusterUnits. Override keyword arguments to test specific scenarios. + """ + supernets = [ + { + "GroupName": "INFRA_MGMT", + "Name": "Infra_7", + "IPv4": { + "SwitchSVI": True, "Name": "Infra_7", "VLANID": 7, + "Cidr": 24, "NetworkType": "Infrastructure", + "Subnet": "10.0.7.0/24", "Network": "10.0.7.0", + "Netmask": "255.255.255.0", "FirstAddress": "10.0.7.1", + "LastAddress": "10.0.7.254", + "Gateway": "10.0.7.1", + "Assignment": [ + {"Name": "Gateway", "IP": "10.0.7.1"}, + {"Name": "TOR1", "IP": "10.0.7.2"}, + {"Name": "TOR2", "IP": "10.0.7.3"}, + ], + }, + }, + { + "GroupName": "HNVPA_Pool1", + "Name": "HNVPA_6", + "IPv4": { + "SwitchSVI": False, "Name": "HNVPA_6", "VLANID": 6, + "Cidr": 23, "NetworkType": "Compute", + "Subnet": "10.0.6.0/23", "Network": "10.0.6.0", + "Netmask": "255.255.254.0", "FirstAddress": "10.0.6.1", + "LastAddress": "10.0.7.254", + "Assignment": [], + }, + }, + { + "GroupName": "TENANT_1", + "Name": "Tenant_201", + "IPv4": { + "SwitchSVI": True, "Name": "Tenant_201", "VLANID": 201, + "Cidr": 23, "NetworkType": "Tenant", + "Subnet": "10.1.0.0/23", "Network": "10.1.0.0", + "Netmask": "255.255.254.0", "FirstAddress": "10.1.0.1", + "LastAddress": "10.1.1.254", + "Gateway": "10.1.0.1", + "Assignment": [ + {"Name": "Gateway", "IP": "10.1.0.1"}, + {"Name": "TOR1", "IP": "10.1.0.2"}, + {"Name": "TOR2", "IP": "10.1.0.3"}, + ], + }, + }, + { + "GroupName": "STORAGE_A", + "Name": "Storage_711_TOR1", + "IPv4": { + "SwitchSVI": True, "Name": "Storage_711_TOR1", "VLANID": 711, + "Cidr": 24, "NetworkType": "Storage", + "Subnet": "10.2.0.0/24", "Network": "10.2.0.0", + "Netmask": "255.255.255.0", + "Gateway": "10.2.0.1", + "Assignment": [ + {"Name": "Gateway", "IP": "10.2.0.1"}, + {"Name": "TOR1", "IP": "10.2.0.2"}, + ], + }, + }, + { + "GroupName": "STORAGE_B", + "Name": "Storage_712_TOR2", + "IPv4": { + "SwitchSVI": True, "Name": "Storage_712_TOR2", "VLANID": 712, + "Cidr": 24, "NetworkType": "Storage", + "Subnet": "10.2.1.0/24", "Network": "10.2.1.0", + "Netmask": "255.255.255.0", + "Gateway": "10.2.1.1", + "Assignment": [ + {"Name": "Gateway", "IP": "10.2.1.1"}, + {"Name": "TOR2", "IP": "10.2.1.2"}, + ], + }, + }, + { + "GroupName": "P2P_BORDER1", + "Name": "P2P_Border1_TOR1", + "IPv4": { + "SwitchSVI": False, "Name": "P2P_Border1_TOR1", "VLANID": 0, + "Cidr": 30, "Subnet": "10.3.0.0/30", "Network": "10.3.0.0", + "FirstAddress": "10.3.0.1", "LastAddress": "10.3.0.2", + "Assignment": [], + }, + }, + { + "GroupName": "P2P_BORDER2", + "Name": "P2P_Border2_TOR1", + "IPv4": { + "SwitchSVI": False, "Name": "P2P_Border2_TOR1", "VLANID": 0, + "Cidr": 30, "Subnet": "10.3.0.4/30", "Network": "10.3.0.4", + "FirstAddress": "10.3.0.5", "LastAddress": "10.3.0.6", + "Assignment": [], + }, + }, + { + "GroupName": "P2P_BORDER1", + "Name": "P2P_Border1_TOR2", + "IPv4": { + "SwitchSVI": False, "Name": "P2P_Border1_TOR2", "VLANID": 0, + "Cidr": 30, "Subnet": "10.3.0.8/30", "Network": "10.3.0.8", + "FirstAddress": "10.3.0.9", "LastAddress": "10.3.0.10", + "Assignment": [], + }, + }, + { + "GroupName": "P2P_BORDER2", + "Name": "P2P_Border2_TOR2", + "IPv4": { + "SwitchSVI": False, "Name": "P2P_Border2_TOR2", "VLANID": 0, + "Cidr": 30, "Subnet": "10.3.0.12/30", "Network": "10.3.0.12", + "FirstAddress": "10.3.0.13", "LastAddress": "10.3.0.14", + "Assignment": [], + }, + }, + { + "GroupName": "LOOPBACK0", + "Name": "Loopback0_TOR1", + "IPv4": { + "SwitchSVI": False, "Name": "Loopback0_TOR1", "VLANID": 0, + "Cidr": 32, "Subnet": "10.4.0.1/32", "Network": "10.4.0.1", + "Assignment": [], + }, + }, + { + "GroupName": "LOOPBACK0", + "Name": "Loopback0_TOR2", + "IPv4": { + "SwitchSVI": False, "Name": "Loopback0_TOR2", "VLANID": 0, + "Cidr": 32, "Subnet": "10.4.0.2/32", "Network": "10.4.0.2", + "Assignment": [], + }, + }, + { + "GroupName": "P2P_IBGP", + "Name": "P2P_IBGP", + "IPv4": { + "SwitchSVI": False, "Name": "P2P_IBGP", "VLANID": 0, + "Cidr": 30, "Subnet": "10.5.0.0/30", "Network": "10.5.0.0", + "FirstAddress": "10.5.0.1", "LastAddress": "10.5.0.2", + "Assignment": [], + }, + }, + { + "GroupName": "UNUSED_VLAN", + "Name": "UNUSED_VLAN", + "IPv4": {"SwitchSVI": False, "Name": "UNUSED_VLAN", "VLANID": 2}, + }, + { + "GroupName": "NativeVlan", + "Name": "NativeVlan", + "IPv4": {"SwitchSVI": False, "Name": "NativeVlan", "VLANID": 99}, + }, + ] + if extra_supernets: + supernets.extend(extra_supernets) + + return { + "Version": "1.0.0", + "Description": "Unit test input", + "InputData": { + "MainEnvData": [{ + "Id": "Env01", "Site": site, "RackName": "rack01", + "NodeCount": node_count, + "ClusterUnits": [ + {"Name": "Cl01", "NodeCount": 4, "Topology": deployment_pattern} + ], + }], + "Switches": [ + {"Make": "Cisco", "Model": "C9336C-FX2", "Type": "Border1", + "Hostname": "border-1a", "ASN": border_asn}, + {"Make": "Cisco", "Model": "C9336C-FX2", "Type": "Border2", + "Hostname": "border-1b", "ASN": border_asn}, + {"Make": tor_make, "Model": tor_model, "Type": "TOR1", + "Hostname": tor1_hostname, "ASN": tor_asn, "Firmware": tor_firmware}, + {"Make": tor_make, "Model": tor_model, "Type": "TOR2", + "Hostname": tor2_hostname, "ASN": tor_asn, "Firmware": tor_firmware}, + {"Make": "Contoso", "Model": None, "Type": "MUX", + "Hostname": "mux-1", "ASN": mux_asn}, + ], + "Supernets": supernets, + "DeploymentPattern": deployment_pattern, + }, + } + + +@pytest.fixture +def tor_builder(): + """A StandardJSONBuilder initialised with default Switched input.""" + return StandardJSONBuilder(_make_tor_input()) + + +class TestTORBuildSwitch: + """StandardJSONBuilder.build_switch — switch metadata from Switches array.""" + + def test_builds_tor1_metadata(self, tor_builder): + tor_builder.build_switch("TOR1") + sw = tor_builder.sections["switch"]["TOR1"] + assert sw["make"] == "cisco" + assert sw["model"] == "93180yc-fx" + assert sw["hostname"] == "tor-1a" + assert sw["firmware"] == "nxos" + + def test_builds_tor2_metadata(self, tor_builder): + tor_builder.build_switch("TOR2") + sw = tor_builder.sections["switch"]["TOR2"] + assert sw["hostname"] == "tor-1b" + assert sw["type"] == "TOR2" + + def test_populates_bgp_map_from_switches(self, tor_builder): + tor_builder.build_switch("TOR1") + assert tor_builder.bgp_map["ASN_BORDER"] == 64846 + assert tor_builder.bgp_map["ASN_TOR"] == 65242 + assert tor_builder.bgp_map["ASN_MUX"] == 65112 + + def test_site_from_main_env_data(self, tor_builder): + tor_builder.build_switch("TOR1") + assert tor_builder.sections["switch"]["TOR1"]["site"] == "site1" + + def test_custom_site(self): + builder = StandardJSONBuilder(_make_tor_input(site="datacenter42")) + builder.build_switch("TOR1") + assert builder.sections["switch"]["TOR1"]["site"] == "datacenter42" + + def test_32bit_mux_asn(self): + """Verify 32-bit ASN (4200003000) stored as integer, not truncated.""" + builder = StandardJSONBuilder(_make_tor_input(mux_asn=4200003000)) + builder.build_switch("TOR1") + assert builder.bgp_map["ASN_MUX"] == 4200003000 + + +class TestTORBuildVlans: + """StandardJSONBuilder.build_vlans — VLAN list from Supernets.""" + + def test_builds_vlans_sorted_by_id(self, tor_builder): + tor_builder.build_switch("TOR1") + tor_builder.build_vlans("TOR1") + ids = [v["vlan_id"] for v in tor_builder.sections["vlans"]] + assert ids == sorted(ids) + + def test_classifies_vlan_groups_to_symbols(self, tor_builder): + tor_builder.build_switch("TOR1") + tor_builder.build_vlans("TOR1") + assert 7 in tor_builder.vlan_map["M"] # INFRA + assert 6 in tor_builder.vlan_map["C"] # HNVPA + assert 201 in tor_builder.vlan_map["C"] # TENANT + assert 711 in tor_builder.vlan_map["S1"] # STORAGE ending TOR1 + assert 712 in tor_builder.vlan_map["S2"] # STORAGE ending TOR2 + + def test_svi_interface_attached_when_ip_present(self, tor_builder): + tor_builder.build_switch("TOR1") + tor_builder.build_vlans("TOR1") + infra = next(v for v in tor_builder.sections["vlans"] if v["vlan_id"] == 7) + assert "interface" in infra + assert infra["interface"]["ip"] == "10.0.7.2" + assert infra["interface"]["cidr"] == 24 + assert infra["interface"]["mtu"] == JUMBO_MTU + + def test_svi_hsrp_for_cisco_tor1(self, tor_builder): + tor_builder.build_switch("TOR1") + tor_builder.build_vlans("TOR1") + infra = next(v for v in tor_builder.sections["vlans"] if v["vlan_id"] == 7) + red = infra["interface"]["redundancy"] + assert red["type"] == "hsrp" + assert red["priority"] == 150 # ACTIVE + assert red["virtual_ip"] == "10.0.7.1" + + def test_svi_hsrp_for_cisco_tor2_is_standby(self, tor_builder): + tor_builder.build_switch("TOR2") + tor_builder.build_vlans("TOR2") + infra = next(v for v in tor_builder.sections["vlans"] if v["vlan_id"] == 7) + assert infra["interface"]["redundancy"]["priority"] == 140 # STANDBY + + def test_unused_vlan_marked_shutdown(self, tor_builder): + tor_builder.build_switch("TOR1") + tor_builder.build_vlans("TOR1") + unused = next(v for v in tor_builder.sections["vlans"] if v["vlan_id"] == 2) + assert unused.get("shutdown") is True + + def test_no_svi_when_no_assignment_ip(self, tor_builder): + """VLANs without Assignment IP for this switch type have no SVI.""" + tor_builder.build_switch("TOR1") + tor_builder.build_vlans("TOR1") + hnvpa = next(v for v in tor_builder.sections["vlans"] if v["vlan_id"] == 6) + assert "interface" not in hnvpa + + +class TestResolveInterfaceVlans: + """StandardJSONBuilder._resolve_interface_vlans — symbolic VLAN resolution.""" + + def _builder_with_vlans(self, switch_type="TOR1"): + builder = StandardJSONBuilder(_make_tor_input()) + builder.build_switch(switch_type) + builder.build_vlans(switch_type) + return builder + + def test_resolves_M_to_infra_vlans(self): + b = self._builder_with_vlans() + assert "7" in b._resolve_interface_vlans("TOR1", "M").split(",") + + def test_resolves_C_to_compute_vlans(self): + b = self._builder_with_vlans() + ids = b._resolve_interface_vlans("TOR1", "C").split(",") + assert "6" in ids and "201" in ids + + def test_resolves_S_for_tor1_uses_S1(self): + b = self._builder_with_vlans() + assert "711" in b._resolve_interface_vlans("TOR1", "S").split(",") + + def test_resolves_S_for_tor2_uses_S2(self): + b = self._builder_with_vlans("TOR2") + assert "712" in b._resolve_interface_vlans("TOR2", "S").split(",") + + def test_resolves_composite_string(self): + b = self._builder_with_vlans() + ids = b._resolve_interface_vlans("TOR1", "M,C").split(",") + assert "7" in ids and "6" in ids + + def test_literal_vlan_passthrough(self): + b = self._builder_with_vlans() + assert b._resolve_interface_vlans("TOR1", "99") == "99" + + def test_empty_string_returns_empty(self): + b = self._builder_with_vlans() + assert b._resolve_interface_vlans("TOR1", "") == "" + + def test_deduplicates_vlans(self): + b = self._builder_with_vlans() + ids = b._resolve_interface_vlans("TOR1", "M,M").split(",") + assert len(ids) == len(set(ids)) + + def test_unknown_symbol_skipped(self): + b = self._builder_with_vlans() + assert b._resolve_interface_vlans("TOR1", "NOSUCHVLAN") == "" + + +class TestTORBuildBGP: + """StandardJSONBuilder.build_bgp — BGP neighbor/network construction.""" + + def _prepared_builder(self, **kw): + builder = StandardJSONBuilder(_make_tor_input(**kw)) + builder.build_switch("TOR1") + builder.build_vlans("TOR1") + builder.sections["interfaces"] = [] + builder._build_ip_mapping() + return builder + + def test_bgp_asn_matches_tor(self): + b = self._prepared_builder() + b.build_bgp("TOR1") + assert b.sections["bgp"]["asn"] == 65242 + + def test_bgp_router_id_from_loopback(self): + b = self._prepared_builder() + b.build_bgp("TOR1") + assert b.sections["bgp"]["router_id"] == "10.4.0.1" + + def test_bgp_has_border_neighbors(self): + b = self._prepared_builder() + b.build_bgp("TOR1") + descs = [n["description"] for n in b.sections["bgp"]["neighbors"]] + assert "TO_Border1" in descs and "TO_Border2" in descs + + def test_bgp_border_asn(self): + b = self._prepared_builder() + b.build_bgp("TOR1") + border1 = next(n for n in b.sections["bgp"]["neighbors"] + if n["description"] == "TO_Border1") + assert border1["remote_as"] == 64846 + + def test_bgp_ibgp_peer(self): + b = self._prepared_builder() + b.build_bgp("TOR1") + ibgp = next(n for n in b.sections["bgp"]["neighbors"] + if n["description"] == "iBGP_PEER") + assert ibgp["remote_as"] == 65242 + assert ibgp["ip"] == "10.5.0.2" + + def test_bgp_mux_neighbor(self): + b = self._prepared_builder() + b.build_bgp("TOR1") + mux = next(n for n in b.sections["bgp"]["neighbors"] + if n["description"] == "TO_HNVPA") + assert mux["remote_as"] == 65112 + assert mux["ebgp_multihop"] == 3 + + def test_32bit_mux_asn_in_bgp(self): + b = self._prepared_builder(mux_asn=4200003000) + b.build_bgp("TOR1") + mux = next(n for n in b.sections["bgp"]["neighbors"] + if n["description"] == "TO_HNVPA") + assert mux["remote_as"] == 4200003000 + + def test_bgp_networks_include_p2p(self): + b = self._prepared_builder() + b.build_bgp("TOR1") + assert "10.3.0.2/30" in b.sections["bgp"]["networks"] + + def test_bgp_networks_include_loopback(self): + b = self._prepared_builder() + b.build_bgp("TOR1") + assert "10.4.0.1/32" in b.sections["bgp"]["networks"] + + def test_bgp_networks_deduplicated(self): + b = self._prepared_builder() + b.build_bgp("TOR1") + nets = b.sections["bgp"]["networks"] + assert len(nets) == len(set(nets)) + + def test_no_mux_when_asn_zero(self): + b = self._prepared_builder(mux_asn=0) + b.build_bgp("TOR1") + descs = [n["description"] for n in b.sections["bgp"]["neighbors"]] + assert "TO_HNVPA" not in descs + + +class TestTORBuildPrefixLists: + """StandardJSONBuilder.build_prefix_lists — DefaultRoute entries.""" + + def test_has_default_route(self, tor_builder): + tor_builder.build_prefix_lists() + assert "DefaultRoute" in tor_builder.sections["prefix_lists"] + assert len(tor_builder.sections["prefix_lists"]["DefaultRoute"]) == 2 + + def test_permit_and_deny(self, tor_builder): + tor_builder.build_prefix_lists() + actions = [e["action"] for e in tor_builder.sections["prefix_lists"]["DefaultRoute"]] + assert "permit" in actions and "deny" in actions + + +class TestTORBuildQoS: + """StandardJSONBuilder.build_qos — simple boolean flag.""" + + def test_qos_is_true(self, tor_builder): + tor_builder.build_qos() + assert tor_builder.sections["qos"] is True + + +class TestTORDeploymentPattern: + """StandardJSONBuilder pattern translation for template compatibility.""" + + def test_hyperconverged_maps_to_fully_converged(self): + b = StandardJSONBuilder(_make_tor_input(deployment_pattern="HyperConverged")) + assert b.deployment_pattern == "fully_converged" + assert b.original_pattern == "hyperconverged" + + def test_switched_stays_switched(self): + b = StandardJSONBuilder(_make_tor_input(deployment_pattern="Switched")) + assert b.deployment_pattern == "switched" + + def test_switchless_stays_switchless(self): + b = StandardJSONBuilder(_make_tor_input(deployment_pattern="Switchless")) + assert b.deployment_pattern == "switchless" + + +class TestTORBuildIPMapping: + """StandardJSONBuilder._build_ip_mapping — IP extraction from Supernets.""" + + def test_p2p_border_ips(self): + b = StandardJSONBuilder(_make_tor_input()) + b._build_ip_mapping() + assert b.ip_map["P2P_BORDER1_TOR1"] == ["10.3.0.2/30"] + assert b.ip_map["P2P_TOR1_BORDER1"] == ["10.3.0.1"] + + def test_loopback_ips(self): + b = StandardJSONBuilder(_make_tor_input()) + b._build_ip_mapping() + assert b.ip_map["LOOPBACK0_TOR1"] == ["10.4.0.1/32"] + assert b.ip_map["LOOPBACK0_TOR2"] == ["10.4.0.2/32"] + + def test_ibgp_ips(self): + b = StandardJSONBuilder(_make_tor_input()) + b._build_ip_mapping() + assert b.ip_map["P2P_IBGP_TOR1"] == ["10.5.0.1"] + assert b.ip_map["P2P_IBGP_TOR2"] == ["10.5.0.2"] + + def test_hnvpa_subnet(self): + b = StandardJSONBuilder(_make_tor_input()) + b._build_ip_mapping() + assert "10.0.6.0/23" in b.ip_map["HNVPA"] From 5cb4ccd393e2827aec302a1eaeede6b8dcff75b1 Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Sun, 8 Feb 2026 05:32:16 +0000 Subject: [PATCH 06/11] ci: rewrite build workflow, fix triage bugs, add copilot instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build workflow (build-switchgentool.yml): - Restructure to 3-job pipeline: test → build → release - Add pytest job (103 tests) as gate before build - Fix Python 3.11 → 3.12 - Remove stale dev/nl/newDesignv1 branch trigger - Remove fake 'Quick source test' (replaced by real pytest) - Remove fallback requirements.txt creation (masks errors) - Enable release job with GitHub Environment approval gate - Set fail-fast: true on build matrix (was false) - Add concurrency group to cancel stale runs - Push triggers: main only (was main + stale branch) Triage workflow (triage-submissions.yml): - Fix checkbox threshold: < 3 → < 2 (template has 2 required) - Fix error message to match actual checkbox labels - Fix unsafe JSON interpolation: env var instead of ${{ }} - Downgrade template patterns (${} / {{}}) to warnings - Add permissions: issues: write New files: - .github/copilot-instructions.md: project-level dev guidance - ROADMAP.md: CI/CD section, DP9 (BMC optional), KD17-20, DC7-9 --- .github/copilot-instructions.md | 113 +++ .github/workflows/build-switchgentool.yml | 161 ++-- .github/workflows/triage-submissions.yml | 26 +- _cisco_configs/reference/ROADMAP.md | 997 ++++++++++++++++++++++ 4 files changed, 1226 insertions(+), 71 deletions(-) create mode 100644 .github/copilot-instructions.md create mode 100644 _cisco_configs/reference/ROADMAP.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..20ddd4f --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,113 @@ +# Copilot Custom Instructions — AzureStack Network Switch Config Generator + +## Project Overview + +Python + Jinja2 CLI tool that generates production network switch configurations for +**Azure Local (Azure Stack HCI)** deployments. It takes a lab-format JSON definition, +converts it to a standardised JSON schema, then renders vendor-specific `.cfg` files +using Jinja2 templates. + +**Supported vendors:** Cisco NX-OS, Dell EMC OS10. +**Supported roles:** TOR1, TOR2 (production switches), BMC (internal lab-only switch). + +## Architecture + +``` +Lab JSON → Converter → Standard JSON → Generator + Jinja2 Templates → .cfg files +``` + +| Stage | Module | Purpose | +|-------|--------|---------| +| Entry | `src/main.py` | CLI parser, logging setup, orchestration | +| Load | `src/loader.py` | JSON/file loading, `get_real_path()` for PyInstaller | +| Convert | `src/convertors/convertors_lab_switch_json.py` | Lab JSON → Standard JSON (TOR switches) | +| Convert | `src/convertors/convertors_bmc_switch_json.py` | Lab JSON → Standard JSON (BMC switches, optional) | +| Generate | `src/generator.py` | Standard JSON + Jinja2 → `.cfg` output files | +| Constants | `src/constants.py` | All magic strings, defaults, lookup tables | +| Utilities | `src/utils.py` | Shared helpers (IP math, etc.) | + +## Key Design Principles + +1. **Unified, generic implementation** — templates and converter logic are parameterized + and data-driven. No sample-specific or model-specific code branches. +2. **Data-driven** — port counts, VLAN IDs, ASNs, IPs, hostnames come from input JSON. + Only structural constants (fixed port roles) are hardcoded. +3. **TOR = production-quality, BMC = internal-minimal** — TOR code must be fully + parameterized. BMC code may hardcode settings but must have clear comments. +4. **BMC is optional** — BMC configs are only generated when a `Type: "BMC"` entry + exists in the input JSON. No BMC entry → only TOR configs. +5. **Refactor freely** — we're on a dev branch; breaking changes are fine with tests. + +## Code Conventions + +- **Package imports**: `src/` is a proper Python package with `__init__.py`. + Use relative imports within `src/` (e.g., `from .constants import CISCO`). +- **Constants**: ALL magic strings, VLAN maps, template dicts live in `src/constants.py`. + Never hardcode values directly in converter or generator code. +- **Path handling**: Use `pathlib.Path` everywhere, never `os.path`. + Use `get_real_path()` from `loader.py` for PyInstaller compatibility (`sys._MEIPASS`). +- **Logging**: Use `logging` module, never `print()`. Get logger via `logging.getLogger(__name__)`. +- **Type hints**: Use `from __future__ import annotations` and modern type hints + (`dict[str, str]` not `Dict[str, str]`). +- **Deep-copy templates**: In-code JSON templates (`SWITCH_TEMPLATE`, `SVI_TEMPLATE`, etc.) + must be deep-copied before mutation — never modify the module-level constant. + +## File Layout + +``` +src/ +├── __init__.py +├── main.py # CLI entry point +├── generator.py # Jinja2 template rendering +├── loader.py # File loading, path resolution +├── constants.py # All constants, lookup tables +├── utils.py # Shared utilities +└── convertors/ + ├── __init__.py + ├── convertors_lab_switch_json.py # TOR converter (StandardJSONBuilder) + └── convertors_bmc_switch_json.py # BMC converter (BMCSwitchConverter) + +input/ +├── standard_input.json # Example standard-format input +├── jinja2_templates/ +│ ├── cisco/nxos/ # 10 templates: bgp, interface, login, port_channel, ... +│ └── dellemc/os10/ # 11 templates: same + vlt.j2 +└── switch_interface_templates/ + ├── cisco/ # Per-model port layouts (93180YC-FX.json, etc.) + └── dellemc/ # Per-model port layouts (s5248f-on.json, etc.) + +tests/ +├── conftest.py # Shared fixtures, helpers, pytest hooks +├── test_unit.py # Unit tests for StandardJSONBuilder methods +├── test_convertors.py # Golden-file integration tests (converter pipeline) +├── test_generator.py # Golden-file integration tests (generator pipeline) +└── test_cases/ # Test data (input JSON + expected outputs) +``` + +## Testing Rules + +- **Framework**: `pytest` — run with `python -m pytest tests/ -v`. +- **Three test files**: `test_unit.py` (unit), `test_convertors.py` (converter integration), + `test_generator.py` (generator integration). +- **Golden-file pattern**: Converter and generator tests compare output against expected + files in `tests/test_cases//expected_outputs/`. +- **Unit tests**: Use small synthetic inputs, test one method at a time. Use `tmp_path` + fixture for any file I/O. No global state, no side effects at import time. +- **Fixtures in `conftest.py`**: Shared fixtures, `load_json()`, `find_json_differences()`. +- **New features need tests**: Every converter method, template change, or bug fix + should have corresponding test coverage. + +## Template Conventions + +- **Jinja2 templates** live in `input/jinja2_templates///`. + Template names match config sections: `bgp.j2`, `vlan.j2`, `interface.j2`, etc. +- **Switch interface templates** live in `input/switch_interface_templates//`. + These are JSON files defining per-model port layouts (which physical ports get which roles). +- Templates use guards (e.g., `{% if port_channels %}`) so they render safely for any + switch type — a BMC switch with no BGP section produces empty BGP output, not an error. + +## Build & Release + +- **PyInstaller** builds cross-platform executables (Windows + Linux). +- **CI/CD** runs pytest → PyInstaller build → GitHub Release (tag-based with environment approval). +- **Python 3.12** is the target version for CI and dev container. diff --git a/.github/workflows/build-switchgentool.yml b/.github/workflows/build-switchgentool.yml index c608da9..f595cf0 100644 --- a/.github/workflows/build-switchgentool.yml +++ b/.github/workflows/build-switchgentool.yml @@ -2,7 +2,7 @@ name: Build Switch Config Generator Tool on: push: - branches: [ main, dev/nl/newDesignv1 ] + branches: [ main ] tags: [ 'v*' ] paths: - 'src/**' @@ -20,16 +20,50 @@ on: - '.github/workflows/build-switchgentool.yml' workflow_dispatch: +# ── Test job needs read; release job needs write (scoped per-job) ───────── permissions: contents: read actions: read +# Cancel in-flight runs for the same branch/PR (tags always run to completion) +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/') }} + jobs: + # ════════════════════════════════════════════════════════════════════════ + # Job 1: Test — run full pytest suite + # ════════════════════════════════════════════════════════════════════════ + test: + name: Test (pytest) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: 'pip' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run tests + run: python -m pytest tests/ -v --tb=short + + # ════════════════════════════════════════════════════════════════════════ + # Job 2: Build — PyInstaller cross-platform executables + # ════════════════════════════════════════════════════════════════════════ build: name: Build on ${{ matrix.os }} + needs: test runs-on: ${{ matrix.os }} strategy: - fail-fast: false + fail-fast: true matrix: include: - os: windows-latest @@ -46,7 +80,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' cache: 'pip' - name: Install build tools (Linux only) @@ -55,22 +89,13 @@ jobs: sudo apt-get update sudo apt-get install -y upx - - name: Ensure requirements + - name: Install dependencies shell: bash run: | python -m pip install --upgrade pip - if [ ! -f requirements.txt ]; then - echo "jinja2>=3.0.0" > requirements.txt - fi pip install -r requirements.txt pip install "pyinstaller==6.11.*" - - name: Quick source test (run as script) - shell: bash - run: | - python -c "import sys; print(sys.version)" - python src/main.py --help - - name: Build (Windows) if: matrix.os == 'windows-latest' shell: powershell @@ -107,19 +132,15 @@ jobs: run: | chmod +x "dist/${{ matrix.exe_name }}" || true "dist/${{ matrix.exe_name }}" --help || (echo "Executable failed to run" && exit 1) - - - name: Test BMC converter module inclusion + + - name: Verify BMC converter module inclusion shell: bash run: | python -c " import sys sys.path.insert(0, 'src') - try: - from convertors.convertors_bmc_switch_json import convert_bmc_switches - print('[OK] BMC converter module can be imported') - except ImportError as e: - print('[ERROR] BMC converter module import failed:', e) - sys.exit(1) + from convertors.convertors_bmc_switch_json import convert_bmc_switches + print('[OK] BMC converter module can be imported') " - name: Stage artifact @@ -135,47 +156,57 @@ jobs: name: ${{ matrix.asset_name }} path: artifact_staging/ - # release: - # name: Create Release - # needs: build - # runs-on: ubuntu-latest - # if: startsWith(github.ref, 'refs/tags/v') - # steps: - # - name: Checkout - # uses: actions/checkout@v4 - - # - name: Download artifacts - # uses: actions/download-artifact@v4 - # with: - # path: ./artifacts - - # - name: Show downloaded files - # run: ls -Rla ./artifacts - - # - name: Create GitHub Release - # uses: softprops/action-gh-release@v2 - # with: - # files: | - # ./artifacts/network-config-generator-windows-amd64/network_config_generator.exe - # ./artifacts/network-config-generator-linux-amd64/network_config_generator - # body: | - # ## Network Switch Config Generator ${{ github.ref_name }} - - # ### Download - # 1) Grab the file for your OS - # 2) (Linux) Make it executable: `chmod +x network_config_generator` - # 3) Run: `./network_config_generator --help` - - # ### Usage - # ```bash - # ./network_config_generator --input_json lab_input.json --output_folder output/ - # ./network_config_generator --input_json standard_input.json --output_folder output/ - # ./network_config_generator --input_json lab_input.json --convertor my.custom.convertor - # ``` - - # ### Features - # - Auto-detects input format (lab vs standard) - # - Converts lab format to standard automatically - # - Generates network switch configurations - # - Custom convertors & multi-switch support - # - Cross-platform executables + # ════════════════════════════════════════════════════════════════════════ + # Job 3: Release — create GitHub Release (tag pushes only) + # ════════════════════════════════════════════════════════════════════════ + release: + name: Create Release + needs: build + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + + # Require approval via GitHub Environment before publishing + environment: production + + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + path: ./artifacts + + - name: Show downloaded files + run: ls -Rla ./artifacts + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: | + ./artifacts/network-config-generator-windows-amd64/network_config_generator.exe + ./artifacts/network-config-generator-linux-amd64/network_config_generator + body: | + ## Network Switch Config Generator ${{ github.ref_name }} + + ### Download + 1) Grab the file for your OS + 2) (Linux) Make it executable: `chmod +x network_config_generator` + 3) Run: `./network_config_generator --help` + + ### Usage + ```bash + ./network_config_generator --input_json lab_input.json --output_folder output/ + ./network_config_generator --input_json standard_input.json --output_folder output/ + ./network_config_generator --input_json lab_input.json --convertor my.custom.convertor + ``` + + ### Features + - Auto-detects input format (lab vs standard) + - Converts lab format to standard automatically + - Generates network switch configurations + - Custom convertors & multi-switch support + - Cross-platform executables diff --git a/.github/workflows/triage-submissions.yml b/.github/workflows/triage-submissions.yml index 3214c44..1880d2b 100644 --- a/.github/workflows/triage-submissions.yml +++ b/.github/workflows/triage-submissions.yml @@ -7,6 +7,9 @@ on: issues: types: [opened, edited] +permissions: + issues: write + jobs: validate-and-assign: # Only run for config submissions @@ -71,16 +74,23 @@ jobs: const spamPatterns = [ /