diff --git a/oxi/interfaces/base.py b/oxi/interfaces/base.py index 639bd83..a543084 100644 --- a/oxi/interfaces/base.py +++ b/oxi/interfaces/base.py @@ -2,11 +2,21 @@ from abc import ABC, abstractmethod from pathlib import Path from typing import TYPE_CHECKING +from ttp import ttp +from oxi.interfaces.contract import Device + if TYPE_CHECKING: from oxi.interfaces.contract import Interfaces, System, Vlans class BaseDevice(ABC): + _REQUIRED_SECTIONS: frozenset[str] = frozenset({"system", "interfaces", "vlans"}) + + def __init__(self, config: str): + self.config: str = config + self._loaded_template = self._load_template() + self._raw: dict = self._run_ttp() + @property @abstractmethod def template(self) -> str: @@ -15,23 +25,37 @@ class BaseDevice(ABC): """ @abstractmethod - def vlans(self) -> "Vlans": ... + def vlans(self) -> list["Vlans"]: ... @abstractmethod - def interfaces(self) -> "Interfaces": ... + def interfaces(self) -> list["Interfaces"]: ... @abstractmethod def system(self) -> "System": ... - def __load_template(self): + def _load_template(self): path = Path(__file__).parent / "template" / self.template if not path.exists(): raise FileNotFoundError(f"Template {self.template} not found") return path.read_text(encoding="utf-8") - def run(self): - self.load = self.__load_template() - return self.load + def _run_ttp(self) -> dict: + p = ttp(data=self.config, template=self._loaded_template) + p.parse() + raw: dict = p.result()[0][0] + missing = self._REQUIRED_SECTIONS - raw.keys() + if missing: + raise ValueError( + f"{self.__class__.__name__}: TTP template '{self.template}' " + f"did not produce required sections: {sorted(missing)}. " + f"Got: {sorted(raw.keys())}" + ) + return raw - -BaseDevice() + def parse(self) -> Device: + data = { + "system": self.system(), + "interfaces": self.interfaces(), + "vlans": self.vlans(), + } + return Device(**data) diff --git a/oxi/interfaces/contract.py b/oxi/interfaces/contract.py index a910e28..9869500 100644 --- a/oxi/interfaces/contract.py +++ b/oxi/interfaces/contract.py @@ -16,10 +16,10 @@ class System(BaseModel): class Vlans(BaseModel): id: int - name: str = Field(alias="description") + name: str | None = Field(default=None, alias="description") class Device(BaseModel): system: System - interfaces: Interfaces - vlans: Vlans + interfaces: list[Interfaces] = [] + vlans: list[Vlans] = [] diff --git a/oxi/interfaces/models/templates/_template.ttp b/oxi/interfaces/models/templates/_template.ttp new file mode 100644 index 0000000..02d8a0c --- /dev/null +++ b/oxi/interfaces/models/templates/_template.ttp @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/oxi/interfaces/models/templates/mikrotik.ttp b/oxi/interfaces/models/templates/mikrotik.ttp new file mode 100644 index 0000000..02d8a0c --- /dev/null +++ b/oxi/interfaces/models/templates/mikrotik.ttp @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file