acex-devkit 1.17.1__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/PKG-INFO +1 -1
  2. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/pyproject.toml +1 -1
  3. acex_devkit-2.1.0/src/acex_devkit/models/__init__.py +87 -0
  4. acex_devkit-2.1.0/src/acex_devkit/models/asset.py +41 -0
  5. acex_devkit-2.1.0/src/acex_devkit/models/base.py +5 -0
  6. acex_devkit-2.1.0/src/acex_devkit/models/collection_agent.py +45 -0
  7. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/composed_configuration.py +30 -6
  8. acex_devkit-2.1.0/src/acex_devkit/models/contact.py +18 -0
  9. acex_devkit-2.1.0/src/acex_devkit/models/credential.py +52 -0
  10. acex_devkit-2.1.0/src/acex_devkit/models/lldp_neighbor.py +27 -0
  11. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/logging.py +3 -2
  12. acex_devkit-2.1.0/src/acex_devkit/models/logical_node.py +30 -0
  13. acex_devkit-2.1.0/src/acex_devkit/models/management_connection.py +24 -0
  14. acex_devkit-2.1.0/src/acex_devkit/models/node_response.py +57 -0
  15. acex_devkit-2.1.0/src/acex_devkit/models/pagination.py +11 -0
  16. acex_devkit-2.1.0/src/acex_devkit/models/region.py +23 -0
  17. acex_devkit-2.1.0/src/acex_devkit/models/site.py +20 -0
  18. acex_devkit-1.17.1/src/acex_devkit/models/__init__.py +0 -17
  19. acex_devkit-1.17.1/src/acex_devkit/models/management_connection.py +0 -16
  20. acex_devkit-1.17.1/src/acex_devkit/models/node_response.py +0 -91
  21. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/README.md +0 -0
  22. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/__init__.py +0 -0
  23. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/configdiffer/__init__.py +0 -0
  24. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/configdiffer/command.py +0 -0
  25. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/configdiffer/configdiffer.py +0 -0
  26. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/configdiffer/diff.py +0 -0
  27. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/configdiffer/old_configdiffer.py +0 -0
  28. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/configdiffer/old_diff.py +0 -0
  29. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/drivers/__init__.py +0 -0
  30. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/drivers/base.py +0 -0
  31. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/drivers/base_driver.py +0 -0
  32. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/exceptions/__init__.py +0 -0
  33. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/acl_model.py +0 -0
  34. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/attribute_value.py +0 -0
  35. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/augment.py +0 -0
  36. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/container_entry.py +0 -0
  37. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/external_value.py +0 -0
  38. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/ned.py +0 -0
  39. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/reference.py +0 -0
  40. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/models/spanning_tree.py +0 -0
  41. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/normalizer/__init__.py +0 -0
  42. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/normalizer/base.py +0 -0
  43. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/normalizer/engine.py +0 -0
  44. {acex_devkit-1.17.1 → acex_devkit-2.1.0}/src/acex_devkit/types/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: acex-devkit
3
- Version: 1.17.1
3
+ Version: 2.1.0
4
4
  Summary: ACE-X DevKit - Development kit for building ACE-X drivers and plugins
5
5
  License: AGPL-3.0
6
6
  Keywords: automation,devkit,sdk,drivers,plugins
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "acex-devkit"
3
- version = "1.17.1"
3
+ version = "2.1.0"
4
4
  description = "ACE-X DevKit - Development kit for building ACE-X drivers and plugins"
5
5
  authors = ["Johan Lahti <johan.lahti@acebit.se>"]
6
6
  readme = "README.md"
