From 0ef5e7798ae72a5fe1a980851fedf7496d382673 Mon Sep 17 00:00:00 2001 From: IluaAir Date: Sun, 7 Jun 2026 08:47:08 +0300 Subject: [PATCH] Refactor Qtech model to utilize centralized VLAN range expansion utility - Replaced the internal `_expand_vlan_range` function in the `Qtech` class with the new `expand_vlan_range` utility from `utils.py` for improved code maintainability. - Added new configuration files `config_1.conf` and `config_2.conf` for Qtech devices to facilitate testing. - Introduced expected output JSON files `config_1.expected.json` and `config_2.expected.json` to validate the parsing of Qtech configurations against expected results. --- oxi/interfaces/models/qtech.py | 43 +---- tests/fixtures/qtech/config_1.conf | 42 +++++ tests/fixtures/qtech/config_1.expected.json | 185 ++++++++++++++++++++ tests/fixtures/qtech/config_2.conf | 36 ++++ tests/fixtures/qtech/config_2.expected.json | 185 ++++++++++++++++++++ 5 files changed, 450 insertions(+), 41 deletions(-) create mode 100644 tests/fixtures/qtech/config_1.conf create mode 100644 tests/fixtures/qtech/config_1.expected.json create mode 100644 tests/fixtures/qtech/config_2.conf create mode 100644 tests/fixtures/qtech/config_2.expected.json diff --git a/oxi/interfaces/models/qtech.py b/oxi/interfaces/models/qtech.py index cf2247b..fc70cf9 100644 --- a/oxi/interfaces/models/qtech.py +++ b/oxi/interfaces/models/qtech.py @@ -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) diff --git a/tests/fixtures/qtech/config_1.conf b/tests/fixtures/qtech/config_1.conf new file mode 100644 index 0000000..df0dcb1 --- /dev/null +++ b/tests/fixtures/qtech/config_1.conf @@ -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 diff --git a/tests/fixtures/qtech/config_1.expected.json b/tests/fixtures/qtech/config_1.expected.json new file mode 100644 index 0000000..e9721f4 --- /dev/null +++ b/tests/fixtures/qtech/config_1.expected.json @@ -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 + } + ] +} \ No newline at end of file diff --git a/tests/fixtures/qtech/config_2.conf b/tests/fixtures/qtech/config_2.conf new file mode 100644 index 0000000..cf22ea4 --- /dev/null +++ b/tests/fixtures/qtech/config_2.conf @@ -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 diff --git a/tests/fixtures/qtech/config_2.expected.json b/tests/fixtures/qtech/config_2.expected.json new file mode 100644 index 0000000..e9a4a80 --- /dev/null +++ b/tests/fixtures/qtech/config_2.expected.json @@ -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 + } + ] +} \ No newline at end of file