From 21c16c2b30d1a4ce85eb2ea7367d0e30824e8fa8 Mon Sep 17 00:00:00 2001 From: David Gallay Date: Fri, 20 Sep 2024 17:20:04 +0200 Subject: [PATCH 1/2] Fixing HAInfo type --- pa_api/xmlapi/types/config/interface.py | 13 ----- pa_api/xmlapi/types/operations/__init__.py | 3 +- pa_api/xmlapi/types/operations/device.py | 62 +--------------------- pa_api/xmlapi/types/operations/ha.py | 47 ++++++++++++++++ pa_api/xmlapi/types/utils.py | 10 +--- 5 files changed, 52 insertions(+), 83 deletions(-) create mode 100644 pa_api/xmlapi/types/operations/ha.py diff --git a/pa_api/xmlapi/types/config/interface.py b/pa_api/xmlapi/types/config/interface.py index d2542ed..5a4c88d 100644 --- a/pa_api/xmlapi/types/config/interface.py +++ b/pa_api/xmlapi/types/config/interface.py @@ -195,13 +195,6 @@ def flatten(self, parent=None) -> Iterable[GenericInterface]: if self.layer3: yield from self.layer3.flatten(parent) - # @model_validator(mode="before") - # @classmethod - # def test(cls, data): - # print("\n" * 5) - # print("Ethernet:", data) - # return data - class AggregateEthernet(XMLBaseModel): model_config = ConfigDict(extra="allow") @@ -229,12 +222,6 @@ class AggregateEthernet(XMLBaseModel): validation_alias=AliasPath("tag", "member"), default_factory=list, ) - # @model_validator(mode="before") - # @classmethod - # def test(cls, data): - # print("\n" * 5) - # print("AggregateEthernet:", data) - # return data def flatten(self, parent=None) -> Iterable[GenericInterface]: if self.name: diff --git a/pa_api/xmlapi/types/operations/__init__.py b/pa_api/xmlapi/types/operations/__init__.py index 9419d71..d92997b 100644 --- a/pa_api/xmlapi/types/operations/__init__.py +++ b/pa_api/xmlapi/types/operations/__init__.py @@ -1,5 +1,6 @@ from . import device, job, software -from .device import Device, HAInfo, VPNFlow +from .device import Device, VPNFlow +from .ha import HAGroup, HAInfo, HALocalInfo, HAPeerInfo from .job import Job, JobResult from .software import SoftwareVersion from .system import SystemInfo diff --git a/pa_api/xmlapi/types/operations/device.py b/pa_api/xmlapi/types/operations/device.py index 195e669..de4844f 100644 --- a/pa_api/xmlapi/types/operations/device.py +++ b/pa_api/xmlapi/types/operations/device.py @@ -2,14 +2,7 @@ from pydantic import AliasPath, ConfigDict, Field -from pa_api.utils import ( - first, -) -from pa_api.xmlapi.types.utils import ( - Datetime, - XMLBaseModel, - mksx, -) +from pa_api.xmlapi.types.utils import Datetime, XMLBaseModel class Device(XMLBaseModel): @@ -119,56 +112,3 @@ class VPNFlow(XMLBaseModel): state: str mon: str owner: str - - -class HAInfo(XMLBaseModel): - model_config = ConfigDict(populate_by_name=True, extra="allow") - - enabled: bool - preemptive: Optional[bool] = None - mode: Optional[str] = None - state: Optional[str] = None - peer_state: Optional[str] = None - priority: Optional[int] = None - peer_priority: Optional[int] = None - is_primary: Optional[bool] = None - peer_conn_status: Optional[str] = None - mgmt_ip: Optional[str] = None - ha1_ipaddr: Optional[str] = None - ha1_backup_ipaddr: Optional[str] = None - ha2_ipaddr: Optional[str] = None - ha1_macaddress: Optional[str] = None - ha1_backup_macaddress: Optional[str] = None - ha2_macaddress: Optional[str] = None - - @classmethod - def from_xml(cls, xml): - # TODO: Use correct pydantic functionalities - if isinstance(xml, (list, tuple)): - xml = first(xml) - if xml is None: - return None - p = mksx(xml) - priority = p("./group/local-info/priority/text()", parser=int) - peer_priority = p("./group/peer-info/priority/text()", parser=int) - is_primary = None - if priority is not None and peer_priority is not None: - is_primary = priority < peer_priority - return HAInfo( - enabled=p("./enabled/text()"), - preemptive=p("./group/local-info/preemptive/text()"), - mode=p("./group/local-info/mode/text()"), - state=p("./group/local-info/state/text()"), - peer_state=p("./group/peer-info/state/text()"), - priority=priority, - peer_priority=peer_priority, - is_primary=is_primary, - peer_conn_status=p("./group/peer-info/conn-status/text()"), - mgmt_ip=p("./group/local-info/mgmt-ip/text()"), - ha1_ipaddr=p("./group/local-info/ha1-ipaddr/text()"), - ha1_backup_ipaddr=p("./group/local-info/ha1-backup-ipaddr/text()"), - ha2_ipaddr=p("./group/local-info/ha2-ipaddr/text()"), - ha1_macaddress=p("./group/local-info/ha1-macaddr/text()"), - ha1_backup_macaddress=p("./group/local-info/ha1-backup-macaddr/text()"), - ha2_macaddress=p("./group/local-info/ha2-macaddr/text()"), - ) diff --git a/pa_api/xmlapi/types/operations/ha.py b/pa_api/xmlapi/types/operations/ha.py new file mode 100644 index 0000000..51098ea --- /dev/null +++ b/pa_api/xmlapi/types/operations/ha.py @@ -0,0 +1,47 @@ +from typing import Optional + +from pydantic import ConfigDict, Field + +from pa_api.xmlapi.types.utils import String, XMLBaseModel + + +class HALocalInfo(XMLBaseModel): + model_config = ConfigDict(populate_by_name=True, extra="allow") + + priority: int + preemptive: bool + state: str + mode: String + ha1_backup_macaddr: str = Field(alias="ha1-backup-macaddr") + ha1_macaddr: str = Field(alias="ha1-macaddr") + mgmt_ip: str = Field(alias="mgmt-ip") + + +class HAPeerInfo(XMLBaseModel): + model_config = ConfigDict(populate_by_name=True, extra="allow") + priority: int + preemptive: bool + state: str + mode: str + conn_status: str = Field(alias="conn-status") + ha1_backup_macaddr: str = Field(alias="ha1-backup-macaddr") + ha1_macaddr: str = Field(alias="ha1-macaddr") + mgmt_ip: str = Field(alias="mgmt-ip") + + +class HAGroup(XMLBaseModel): + model_config = ConfigDict(populate_by_name=True, extra="allow") + + local_info: HALocalInfo = Field(alias="local-info") + peer_info: HAPeerInfo = Field(alias="peer-info") + + @property + def is_primary(self): + return self.local_info.priority < self.peer_info.priority + + +class HAInfo(XMLBaseModel): + model_config = ConfigDict(populate_by_name=True, extra="allow") + + enabled: bool + group: Optional[HAGroup] diff --git a/pa_api/xmlapi/types/utils.py b/pa_api/xmlapi/types/utils.py index 2a7d839..7c1dd31 100644 --- a/pa_api/xmlapi/types/utils.py +++ b/pa_api/xmlapi/types/utils.py @@ -23,8 +23,8 @@ class XMLBaseModel(BaseModel): @classmethod def from_xml(cls, xml) -> Self: - rulebase = first(el2dict(xml).values()) - return cls.model_validate(rulebase) + data = first(el2dict(xml).values()) + return cls.model_validate(data) def parse_datetime(d): @@ -95,12 +95,6 @@ def ensure_list(v: Any) -> typing.List[Any]: # Similar to typing.List, but ensure to always return a list List = Annotated[typing.List[Element], BeforeValidator(ensure_list)] -# from pydantic import TypeAdapter -# ta = TypeAdapter(List[int]) -# print(ta.validate_python(5)) -# print(ta.validate_python([5])) -# print(ta.validate_python()) - def xml_text(v: Any): if isinstance(v, dict) and "#text" in v: From 821f3de2786d951a436afcb87980f597a669c107 Mon Sep 17 00:00:00 2001 From: David Gallay Date: Fri, 20 Sep 2024 17:23:05 +0200 Subject: [PATCH 2/2] Updated package version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b78d964..bcdd166 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pa-api-sdk" -version = "0.1.3" +version = "0.1.4" description = "" authors = ["David Gallay "] readme = "README.md"