acex-devkit 1.12.0__tar.gz → 1.14.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 (29) hide show
  1. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/PKG-INFO +1 -1
  2. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/pyproject.toml +1 -1
  3. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/composed_configuration.py +58 -8
  4. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/README.md +0 -0
  5. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/__init__.py +0 -0
  6. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/configdiffer/__init__.py +0 -0
  7. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/configdiffer/command.py +0 -0
  8. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/configdiffer/configdiffer.py +0 -0
  9. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/configdiffer/diff.py +0 -0
  10. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/configdiffer/old_configdiffer.py +0 -0
  11. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/configdiffer/old_diff.py +0 -0
  12. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/drivers/__init__.py +0 -0
  13. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/drivers/base.py +0 -0
  14. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/drivers/base_driver.py +0 -0
  15. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/exceptions/__init__.py +0 -0
  16. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/__init__.py +0 -0
  17. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/acl_model.py +0 -0
  18. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/attribute_value.py +0 -0
  19. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/container_entry.py +0 -0
  20. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/external_value.py +0 -0
  21. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/logging.py +0 -0
  22. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/management_connection.py +0 -0
  23. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/ned.py +0 -0
  24. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/node_response.py +0 -0
  25. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/models/spanning_tree.py +0 -0
  26. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/normalizer/__init__.py +0 -0
  27. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/normalizer/base.py +0 -0
  28. {acex_devkit-1.12.0 → acex_devkit-1.14.0}/src/acex_devkit/normalizer/engine.py +0 -0
  29. {acex_devkit-1.12.0 → acex_devkit-1.14.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.12.0
3
+ Version: 1.14.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.12.0"
3
+ version = "1.14.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"
@@ -1,5 +1,5 @@
1
1
 
2
- from pydantic import BaseModel, Field
2
+ from pydantic import BaseModel, ConfigDict, Field, SerializeAsAny
3
3
  from typing import Optional, Dict, List, Literal, ClassVar, Union, Any
4
4
  from enum import Enum
5
5
 
@@ -147,7 +147,45 @@ class StormControlAttributes(BaseModel):
147
147
  action: Optional[AttributeValue[Literal["trap", "shutdown"]]] = None
148
148
 
149
149
 
150
- class InterfaceTemplateAttributes(ContainerEntry, BaseModel):
150
+ # --- Augments --------------------------------------------------------------
151
+ # Vendor/os-specific augments mount on target tree components via the
152
+ # `Augmentable` mixin. Devkit only knows about `AugmentAttributes` — the
153
+ # generic base — and uses `extra='allow'` to round-trip subclass-specific
154
+ # fields. Concrete augment payload classes (CiscoDeviceTrackingPolicy-
155
+ # Attributes, etc.) live in the backend alongside their ConfigComponent
156
+ # classes, so adding a new vendor augment requires no devkit edit.
157
+
158
+ class AugmentAttributes(BaseModel):
159
+ """
160
+ Base for vendor/os-specific augments that mount on target tree components.
161
+
162
+ Subclasses live in the backend (next to their ConfigComponent) and add
163
+ typed payload fields. `extra='allow'` lets those fields round-trip
164
+ through serialize → JSON → re-validate without devkit knowing about them.
165
+
166
+ Augments live on a target node's `augments` dict, keyed by `type`. The
167
+ target itself is implicit (it's the node carrying this augment).
168
+ """
169
+ model_config = ConfigDict(extra="allow")
170
+ type: str
171
+
172
+
173
+ class Augmentable(BaseModel):
174
+ """
175
+ Mixin that gives a target node a slot for vendor/os-specific augments.
176
+ Drivers walk `augments` per target and dispatch by augment type; targets
177
+ that no driver augments simply carry an empty dict.
178
+
179
+ `SerializeAsAny[AugmentAttributes]` makes Pydantic serialize each value
180
+ using its runtime type (the concrete subclass defined in backend),
181
+ not the declared base type. Combined with `extra='allow'` on
182
+ AugmentAttributes, this round-trips subclass-declared fields through
183
+ serialize → JSON → re-validate without devkit knowing the subclasses.
184
+ """
185
+ augments: Dict[str, SerializeAsAny[AugmentAttributes]] = {}
186
+
187
+
188
+ class InterfaceTemplateAttributes(ContainerEntry, Augmentable):
151
189
  "Reusable named set of interface attributes that interfaces can reference."
152
190
  identity_fields: ClassVar[tuple[str, ...]] = ("name",)
153
191
  name: AttributeValue[str]
@@ -194,7 +232,7 @@ class InterfaceTemplateAttributes(ContainerEntry, BaseModel):
194
232
  lacp_interval: Optional[AttributeValue[Literal["fast", "slow"]]] = None
195
233
 
196
234
 
197
- class Interface(ContainerEntry, BaseModel):
235
+ class Interface(ContainerEntry, Augmentable):
198
236
  "Base class for all interfaces"
199
237
  identity_fields: ClassVar[tuple[str, ...]] = ("index", "type")
200
238
  index: AttributeValue[int]
@@ -394,16 +432,15 @@ class SnmpConfig(ContainerEntry, BaseModel):
394
432
  contact: Optional[AttributeValue[str]] = None
395
433
 
396
434
 
397
- class SnmpCommunity(ContainerEntry, BaseModel):
435
+ class SnmpCommunity(ContainerEntry, Augmentable):
398
436
  identity_fields: ClassVar[tuple[str, ...]] = ("name",)
399
437
  name: AttributeValue[str]
400
438
  community: Optional[AttributeValue[str]] = None # Community string
401
439
  access: Optional[AttributeValue[SnmpAccess]] = AttributeValue(value=SnmpAccess.READ_ONLY)
402
440
  view: Optional[AttributeValue[str]] = None
403
- ipv4_acl: Optional[AttributeValue[str]] = None # Cisco and "liknande" vendors
441
+ ipv4_acl: Optional[AttributeValue[str]] = None # Cisco and "liknande" vendors
404
442
  ipv6_acl: Optional[AttributeValue[str]] = None
405
443
  source_interface: Optional[Reference] = None
406
- clients: Optional[AttributeValue[List[str]]] = None # Juniper specific
407
444
 
408
445
 
409
446
  class SnmpUser(ContainerEntry, BaseModel):
@@ -736,10 +773,9 @@ class TripleA(BaseModel):
736
773
  authorization: aaaAuthorization = aaaAuthorization()
737
774
  accounting: aaaAccounting = aaaAccounting()
738
775
 
739
- class VTPAttributes(BaseModel):
776
+ class VTPAttributes(Augmentable):
740
777
  domain_name: Optional[AttributeValue[str]] = None
741
778
  mode: Optional[AttributeValue[Literal["server", "client", "transparent", 'off']]] = None
742
- primary_server: Optional[AttributeValue[bool]] = False # Cisco proprietary
743
779
  version: Optional[AttributeValue[Literal[1, 2, 3]]] = None
744
780
  password: Optional[AttributeValue[str]] = None
745
781
  password_hashed: Optional[AttributeValue[str]] = None
@@ -875,6 +911,18 @@ class Sampling(BaseModel):
875
911
  netflow: Optional[Netflow] = Netflow()
876
912
  #sflow: Optional[Sflow] = Sflow() # Sflow can be added in the future, similar structure to Netflow
877
913
 
914
+ class DnsServerAttributes(ContainerEntry, BaseModel):
915
+ identity_fields: ClassVar[tuple[str, ...]] = ("address",)
916
+ address: Optional[AttributeValue[str]] = None
917
+ port: Optional[AttributeValue[int]] = None # Keeping option to allow for use where needed, even if default DNS port is 53
918
+ source_interface: Optional[Reference] = None # Keeping option to allow for use where needed
919
+ network_instance: Optional[AttributeValue[str]] = None
920
+
921
+ class Dns(BaseModel):
922
+ # Placeholder for DNS configuration. Can be expanded with actual DNS attributes as needed.
923
+ #enabled: Optional[AttributeValue[bool]] = None
924
+ dns_servers: Optional[Dict[str, DnsServerAttributes]] = {} # key is server name, value is IP address
925
+
878
926
  class System(BaseModel):
879
927
  config: SystemConfig = SystemConfig()
880
928
  aaa: Optional[TripleA] = TripleA()
@@ -884,6 +932,7 @@ class System(BaseModel):
884
932
  snmp: Optional[Snmp] = Snmp()
885
933
  vtp: Optional[VTP] = VTP()
886
934
  dhcp: Optional[Dhcp] = Dhcp()
935
+ dns: Optional[Dns] = Dns()
887
936
  services: Optional[Services] = Services()
888
937
 
889
938
  # For different types of interfaces that are fine for response model:
@@ -896,6 +945,7 @@ InterfaceType = Union[
896
945
  ManagementInterface,
897
946
  ]
898
947
 
948
+
899
949
  class ComposedConfiguration(BaseModel):
900
950
  system: Optional[System] = System()
901
951
  acl: Optional[Acl] = Acl()
File without changes