@@ -0,0 +1,87 @@
1
+ """Models for ACE-X DevKit."""
2
+
3
+ from .base import PersistedResponse
4
+ from .external_value import ExternalValue
5
+ from .attribute_value import AttributeValue
6
+ from .management_connection import ManagementConnection, ManagementConnectionBase, ManagementConnectionResponse, ConnectionType
7
+ from .asset import Asset, AssetResponse, AssetClusterBase, AssetClusterCreate, AssetClusterUpdate, AssetClusterAssetResponse, AssetClusterResponse
8
+ from .ned import Ned
9
+ from .logical_node import LogicalNodeBase, LogicalNodeCreate, LogicalNodeListResponse, LogicalNodeResponse, LogicalNodeConfigResponse
10
+ from .node_response import NodeResponse, NodeListItem, AssetRefType, NodeStatus
11
+ from .credential import (
12
+ CredentialBase,
13
+ CredentialFieldBase,
14
+ CredentialFieldResponse,
15
+ CredentialResponse,
16
+ CredentialCreate,
17
+ CredentialUpdate,
18
+ CredentialSecret,
19
+ NodeCredentialCreate,
20
+ NodeCredentialResponse,
21
+ )
22
+ from .contact import ContactBase, ContactResponse
23
+ from .site import SiteBase, SiteResponse
24
+ from .region import RegionBase, RegionSiteInfo, RegionResponse
25
+ from .collection_agent import (
26
+ CollectionAgentBase,
27
+ CollectionAgentMatchRuleBase,
28
+ CollectionAgentMatchRuleResponse,
29
+ CollectionAgentCreate,
30
+ CollectionAgentUpdate,
31
+ CollectionAgentResponse,
32
+ )
33
+ from .lldp_neighbor import LldpNeighborBase, LldpNeighborEntry, LldpNeighborUpload, LldpNeighborResponse
34
+ from .pagination import PaginatedResponse
35
+
36
+ __all__ = [
37
+ "PersistedResponse",
38
+ "ExternalValue",
39
+ "AttributeValue",
40
+ "ManagementConnection",
41
+ "ManagementConnectionBase",
42
+ "ManagementConnectionResponse",
43
+ "ConnectionType",
44
+ "Asset",
45
+ "AssetResponse",
46
+ "AssetClusterBase",
47
+ "AssetClusterCreate",
48
+ "AssetClusterUpdate",
49
+ "AssetClusterAssetResponse",
50
+ "AssetClusterResponse",
51
+ "Ned",
52
+ "LogicalNodeBase",
53
+ "LogicalNodeCreate",
54
+ "LogicalNodeListResponse",
55
+ "LogicalNodeResponse",
56
+ "LogicalNodeConfigResponse",
57
+ "NodeResponse",
58
+ "NodeListItem",
59
+ "AssetRefType",
60
+ "NodeStatus",
61
+ "CredentialBase",
62
+ "CredentialFieldBase",
63
+ "CredentialFieldResponse",
64
+ "CredentialResponse",
65
+ "CredentialCreate",
66
+ "CredentialUpdate",
67
+ "CredentialSecret",
68
+ "NodeCredentialCreate",
69
+ "NodeCredentialResponse",
70
+ "ContactBase",
71
+ "ContactResponse",
72
+ "SiteBase",
73
+ "SiteResponse",
74
+ "RegionBase",
75
+ "RegionSiteInfo",
76
+ "RegionResponse",
77
+ "CollectionAgentBase",
78
+ "CollectionAgentMatchRuleBase",
79
+ "CollectionAgentMatchRuleResponse",
80
+ "CollectionAgentCreate",
81
+ "CollectionAgentUpdate",
82
+ "CollectionAgentResponse",
83
+ "LldpNeighborBase",
84
+ "LldpNeighborEntry",
85
+ "LldpNeighborUpload",
86
+ "LldpNeighborResponse",
87
+ ]
@@ -0,0 +1,41 @@
1
+ from typing import Optional, Literal
2
+ from pydantic import BaseModel, Field
3
+
4
+ from acex_devkit.models.base import PersistedResponse
5
+
6
+
7
+ class Asset(BaseModel):
8
+ vendor: str = Field(default="cisco")
9
+ serial_number: str = Field(default="abc123")
10
+ os: str = Field(default="ios")
11
+ os_version: str = Field(default="12.0.1")
12
+ hardware_model: str = Field(default="")
13
+ ned_id: Optional[str] = None
14
+
15
+
16
+ class AssetResponse(PersistedResponse, Asset):
17
+ type: Literal["asset"] = "asset"
18
+
19
+
20
+ class AssetClusterBase(BaseModel):
21
+ name: str
22
+ ned_id: Optional[str] = None
23
+
24
+
25
+ class AssetClusterCreate(AssetClusterBase):
26
+ pass
27
+
28
+
29
+ class AssetClusterUpdate(BaseModel):
30
+ name: Optional[str] = None
31
+ ned_id: Optional[str] = None
32
+ asset_ids: Optional[list[int]] = None
33
+
34
+
35
+ class AssetClusterAssetResponse(PersistedResponse, Asset):
36
+ cluster_index: Optional[int] = None
37
+
38
+
39
+ class AssetClusterResponse(PersistedResponse, AssetClusterBase):
40
+ type: Literal["asset_cluster"] = "asset_cluster"
41
+ assets: list[AssetClusterAssetResponse] = []
@@ -0,0 +1,5 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class PersistedResponse(BaseModel):
5
+ id: int
@@ -0,0 +1,45 @@
1
+ from pydantic import BaseModel
2
+ from typing import Optional
3
+
4
+ from acex_devkit.models.base import PersistedResponse
5
+
6
+
7
+ class CollectionAgentBase(BaseModel):
8
+ name: str
9
+ description: Optional[str] = None
10
+ interval_seconds: int = 21600
11
+ enabled: bool = True
12
+
13
+
14
+ class CollectionAgentMatchRuleBase(BaseModel):
15
+ region: Optional[str] = None
16
+ site: Optional[str] = None
17
+ vendor: Optional[str] = None
18
+ os: Optional[str] = None
19
+ status: Optional[str] = None
20
+ role: Optional[str] = None
21
+
22
+
23
+ class CollectionAgentMatchRuleResponse(PersistedResponse, CollectionAgentMatchRuleBase):
24
+ pass
25
+
26
+
27
+ class CollectionAgentCreate(CollectionAgentBase):
28
+ pass
29
+
30
+
31
+ class CollectionAgentUpdate(BaseModel):
32
+ name: Optional[str] = None
33
+ description: Optional[str] = None
34
+ interval_seconds: Optional[int] = None
35
+ enabled: Optional[bool] = None
36
+
37
+
38
+ class CollectionAgentResponse(PersistedResponse, CollectionAgentBase):
39
+ config_revision: int = 0
40
+ last_manifest_poll: Optional[str] = None
41
+ acked_revision: int = 0
42
+ acked_at: Optional[str] = None
43
+ nodes: list[int] = []
44
+ rules: list[CollectionAgentMatchRuleResponse] = []
45
+ resolved_nodes: list[int] = []
@@ -706,8 +706,14 @@ class aaaAuthenticationAdminUsers(ContainerEntry, BaseModel):
706
706
  identity_fields: ClassVar[tuple[str, ...]] = ()
