diff --git a/oxi/interfaces/base.py b/oxi/interfaces/base.py index a159243..6955b72 100644 --- a/oxi/interfaces/base.py +++ b/oxi/interfaces/base.py @@ -1,20 +1,22 @@ from abc import ABC, abstractmethod from pathlib import Path from typing import TYPE_CHECKING - from ttp import ttp from oxi.interfaces.contract import Device +import xml.etree.ElementTree as ET if TYPE_CHECKING: from oxi.interfaces.contract import Interfaces, System, Vlans class BaseDevice(ABC): - _REQUIRED_SECTIONS: frozenset[str] = frozenset({"system", "interfaces", "vlans"}) + _REQUIRED_SECTIONS: frozenset[str] = frozenset({"system", "interfaces"}) + _OPTIONAL_SECTIONS: frozenset[str] = frozenset({"vlans"}) def __init__(self, config: str): self.config: str = config self._loaded_template = self._load_template() + self._validate_template_groups() self._raw: dict = self._run_ttp() @property @@ -75,6 +77,24 @@ class BaseDevice(ABC): raise FileNotFoundError(f"Template {self.template} not found") return path.read_text(encoding="utf-8") + def _validate_template_groups(self) -> None: + """Проверка что TTP темлпейт имеет декларированные группы для всех требуемых и опциональных секций""" + try: + root = ET.fromstring(self._loaded_template) + except ET.ParseError: + root = ET.fromstring(f"") + + declared = {g.get("name") for g in root.iter("group") if g.get("name")} + expected = self._REQUIRED_SECTIONS | self._OPTIONAL_SECTIONS + missing = expected - declared + + if missing: + raise ValueError( + f"{self.__class__.__name__}: template '{self.template}' " + f"missing group declarations: {sorted(missing)}. " + f"Declared groups: {sorted(declared)}" + ) + def _run_ttp(self) -> dict: p = ttp(data=self.config, template=self._loaded_template) p.parse() diff --git a/oxi/interfaces/models/mikrotik.py b/oxi/interfaces/models/mikrotik.py index c84260d..6b6f638 100644 --- a/oxi/interfaces/models/mikrotik.py +++ b/oxi/interfaces/models/mikrotik.py @@ -1,3 +1,4 @@ +import re from typing import TYPE_CHECKING from oxi.interfaces import register_parser from oxi.interfaces.base import BaseDevice @@ -19,11 +20,13 @@ class Mikrotik(BaseDevice): print("-" * 12) def vlans(self) -> list["Vlans"]: - print(f"{self._raw["vlans"]=}") - print("-" * 12) + raw = self._raw.get("vlans", []) + print(raw) if __name__ == "__main__": - mikr = Mikrotik() - mikr.run() + with open("../../test.txt") as file: + data = file.read() + mikr = Mikrotik(data) + mikr.parse() print(mikr.load) diff --git a/oxi/interfaces/models/templates/mikrotik.ttp b/oxi/interfaces/models/templates/mikrotik.ttp index a535494..7cc958f 100644 --- a/oxi/interfaces/models/templates/mikrotik.ttp +++ b/oxi/interfaces/models/templates/mikrotik.ttp @@ -1,31 +1,47 @@ + some templates - \ No newline at end of file