acex-devkit 1.13.0__tar.gz → 1.14.1__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.13.0 → acex_devkit-1.14.1}/PKG-INFO +1 -1
  2. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/pyproject.toml +1 -1
  3. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/composed_configuration.py +94 -22
  4. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/README.md +0 -0
  5. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/__init__.py +0 -0
  6. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/configdiffer/__init__.py +0 -0
  7. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/configdiffer/command.py +0 -0
  8. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/configdiffer/configdiffer.py +0 -0
  9. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/configdiffer/diff.py +0 -0
  10. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/configdiffer/old_configdiffer.py +0 -0
  11. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/configdiffer/old_diff.py +0 -0
  12. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/drivers/__init__.py +0 -0
  13. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/drivers/base.py +0 -0
  14. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/drivers/base_driver.py +0 -0
  15. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/exceptions/__init__.py +0 -0
  16. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/__init__.py +0 -0
  17. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/acl_model.py +0 -0
  18. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/attribute_value.py +0 -0
  19. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/container_entry.py +0 -0
  20. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/external_value.py +0 -0
  21. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/logging.py +0 -0
  22. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/management_connection.py +0 -0
  23. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/ned.py +0 -0
  24. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/node_response.py +0 -0
  25. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/models/spanning_tree.py +0 -0
  26. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/normalizer/__init__.py +0 -0
  27. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/normalizer/base.py +0 -0
  28. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/src/acex_devkit/normalizer/engine.py +0 -0
  29. {acex_devkit-1.13.0 → acex_devkit-1.14.1}/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.13.0
3
+ Version: 1.14.1
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.13.0"
3
+ version = "1.14.1"
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]
@@ -351,7 +389,24 @@ class NetworkInstance(ContainerEntry, BaseModel):
351
389
  class LacpConfig(BaseModel):
352
390
  system_priority: Optional[AttributeValue[int]] = None
353
391
  system_id_mac: Optional[AttributeValue[str]] = None
354
- load_balance_algorithm: Optional[AttributeValue[list[Literal["src-mac", "dst-mac", "src-dst-mac", "src-ip", "dst-ip", "src-dst-ip", "src-port", "dst-port", "src-dst-port"]]]] = None
392
+ load_balance_algorithm: Optional[
393
+ AttributeValue[
394
+ list[
395
+ Literal[
396
+ "src-mac",
397
+ "dst-mac",
398
+ "src-dst-mac",
399
+ "src-ip",
400
+ "dst-ip",
401
+ "src-dst-ip",
402
+ "src-port",
403
+ "dst-port",
404
+ "src-dst-port",
405
+ ]
406
+ ]
407
+ ]
408
+ ] = None
409
+
355
410
 
356
411
  class Lacp(BaseModel):
357
412
  config: Optional[LacpConfig] = LacpConfig()
@@ -394,16 +449,15 @@ class SnmpConfig(ContainerEntry, BaseModel):
394
449
  contact: Optional[AttributeValue[str]] = None
395
450
 
396
451
 
397
- class SnmpCommunity(ContainerEntry, BaseModel):
452
+ class SnmpCommunity(ContainerEntry, Augmentable):
398
453
  identity_fields: ClassVar[tuple[str, ...]] = ("name",)
399
454
  name: AttributeValue[str]
400
455
  community: Optional[AttributeValue[str]] = None # Community string
401
456
  access: Optional[AttributeValue[SnmpAccess]] = AttributeValue(value=SnmpAccess.READ_ONLY)
402
457
  view: Optional[AttributeValue[str]] = None
403
- ipv4_acl: Optional[AttributeValue[str]] = None # Cisco and "liknande" vendors
458
+ ipv4_acl: Optional[AttributeValue[str]] = None # Cisco and "liknande" vendors
404
459
  ipv6_acl: Optional[AttributeValue[str]] = None
405
460
  source_interface: Optional[Reference] = None
406
- clients: Optional[AttributeValue[List[str]]] = None # Juniper specific
407
461
 
408
462
 
409
463
  class SnmpUser(ContainerEntry, BaseModel):
@@ -736,10 +790,9 @@ class TripleA(BaseModel):
736
790
  authorization: aaaAuthorization = aaaAuthorization()
737
791
  accounting: aaaAccounting = aaaAccounting()
738
792
 
739
- class VTPAttributes(BaseModel):
793
+ class VTPAttributes(Augmentable):
740
794
  domain_name: Optional[AttributeValue[str]] = None
741
795
  mode: Optional[AttributeValue[Literal["server", "client", "transparent", 'off']]] = None
742
- primary_server: Optional[AttributeValue[bool]] = False # Cisco proprietary
743
796
  version: Optional[AttributeValue[Literal[1, 2, 3]]] = None
744
797
  password: Optional[AttributeValue[str]] = None
745
798
  password_hashed: Optional[AttributeValue[str]] = None
@@ -776,9 +829,12 @@ class NetflowFormat(str, Enum):
776
829
  NETFLOW_V9 = "NetFlow v9"
777
830
  NETFLOW_V5 = "NetFlow v5"
778
831
 
779
- class NetflowRecordIpv4Match(BaseModel):
832
+
833
+ class NetflowRecordIpv4Match(ContainerEntry, BaseModel):
834
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
835
+ name: AttributeValue[str]
780
836
  # Leaf-level ipv4 matches (Cisco style "match ipv4 <field>"). True = match this field, False = No. None = Ignore the field