707
707
  config: Optional[Dict[str, adminUser]] = {}
708
708
 
709
+ class aaaAuthenticationConfig(ContainerEntry, Augmentable):
710
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
711
+ name: Optional[AttributeValue[str]] = None # ex. default, CONSOLE, etc.
712
+ methods: Optional[Dict[str, aaaAuthenticationMethods]] = {}
713
+
709
714
  class aaaAuthentication(BaseModel):
710
- config: Optional[Dict[str, aaaAuthenticationMethods]] = {}
715
+ #config: Optional[Dict[str, aaaAuthenticationMethods]] = {}
716
+ config: aaaAuthenticationConfig = aaaAuthenticationConfig()
711
717
  admin_user: Optional[Dict[str, aaaAuthenticationAdminUsers]] = {}
712
718
  users: Optional[Dict[str, aaaAuthenticationUsers]] = {}
713
719
 
@@ -738,10 +744,18 @@ class aaaAuthorizationEvents(aaaBaseClass):
738
744
  #event: Optional[AttributeValue[List[str]]] = None
739
745
  event: Optional[AttributeValue[str]] = None
740
746
 
741
- class aaaAuthorization(BaseModel):
742
- config: Optional[Dict[str, aaaAuthorizationMethods]] = {}
747
+ class aaaAuthorizationConfig(ContainerEntry, Augmentable):
748
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
749
+ name: Optional[AttributeValue[str]] = None # ex. default, CONSOLE, etc.
750
+ methods: Optional[Dict[str, aaaAuthorizationMethods]] = {}
743
751
  events: Optional[Dict[str, aaaAuthorizationEvents]] = {}
744
752
 
