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