Enhance Keenetic model and update templates for improved data handling
- Implemented the `interfaces` and `vlans` methods in the `Keenetic` model to process and decode interface and VLAN data. - Added a `_decode_utf` method to handle UTF-8 encoded descriptions. - Updated the Keenetic TTP template to define structured groups for system, interfaces, and VLANs. - Refactored file paths in the `Mikrotik` model for consistency and clarity.
This commit is contained in:
@@ -106,7 +106,7 @@ class BaseDevice(ABC):
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"{self.__class__.__name__}: TTP template '{self.template}' "
|
f"{self.__class__.__name__}: TTP template '{self.template}' "
|
||||||
f"did not produce required sections: {sorted(missing)}. "
|
f"did not produce required sections: {sorted(missing)}. "
|
||||||
f"Got: {sorted(raw.keys())}"
|
f"Got: {(raw.keys())}"
|
||||||
)
|
)
|
||||||
return raw
|
return raw
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,54 @@
|
|||||||
|
from ipaddress import ip_interface
|
||||||
|
from pprint import pprint
|
||||||
from oxi.interfaces import register_parser
|
from oxi.interfaces import register_parser
|
||||||
from oxi.interfaces.base import BaseDevice
|
from oxi.interfaces.base import BaseDevice
|
||||||
|
from oxi.interfaces.contract import Interfaces, System, Vlans
|
||||||
|
|
||||||
|
|
||||||
@register_parser(["NDMS", "keenetic", "KeeneticOS"])
|
@register_parser(["NDMS", "keenetic", "KeeneticOS"])
|
||||||
class Keenetic(BaseDevice):
|
class Keenetic(BaseDevice):
|
||||||
template = "keenetic.ttp"
|
template = "keenetic.ttp"
|
||||||
|
|
||||||
def system(self): ...
|
def system(self):
|
||||||
|
return System(**self._raw["system"])
|
||||||
|
|
||||||
def interfaces(self): ...
|
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 vlans(self): ...
|
def interfaces(self):
|
||||||
|
interfaces: list[dict] = self._raw["interfaces"]
|
||||||
|
for item in interfaces:
|
||||||
|
if item.get("ip_address") and item.get("netmask"):
|
||||||
|
ipaddress = ip_interface(
|
||||||
|
f"{item.get('ip_address')}/{item.get('netmask')}"
|
||||||
|
)
|
||||||
|
item["mask"] = ipaddress.network.prefixlen
|
||||||
|
item.pop("netmask", "Key not found")
|
||||||
|
if item.get("description"):
|
||||||
|
decoded = self._decode_utf(item.get("description", ""))
|
||||||
|
item["description"] = decoded
|
||||||
|
return [Interfaces(**item) for item in interfaces]
|
||||||
|
|
||||||
|
def vlans(self):
|
||||||
|
vlans = self._raw["vlans"]
|
||||||
|
for item in vlans:
|
||||||
|
if item.get("description"):
|
||||||
|
decoded = self._decode_utf(item.get("description", ""))
|
||||||
|
item["description"] = decoded
|
||||||
|
return [Vlans(**item) for item in vlans]
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
with open("../../test2.txt") as file:
|
with open("./test2.txt") as file:
|
||||||
data = file.read()
|
data = file.read()
|
||||||
mikr = Keenetic(data)
|
mikr = Keenetic(data)
|
||||||
print(mikr.parse().json())
|
print(mikr.parse().model_dump_json())
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
from oxi.interfaces import register_parser
|
from oxi.interfaces import register_parser
|
||||||
from oxi.interfaces.base import BaseDevice
|
from oxi.interfaces.base import BaseDevice
|
||||||
from oxi.interfaces.contract import Interfaces, System, Vlans
|
from oxi.interfaces.contract import Interfaces, System, Vlans
|
||||||
@@ -19,7 +20,8 @@ class Mikrotik(BaseDevice):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
with open("../../test.txt") as file:
|
print(os.path.abspath(os.curdir))
|
||||||
|
with open("./test.txt") as file:
|
||||||
data = file.read()
|
data = file.read()
|
||||||
mikr = Mikrotik(data)
|
mikr = Mikrotik(data)
|
||||||
print(mikr.parse().json())
|
print(mikr.parse().json())
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
<doc>
|
<doc>
|
||||||
</doc>
|
</doc>
|
||||||
<var>
|
<vars>
|
||||||
</var>
|
</vars>
|
||||||
|
|
||||||
<group>
|
<group name="system">
|
||||||
|
...
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<group name="interfaces">
|
||||||
|
...
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<group name="vlans">
|
||||||
|
...
|
||||||
</group>
|
</group>
|
||||||
29
oxi/interfaces/models/templates/keenetic.ttp
Normal file
29
oxi/interfaces/models/templates/keenetic.ttp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<doc>
|
||||||
|
</doc>
|
||||||
|
<vars>
|
||||||
|
default_system = {
|
||||||
|
"model": "",
|
||||||
|
"serial_number": ""
|
||||||
|
}
|
||||||
|
default_interfaces = {}
|
||||||
|
</vars>
|
||||||
|
|
||||||
|
<group name="system" default="default_system">
|
||||||
|
! release: {{ version }}
|
||||||
|
! model: {{ model | ORPHRASE }}
|
||||||
|
! hw_version: {{ serial_number }}
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<group name="interfaces">
|
||||||
|
interface {{ name | _start_ | exclude("Vlan") }}
|
||||||
|
rename {{ rename }}
|
||||||
|
description {{ description | ORPHRASE }}
|
||||||
|
ip address {{ ip_address }} {{ netmask }}
|
||||||
|
{{ shutdown | re("up") | replace("up","False") | strip('"') }}
|
||||||
|
{{ shutdown | re("down") | replace("down","True") | strip('"') }}
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<group name="vlans">
|
||||||
|
interface {{ ignore }}/Vlan{{ vlan_id }}
|
||||||
|
description {{ description | ORPHRASE | strip('"') }}
|
||||||
|
</group>
|
||||||
Reference in New Issue
Block a user