acex-devkit 1.17.1__tar.gz → 2.0.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.0.0}/PKG-INFO +1 -1
  2. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/pyproject.toml +1 -1
  3. acex_devkit-2.0.0/src/acex_devkit/models/__init__.py +87 -0
  4. acex_devkit-2.0.0/src/acex_devkit/models/asset.py +41 -0
  5. acex_devkit-2.0.0/src/acex_devkit/models/base.py +5 -0
  6. acex_devkit-2.0.0/src/acex_devkit/models/collection_agent.py +45 -0
  7. acex_devkit-2.0.0/src/acex_devkit/models/contact.py +18 -0
  8. acex_devkit-2.0.0/src/acex_devkit/models/credential.py +52 -0
  9. acex_devkit-2.0.0/src/acex_devkit/models/lldp_neighbor.py +27 -0
  10. acex_devkit-2.0.0/src/acex_devkit/models/logical_node.py +30 -0
  11. acex_devkit-2.0.0/src/acex_devkit/models/management_connection.py +24 -0
  12. acex_devkit-2.0.0/src/acex_devkit/models/node_response.py +57 -0
  13. acex_devkit-2.0.0/src/acex_devkit/models/pagination.py +11 -0
  14. acex_devkit-2.0.0/src/acex_devkit/models/region.py +23 -0
  15. acex_devkit-2.0.0/src/acex_devkit/models/site.py +20 -0
  16. acex_devkit-1.17.1/src/acex_devkit/models/__init__.py +0 -17
  17. acex_devkit-1.17.1/src/acex_devkit/models/management_connection.py +0 -16
  18. acex_devkit-1.17.1/src/acex_devkit/models/node_response.py +0 -91
  19. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/README.md +0 -0
  20. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/__init__.py +0 -0
  21. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/configdiffer/__init__.py +0 -0
  22. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/configdiffer/command.py +0 -0
  23. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/configdiffer/configdiffer.py +0 -0
  24. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/configdiffer/diff.py +0 -0
  25. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/configdiffer/old_configdiffer.py +0 -0
  26. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/configdiffer/old_diff.py +0 -0
  27. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/drivers/__init__.py +0 -0
  28. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/drivers/base.py +0 -0
  29. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/drivers/base_driver.py +0 -0
  30. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/exceptions/__init__.py +0 -0
  31. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/acl_model.py +0 -0
  32. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/attribute_value.py +0 -0
  33. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/augment.py +0 -0
  34. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/composed_configuration.py +0 -0
  35. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/container_entry.py +0 -0
  36. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/external_value.py +0 -0
  37. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/logging.py +0 -0
  38. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/ned.py +0 -0
  39. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/reference.py +0 -0
  40. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/models/spanning_tree.py +0 -0
  41. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/normalizer/__init__.py +0 -0
  42. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/normalizer/base.py +0 -0
  43. {acex_devkit-1.17.1 → acex_devkit-2.0.0}/src/acex_devkit/normalizer/engine.py +0 -0
  44. {acex_devkit-1.17.1 → acex_devkit-2.0.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.0.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.0.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] = []
@@ -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
@@ -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