753
+ class aaaAuthorization(BaseModel):
754
+ #config: Optional[Dict[str, aaaAuthorizationMethods]] = {}
755
+ config: aaaAuthorizationConfig = aaaAuthorizationConfig()
756
+ #methods: Optional[Dict[str, aaaAuthorizationMethods]] = {}
757
+ #events: Optional[Dict[str, aaaAuthorizationEvents]] = {}
758
+
745
759
  # Accounting Models
746
760
  class aaaAccountingMethods(ContainerEntry, BaseModel):
747
761
  identity_fields: ClassVar[tuple[str, ...]] = ()
@@ -769,11 +783,21 @@ class aaaAccountingEvents(ContainerEntry, BaseModel):
769
783
  #events: Optional[List[str]] = Field(default_factory=list) # Ex. ['send','stop-record','authentication', 'failure']
770
784
  event: Optional[AttributeValue[str]] = None
771
785
 
772
- class aaaAccounting(BaseModel):
773
- config: Optional[Dict[str, aaaAccountingMethods]] = {}
786
+ class aaaAccountingConfig(ContainerEntry, Augmentable):
787
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
788
+ name: Optional[AttributeValue[str]] = None # ex. default, CONSOLE, etc.
789
+ methods: Optional[Dict[str, aaaAccountingMethods]] = {}
774
790
  events: Optional[Dict[str, aaaAccountingEvents]] = {}
775
791
 
776
- class aaaGlobalAttributes(BaseModel):
792
+ class aaaAccounting(BaseModel):
793
+ #config: Optional[Dict[str, aaaAccountingMethods]] = {}
794
+ config: aaaAccountingConfig = aaaAccountingConfig()
795
+ #methods: Optional[Dict[str, aaaAccountingMethods]] = {}
796
+ #events: Optional[Dict[str, aaaAccountingEvents]] = {}
797
+
798
+ class aaaGlobalAttributes(ContainerEntry, BaseModel):
799
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
800
+ name: Optional[AttributeValue[str]] = None # ex. default, CONSOLE, etc.
777
801
  enabled: Optional[AttributeValue[bool]] = False # default False
778
802
 
779
803
  class TripleA(BaseModel):
@@ -0,0 +1,18 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import Optional
3
+
4
+ from acex_devkit.models.base import PersistedResponse
5
+
6
+
7
+ class ContactBase(BaseModel):
8
+ name: str = Field(default="")
9
+ display_name: Optional[str] = None
10
+ first_name: Optional[str] = None
11
+ family_name: Optional[str] = None
12
+ email: Optional[str] = None
13
+ phone: Optional[str] = None
14
+ role: Optional[str] = None
15
+
16
+
17
+ class ContactResponse(PersistedResponse, ContactBase):
18
+ pass
@@ -0,0 +1,52 @@
1
+ from pydantic import BaseModel
2
+ from typing import Optional, Dict, List
3
+
4
+ from acex_devkit.models.base import PersistedResponse
5
+
6
+
7
+ class CredentialFieldBase(BaseModel):
8
+ field_name: str
9
+ sensitive: bool = True
10
+
11
+
12
+ class CredentialBase(BaseModel):
13
+ name: str
14
+ credential_type: str
15
+ source: str = "local"
16
+ vault_path: Optional[str] = None
17
+
18
+
19
+ class CredentialFieldResponse(CredentialFieldBase):
20
+ field_value: Optional[str] = None
21
+
22
+
23
+ class CredentialResponse(PersistedResponse, CredentialBase):
24
+ fields: List[CredentialFieldResponse] = []
25
+
26
+
27
+ class CredentialCreate(CredentialBase):
28
+ fields: Dict[str, str]
29
+
30
+
31
+ class CredentialUpdate(BaseModel):
32
+ name: Optional[str] = None
33
+ source: Optional[str] = None
34
+ vault_path: Optional[str] = None
35
+ fields: Optional[Dict[str, str]] = None
36
+
37
+
38
+ class CredentialSecret(BaseModel):
39
+ id: int
40
+ credential_type: str
41
+ fields: Dict[str, str] = {}
42
+
43
+
44
+ class NodeCredentialCreate(BaseModel):
45
+ credential_id: int
46
+
47
+
48
+ class NodeCredentialResponse(PersistedResponse):
49
+ node_id: int
50
+ credential_id: int
51
+ credential_name: Optional[str] = None
52
+ credential_type: Optional[str] = None
@@ -0,0 +1,27 @@
1
+ from pydantic import BaseModel
2
+ from typing import Optional
3
+ from datetime import datetime
4
+
5
+ from acex_devkit.models.base import PersistedResponse
6
+
7
+
8
+ class LldpNeighborBase(BaseModel):
9
+ local_interface: str
10
+ remote_device: str
11
+ remote_interface: str = ""
12
+ discovery_protocol: str = "lldp"
13
+
14
+
15
+ class LldpNeighborEntry(LldpNeighborBase):
16
+ pass
17
+
18
+
19
+ class LldpNeighborUpload(BaseModel):
20
+ node_instance_id: int
21
+ neighbors: list[LldpNeighborEntry]
22
+
23
+
24
+ class LldpNeighborResponse(PersistedResponse, LldpNeighborBase):
25
+ node_instance_id: int
26
+ remote_node_id: Optional[int] = None
27
+ collected_at: datetime
@@ -42,7 +42,8 @@ class LoggingConfig(Augmentable):
42
42
  severity: Optional[AttributeValue[LoggingSeverity]] = None
