Compare commits
10 Commits
229bef99f6
...
686cd6d715
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
686cd6d715 | ||
|
|
acb3a6291c | ||
|
|
9c90279868 | ||
|
|
2ea056aa17 | ||
|
|
a617bd6ecd | ||
|
|
0ef5e7798a | ||
|
|
1bc01c9c1b | ||
|
|
170a2ebf85 | ||
|
|
168111e23c | ||
|
|
d329ddc4ad |
@@ -67,6 +67,19 @@ class BaseDevice(ABC):
|
||||
"""
|
||||
return self.raw.get("system", None)
|
||||
|
||||
@staticmethod
|
||||
def _as_list(data) -> list:
|
||||
"""Normalize a TTP group result to a list.
|
||||
|
||||
TTP returns a single dict when a group matches exactly one entry and a
|
||||
list when it matches several. Callers always expect a list.
|
||||
"""
|
||||
if data is None:
|
||||
return []
|
||||
if isinstance(data, dict):
|
||||
return [data]
|
||||
return data
|
||||
|
||||
def _validate_contract(self) -> dict:
|
||||
if self.raw is None:
|
||||
msg = (
|
||||
@@ -76,7 +89,7 @@ class BaseDevice(ABC):
|
||||
)
|
||||
raise OxiAPIError(msg, status_code=404)
|
||||
system_data = self.system()
|
||||
interfaces_data = self.interfaces() or []
|
||||
interfaces_data = self._as_list(self.interfaces())
|
||||
result = {
|
||||
"system": System(**system_data),
|
||||
"interfaces": [Interfaces(**item) for item in interfaces_data],
|
||||
@@ -89,7 +102,7 @@ class BaseDevice(ABC):
|
||||
f"{self.__class__.__name__}: template '{self.template}' declares optional group "
|
||||
f"'vlans', but TTP did not return it."
|
||||
)
|
||||
vlans_data = self.vlans() or []
|
||||
vlans_data = self._as_list(self.vlans())
|
||||
result["vlans"] = [Vlans(**item) for item in vlans_data]
|
||||
return result
|
||||
|
||||
|
||||
@@ -1,29 +1,6 @@
|
||||
from oxi.interfaces import register_parser
|
||||
from oxi.interfaces.base import BaseDevice
|
||||
|
||||
|
||||
def _expand_vlan_range(value: str | list[str]) -> list[str]:
|
||||
if isinstance(value, list):
|
||||
value = ",".join(str(item) for item in value)
|
||||
|
||||
result: list[str] = []
|
||||
for part in value.split(","):
|
||||
part = part.strip()
|
||||
if not part:
|
||||
continue
|
||||
if "-" not in part:
|
||||
result.append(part)
|
||||
continue
|
||||
start_s, end_s = part.split("-", 1)
|
||||
try:
|
||||
start, end = int(start_s), int(end_s)
|
||||
except ValueError:
|
||||
result.append(part)
|
||||
continue
|
||||
if start > end:
|
||||
start, end = end, start
|
||||
result.extend(str(vlan_id) for vlan_id in range(start, end + 1))
|
||||
return result
|
||||
from oxi.interfaces.utils import expand_vlan_range
|
||||
|
||||
|
||||
@register_parser("eltex")
|
||||
@@ -54,15 +31,8 @@ class Eltex(BaseDevice):
|
||||
tail = item.get("vlan_tail")
|
||||
if tail:
|
||||
ids = [*ids, tail] if isinstance(ids, list) else f"{ids},{tail}"
|
||||
for vid in _expand_vlan_range(ids):
|
||||
for vid in expand_vlan_range(ids):
|
||||
if vid in named_vlan:
|
||||
continue
|
||||
vlans.append({"vlan_id": vid})
|
||||
return vlans
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("./test_not_found.txt") as file:
|
||||
data = file.read()
|
||||
eltex = Eltex(data)
|
||||
print(eltex.parse())
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
from ipaddress import ip_interface
|
||||
from oxi.interfaces import register_parser
|
||||
from oxi.interfaces.base import BaseDevice
|
||||
from oxi.interfaces.utils import decode_utf
|
||||
|
||||
|
||||
@register_parser(["NDMS", "keenetic", "KeeneticOS"])
|
||||
class Keenetic(BaseDevice):
|
||||
template = "keenetic.ttp"
|
||||
|
||||
def _decode_utf(self, text: str):
|
||||
if "\\x" in text:
|
||||
desc = text.strip('"')
|
||||
decoded = (
|
||||
desc.encode("utf-8")
|
||||
.decode("unicode_escape")
|
||||
.encode("latin1")
|
||||
.decode("utf-8")
|
||||
)
|
||||
return decoded
|
||||
return text
|
||||
|
||||
def interfaces(self):
|
||||
interfaces: list[dict] = self.raw["interfaces"]
|
||||
for item in interfaces:
|
||||
@@ -29,7 +18,7 @@ class Keenetic(BaseDevice):
|
||||
item["mask"] = ipaddress.network.prefixlen
|
||||
item.pop("netmask", "Key not found")
|
||||
if item.get("description"):
|
||||
decoded = self._decode_utf(item.get("description", ""))
|
||||
decoded = decode_utf(item.get("description", ""))
|
||||
item["description"] = decoded
|
||||
return interfaces
|
||||
|
||||
@@ -37,13 +26,6 @@ class Keenetic(BaseDevice):
|
||||
vlans = self.raw["vlans"]
|
||||
for item in vlans:
|
||||
if item.get("description"):
|
||||
decoded = self._decode_utf(item.get("description", ""))
|
||||
decoded = decode_utf(item.get("description", ""))
|
||||
item["description"] = decoded
|
||||
return vlans
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("./test2.txt") as file:
|
||||
data = file.read()
|
||||
mikr = Keenetic(data)
|
||||
print(mikr.parse().model_dump_json())
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import os
|
||||
from oxi.interfaces import register_parser
|
||||
from oxi.interfaces.base import BaseDevice
|
||||
|
||||
@@ -6,11 +5,3 @@ from oxi.interfaces.base import BaseDevice
|
||||
@register_parser(["routeros", "ros", "mikrotik"])
|
||||
class Mikrotik(BaseDevice):
|
||||
template = "mikrotik.ttp"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(os.path.abspath(os.curdir))
|
||||
with open("./test.txt") as file:
|
||||
data = file.read()
|
||||
mikr = Mikrotik(data)
|
||||
print(mikr.parse().json())
|
||||
|
||||
@@ -1,32 +1,6 @@
|
||||
from oxi.interfaces import register_parser
|
||||
from oxi.interfaces.base import BaseDevice
|
||||
|
||||
|
||||
def _expand_vlan_range(value: str | list[str]) -> list[str]:
|
||||
"""Expand values like '1,7,14-15' into individual VLAN IDs."""
|
||||
if isinstance(value, list):
|
||||
value = ",".join(str(item) for item in value)
|
||||
|
||||
result: list[str] = []
|
||||
if not value:
|
||||
return result
|
||||
for part in value.split(","):
|
||||
part = part.strip()
|
||||
if not part:
|
||||
continue
|
||||
if "-" in part:
|
||||
start_s, end_s = part.split("-", 1)
|
||||
try:
|
||||
start, end = int(start_s), int(end_s)
|
||||
except ValueError:
|
||||
result.append(part)
|
||||
continue
|
||||
if start > end:
|
||||
start, end = end, start
|
||||
result.extend(str(i) for i in range(start, end + 1))
|
||||
else:
|
||||
result.append(part)
|
||||
return result
|
||||
from oxi.interfaces.utils import expand_vlan_range
|
||||
|
||||
|
||||
@register_parser(["QTECH"])
|
||||
@@ -48,21 +22,8 @@ class Qtech(BaseDevice):
|
||||
tail = item.get("vlan_tail")
|
||||
if tail:
|
||||
ids = [*ids, tail] if isinstance(ids, list) else f"{ids},{tail}"
|
||||
for vid in _expand_vlan_range(ids):
|
||||
for vid in expand_vlan_range(ids):
|
||||
if vid in named_vlan:
|
||||
continue
|
||||
vlans.append({"vlan_id": vid})
|
||||
return vlans
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("./test3.txt") as file:
|
||||
data = file.read()
|
||||
qtech = Qtech(data)
|
||||
qt = qtech.parse()
|
||||
print(qt)
|
||||
with open("./test3-1.txt") as file:
|
||||
data = file.read()
|
||||
qtech = Qtech(data)
|
||||
qt = qtech.parse()
|
||||
print(qt)
|
||||
|
||||
@@ -21,17 +21,3 @@ class Quasar(BaseDevice):
|
||||
if ether_interface:
|
||||
interfaces.append(ether_interface)
|
||||
return interfaces
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("./test7.txt") as file:
|
||||
data = file.read()
|
||||
quasar = Quasar(data)
|
||||
qt = quasar.parse()
|
||||
print(qt)
|
||||
print()
|
||||
with open("./test8.txt") as file:
|
||||
data = file.read()
|
||||
quasar = Quasar(data)
|
||||
qt = quasar.parse()
|
||||
print(qt)
|
||||
|
||||
@@ -26,6 +26,8 @@ Active-image: {{ ignore }} {{ _start_ }}
|
||||
<group name="interfaces">
|
||||
interface {{ interface | ORPHRASE }}
|
||||
ip address {{ ip_address }} {{ mask | to_cidr }}
|
||||
name {{ description }}
|
||||
description {{ description }}
|
||||
</group>
|
||||
|
||||
<group name="vlans">
|
||||
|
||||
@@ -42,6 +42,6 @@ add comment={{ comment | _start_ | ORPHRASE | exclude("disabled=") | strip('"')}
|
||||
## disabled with comment with/without quotes
|
||||
add comment={{ comment | _start_ | ORPHRASE | exclude("disabled=") | strip('"')}} disabled={{ disabled | replace("yes","True") | strip('"') }} interface={{ interface }} name={{ name | ORPHRASE | strip('"') }} vlan-id={{ vlan_id }}
|
||||
## disabled no comment
|
||||
add interface={{ interface | _start_ }} name={{ name | ORPHRASE | strip('"') }} vlan-id={{ vlan_id }} disabled={{ disabled | replace("yes","True") | strip('"') }}
|
||||
add disabled={{ disabled | _start_ | replace("yes","True") | strip('"') }} interface={{ interface }} name={{ name | ORPHRASE | strip('"') }} vlan-id={{ vlan_id }}
|
||||
</group>
|
||||
|
||||
|
||||
55
tests/fixtures/eltex/config.conf
vendored
Normal file
55
tests/fixtures/eltex/config.conf
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
!
|
||||
Active-image: flash://system/images/mes3300-669-3R3.ros
|
||||
! Version: 6.6.9.3
|
||||
! Commit: 3a5c2e39
|
||||
! Build: 3 (master)
|
||||
! MD5 Digest: 7bc289cc18be560954bd5cb0afd9b2d5
|
||||
! Date: 22-Sep-2025
|
||||
! Time: 12:38:20
|
||||
! Inactive-image: flash://system/images/_image1.bin
|
||||
! Version: 6.6.2
|
||||
! Commit: 3ebc7503
|
||||
! Build: 5 (master)
|
||||
! MD5 Digest: a3f15a788c97c71e07e90d84c0ff3b12
|
||||
! Date: 20-Nov-2023
|
||||
! Time: 16:39:20
|
||||
!
|
||||
! Unit MAC address Hardware version Serial number
|
||||
! ---- ----------------- ---------------- -------------
|
||||
! 1 90:54:b7:6b:9d:40 01.01.01 ESG7007778
|
||||
! 2 90:54:b7:6b:bb:80 01.01.01 ESG7007777
|
||||
!
|
||||
!
|
||||
!
|
||||
interface TenGigabitEthernet1/0/2
|
||||
shutdown
|
||||
description FREE
|
||||
storm-control broadcast pps 3000
|
||||
storm-control multicast pps 3000
|
||||
exit
|
||||
!
|
||||
interface TenGigabitEthernet1/0/11
|
||||
shutdown
|
||||
description FREE
|
||||
storm-control broadcast pps 3000
|
||||
storm-control multicast pps 3000
|
||||
exit
|
||||
!
|
||||
interface vlan 1700
|
||||
name sw-test_HW
|
||||
ip address 13.36.8.1 255.255.255.0
|
||||
exit
|
||||
!
|
||||
vlan database
|
||||
vlan 114-115,120,130,414,610,999-1000,1701-1703,1705,1801,2001,2011
|
||||
vlan 2021-2022,3157-3158,3333-3334
|
||||
exit
|
||||
!
|
||||
interface vlan 666
|
||||
name test
|
||||
exit
|
||||
!
|
||||
interface vlan 777
|
||||
name test2
|
||||
exit
|
||||
!
|
||||
137
tests/fixtures/eltex/config.expected.json
vendored
Normal file
137
tests/fixtures/eltex/config.expected.json
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
{
|
||||
"system": {
|
||||
"model": "",
|
||||
"serial_number": "ESG7007778",
|
||||
"version": "6.6.9.3"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": "TenGigabitEthernet1/0/2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "FREE"
|
||||
},
|
||||
{
|
||||
"interface": "TenGigabitEthernet1/0/11",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "FREE"
|
||||
},
|
||||
{
|
||||
"interface": "vlan 1700",
|
||||
"ip_address": "13.36.8.1",
|
||||
"mask": 24,
|
||||
"description": "sw-test_HW"
|
||||
},
|
||||
{
|
||||
"interface": "vlan 666",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "test"
|
||||
},
|
||||
{
|
||||
"interface": "vlan 777",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "test2"
|
||||
}
|
||||
],
|
||||
"vlans": [
|
||||
{
|
||||
"vlan_id": 1700,
|
||||
"description": "sw-test_HW"
|
||||
},
|
||||
{
|
||||
"vlan_id": 114,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 115,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 120,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 130,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 414,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 610,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 999,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 1000,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 1701,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 1702,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 1703,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 1705,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 1801,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2001,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2011,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2021,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2022,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 3157,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 3158,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 3333,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 3334,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 666,
|
||||
"description": "test"
|
||||
},
|
||||
{
|
||||
"vlan_id": 777,
|
||||
"description": "test2"
|
||||
}
|
||||
]
|
||||
}
|
||||
1
tests/fixtures/eltex/not_found.conf
vendored
Normal file
1
tests/fixtures/eltex/not_found.conf
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node not found
|
||||
38
tests/fixtures/huawei/config.conf
vendored
Normal file
38
tests/fixtures/huawei/config.conf
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# Huawei Versatile Routing Platform Software
|
||||
# VRP (R) software, Version 5.170 (S5731 V200R019C00SPC500)
|
||||
# Copyright (C) 2000-2019 HUAWEI TECH Co., Ltd.
|
||||
#
|
||||
# DDR Memory Size : 4096 M bytes
|
||||
# FLASH Total Memory Size : 1024 M bytes
|
||||
# FLASH Available Memory Size : 739 M bytes
|
||||
# Pcb Version : VER.B
|
||||
# BootROM Version : 0000.04e4
|
||||
# BootLoad Version : 0213.0000
|
||||
# CPLD Version : 0104
|
||||
# Software Version : VRP (R) Software, Version 5.170 (V200R019C00SPC500)
|
||||
# FLASH Version : 0000.0000
|
||||
# PWR1 information
|
||||
# Pcb Version : PWR VER.D
|
||||
# PWR2 information
|
||||
# Pcb Version : PWR VER.D
|
||||
# FAN1 information
|
||||
# Pcb Version : NA
|
||||
# FAN2 information
|
||||
# Pcb Version : NA
|
||||
# ESN of slot 1: 102266666666
|
||||
# ESN of slot 2: 102288888888
|
||||
interface GigabitEthernet0/0/33
|
||||
port link-type access
|
||||
port default vlan 101
|
||||
loopback-detect enable
|
||||
stp disable
|
||||
storm-control broadcast min-rate 1500 max-rate 2500
|
||||
storm-control multicast min-rate 1000 max-rate 2000
|
||||
storm-control action error-down
|
||||
#
|
||||
interface Vlanif120
|
||||
description SSH
|
||||
ip address 10.26.196.254 255.255.255.0
|
||||
#
|
||||
vlan batch 13 26 101 to 103 110 120 130 201 to 204 209 to 212 350 360
|
||||
#
|
||||
95
tests/fixtures/huawei/config.expected.json
vendored
Normal file
95
tests/fixtures/huawei/config.expected.json
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
{
|
||||
"system": {
|
||||
"model": "S5731",
|
||||
"serial_number": "102266666666",
|
||||
"version": "5.170"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": "GigabitEthernet0/0/33",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "Vlanif120",
|
||||
"ip_address": "10.26.196.254",
|
||||
"mask": 24,
|
||||
"description": "SSH"
|
||||
}
|
||||
],
|
||||
"vlans": [
|
||||
{
|
||||
"vlan_id": 13,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 26,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 101,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 102,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 103,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 110,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 120,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 130,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 201,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 202,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 203,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 204,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 209,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 210,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 211,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 212,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 350,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 360,
|
||||
"description": null
|
||||
}
|
||||
]
|
||||
}
|
||||
341
tests/fixtures/keenetic/config.conf
vendored
Normal file
341
tests/fixtures/keenetic/config.conf
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
!
|
||||
! release: 4.03.C.6.2-7
|
||||
! sandbox: stable
|
||||
! title: 4.3.6.2
|
||||
! arch: mips
|
||||
!
|
||||
! ndm:
|
||||
! exact: 0-a3057529fd
|
||||
! cdate: 29 Sep 2025
|
||||
!
|
||||
! bsp:
|
||||
! exact: 0-03b50470c4
|
||||
! cdate: 30 Sep 2025
|
||||
!
|
||||
! ndw:
|
||||
! features: dual_image,led_control,wifi_button,wifi5ghz,
|
||||
! vht2ghz,mimo2ghz,mimo5ghz,atf2ghz,atf5ghz,wifi6,wifi_ft,
|
||||
! wpa3,hwnat
|
||||
! components: base,cloudcontrol,corewireless,ddns,dhcpd,
|
||||
! dns-filter,dns-https,dns-tls,dot1x,easyconfig,igmp,ip6,
|
||||
! lang-en,lang-ru,miniupnpd,mws,nathelper-ftp,nathelper-
|
||||
! h323,nathelper-pptp,nathelper-rtsp,nathelper-sip,ndmp,
|
||||
! ndns,openvpn,pingcheck,ppe,pppoe,pptp,ssh,trafficcontrol,
|
||||
! wireguard
|
||||
!
|
||||
! ndw3:
|
||||
! version: 1.101.18.1
|
||||
!
|
||||
! ndw4:
|
||||
! version: 4.3.C.6.2
|
||||
!
|
||||
! manufacturer: Keenetic Ltd.
|
||||
! vendor: Keenetic
|
||||
! series: KN
|
||||
! model: Sprinter (KN-3710)
|
||||
! hw_version: 7777777
|
||||
! hw_type: router
|
||||
! hw_id: KN-3710
|
||||
! device: Sprinter
|
||||
! region: EA
|
||||
! description: Keenetic Sprinter (KN-3710)
|
||||
! $$$ Agent: http/rci
|
||||
! $$$ Last change: Fri, 3 Oct 2025 18:37:40 GMT
|
||||
! $$$ Model: Keenetic Sprinter
|
||||
! $$$ Username: admin
|
||||
! $$$ Version: 2.06.1
|
||||
system
|
||||
set net.ipv4.ip_forward 1
|
||||
set net.ipv4.neigh.default.gc_thresh1 256
|
||||
set net.ipv4.neigh.default.gc_thresh2 1024
|
||||
set net.ipv4.neigh.default.gc_thresh3 2048
|
||||
set net.ipv4.tcp_fin_timeout 30
|
||||
set net.ipv4.tcp_keepalive_time 120
|
||||
set net.ipv6.conf.all.forwarding 1
|
||||
set net.ipv6.neigh.default.gc_thresh1 256
|
||||
set net.ipv6.neigh.default.gc_thresh2 1024
|
||||
set net.ipv6.neigh.default.gc_thresh3 2048
|
||||
set net.netfilter.nf_conntrack_tcp_timeout_established 1200
|
||||
set vm.overcommit_memory 0
|
||||
set vm.vfs_cache_pressure 1000
|
||||
clock timezone Europe/Berlin
|
||||
domainname WORKGROUP
|
||||
hostname test_HW
|
||||
caption default
|
||||
description "Keenetic Sprinter (KN-3710)"
|
||||
ndss dump-report disable
|
||||
!
|
||||
dyndns profile _WEBADMIN
|
||||
!
|
||||
interface GigabitEthernet0
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/1
|
||||
rename 1
|
||||
switchport mode access
|
||||
switchport access vlan 1
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/2
|
||||
rename 2
|
||||
switchport mode access
|
||||
switchport access vlan 1
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/3
|
||||
rename 3
|
||||
switchport mode access
|
||||
switchport access vlan 1
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/Vlan1
|
||||
description "Home VLAN"
|
||||
ip dhcp client dns-routes
|
||||
ip name-servers
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/Vlan2
|
||||
rename ISP
|
||||
description "\xd0\x9f\xd0\xbe\xd0\xb4\xd0\xba\xd0\xbb\xd1\x8e\xd1\x87\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5 Ethernet"
|
||||
dyndns nobind
|
||||
mac address factory wan
|
||||
security-level public
|
||||
ip address dhcp
|
||||
ip dhcp client hostname test_HW
|
||||
ip dhcp client dns-routes
|
||||
ip mtu 1500
|
||||
ip access-group _WEBADMIN_ISP in
|
||||
ip global 57342
|
||||
ip no name-servers
|
||||
igmp upstream
|
||||
ipv6 address auto
|
||||
ipv6 prefix auto
|
||||
ipv6 no name-servers auto
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/0
|
||||
rename 0
|
||||
role inet for ISP
|
||||
switchport mode access
|
||||
switchport access vlan 2
|
||||
up
|
||||
!
|
||||
interface GigabitEthernet0/Vlan3
|
||||
dyndns nobind
|
||||
ip dhcp client dns-routes
|
||||
ip name-servers
|
||||
up
|
||||
!
|
||||
interface WifiMaster0
|
||||
country-code RU
|
||||
compatibility BGN+AX
|
||||
rekey-interval 86400
|
||||
up
|
||||
!
|
||||
interface WifiMaster0/AccessPoint0
|
||||
mac access-list type none
|
||||
authentication wpa-psk ns3 7777ggggddddsss
|
||||
encryption enable
|
||||
encryption wpa2
|
||||
ip dhcp client dns-routes
|
||||
ssid test_HW_2.4G
|
||||
up
|
||||
!
|
||||
interface WifiMaster0/AccessPoint1
|
||||
mac access-list type none
|
||||
security-level private
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
down
|
||||
!
|
||||
interface WifiMaster0/AccessPoint2
|
||||
mac access-list type none
|
||||
security-level private
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
down
|
||||
!
|
||||
interface WifiMaster0/WifiStation0
|
||||
security-level public
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
standby enable
|
||||
standby timeout 600
|
||||
down
|
||||
!
|
||||
interface WifiMaster1
|
||||
country-code RU
|
||||
compatibility AN+AC+AX
|
||||
channel width 40-above/80
|
||||
rekey-interval 86400
|
||||
up
|
||||
!
|
||||
interface WifiMaster1/AccessPoint0
|
||||
mac access-list type none
|
||||
authentication wpa-psk ns3 7777ggggddddsss
|
||||
encryption enable
|
||||
encryption wpa2
|
||||
ip dhcp client dns-routes
|
||||
ssid test_HW_5G
|
||||
up
|
||||
!
|
||||
interface WifiMaster1/AccessPoint1
|
||||
mac access-list type none
|
||||
security-level private
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
down
|
||||
!
|
||||
interface WifiMaster1/AccessPoint2
|
||||
mac access-list type none
|
||||
security-level private
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
down
|
||||
!
|
||||
interface WifiMaster1/WifiStation0
|
||||
security-level public
|
||||
encryption no enable
|
||||
ip dhcp client dns-routes
|
||||
standby enable
|
||||
standby timeout 600
|
||||
down
|
||||
!
|
||||
interface Bridge0
|
||||
rename Home
|
||||
description "Home network"
|
||||
dyndns nobind
|
||||
include GigabitEthernet0/Vlan1
|
||||
include WifiMaster0/AccessPoint0
|
||||
include WifiMaster1/AccessPoint0
|
||||
mac access-list type none
|
||||
security-level private
|
||||
ip address 17.36.1.1 255.255.255.0
|
||||
ip dhcp client dns-routes
|
||||
ip access-group _WEBADMIN_Home in
|
||||
ip name-servers
|
||||
band-steering
|
||||
up
|
||||
!
|
||||
interface Bridge1
|
||||
rename Guest
|
||||
description "Guest network"
|
||||
traffic-shape rate 5120
|
||||
dyndns nobind
|
||||
include GigabitEthernet0/Vlan3
|
||||
mac access-list type none
|
||||
peer-isolation
|
||||
security-level protected
|
||||
ip address 10.1.30.1 255.255.255.0
|
||||
ip dhcp client dns-routes
|
||||
ip name-servers
|
||||
down
|
||||
!
|
||||
interface Bridge2
|
||||
rename Test
|
||||
mac access-list type none
|
||||
security-level public
|
||||
ip dhcp client dns-routes
|
||||
up
|
||||
!
|
||||
interface OpenVPN0
|
||||
description test_HW-udp
|
||||
role misc
|
||||
security-level public
|
||||
ip dhcp client dns-routes
|
||||
ip tcp adjust-mss pmtu
|
||||
ip name-servers
|
||||
ipv6 name-servers auto
|
||||
openvpn accept-routes
|
||||
openvpn connect
|
||||
up
|
||||
!
|
||||
interface OpenVPN2
|
||||
description test_HW-tcp
|
||||
role misc
|
||||
dyndns nobind
|
||||
security-level public
|
||||
ip dhcp client dns-routes
|
||||
ip tcp adjust-mss pmtu
|
||||
openvpn accept-routes
|
||||
openvpn connect
|
||||
down
|
||||
!
|
||||
interface Wireguard0
|
||||
description test_HW
|
||||
dyndns nobind
|
||||
security-level public
|
||||
ip address 10.3.100.1 255.255.255.0
|
||||
ip mtu 1324
|
||||
ip tcp adjust-mss pmtu
|
||||
wireguard listen-port 65513
|
||||
wireguard peer 7777ggggddddsss= !test_HW
|
||||
allow-ips 0.0.0.0 0.0.0.0
|
||||
connect
|
||||
!
|
||||
up
|
||||
!
|
||||
interface Wireguard1
|
||||
description test_HW
|
||||
dyndns nobind
|
||||
security-level private
|
||||
ip address 10.1.100.1 255.255.255.0
|
||||
ip mtu 1324
|
||||
ip access-group _WEBADMIN_Wireguard1 in
|
||||
ip tcp adjust-mss pmtu
|
||||
wireguard listen-port 65511
|
||||
wireguard peer 7777ggggddddsss= !test_HW
|
||||
allow-ips 10.1.100.0 255.255.255.0
|
||||
allow-ips 17.36.3.0 255.255.255.0
|
||||
allow-ips 17.36.1.0 255.255.255.0
|
||||
allow-ips 0.0.0.0 0.0.0.0
|
||||
connect
|
||||
!
|
||||
up
|
||||
!
|
||||
interface Wireguard2
|
||||
description test_HW
|
||||
dyndns nobind
|
||||
security-level private
|
||||
ip address 10.2.100.1 255.255.255.0
|
||||
ip access-group _WEBADMIN_Wireguard2 in
|
||||
ip tcp adjust-mss pmtu
|
||||
wireguard listen-port 65512
|
||||
wireguard peer 7777ggggddddsss= !test_HW
|
||||
allow-ips 0.0.0.0 0.0.0.0
|
||||
connect
|
||||
!
|
||||
up
|
||||
!
|
||||
ip ssh
|
||||
port 22
|
||||
security-level public
|
||||
lockout-policy 5 15 3
|
||||
!
|
||||
ip hotspot
|
||||
policy Home permit
|
||||
host 7777ggggddddsss permit
|
||||
host 7777ggggddddsss priority 4
|
||||
!
|
||||
ipv6 subnet Default
|
||||
bind Home
|
||||
mode slaac
|
||||
prefix length 64
|
||||
number 0
|
||||
!
|
||||
ppe software
|
||||
ppe hardware
|
||||
upnp lan Home
|
||||
service dhcp
|
||||
service dns-proxy
|
||||
service http
|
||||
service telnet
|
||||
service ssh
|
||||
service ntp
|
||||
service upnp
|
||||
!
|
||||
easyconfig disable
|
||||
components
|
||||
auto-update disable
|
||||
auto-update channel stable
|
||||
!
|
||||
161
tests/fixtures/keenetic/config.expected.json
vendored
Normal file
161
tests/fixtures/keenetic/config.expected.json
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
{
|
||||
"system": {
|
||||
"model": "Sprinter (KN-3710)",
|
||||
"serial_number": "7777777",
|
||||
"version": "4.03.C.6.2-7"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": "GigabitEthernet0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "GigabitEthernet0/1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "GigabitEthernet0/2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "GigabitEthernet0/3",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "GigabitEthernet0/0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0/AccessPoint0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0/AccessPoint1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0/AccessPoint2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster0/WifiStation0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1/AccessPoint0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1/AccessPoint1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1/AccessPoint2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "WifiMaster1/WifiStation0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "Bridge0",
|
||||
"ip_address": "17.36.1.1",
|
||||
"mask": 24,
|
||||
"description": "Home network"
|
||||
},
|
||||
{
|
||||
"interface": "Bridge1",
|
||||
"ip_address": "10.1.30.1",
|
||||
"mask": 24,
|
||||
"description": "Guest network"
|
||||
},
|
||||
{
|
||||
"interface": "Bridge2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "OpenVPN0",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "test_HW-udp"
|
||||
},
|
||||
{
|
||||
"interface": "OpenVPN2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "test_HW-tcp"
|
||||
},
|
||||
{
|
||||
"interface": "Wireguard0",
|
||||
"ip_address": "10.3.100.1",
|
||||
"mask": 24,
|
||||
"description": "test_HW"
|
||||
},
|
||||
{
|
||||
"interface": "Wireguard1",
|
||||
"ip_address": "10.1.100.1",
|
||||
"mask": 24,
|
||||
"description": "test_HW"
|
||||
},
|
||||
{
|
||||
"interface": "Wireguard2",
|
||||
"ip_address": "10.2.100.1",
|
||||
"mask": 24,
|
||||
"description": "test_HW"
|
||||
}
|
||||
],
|
||||
"vlans": [
|
||||
{
|
||||
"vlan_id": 1,
|
||||
"description": "Home VLAN"
|
||||
},
|
||||
{
|
||||
"vlan_id": 2,
|
||||
"description": "Подключение Ethernet"
|
||||
},
|
||||
{
|
||||
"vlan_id": 3,
|
||||
"description": "Home network"
|
||||
}
|
||||
]
|
||||
}
|
||||
123
tests/fixtures/mikrotik/config.conf
vendored
Normal file
123
tests/fixtures/mikrotik/config.conf
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
# 2026-02-18 22:32:59 by RouterOS 7.19.3
|
||||
# software id = 0V5S-56MC
|
||||
# version: 7.12
|
||||
# model = C52iG-5HaxD2HaxD
|
||||
# serial number = HE108BBGW0B
|
||||
/interface bridge
|
||||
add name=bridge.LAN
|
||||
/interface ethernet
|
||||
set [ find default-name=ether1 ] mac-address=C4:AD:32:B2:A1:9A poe-out=off
|
||||
set [ find default-name=ether4 ] comment=test
|
||||
/interface vlan
|
||||
add comment="super test vlan" interface=ether4 name="test vlan" vlan-id=255
|
||||
add disabled=yes interface=ether5 name="test test vlan" vlan-id=254
|
||||
/interface list
|
||||
add name=LAN
|
||||
add name=WAN
|
||||
/interface wifi channel
|
||||
add band=2ghz-ax disabled=no name=ch-2ghz width=20/40mhz
|
||||
add band=5ghz-ax disabled=no name=ch-5ghz width=20/40mhz
|
||||
/interface wifi security
|
||||
add authentication-types=wpa2-psk name=common-auth wps=disable
|
||||
/interface wifi configuration
|
||||
add name=common-auth security=common-auth ssid=test_HW
|
||||
/interface wifi
|
||||
set [ find default-name=wifi1 ] channel=ch-5ghz configuration=common-auth configuration.mode=ap disabled=no
|
||||
set [ find default-name=wifi2 ] channel=ch-2ghz configuration=common-auth configuration.mode=ap disabled=no
|
||||
/ip pool
|
||||
add name=dhcp_pool0 ranges=172.16.3.2-172.16.3.254
|
||||
add name=dhcp_pool1 ranges=192.168.3.2-192.168.3.254
|
||||
/ip dhcp-server
|
||||
add address-pool=dhcp_pool0 interface=bridge.LAN lease-time=10h name=dhcp1
|
||||
/ppp profile
|
||||
add name=new_antizapret on-down="/ip dns cache flush\r\
|
||||
\n" on-up="/ip dns cache flush\r\
|
||||
\n"
|
||||
add name=robovps on-down="/ip dns cache flush" on-up="/ip dns cache flush" use-ipv6=no
|
||||
/routing table
|
||||
add disabled=no fib name=test_HW_table
|
||||
/interface bridge port
|
||||
add bridge=bridge.LAN interface=ether2 learn=yes
|
||||
add bridge=bridge.LAN interface=ether3
|
||||
add bridge=bridge.LAN interface=ether4
|
||||
add bridge=bridge.LAN interface=ether5
|
||||
add bridge=bridge.LAN interface=wifi1
|
||||
add bridge=bridge.LAN interface=wifi2
|
||||
/ipv6 settings
|
||||
set disable-ipv6=yes forward=no
|
||||
/interface detect-internet
|
||||
set detect-interface-list=all
|
||||
/interface list member
|
||||
add interface=bridge.LAN list=LAN
|
||||
add interface=ether1 list=WAN
|
||||
/interface ovpn-server server
|
||||
add mac-address=FE:25:E0:B8:66:01 name=ovpn-server1
|
||||
/ip address
|
||||
add address=172.16.3.1/24 interface=bridge.LAN network=172.16.3.0
|
||||
add address=10.38.3.245/24 interface=ether1 network=10.38.3.0
|
||||
add address=10.1.100.2/24 interface=wireguard2 network=10.1.100.0
|
||||
add address=100.10.10.1/24 disabled=yes interface=ether4 network=100.10.10.0
|
||||
/ip dhcp-server lease
|
||||
add address=172.16.3.20 client-id=1:d8:3a:dd:22:28:1d mac-address=D8:3A:DD:21:28:1D server=dhcp1
|
||||
add address=172.16.3.4 client-id=1:2c:cd:29:1a:ea:6d comment=test_HW mac-address=1E:CD:29:8A:EA:6D server=dhcp1
|
||||
/ip dhcp-server network
|
||||
add address=172.16.3.0/24 dns-server=172.16.3.1 gateway=172.16.3.1
|
||||
/ip dns
|
||||
set allow-remote-requests=yes servers=217.10.44.35
|
||||
/ip dns static
|
||||
add address=172.16.3.20 regexp=".*\\.home\$" type=A
|
||||
add address=172.16.3.20 regexp=".*\\.home.uk\$" type=A
|
||||
add address=172.16.3.20 disabled=yes regexp=".*\\.home.uk\$" type=A
|
||||
/ip firewall address-list
|
||||
add address=172.16.3.0/24 list=test_HW
|
||||
add address=172.16.2.0/24 list=test_HW
|
||||
add address=172.16.1.0/24 list=test_HW
|
||||
add address=255.255.255.255 list=test_HW
|
||||
/ip firewall filter
|
||||
add action=drop chain=forward out-interface=ether1 src-address=172.16.3.11
|
||||
add action=accept chain=input src-address=255.255.255.255
|
||||
add action=accept chain=forward in-interface=wireguard2
|
||||
add action=accept chain=forward connection-state=established,related in-interface=ether1
|
||||
add action=accept chain=input connection-state=established,related in-interface=ether1
|
||||
add action=accept chain=input in-interface=bridge.LAN
|
||||
add action=drop chain=input in-interface=ether1
|
||||
add action=drop chain=forward in-interface=ether1
|
||||
/ip firewall mangle
|
||||
add action=passthrough chain=prerouting connection-mark=test_HW src-address=172.16.3.20
|
||||
/ip firewall nat
|
||||
add action=masquerade chain=srcnat out-interface=ether1
|
||||
add action=masquerade chain=srcnat comment=test_HW out-interface=test_HW
|
||||
/ip firewall service-port
|
||||
set ftp disabled=yes
|
||||
set tftp disabled=yes
|
||||
set h323 disabled=yes
|
||||
/ip route
|
||||
add disabled=no distance=1 dst-address=172.16.1.0/24 gateway=10.1.100.1
|
||||
add disabled=no distance=1 dst-address=172.16.2.0/24 gateway=10.1.100.1
|
||||
add disabled=no distance=1 dst-address=255.255.255.255/32 gateway=10.38.3.1
|
||||
add disabled=no distance=3 dst-address=0.0.0.0/0 gateway=10.38.3.1 routing-table=main scope=30 suppress-hw-offload=no target-scope=10
|
||||
add disabled=yes distance=2 dst-address=0.0.0.0/0 gateway=10.38.3.1 routing-table=main scope=30 suppress-hw-offload=no target-scope=10
|
||||
add comment=test_HW disabled=no distance=1 dst-address=185.255.255.255/32 gateway=10.38.3.1 routing-table=main scope=30 suppress-hw-offload=no target-scope=10
|
||||
add comment=test_HW disabled=no distance=1 dst-address=192.168.255.255/32 gateway=10.38.3.1 routing-table=main scope=30 suppress-hw-offload=no target-scope=10
|
||||
/ip service
|
||||
set telnet disabled=yes
|
||||
/system clock
|
||||
set time-zone-name=Europe/Berlin
|
||||
/system identity
|
||||
set name=test_HW
|
||||
/system logging
|
||||
set 0 topics=info,!wireless
|
||||
/system note
|
||||
set show-at-login=no
|
||||
/system ntp client
|
||||
set enabled=yes
|
||||
/system ntp client servers
|
||||
add address=pool.ntp.org
|
||||
/tool mac-server
|
||||
set allowed-interface-list=LAN
|
||||
/tool mac-server mac-winbox
|
||||
set allowed-interface-list=LAN
|
||||
/tool mac-server ping
|
||||
set enabled=no
|
||||
/user aaa
|
||||
set default-group=full use-radius=yes
|
||||
43
tests/fixtures/mikrotik/config.expected.json
vendored
Normal file
43
tests/fixtures/mikrotik/config.expected.json
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"system": {
|
||||
"model": "C52iG-5HaxD2HaxD",
|
||||
"serial_number": "HE108BBGW0B",
|
||||
"version": "7.12"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": "bridge.LAN",
|
||||
"ip_address": "172.16.3.1",
|
||||
"mask": 24,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "ether1",
|
||||
"ip_address": "10.38.3.245",
|
||||
"mask": 24,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "wireguard2",
|
||||
"ip_address": "10.1.100.2",
|
||||
"mask": 24,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "ether4",
|
||||
"ip_address": "100.10.10.1",
|
||||
"mask": 24,
|
||||
"description": null
|
||||
}
|
||||
],
|
||||
"vlans": [
|
||||
{
|
||||
"vlan_id": 255,
|
||||
"description": "test vlan"
|
||||
},
|
||||
{
|
||||
"vlan_id": 254,
|
||||
"description": "test test vlan"
|
||||
}
|
||||
]
|
||||
}
|
||||
42
tests/fixtures/qtech/config_1.conf
vendored
Normal file
42
tests/fixtures/qtech/config_1.conf
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
! QTECH LLC Internetwork Operating System Software
|
||||
! QSW-8330-40T-DC Series Software, Version 2.2.0C Build 96279, RELEASE SOFTWARE
|
||||
! ROM: System Bootstrap, Version 0.4.7,hardware version:A
|
||||
! Serial num:6060606060606060, ID num:555555555555
|
||||
! System image file is "Switch.bin"
|
||||
! QTECH LLC QSW-8330-40T-DC RISC
|
||||
! 524288K bytes of memory,16384K bytes of flash
|
||||
! Base ethernet MAC Address: 08:c6:b3:08:cf:ff
|
||||
! snmp info:
|
||||
! vend_ID:27514 product_ID:404 system_ID:1.3.6.1.4.1.27514
|
||||
interface GigaEthernet1/0/9
|
||||
shutdown
|
||||
description FREE
|
||||
switchport pvid 102
|
||||
storm-control broadcast threshold 15
|
||||
storm-control broadcast action shutdown
|
||||
storm-control broadcast auto_resume 60s
|
||||
storm-control multicast threshold 10
|
||||
storm-control multicast action shutdown
|
||||
storm-control multicast auto_resume 60s
|
||||
qos policy IPP3 ingress
|
||||
!
|
||||
interface VLAN1
|
||||
ip address 192.168.0.1 255.255.0.0
|
||||
ip mtu 1500
|
||||
no ip directed-broadcast
|
||||
!
|
||||
interface VLAN1002
|
||||
description test-1002
|
||||
ip address 13.36.8.1 255.255.255.0
|
||||
ip mtu 1500
|
||||
no ip directed-broadcast
|
||||
!
|
||||
vlan 772
|
||||
name test
|
||||
!
|
||||
vlan 888
|
||||
name test_super
|
||||
!
|
||||
vlan 1,7,14-15,44,101-102,115,117-124,130-136,139,167,200-205,772
|
||||
,1607
|
||||
vlan 888,2016,2085-2088
|
||||
185
tests/fixtures/qtech/config_1.expected.json
vendored
Normal file
185
tests/fixtures/qtech/config_1.expected.json
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
{
|
||||
"system": {
|
||||
"model": "QSW-8330-40T-DC",
|
||||
"serial_number": "6060606060606060",
|
||||
"version": "96279"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": "GigaEthernet1/0/9",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "FREE"
|
||||
},
|
||||
{
|
||||
"interface": "VLAN1",
|
||||
"ip_address": "192.168.0.1",
|
||||
"mask": 16,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "VLAN1002",
|
||||
"ip_address": "13.36.8.1",
|
||||
"mask": 24,
|
||||
"description": "test-1002"
|
||||
}
|
||||
],
|
||||
"vlans": [
|
||||
{
|
||||
"vlan_id": 772,
|
||||
"description": "test"
|
||||
},
|
||||
{
|
||||
"vlan_id": 888,
|
||||
"description": "test_super"
|
||||
},
|
||||
{
|
||||
"vlan_id": 1,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 7,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 14,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 15,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 44,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 101,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 102,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 115,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 117,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 118,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 119,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 120,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 121,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 122,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 123,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 124,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 130,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 131,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 132,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 133,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 134,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 135,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 136,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 139,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 167,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 200,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 201,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 202,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 203,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 204,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 205,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 1607,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2016,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2085,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2086,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2087,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2088,
|
||||
"description": null
|
||||
}
|
||||
]
|
||||
}
|
||||
36
tests/fixtures/qtech/config_2.conf
vendored
Normal file
36
tests/fixtures/qtech/config_2.conf
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
! QTECH LLC Internetwork Operating System Software
|
||||
! QSW-8330-40T-DC Series Software, Version 2.2.0C Build 96279, RELEASE SOFTWARE
|
||||
! ROM: System Bootstrap, Version 0.4.7,hardware version:A
|
||||
! Serial num:6060606060606060, ID num:555555555555
|
||||
! System image file is "Switch.bin"
|
||||
! QTECH LLC QSW-8330-40T-DC RISC
|
||||
! 524288K bytes of memory,16384K bytes of flash
|
||||
! Base ethernet MAC Address: 08:c6:b3:08:cf:f7
|
||||
! snmp info:
|
||||
! vend_ID:27514 product_ID:404 system_ID:1.3.6.1.4.1.27514
|
||||
interface GigaEthernet1/0/9
|
||||
shutdown
|
||||
description FREE
|
||||
switchport pvid 102
|
||||
storm-control broadcast threshold 15
|
||||
storm-control broadcast action shutdown
|
||||
storm-control broadcast auto_resume 60s
|
||||
storm-control multicast threshold 10
|
||||
storm-control multicast action shutdown
|
||||
storm-control multicast auto_resume 60s
|
||||
qos policy IPP3 ingress
|
||||
!
|
||||
interface VLAN1
|
||||
ip address 192.168.0.1 255.255.0.0
|
||||
ip mtu 1500
|
||||
no ip directed-broadcast
|
||||
!
|
||||
interface VLAN1002
|
||||
description test-1002
|
||||
ip address 13.36.8.1 255.255.255.0
|
||||
ip mtu 1500
|
||||
no ip directed-broadcast
|
||||
!
|
||||
vlan 1,7,14-15,44,101-102,115,117-124,130-136,139,167,200-205,772
|
||||
,1607
|
||||
vlan 888,2016,2085-2088
|
||||
185
tests/fixtures/qtech/config_2.expected.json
vendored
Normal file
185
tests/fixtures/qtech/config_2.expected.json
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
{
|
||||
"system": {
|
||||
"model": "QSW-8330-40T-DC",
|
||||
"serial_number": "6060606060606060",
|
||||
"version": "96279"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": "GigaEthernet1/0/9",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "FREE"
|
||||
},
|
||||
{
|
||||
"interface": "VLAN1",
|
||||
"ip_address": "192.168.0.1",
|
||||
"mask": 16,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"interface": "VLAN1002",
|
||||
"ip_address": "13.36.8.1",
|
||||
"mask": 24,
|
||||
"description": "test-1002"
|
||||
}
|
||||
],
|
||||
"vlans": [
|
||||
{
|
||||
"vlan_id": 1,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 7,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 14,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 15,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 44,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 101,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 102,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 115,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 117,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 118,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 119,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 120,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 121,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 122,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 123,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 124,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 130,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 131,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 132,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 133,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 134,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 135,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 136,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 139,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 167,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 200,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 201,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 202,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 203,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 204,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 205,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 772,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 1607,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 888,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2016,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2085,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2086,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2087,
|
||||
"description": null
|
||||
},
|
||||
{
|
||||
"vlan_id": 2088,
|
||||
"description": null
|
||||
}
|
||||
]
|
||||
}
|
||||
41
tests/fixtures/quasar/config_1.conf
vendored
Normal file
41
tests/fixtures/quasar/config_1.conf
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# Copyright © 2021-2022, TechArgos LLC
|
||||
# ----------- -----------------
|
||||
# Subsystem Version
|
||||
# ----------- -----------------
|
||||
# Engine 0.2.17.2022-10-21
|
||||
# DPlane 0.2.18.2022-05-16
|
||||
# BfMonitor 1.1.2.2022-08-25
|
||||
# CLI.core 1.0.3.2022-09-30
|
||||
# CLI.engine 1.2.2.2022-10-12
|
||||
# RConsole 0.3.4.2022-01-12
|
||||
# RcAppParams 0.3.1.2022-01-12
|
||||
# SNMP 0.0.11.2022-04-26
|
||||
# Zabbix 0.2.13.2022-01-26
|
||||
# WebUI 1.1.3.2022-10-19
|
||||
# BF.core 9.3.1.2021-01-30
|
||||
#
|
||||
# ------------------------- ---------------
|
||||
# Platform EEPROM field Value
|
||||
# ------------------------- ---------------
|
||||
# Product Name Quasar-T-Q-0002
|
||||
# Product Number HB4NC011234M
|
||||
# Local MAC N/A
|
||||
# Product Serial Number WEE1C1CC0004A
|
||||
# Product Version 0.0
|
||||
# System Manufacturing Date 2026-06-07
|
||||
config ethernet ipv4 address 25.25.1.221/24 gateway 25.25.1.254 enable
|
||||
|
||||
config interface 7/4 fec none mode force-up enable
|
||||
config interface 8/1 fec none mode force-up enable
|
||||
config interface 8/2 fec none mode force-up enable
|
||||
config interface 8/3 fec none mode force-up enable
|
||||
config interface 8/4 fec none mode force-up enable
|
||||
config interface 9/1 fec none mode force-up enable
|
||||
config interface 9/2 fec none mode force-up enable
|
||||
config interface 7/4 description "IN DWDM / OUT TEST_HW_08_N0_p1"
|
||||
config interface 8/1 description "IN DWDM / OUT TEST_HW_09_N1_p0"
|
||||
config interface 8/2 description "IN DWDM / OUT TEST_HW_09_N0_p0"
|
||||
config interface 8/3 description "IN DWDM / OUT TEST_HW_10_N1_p0"
|
||||
config interface 8/4 description "IN DWDM / OUT TEST_HW_10_N0_p0"
|
||||
config interface 9/1 description "IN DWDM / OUT TEST_HW_11_N0_p0"
|
||||
config interface 9/2 description "IN DWDM / OUT TEST_HW_11_N0_p1"
|
||||
58
tests/fixtures/quasar/config_1.expected.json
vendored
Normal file
58
tests/fixtures/quasar/config_1.expected.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"system": {
|
||||
"model": "Quasar-T-Q-0002",
|
||||
"serial_number": "WEE1C1CC0004A",
|
||||
"version": "0.2.17.2022-10-21"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": "7/4",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "IN DWDM / OUT TEST_HW_08_N0_p1"
|
||||
},
|
||||
{
|
||||
"interface": "8/1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "IN DWDM / OUT TEST_HW_09_N1_p0"
|
||||
},
|
||||
{
|
||||
"interface": "8/2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "IN DWDM / OUT TEST_HW_09_N0_p0"
|
||||
},
|
||||
{
|
||||
"interface": "8/3",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "IN DWDM / OUT TEST_HW_10_N1_p0"
|
||||
},
|
||||
{
|
||||
"interface": "8/4",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "IN DWDM / OUT TEST_HW_10_N0_p0"
|
||||
},
|
||||
{
|
||||
"interface": "9/1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "IN DWDM / OUT TEST_HW_11_N0_p0"
|
||||
},
|
||||
{
|
||||
"interface": "9/2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "IN DWDM / OUT TEST_HW_11_N0_p1"
|
||||
},
|
||||
{
|
||||
"interface": "ethernet",
|
||||
"ip_address": "25.25.1.221",
|
||||
"mask": 24,
|
||||
"description": null
|
||||
}
|
||||
],
|
||||
"vlans": []
|
||||
}
|
||||
43
tests/fixtures/quasar/config_2.conf
vendored
Normal file
43
tests/fixtures/quasar/config_2.conf
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copyright © 2021-2024, TechArgos LLC
|
||||
# ----------- ------------------
|
||||
# Component Version
|
||||
# ----------- ------------------
|
||||
# Assembly 0.2.23_9.9.1_GA
|
||||
# Engine 2.23.15.2024-08-22
|
||||
# DPlane 0.2.20.2023-10-17
|
||||
# BfMonitor 1.4.0.2024-08-27
|
||||
# CLI.core 1.0.3.2022-09-30
|
||||
# CLI.engine 1.3.4.2024-08-22
|
||||
# RConsole 1.0.1.2022-12-23
|
||||
# RcAppParams 1.0.1.2022-12-23
|
||||
# SNMP 0.3.0.2024-07-08
|
||||
# Zabbix 0.2.13.2022-01-26
|
||||
# WebUI 1.3.34.2024-08-30
|
||||
# NMS.agent 1.2.12.2024-08-21
|
||||
# SysLog 0.7.12.2024-02-02
|
||||
# NTPd 0.1.5.2024-07-15
|
||||
# AAA 0.0.8.2023-11-16
|
||||
#
|
||||
# ------------------------- --------------------
|
||||
# Platform EEPROM field Value
|
||||
# ------------------------- --------------------
|
||||
# Product Name D5232C-T
|
||||
# Part Number TA-PB-D5232C-T-AC-PI
|
||||
# Local MAC N/A
|
||||
# Product Serial Number WHF1C87123456A
|
||||
# Product Version 0.0
|
||||
# System Manufacturing Date 2026-06-07
|
||||
config ethernet ipv4 address 25.25.18.19/24 gateway 25.25.18.254 enable
|
||||
config interface 1/1 description "TEST_HW_1_1"
|
||||
config interface 1/3 description "TEST_HW_1_3"
|
||||
config interface 2/1 description "TEST_HW_2_1"
|
||||
config interface 2/2 description "TEST_HW_2_2"
|
||||
config interface 2/3 description "TEST_HW_2_3"
|
||||
config interface 2/4 description "TEST_HW_2_4"
|
||||
config interface 3/1 description "TEST_HW_3_1"
|
||||
config interface 3/3 description "TEST_HW_3_3"
|
||||
config interface 3/4 description "TEST_HW_3_4"
|
||||
config interface 4/1 description "TEST_HW_4_1"
|
||||
config interface 4/2 description "TEST_HW_4_2"
|
||||
config interface 4/3 description "TEST_HW_4_3"
|
||||
config interface 4/4 description "TEST_HW_4_4"
|
||||
94
tests/fixtures/quasar/config_2.expected.json
vendored
Normal file
94
tests/fixtures/quasar/config_2.expected.json
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"system": {
|
||||
"model": "D5232C-T",
|
||||
"serial_number": "WHF1C87123456A",
|
||||
"version": "0.2.23_9.9.1_GA"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": "1/1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_1_1"
|
||||
},
|
||||
{
|
||||
"interface": "1/3",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_1_3"
|
||||
},
|
||||
{
|
||||
"interface": "2/1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_2_1"
|
||||
},
|
||||
{
|
||||
"interface": "2/2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_2_2"
|
||||
},
|
||||
{
|
||||
"interface": "2/3",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_2_3"
|
||||
},
|
||||
{
|
||||
"interface": "2/4",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_2_4"
|
||||
},
|
||||
{
|
||||
"interface": "3/1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_3_1"
|
||||
},
|
||||
{
|
||||
"interface": "3/3",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_3_3"
|
||||
},
|
||||
{
|
||||
"interface": "3/4",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_3_4"
|
||||
},
|
||||
{
|
||||
"interface": "4/1",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_4_1"
|
||||
},
|
||||
{
|
||||
"interface": "4/2",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_4_2"
|
||||
},
|
||||
{
|
||||
"interface": "4/3",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_4_3"
|
||||
},
|
||||
{
|
||||
"interface": "4/4",
|
||||
"ip_address": null,
|
||||
"mask": null,
|
||||
"description": "TEST_HW_4_4"
|
||||
},
|
||||
{
|
||||
"interface": "ethernet",
|
||||
"ip_address": "25.25.18.19",
|
||||
"mask": 24,
|
||||
"description": null
|
||||
}
|
||||
],
|
||||
"vlans": []
|
||||
}
|
||||
38
tests/test_models.py
Normal file
38
tests/test_models.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from conftest import FIXTURES, load
|
||||
from oxi.interfaces import device_registry
|
||||
|
||||
MODEL_CASES = [
|
||||
("mikrotik", "config.conf", "config.expected.json"),
|
||||
("keenetic", "config.conf", "config.expected.json"),
|
||||
("qtech", "config_1.conf", "config_1.expected.json"),
|
||||
("qtech", "config_2.conf", "config_2.expected.json"),
|
||||
("huawei", "config.conf", "config.expected.json"),
|
||||
("eltex", "config.conf", "config.expected.json"),
|
||||
("quasar", "config_1.conf", "config_1.expected.json"),
|
||||
("quasar", "config_2.conf", "config_2.expected.json"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model_key, fixture, expected_file", MODEL_CASES)
|
||||
def test_parse_matches_golden(model_key, fixture, expected_file):
|
||||
cls = device_registry[model_key]
|
||||
raw = load(model_key, fixture)
|
||||
|
||||
parsed = cls(raw).parse().model_dump(by_alias=True, mode="json")
|
||||
|
||||
expected = json.loads((FIXTURES / model_key / expected_file).read_text("utf-8"))
|
||||
assert parsed == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model_key, fixture, _expected", MODEL_CASES)
|
||||
def test_parse_has_required_sections(model_key, fixture, _expected):
|
||||
cls = device_registry[model_key]
|
||||
device = cls(load(model_key, fixture)).parse()
|
||||
|
||||
assert device.system is not None
|
||||
assert isinstance(device.interfaces, list)
|
||||
assert isinstance(device.vlans, list)
|
||||
Reference in New Issue
Block a user