781
- netflow_record: Optional[AttributeValue[str]] = None # Reference to parent record, used for easier access in config component
837
+ netflow_record: Optional[AttributeValue[str]] = None # Reference to parent record, used for easier access in config component
782
838
  dscp: Optional[AttributeValue[bool]] = None
783
839
  fragmentation: Optional[AttributeValue[bool]] = None
784
840
  header_length: Optional[AttributeValue[bool]] = None
@@ -793,35 +849,46 @@ class NetflowRecordIpv4Match(BaseModel):
793
849
  ttl: Optional[AttributeValue[bool]] = None
794
850
  version: Optional[AttributeValue[bool]] = None
795
851
 
796
- class NetflowRecordAttributes(BaseModel): # Cisco flow record
852
+
853
+ class NetflowRecordAttributes(ContainerEntry, BaseModel): # Cisco flow record
854
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
855
+ name: AttributeValue[str]
797
856
  match_ipv4: Optional[NetflowRecordIpv4Match] = None
798
- #match_ipv4: Optional[Dict[str, NetflowRecordIpv4Match]] = {}
857
+ # match_ipv4: Optional[Dict[str, NetflowRecordIpv4Match]] = {}
799
858
  application_name: Optional[AttributeValue[bool]] = None
800
859
 
801
860
  # Escape hatch for vendor-specific match knobs not yet modeled
802
- match_vendor_specific: Optional[AttributeValue[Dict[str, Any]]] = None # keeping a flexible option if needed. Not advertised to users.
861
+ match_vendor_specific: Optional[AttributeValue[Dict[str, Any]]] = None # keeping a flexible option if needed. Not advertised to users.
803
862
 
804
863
  collect_timestamp_absolute_first: Optional[AttributeValue[bool]] = None
805
864
  collect_timestamp_absolute_last: Optional[AttributeValue[bool]] = None
806
865
 
807
- class NetflowCollectorAttributes(BaseModel): # Cisco flow monitor
808
- netflow_record: Optional[AttributeValue[str]] = None # Reference to record, used for easier access in config component
809
- netflow_exporter: Optional[AttributeValue[str]] = None # Reference to exporter, used for easier access in config component
866
+
867
+ class NetflowCollectorAttributes(ContainerEntry, BaseModel): # Cisco flow monitor
868
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
869
+ name: AttributeValue[str]
870
+ records: Optional[Dict[str, Reference]] = {} # References to records, used for easier access in config component
871
+ exporters: Optional[Dict[str, Reference]] = {} # References to exporters, used for easier access in config component
810
872
  cache_inactive: Optional[AttributeValue[int]] = None
811
873
  cache_active: Optional[AttributeValue[int]] = None
812
874
  interfaces: Optional[Dict[str, Reference]] = {} # allow for disabling netflow on specific interfaces
813
875
 
814
- class NetflowExporterOptions(BaseModel):
876
+
877
+ class NetflowExporterOptions(ContainerEntry, BaseModel):
815
878
  # Mostly timeouts atm
879
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
880
+ name: AttributeValue[str]
816
881
  interface_table_timeout: Optional[AttributeValue[int]] = None
817
882
  vrf_table_timeout: Optional[AttributeValue[int]] = None
818
883
  sampler_table: Optional[AttributeValue[bool]] = None
819
884
  application_table_timeout: Optional[AttributeValue[int]] = None
820
885
  application_attributes_timeout: Optional[AttributeValue[int]] = None
821
- netflow_exporter: Optional[AttributeValue[str]] = None # Reference to parent exporter, used for easier access in config component
886
+ netflow_exporter: Optional[AttributeValue[str]] = None # Reference to parent exporter, used for easier access in config component
822
887
 
823
- class NetflowExporterAttributes(ContainerEntry, BaseModel): # Cisco flow exporter
824
- identity_fields: ClassVar[tuple[str, ...]] = ("address",)
888
+
889
+ class NetflowExporterAttributes(ContainerEntry, BaseModel): # Cisco flow exporter
890
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
891
+ name: AttributeValue[str]
825
892
  address: Optional[AttributeValue[str]] = None
826
893
  port: Optional[AttributeValue[int]] = None
827
894
  netflow_format: Optional[AttributeValue[str]] = None
@@ -829,10 +896,14 @@ class NetflowExporterAttributes(ContainerEntry, BaseModel): # Cisco flow exporte
829
896
  network_instance: Optional[AttributeValue[str]] = None
830
897
  options: Optional[NetflowExporterOptions] = None
831
898
 
832
- class NetflowGlobalConfigAttributes(BaseModel):
899
+
900
+ class NetflowGlobalConfigAttributes(ContainerEntry, BaseModel):
901
+ identity_fields: ClassVar[tuple[str, ...]] = ("name",)
902
+ name: AttributeValue[str]
833
903
  enabled: Optional[AttributeValue[bool]] = None
834
904
  version: Optional[AttributeValue[int]] = None
835
905
 
906
+
836
907
  class Netflow(BaseModel):
837
908
  config: Optional[NetflowGlobalConfigAttributes] = None
838
909
  records: Optional[Dict[str, NetflowRecordAttributes]] = {}
@@ -909,6 +980,7 @@ InterfaceType = Union[
909
980
  ManagementInterface,
910
981
  ]
911
982
 
983
+
912
984
  class ComposedConfiguration(BaseModel):
913
985
  system: Optional[System] = System()
914
986
  acl: Optional[Acl] = Acl()
File without changes