43
43
  buffer_size: Optional[AttributeValue[int]] = None
44
44
 
45
- class Console(Augmentable):
45
+ class Console(ContainerEntry, Augmentable):
46
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
46
47
  name: Optional[AttributeValue[str]] = None
47
48
  line_number: Optional[AttributeValue[int]] = None
48
49
  logging_synchronous: Optional[AttributeValue[bool]] = None
@@ -58,7 +59,7 @@ class RemoteServer(ContainerEntry, BaseModel):
58
59
  class RemoteServers(BaseModel):
59
60
  servers: Dict[str, RemoteServer] = {}
60
61
 
61
- class VtyLine(ContainerEntry, BaseModel):
62
+ class VtyLine(ContainerEntry, Augmentable):
62
63
  identity_fields: ClassVar[tuple[str, ...]] = ("line_number",)
63
64
  name: Optional[AttributeValue[str]] = None
64
65
  line_number: Optional[AttributeValue[int]] = None
@@ -0,0 +1,30 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import Optional, Dict, Any
3
+
4
+ from acex_devkit.models.base import PersistedResponse
5
+ from acex_devkit.models.composed_configuration import ComposedConfiguration
6
+
7
+
8
+ class LogicalNodeBase(BaseModel):
9
+ hostname: str = Field(default="R1")
10
+ role: str = Field(default="core")
11
+ site: Optional[str] = Field(default=None)
12
+ sequence: Optional[int] = Field(default=None)
13
+
14
+
15
+ class LogicalNodeCreate(LogicalNodeBase):
16
+ pass
17
+
18
+
19
+ class LogicalNodeListResponse(PersistedResponse, LogicalNodeBase):
20
+ regions: list[str] = []
21
+
22
+
23
+ class LogicalNodeResponse(PersistedResponse, LogicalNodeBase):
24
+ regions: list[str] = []
25
+
26
+
27
+ class LogicalNodeConfigResponse(PersistedResponse, LogicalNodeBase):
28
+ configuration: ComposedConfiguration
29
+ meta_data: Dict[str, Any] = {}
30
+ regions: list[str] = []
@@ -0,0 +1,24 @@
1
+ from pydantic import BaseModel
2
+ from typing import Optional
3
+ from enum import Enum
4
+
5
+ from acex_devkit.models.base import PersistedResponse
6
+
7
+
8
+ class ConnectionType(str, Enum):
9
+ ssh = "ssh"
10
+ telnet = "telnet"
11
+
12
+
13
+ class ManagementConnectionBase(BaseModel):
14
+ primary: bool = True
15
+ connection_type: ConnectionType = ConnectionType.ssh
16
+ target_ip: Optional[str] = None
17
+
18
+
19
+ class ManagementConnectionResponse(PersistedResponse, ManagementConnectionBase):
20
+ node_id: int
21
+
22
+
23
+ # Kept for backward compatibility
24
+ ManagementConnection = ManagementConnectionResponse
@@ -0,0 +1,57 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import Annotated, Optional, Union
3
+ from enum import Enum
4
+ from datetime import datetime
5
+
6
+ from acex_devkit.models.base import PersistedResponse
7
+ from acex_devkit.models.logical_node import LogicalNodeResponse
8
+ from acex_devkit.models.asset import Asset, AssetClusterBase, AssetClusterAssetResponse, AssetResponse, AssetClusterResponse
9
+
10
+
11
+ class AssetRefType(str, Enum):
12
+ asset = "asset"
13
+ asset_cluster = "asset_cluster"
14
+
15
+
16
+ class NodeStatus(str, Enum):
17
+ planned = "planned"
18
+ init = "init"
19
+ active = "active"
20
+ decommissioned = "decommissioned"
21
+
22
+
23
+ class NodeBase(BaseModel):
24
+ asset_ref_id: int
25
+ asset_ref_type: Optional[AssetRefType] = None
26
+ logical_node_id: int
27
+ status: Optional[NodeStatus] = None
28
+
29
+
30
+ class NodeListItem(PersistedResponse, NodeBase):
31
+ hostname: Optional[str] = None
32
+ site: Optional[str] = None
33
+ role: Optional[str] = None
34
+ regions: list[str] = []
35
+ vendor: Optional[str] = None
36
+ os: Optional[str] = None
37
+ ned_id: Optional[str] = None
38
+ created_at: Optional[datetime] = None
39
+ updated_at: Optional[datetime] = None
40
+
41
+
42
+ class NodeResponse(PersistedResponse, NodeBase):
43
+ asset: Annotated[Union[AssetResponse, AssetClusterResponse], Field(discriminator="type")]
44
+ logical_node: LogicalNodeResponse
45
+ regions: list[str] = []
46
+ created_at: datetime
47
+ updated_at: Optional[datetime] = None
48
+
49
+
50
+ __all__ = [
51
+ "LogicalNodeResponse",
52
+ "AssetRefType",
53
+ "NodeStatus",
54
+ "NodeBase",
55
+ "NodeListItem",
56
+ "NodeResponse",
57
+ ]
@@ -0,0 +1,11 @@
1
+ from pydantic import BaseModel
2
+ from typing import Generic, TypeVar, List
3
+
4
+ T = TypeVar("T")
5
+
6
+
7
+ class PaginatedResponse(BaseModel, Generic[T]):
8
+ items: List[T]
9
+ total: int
10
+ limit: int
11
+ offset: int
@@ -0,0 +1,23 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import Optional
3
+
4
+ from acex_devkit.models.base import PersistedResponse
5
+
6
+
7
+ class RegionBase(BaseModel):
8
+ name: str = Field(default="")
9
+ display_name: Optional[str] = None
10
+ description: Optional[str] = None
11
+
12
+
13
+ class RegionSiteInfo(BaseModel):
14
+ name: str
15
+ display_name: Optional[str] = None
16
+ city: Optional[str] = None
17
+ country: Optional[str] = None
18
+ latitude: Optional[float] = None
19
+ longitude: Optional[float] = None
20
+
21
+
22
+ class RegionResponse(PersistedResponse, RegionBase):
23
+ sites: list[RegionSiteInfo] = []
@@ -0,0 +1,20 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import Optional
3
+
4
+ from acex_devkit.models.base import PersistedResponse
5
+ from acex_devkit.models.contact import ContactResponse
6
+
7
+
8
+ class SiteBase(BaseModel):
9
+ name: str = Field(default="")
10
+ display_name: Optional[str] = None
11
+ address: Optional[str] = None
12
+ city: Optional[str] = None
13
+ country: Optional[str] = None
14
+ latitude: Optional[float] = None
15
+ longitude: Optional[float] = None
16
+ description: Optional[str] = None
17
+
18
+
19
+ class SiteResponse(PersistedResponse, SiteBase):
20
+ contacts: list[ContactResponse] = []
@@ -1,17 +0,0 @@
1
- """Models for ACE-X DevKit."""
2
-
3
- # TODO: Move all models to this package
4
- # TODO: Move all base classes to this package
5
-
6
- from .external_value import ExternalValue
7
- from .attribute_value import AttributeValue
8
- from .node_response import NodeResponse, NodeListItem, LogicalNodeResponse
9
- from .management_connection import ManagementConnection, ConnectionType
10
-
11
- __all__ = [
12
- ExternalValue,
13
- AttributeValue,
14
- NodeResponse,
15
- NodeListItem,
16
- LogicalNodeResponse
17
- ]
@@ -1,16 +0,0 @@
1
- from pydantic import BaseModel
2
- from typing import Optional
3
- from enum import Enum
4
-
5
-
6
- class ConnectionType(str, Enum):
7
- ssh = "ssh"
8
- telnet = "telnet"
9
-
10
-
11
- class ManagementConnection(BaseModel):
12
- id: Optional[int] = None
13
- node_id: Optional[int] = None
14
- primary: bool = True
15
- connection_type: ConnectionType = ConnectionType.ssh
16
- target_ip: Optional[str] = None
@@ -1,91 +0,0 @@
1
- from pydantic import BaseModel, Field
2
- from typing import Annotated, Optional, Dict, Any, List, Literal, Union
3
- from enum import Enum
4
- from datetime import datetime
5
- from acex_devkit.models.composed_configuration import ComposedConfiguration
6
-
7
-
8
- class LogicalNodeResponse(BaseModel):
9
- id: Optional[int] = None
10
- hostname: Optional[str] = None
11
- role: Optional[str] = None
12
- site: Optional[str] = None
13
- sequence: Optional[int] = None
14
- configuration: Optional[ComposedConfiguration] = None
15
- meta_data: Optional[Dict[str, Any]] = None
16
-
17
-
18
- class Asset(BaseModel):
19
- id: Optional[int] = None
20
- type: Literal["asset"] = "asset"
21
- vendor: Optional[str] = None
22
- serial_number: Optional[str] = None
23
- os: Optional[str] = None
24
- os_version: Optional[str] = None
25
- hardware_model: Optional[str] = None
26
- ned_id: Optional[str] = None
27
-
28
-
29
- class AssetClusterAsset(BaseModel):
30
- id: Optional[int] = None
31
- vendor: Optional[str] = None
32
- serial_number: Optional[str] = None
33
- os: Optional[str] = None
34
- os_version: Optional[str] = None
35
- hardware_model: Optional[str] = None
36
- ned_id: Optional[str] = None
37
- cluster_index: Optional[int] = None
38
-
39
-
40
- class AssetCluster(BaseModel):
41
- id: Optional[int] = None
42
- type: Literal["asset_cluster"] = "asset_cluster"
43
- name: Optional[str] = None
44
- ned_id: Optional[str] = None
45
- assets: List[AssetClusterAsset] = []
46
-
47
-
48
- class AssetRefType(str, Enum):
49
- asset = "asset"
50
- asset_cluster = "asset_cluster"
51
-
52
-
53
- class NodeStatus(str, Enum):
54
- planned = "planned"
55
- init = "init"
56
- active = "active"
57
- decommissioned = "decommissioned"
58
-
59
-
60
- class NodeBase(BaseModel):
61
- asset_ref_id: int
62
- asset_ref_type: Optional[AssetRefType] = None
63
- logical_node_id: int
64
- status: Optional[NodeStatus] = None
65
-
66
- class Node(NodeBase):
67
- id: Optional[int] = None
68
- created_at: Optional[datetime] = None
69
- updated_at: Optional[datetime] = None
70
-
71
-
72
- class NodeListItem(NodeBase):
73
- """Enriched list representation with denormalized fields from asset and logical_node."""
74
- id: Optional[int] = None
75
- # From logical_node
76
- hostname: Optional[str] = None
77
- site: Optional[str] = None
78
- # From asset
79
- vendor: Optional[str] = None
80
- os: Optional[str] = None
81
- ned_id: Optional[str] = None
82
- created_at: Optional[datetime] = None
83
- updated_at: Optional[datetime] = None
84
-
85
-
86
- class NodeResponse(NodeBase):
87
- id: Optional[int] = None
88
- asset: Annotated[Union[Asset, AssetCluster], Field(discriminator="type")]
89
- logical_node: LogicalNodeResponse
90
- created_at: datetime
91
- updated_at: Optional[datetime] = None
File without changes