diff --git a/catalystwan/api/policy_api.py b/catalystwan/api/policy_api.py index dd282bcb..6221fd3d 100644 --- a/catalystwan/api/policy_api.py +++ b/catalystwan/api/policy_api.py @@ -6,108 +6,48 @@ from uuid import UUID from catalystwan.api.task_status_api import Task -from catalystwan.endpoints.configuration.policy.definition.access_control_list import ( - AclPolicyGetResponse, - ConfigurationPolicyAclDefinition, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints, PolicyListEndpoints +from catalystwan.endpoints.configuration.policy.definition.access_control_list import ConfigurationPolicyAclDefinition from catalystwan.endpoints.configuration.policy.definition.access_control_list_ipv6 import ( - AclIPv6PolicyGetResponse, ConfigurationPolicyAclIPv6Definition, ) -from catalystwan.endpoints.configuration.policy.definition.control import ( - ConfigurationPolicyControlDefinition, - ControlPolicyGetResponse, -) +from catalystwan.endpoints.configuration.policy.definition.control import ConfigurationPolicyControlDefinition from catalystwan.endpoints.configuration.policy.definition.device_access import ( ConfigurationPolicyDeviceAccessDefinition, - DeviceAccessPolicyGetResponse, ) from catalystwan.endpoints.configuration.policy.definition.device_access_ipv6 import ( ConfigurationPolicyDeviceAccessIPv6Definition, - DeviceAccessIPv6PolicyGetResponse, -) -from catalystwan.endpoints.configuration.policy.definition.hub_and_spoke import ( - ConfigurationPolicyHubAndSpokeDefinition, - HubAndSpokePolicyGetResponse, -) -from catalystwan.endpoints.configuration.policy.definition.mesh import ( - ConfigurationPolicyMeshDefinition, - MeshPolicyGetResponse, -) -from catalystwan.endpoints.configuration.policy.definition.qos_map import ( - ConfigurationPolicyQoSMapDefinition, - QoSMapPolicyGetResponse, -) -from catalystwan.endpoints.configuration.policy.definition.rewrite import ( - ConfigurationPolicyRewriteRuleDefinition, - RewritePolicyGetResponse, -) -from catalystwan.endpoints.configuration.policy.definition.rule_set import ( - ConfigurationPolicyRuleSetDefinition, - RuleSetGetResponse, ) +from catalystwan.endpoints.configuration.policy.definition.hub_and_spoke import ConfigurationPolicyHubAndSpokeDefinition +from catalystwan.endpoints.configuration.policy.definition.mesh import ConfigurationPolicyMeshDefinition +from catalystwan.endpoints.configuration.policy.definition.qos_map import ConfigurationPolicyQoSMapDefinition +from catalystwan.endpoints.configuration.policy.definition.rewrite import ConfigurationPolicyRewriteRuleDefinition +from catalystwan.endpoints.configuration.policy.definition.rule_set import ConfigurationPolicyRuleSetDefinition from catalystwan.endpoints.configuration.policy.definition.security_group import ( ConfigurationPolicySecurityGroupDefinition, - SecurityGroupGetResponse, -) -from catalystwan.endpoints.configuration.policy.definition.traffic_data import ( - ConfigurationPolicyDataDefinition, - TrafficDataPolicy, - TrafficDataPolicyGetResponse, ) +from catalystwan.endpoints.configuration.policy.definition.traffic_data import ConfigurationPolicyDataDefinition from catalystwan.endpoints.configuration.policy.definition.vpn_membership import ( ConfigurationPolicyVPNMembershipGroupDefinition, - VPNMembershipPolicyGetResponse, ) from catalystwan.endpoints.configuration.policy.definition.zone_based_firewall import ( ConfigurationPolicyZoneBasedFirewallDefinition, - ZoneBasedFWPolicyGetResponse, ) from catalystwan.endpoints.configuration.policy.list.app import AppListInfo, ConfigurationPolicyApplicationList -from catalystwan.endpoints.configuration.policy.list.app_probe import ( - AppProbeClassListInfo, - ConfigurationPolicyAppProbeClassList, -) +from catalystwan.endpoints.configuration.policy.list.app_probe import ConfigurationPolicyAppProbeClassList from catalystwan.endpoints.configuration.policy.list.as_path import ASPathListInfo, ConfigurationPolicyASPathList -from catalystwan.endpoints.configuration.policy.list.class_map import ( - ClassMapListInfo, - ConfigurationPolicyForwardingClassList, -) +from catalystwan.endpoints.configuration.policy.list.class_map import ConfigurationPolicyForwardingClassList from catalystwan.endpoints.configuration.policy.list.color import ColorListInfo, ConfigurationPolicyColorList -from catalystwan.endpoints.configuration.policy.list.community import ( - CommunityListInfo, - ConfigurationPolicyCommunityList, -) -from catalystwan.endpoints.configuration.policy.list.data_ipv6_prefix import ( - ConfigurationPolicyDataIPv6PrefixList, - DataIPv6PrefixListInfo, -) -from catalystwan.endpoints.configuration.policy.list.data_prefix import ( - ConfigurationPolicyDataPrefixList, - DataPrefixListInfo, -) -from catalystwan.endpoints.configuration.policy.list.expanded_community import ( - ConfigurationPolicyExpandedCommunityList, - ExpandedCommunityListInfo, -) +from catalystwan.endpoints.configuration.policy.list.community import ConfigurationPolicyCommunityList +from catalystwan.endpoints.configuration.policy.list.data_ipv6_prefix import ConfigurationPolicyDataIPv6PrefixList +from catalystwan.endpoints.configuration.policy.list.data_prefix import ConfigurationPolicyDataPrefixList +from catalystwan.endpoints.configuration.policy.list.expanded_community import ConfigurationPolicyExpandedCommunityList from catalystwan.endpoints.configuration.policy.list.fqdn import ConfigurationPolicyFQDNList, FQDNListInfo -from catalystwan.endpoints.configuration.policy.list.geo_location import ( - ConfigurationPolicyGeoLocationList, - GeoLocationListInfo, -) -from catalystwan.endpoints.configuration.policy.list.ips_signature import ( - ConfigurationPolicyIPSSignatureList, - IPSSignatureListInfo, -) -from catalystwan.endpoints.configuration.policy.list.ipv6_prefix import ( - ConfigurationPolicyIPv6PrefixList, - IPv6PrefixListInfo, -) +from catalystwan.endpoints.configuration.policy.list.geo_location import ConfigurationPolicyGeoLocationList +from catalystwan.endpoints.configuration.policy.list.ips_signature import ConfigurationPolicyIPSSignatureList +from catalystwan.endpoints.configuration.policy.list.ipv6_prefix import ConfigurationPolicyIPv6PrefixList from catalystwan.endpoints.configuration.policy.list.local_app import ConfigurationPolicyLocalAppList, LocalAppListInfo -from catalystwan.endpoints.configuration.policy.list.local_domain import ( - ConfigurationPolicyLocalDomainList, - LocalDomainListInfo, -) +from catalystwan.endpoints.configuration.policy.list.local_domain import ConfigurationPolicyLocalDomainList from catalystwan.endpoints.configuration.policy.list.mirror import ConfigurationPolicyMirrorList, MirrorListInfo from catalystwan.endpoints.configuration.policy.list.policer import ConfigurationPolicyPolicerClassList, PolicerListInfo from catalystwan.endpoints.configuration.policy.list.port import ConfigurationPolicyPortList, PortListInfo @@ -141,22 +81,9 @@ VSmartConnectivityStatus, ) from catalystwan.models.misc.application_protocols import ApplicationProtocol -from catalystwan.models.policy import AnyPolicyDefinition, AnyPolicyList -from catalystwan.models.policy.centralized import CentralizedPolicy, CentralizedPolicyEditPayload, CentralizedPolicyInfo -from catalystwan.models.policy.definitions.access_control_list import AclPolicy -from catalystwan.models.policy.definitions.access_control_list_ipv6 import AclIPv6Policy -from catalystwan.models.policy.definitions.control import ControlPolicy -from catalystwan.models.policy.definitions.device_access import DeviceAccessPolicy -from catalystwan.models.policy.definitions.device_access_ipv6 import DeviceAccessIPv6Policy -from catalystwan.models.policy.definitions.hub_and_spoke import HubAndSpokePolicy -from catalystwan.models.policy.definitions.mesh import MeshPolicy -from catalystwan.models.policy.definitions.qos_map import QoSMapPolicy -from catalystwan.models.policy.definitions.rewrite import RewritePolicy -from catalystwan.models.policy.definitions.rule_set import RuleSet -from catalystwan.models.policy.definitions.security_group import SecurityGroup -from catalystwan.models.policy.definitions.vpn_membership import VPNMembershipPolicy -from catalystwan.models.policy.definitions.zone_based_firewall import ZoneBasedFWPolicy -from catalystwan.models.policy.lists import ( +from catalystwan.models.policy import ( + AnyPolicyDefinition, + AnyPolicyList, AppList, AppProbeClassList, ASPathList, @@ -174,7 +101,6 @@ LocalDomainList, MirrorList, PolicerList, - PolicyListBase, PortList, PreferredColorGroupList, PrefixList, @@ -188,6 +114,33 @@ VPNList, ZoneList, ) +from catalystwan.models.policy.centralized import CentralizedPolicy, CentralizedPolicyEditPayload, CentralizedPolicyInfo +from catalystwan.models.policy.definition.access_control_list import AclPolicy, AclPolicyGetResponse +from catalystwan.models.policy.definition.access_control_list_ipv6 import AclIPv6Policy, AclIPv6PolicyGetResponse +from catalystwan.models.policy.definition.control import ControlPolicy, ControlPolicyGetResponse +from catalystwan.models.policy.definition.device_access import DeviceAccessPolicy, DeviceAccessPolicyGetResponse +from catalystwan.models.policy.definition.device_access_ipv6 import ( + DeviceAccessIPv6Policy, + DeviceAccessIPv6PolicyGetResponse, +) +from catalystwan.models.policy.definition.hub_and_spoke import HubAndSpokePolicy, HubAndSpokePolicyGetResponse +from catalystwan.models.policy.definition.mesh import MeshPolicy, MeshPolicyGetResponse +from catalystwan.models.policy.definition.qos_map import QoSMapPolicy, QoSMapPolicyGetResponse +from catalystwan.models.policy.definition.rewrite import RewritePolicy, RewritePolicyGetResponse +from catalystwan.models.policy.definition.rule_set import RuleSet, RuleSetGetResponse +from catalystwan.models.policy.definition.security_group import SecurityGroup, SecurityGroupGetResponse +from catalystwan.models.policy.definition.traffic_data import TrafficDataPolicy, TrafficDataPolicyGetResponse +from catalystwan.models.policy.definition.vpn_membership import VPNMembershipPolicy, VPNMembershipPolicyGetResponse +from catalystwan.models.policy.definition.zone_based_firewall import ZoneBasedFWPolicy, ZoneBasedFWPolicyGetResponse +from catalystwan.models.policy.list.app_probe import AppProbeClassListInfo +from catalystwan.models.policy.list.class_map import ClassMapListInfo +from catalystwan.models.policy.list.communities import CommunityListInfo, ExpandedCommunityListInfo +from catalystwan.models.policy.list.data_ipv6_prefix import DataIPv6PrefixListInfo +from catalystwan.models.policy.list.data_prefix import DataPrefixListInfo +from catalystwan.models.policy.list.geo_location import GeoLocationListInfo +from catalystwan.models.policy.list.ips_signature import IPSSignatureListInfo +from catalystwan.models.policy.list.ipv6_prefix import IPv6PrefixListInfo +from catalystwan.models.policy.list.local_domain import LocalDomainListInfo from catalystwan.models.policy.localized import ( LocalizedPolicy, LocalizedPolicyDeviceInfo, @@ -197,10 +150,9 @@ from catalystwan.models.policy.policy_definition import ( PolicyDefinitionBase, PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, PolicyDefinitionInfo, ) -from catalystwan.models.policy.policy_list import PolicyListEndpoints +from catalystwan.models.policy.policy_list import PolicyListBase from catalystwan.models.policy.security import ( AnySecurityPolicy, AnySecurityPolicyInfo, diff --git a/catalystwan/endpoints/configuration/policy/abstractions.py b/catalystwan/endpoints/configuration/policy/abstractions.py new file mode 100644 index 00000000..94e8d281 --- /dev/null +++ b/catalystwan/endpoints/configuration/policy/abstractions.py @@ -0,0 +1,48 @@ +from typing import Protocol +from uuid import UUID + +from pydantic import BaseModel + +from catalystwan.models.policy import AnyPolicyList +from catalystwan.models.policy.policy_definition import ( + PolicyDefinitionEditResponse, + PolicyDefinitionGetResponse, + PolicyDefinitionId, + PolicyDefinitionInfo, +) +from catalystwan.models.policy.policy_list import PolicyListId, PolicyListInfo +from catalystwan.typed_list import DataSequence + + +class PolicyListEndpoints(Protocol): + def create_policy_list(self, payload: AnyPolicyList) -> PolicyListId: + ... + + def delete_policy_list(self, id: UUID) -> None: + ... + + def edit_policy_list(self, id: UUID, payload: AnyPolicyList) -> None: + ... + + def get_lists_by_id(self, id: UUID) -> PolicyListInfo: + ... + + def get_policy_lists(self) -> DataSequence[PolicyListInfo]: + ... + + +class PolicyDefinitionEndpoints(Protocol): + def create_policy_definition(self, payload: BaseModel) -> PolicyDefinitionId: + ... + + def delete_policy_definition(self, id: UUID) -> None: + ... + + def edit_policy_definition(self, id: UUID, payload: BaseModel) -> PolicyDefinitionEditResponse: + ... + + def get_definitions(self) -> DataSequence[PolicyDefinitionInfo]: + ... + + def get_policy_definition(self, id: UUID) -> PolicyDefinitionGetResponse: + ... diff --git a/catalystwan/endpoints/configuration/policy/definition/access_control_list.py b/catalystwan/endpoints/configuration/policy/definition/access_control_list.py index 76da0782..4ee7cadc 100644 --- a/catalystwan/endpoints/configuration/policy/definition/access_control_list.py +++ b/catalystwan/endpoints/configuration/policy/definition/access_control_list.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.access_control_list import AclPolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.access_control_list import ( + AclPolicy, + AclPolicyEditPayload, + AclPolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class AclPolicyEditPayload(AclPolicy, PolicyDefinitionId): - pass - - -class AclPolicyGetResponse(AclPolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyAclDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/acl") def create_policy_definition(self, payload: AclPolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/access_control_list_ipv6.py b/catalystwan/endpoints/configuration/policy/definition/access_control_list_ipv6.py index 3e19d8ec..8c4ef74a 100644 --- a/catalystwan/endpoints/configuration/policy/definition/access_control_list_ipv6.py +++ b/catalystwan/endpoints/configuration/policy/definition/access_control_list_ipv6.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.access_control_list_ipv6 import AclIPv6Policy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.access_control_list_ipv6 import ( + AclIPv6Policy, + AclIPv6PolicyEditPayload, + AclIPv6PolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class AclIPv6PolicyEditPayload(AclIPv6Policy, PolicyDefinitionId): - pass - - -class AclIPv6PolicyGetResponse(AclIPv6Policy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyAclIPv6Definition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/aclv6") def create_policy_definition(self, payload: AclIPv6Policy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/control.py b/catalystwan/endpoints/configuration/policy/definition/control.py index f502c5ee..b5f94c8f 100644 --- a/catalystwan/endpoints/configuration/policy/definition/control.py +++ b/catalystwan/endpoints/configuration/policy/definition/control.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.control import ControlPolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.control import ( + ControlPolicy, + ControlPolicyEditPayload, + ControlPolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class ControlPolicyEditPayload(ControlPolicy, PolicyDefinitionId): - pass - - -class ControlPolicyGetResponse(ControlPolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyControlDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/control") def create_policy_definition(self, payload: ControlPolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/device_access.py b/catalystwan/endpoints/configuration/policy/definition/device_access.py index 05228648..c12ec51a 100644 --- a/catalystwan/endpoints/configuration/policy/definition/device_access.py +++ b/catalystwan/endpoints/configuration/policy/definition/device_access.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.device_access import DeviceAccessPolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.device_access import ( + DeviceAccessPolicy, + DeviceAccessPolicyEditPayload, + DeviceAccessPolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class DeviceAccessPolicyEditPayload(DeviceAccessPolicy, PolicyDefinitionId): - pass - - -class DeviceAccessPolicyGetResponse(DeviceAccessPolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyDeviceAccessDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/deviceaccesspolicy") def create_policy_definition(self, payload: DeviceAccessPolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/device_access_ipv6.py b/catalystwan/endpoints/configuration/policy/definition/device_access_ipv6.py index 82a275cb..525c685c 100644 --- a/catalystwan/endpoints/configuration/policy/definition/device_access_ipv6.py +++ b/catalystwan/endpoints/configuration/policy/definition/device_access_ipv6.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.device_access_ipv6 import DeviceAccessIPv6Policy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.device_access_ipv6 import ( + DeviceAccessIPv6Policy, + DeviceAccessIPv6PolicyEditPayload, + DeviceAccessIPv6PolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class DeviceAccessIPv6PolicyEditPayload(DeviceAccessIPv6Policy, PolicyDefinitionId): - pass - - -class DeviceAccessIPv6PolicyGetResponse(DeviceAccessIPv6Policy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyDeviceAccessIPv6Definition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/deviceaccesspolicyv6") def create_policy_definition(self, payload: DeviceAccessIPv6Policy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/hub_and_spoke.py b/catalystwan/endpoints/configuration/policy/definition/hub_and_spoke.py index 6d4a8dbc..2c783f8d 100644 --- a/catalystwan/endpoints/configuration/policy/definition/hub_and_spoke.py +++ b/catalystwan/endpoints/configuration/policy/definition/hub_and_spoke.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.hub_and_spoke import HubAndSpokePolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.hub_and_spoke import ( + HubAndSpokePolicy, + HubAndSpokePolicyEditPayload, + HubAndSpokePolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class HubAndSpokePolicyEditPayload(HubAndSpokePolicy, PolicyDefinitionId): - pass - - -class HubAndSpokePolicyGetResponse(HubAndSpokePolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyHubAndSpokeDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/hubandspoke") def create_policy_definition(self, payload: HubAndSpokePolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/mesh.py b/catalystwan/endpoints/configuration/policy/definition/mesh.py index 9dba385c..6a2e6b41 100644 --- a/catalystwan/endpoints/configuration/policy/definition/mesh.py +++ b/catalystwan/endpoints/configuration/policy/definition/mesh.py @@ -4,11 +4,10 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.mesh import MeshPolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.mesh import MeshPolicy, MeshPolicyEditPayload, MeshPolicyGetResponse from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +15,6 @@ from catalystwan.typed_list import DataSequence -class MeshPolicyEditPayload(MeshPolicy, PolicyDefinitionId): - pass - - -class MeshPolicyGetResponse(MeshPolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyMeshDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/mesh") def create_policy_definition(self, payload: MeshPolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/qos_map.py b/catalystwan/endpoints/configuration/policy/definition/qos_map.py index 620a530d..c07ea297 100644 --- a/catalystwan/endpoints/configuration/policy/definition/qos_map.py +++ b/catalystwan/endpoints/configuration/policy/definition/qos_map.py @@ -4,11 +4,10 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.qos_map import QoSMapPolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.qos_map import QoSMapPolicy, QoSMapPolicyEditPayload, QoSMapPolicyGetResponse from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +15,6 @@ from catalystwan.typed_list import DataSequence -class QoSMapPolicyEditPayload(QoSMapPolicy, PolicyDefinitionId): - pass - - -class QoSMapPolicyGetResponse(QoSMapPolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyQoSMapDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/qosmap") def create_policy_definition(self, payload: QoSMapPolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/rewrite.py b/catalystwan/endpoints/configuration/policy/definition/rewrite.py index 57dd8b26..7d9d656a 100644 --- a/catalystwan/endpoints/configuration/policy/definition/rewrite.py +++ b/catalystwan/endpoints/configuration/policy/definition/rewrite.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.rewrite import RewritePolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.rewrite import ( + RewritePolicy, + RewritePolicyEditPayload, + RewritePolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class RewritePolicyEditPayload(RewritePolicy, PolicyDefinitionId): - pass - - -class RewritePolicyGetResponse(RewritePolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyRewriteRuleDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/rewriterule") def create_policy_definition(self, payload: RewritePolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/rule_set.py b/catalystwan/endpoints/configuration/policy/definition/rule_set.py index 15edb05b..92119e2d 100644 --- a/catalystwan/endpoints/configuration/policy/definition/rule_set.py +++ b/catalystwan/endpoints/configuration/policy/definition/rule_set.py @@ -4,11 +4,10 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.rule_set import RuleSet +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.rule_set import RuleSet, RuleSetEditPayload, RuleSetGetResponse from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +15,6 @@ from catalystwan.typed_list import DataSequence -class RuleSetEditPayload(RuleSet, PolicyDefinitionId): - pass - - -class RuleSetGetResponse(RuleSet, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyRuleSetDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/ruleset") def create_policy_definition(self, payload: RuleSet) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/security_group.py b/catalystwan/endpoints/configuration/policy/definition/security_group.py index 9ca7c970..a210f2ea 100644 --- a/catalystwan/endpoints/configuration/policy/definition/security_group.py +++ b/catalystwan/endpoints/configuration/policy/definition/security_group.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.security_group import SecurityGroup +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.security_group import ( + SecurityGroup, + SecurityGroupEditPayload, + SecurityGroupGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class SecurityGroupEditPayload(SecurityGroup, PolicyDefinitionId): - pass - - -class SecurityGroupGetResponse(SecurityGroup, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicySecurityGroupDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/securitygroup") def create_policy_definition(self, payload: SecurityGroup) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/traffic_data.py b/catalystwan/endpoints/configuration/policy/definition/traffic_data.py index c3cacf27..4a5e6a77 100644 --- a/catalystwan/endpoints/configuration/policy/definition/traffic_data.py +++ b/catalystwan/endpoints/configuration/policy/definition/traffic_data.py @@ -5,11 +5,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.traffic_data import TrafficDataPolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.traffic_data import ( + TrafficDataPolicy, + TrafficDataPolicyEditPayload, + TrafficDataPolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -17,14 +20,6 @@ from catalystwan.typed_list import DataSequence -class TrafficDataPolicyEditPayload(TrafficDataPolicy, PolicyDefinitionId): - pass - - -class TrafficDataPolicyGetResponse(TrafficDataPolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyDataDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/data") def create_policy_definition(self, payload: TrafficDataPolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/vpn_membership.py b/catalystwan/endpoints/configuration/policy/definition/vpn_membership.py index a63bf1c4..22862eeb 100644 --- a/catalystwan/endpoints/configuration/policy/definition/vpn_membership.py +++ b/catalystwan/endpoints/configuration/policy/definition/vpn_membership.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.vpn_membership import VPNMembershipPolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.vpn_membership import ( + VPNMembershipPolicy, + VPNMembershipPolicyEditPayload, + VPNMembershipPolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class VPNMembershipPolicyEditPayload(VPNMembershipPolicy, PolicyDefinitionId): - pass - - -class VPNMembershipPolicyGetResponse(VPNMembershipPolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyVPNMembershipGroupDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/vpnmembershipgroup") def create_policy_definition(self, payload: VPNMembershipPolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/definition/zone_based_firewall.py b/catalystwan/endpoints/configuration/policy/definition/zone_based_firewall.py index b805c1fb..1808f98f 100644 --- a/catalystwan/endpoints/configuration/policy/definition/zone_based_firewall.py +++ b/catalystwan/endpoints/configuration/policy/definition/zone_based_firewall.py @@ -4,11 +4,14 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.definitions.zone_based_firewall import ZoneBasedFWPolicy +from catalystwan.endpoints.configuration.policy.abstractions import PolicyDefinitionEndpoints +from catalystwan.models.policy.definition.zone_based_firewall import ( + ZoneBasedFWPolicy, + ZoneBasedFWPolicyEditPayload, + ZoneBasedFWPolicyGetResponse, +) from catalystwan.models.policy.policy_definition import ( PolicyDefinitionEditResponse, - PolicyDefinitionEndpoints, - PolicyDefinitionGetResponse, PolicyDefinitionId, PolicyDefinitionInfo, PolicyDefinitionPreview, @@ -16,14 +19,6 @@ from catalystwan.typed_list import DataSequence -class ZoneBasedFWPolicyEditPayload(ZoneBasedFWPolicy, PolicyDefinitionId): - pass - - -class ZoneBasedFWPolicyGetResponse(ZoneBasedFWPolicy, PolicyDefinitionGetResponse): - pass - - class ConfigurationPolicyZoneBasedFirewallDefinition(APIEndpoints, PolicyDefinitionEndpoints): @post("/template/policy/definition/zonebasedfw") def create_policy_definition(self, payload: ZoneBasedFWPolicy) -> PolicyDefinitionId: diff --git a/catalystwan/endpoints/configuration/policy/list/app.py b/catalystwan/endpoints/configuration/policy/list/app.py index eb39f8a8..878d56b4 100644 --- a/catalystwan/endpoints/configuration/policy/list/app.py +++ b/catalystwan/endpoints/configuration/policy/list/app.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import AppList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.app import AppList, AppListEditPayload, AppListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class AppListEditPayload(AppList, PolicyListId): - pass - - -class AppListInfo(AppList, PolicyListInfo): - pass - - class ConfigurationPolicyApplicationList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/app") def create_policy_list(self, payload: AppList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/app_probe.py b/catalystwan/endpoints/configuration/policy/list/app_probe.py index b51ce61b..44c37800 100644 --- a/catalystwan/endpoints/configuration/policy/list/app_probe.py +++ b/catalystwan/endpoints/configuration/policy/list/app_probe.py @@ -4,25 +4,16 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import AppProbeClassList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.app_probe import ( + AppProbeClassList, + AppProbeClassListEditPayload, + AppProbeClassListInfo, ) +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class AppProbeClassListEditPayload(AppProbeClassList, PolicyListId): - pass - - -class AppProbeClassListInfo(AppProbeClassList, PolicyListInfo): - pass - - class ConfigurationPolicyAppProbeClassList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/appprobe") def create_policy_list(self, payload: AppProbeClassList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/as_path.py b/catalystwan/endpoints/configuration/policy/list/as_path.py index 6d28efff..d643a061 100644 --- a/catalystwan/endpoints/configuration/policy/list/as_path.py +++ b/catalystwan/endpoints/configuration/policy/list/as_path.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import ASPathList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.as_path import ASPathList, ASPathListEditPayload, ASPathListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class ASPathListEditPayload(ASPathList, PolicyListId): - pass - - -class ASPathListInfo(ASPathList, PolicyListInfo): - pass - - class ConfigurationPolicyASPathList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/aspath") def create_policy_list(self, payload: ASPathList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/class_map.py b/catalystwan/endpoints/configuration/policy/list/class_map.py index 45469301..fa68b803 100644 --- a/catalystwan/endpoints/configuration/policy/list/class_map.py +++ b/catalystwan/endpoints/configuration/policy/list/class_map.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import ClassMapList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.class_map import ClassMapList, ClassMapListEditPayload, ClassMapListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class ClassMapListEditPayload(ClassMapList, PolicyListId): - pass - - -class ClassMapListInfo(ClassMapList, PolicyListInfo): - pass - - class ConfigurationPolicyForwardingClassList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/class") def create_policy_list(self, payload: ClassMapList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/color.py b/catalystwan/endpoints/configuration/policy/list/color.py index 920b899d..135120e5 100644 --- a/catalystwan/endpoints/configuration/policy/list/color.py +++ b/catalystwan/endpoints/configuration/policy/list/color.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import ColorList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.color import ColorList, ColorListEditPayload, ColorListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class ColorListEditPayload(ColorList, PolicyListId): - pass - - -class ColorListInfo(ColorList, PolicyListInfo): - pass - - class ConfigurationPolicyColorList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/color") def create_policy_list(self, payload: ColorList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/community.py b/catalystwan/endpoints/configuration/policy/list/community.py index 4fd995a5..14fa3115 100644 --- a/catalystwan/endpoints/configuration/policy/list/community.py +++ b/catalystwan/endpoints/configuration/policy/list/community.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import CommunityList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.communities import CommunityList, CommunityListEditPayload, CommunityListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class CommunityListEditPayload(CommunityList, PolicyListId): - pass - - -class CommunityListInfo(CommunityList, PolicyListInfo): - pass - - class ConfigurationPolicyCommunityList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/community") def create_policy_list(self, payload: CommunityList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/data_ipv6_prefix.py b/catalystwan/endpoints/configuration/policy/list/data_ipv6_prefix.py index 767f05db..ec7a7cad 100644 --- a/catalystwan/endpoints/configuration/policy/list/data_ipv6_prefix.py +++ b/catalystwan/endpoints/configuration/policy/list/data_ipv6_prefix.py @@ -4,25 +4,16 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import DataIPv6PrefixList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.data_ipv6_prefix import ( + DataIPv6PrefixList, + DataIPv6PrefixListEditPayload, + DataIPv6PrefixListInfo, ) +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class DataIPv6PrefixListEditPayload(DataIPv6PrefixList, PolicyListId): - pass - - -class DataIPv6PrefixListInfo(DataIPv6PrefixList, PolicyListInfo): - pass - - class ConfigurationPolicyDataIPv6PrefixList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/dataipv6prefix") def create_policy_list(self, payload: DataIPv6PrefixList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/data_prefix.py b/catalystwan/endpoints/configuration/policy/list/data_prefix.py index 8603730a..45824666 100644 --- a/catalystwan/endpoints/configuration/policy/list/data_prefix.py +++ b/catalystwan/endpoints/configuration/policy/list/data_prefix.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import DataPrefixList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.data_prefix import DataPrefixList, DataPrefixListEditPayload, DataPrefixListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class DataPrefixListEditPayload(DataPrefixList, PolicyListId): - pass - - -class DataPrefixListInfo(DataPrefixList, PolicyListInfo): - pass - - class ConfigurationPolicyDataPrefixList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/dataprefix") def create_policy_list(self, payload: DataPrefixList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/expanded_community.py b/catalystwan/endpoints/configuration/policy/list/expanded_community.py index 939bbddc..0c1d81a3 100644 --- a/catalystwan/endpoints/configuration/policy/list/expanded_community.py +++ b/catalystwan/endpoints/configuration/policy/list/expanded_community.py @@ -4,25 +4,16 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import ExpandedCommunityList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.communities import ( + ExpandedCommunityList, + ExpandedCommunityListEditPayload, + ExpandedCommunityListInfo, ) +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class ExpandedCommunityListEditPayload(ExpandedCommunityList, PolicyListId): - pass - - -class ExpandedCommunityListInfo(ExpandedCommunityList, PolicyListInfo): - pass - - class ConfigurationPolicyExpandedCommunityList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/expandedcommunity") def create_policy_list(self, payload: ExpandedCommunityList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/fqdn.py b/catalystwan/endpoints/configuration/policy/list/fqdn.py index 7b73d268..f796c611 100644 --- a/catalystwan/endpoints/configuration/policy/list/fqdn.py +++ b/catalystwan/endpoints/configuration/policy/list/fqdn.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import FQDNList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.fqdn import FQDNList, FQDNListEditPayload, FQDNListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class FQDNListEditPayload(FQDNList, PolicyListId): - pass - - -class FQDNListInfo(FQDNList, PolicyListInfo): - pass - - class ConfigurationPolicyFQDNList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/fqdn") def create_policy_list(self, payload: FQDNList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/geo_location.py b/catalystwan/endpoints/configuration/policy/list/geo_location.py index a227a547..2c7d4748 100644 --- a/catalystwan/endpoints/configuration/policy/list/geo_location.py +++ b/catalystwan/endpoints/configuration/policy/list/geo_location.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import GeoLocationList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.geo_location import GeoLocationList, GeoLocationListEditPayload, GeoLocationListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class GeoLocationListEditPayload(GeoLocationList, PolicyListId): - pass - - -class GeoLocationListInfo(GeoLocationList, PolicyListInfo): - pass - - class ConfigurationPolicyGeoLocationList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/geolocation") def create_policy_list(self, payload: GeoLocationList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/ips_signature.py b/catalystwan/endpoints/configuration/policy/list/ips_signature.py index c1f60c61..040f2f40 100644 --- a/catalystwan/endpoints/configuration/policy/list/ips_signature.py +++ b/catalystwan/endpoints/configuration/policy/list/ips_signature.py @@ -4,25 +4,16 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import IPSSignatureList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.ips_signature import ( + IPSSignatureList, + IPSSignatureListEditPayload, + IPSSignatureListInfo, ) +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class IPSSignatureListEditPayload(IPSSignatureList, PolicyListId): - pass - - -class IPSSignatureListInfo(IPSSignatureList, PolicyListInfo): - pass - - class ConfigurationPolicyIPSSignatureList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/ipssignature") def create_policy_list(self, payload: IPSSignatureList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/ipv6_prefix.py b/catalystwan/endpoints/configuration/policy/list/ipv6_prefix.py index 9af6b8f9..8f9030be 100644 --- a/catalystwan/endpoints/configuration/policy/list/ipv6_prefix.py +++ b/catalystwan/endpoints/configuration/policy/list/ipv6_prefix.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import IPv6PrefixList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.ipv6_prefix import IPv6PrefixList, IPv6PrefixListEditPayload, IPv6PrefixListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class IPv6PrefixListEditPayload(IPv6PrefixList, PolicyListId): - pass - - -class IPv6PrefixListInfo(IPv6PrefixList, PolicyListInfo): - pass - - class ConfigurationPolicyIPv6PrefixList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/ipv6prefix") def create_policy_list(self, payload: IPv6PrefixList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/local_app.py b/catalystwan/endpoints/configuration/policy/list/local_app.py index 4d495408..1c00b564 100644 --- a/catalystwan/endpoints/configuration/policy/list/local_app.py +++ b/catalystwan/endpoints/configuration/policy/list/local_app.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import LocalAppList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.local_app import LocalAppList, LocalAppListEditPayload, LocalAppListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class LocalAppListEditPayload(LocalAppList, PolicyListId): - pass - - -class LocalAppListInfo(LocalAppList, PolicyListInfo): - pass - - class ConfigurationPolicyLocalAppList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/localapp") def create_policy_list(self, payload: LocalAppList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/local_domain.py b/catalystwan/endpoints/configuration/policy/list/local_domain.py index 1359e5cb..4b2de258 100644 --- a/catalystwan/endpoints/configuration/policy/list/local_domain.py +++ b/catalystwan/endpoints/configuration/policy/list/local_domain.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import LocalDomainList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.local_domain import LocalDomainList, LocalDomainListEditPayload, LocalDomainListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class LocalDomainListEditPayload(LocalDomainList, PolicyListId): - pass - - -class LocalDomainListInfo(LocalDomainList, PolicyListInfo): - pass - - class ConfigurationPolicyLocalDomainList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/localdomain") def create_policy_list(self, payload: LocalDomainList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/mirror.py b/catalystwan/endpoints/configuration/policy/list/mirror.py index ab0bb69d..8e4b1bd7 100644 --- a/catalystwan/endpoints/configuration/policy/list/mirror.py +++ b/catalystwan/endpoints/configuration/policy/list/mirror.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import MirrorList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.mirror import MirrorList, MirrorListEditPayload, MirrorListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class MirrorListEditPayload(MirrorList, PolicyListId): - pass - - -class MirrorListInfo(MirrorList, PolicyListInfo): - pass - - class ConfigurationPolicyMirrorList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/mirror") def create_policy_list(self, payload: MirrorList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/policer.py b/catalystwan/endpoints/configuration/policy/list/policer.py index 9166b20d..1b578ec7 100644 --- a/catalystwan/endpoints/configuration/policy/list/policer.py +++ b/catalystwan/endpoints/configuration/policy/list/policer.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import PolicerList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.policer import PolicerList, PolicerListEditPayload, PolicerListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class PolicerListEditPayload(PolicerList, PolicyListId): - pass - - -class PolicerListInfo(PolicerList, PolicyListInfo): - pass - - class ConfigurationPolicyPolicerClassList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/policer") def create_policy_list(self, payload: PolicerList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/port.py b/catalystwan/endpoints/configuration/policy/list/port.py index 6eb87fdd..344835b8 100644 --- a/catalystwan/endpoints/configuration/policy/list/port.py +++ b/catalystwan/endpoints/configuration/policy/list/port.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import PortList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.port import PortList, PortListEditPayload, PortListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class PortListEditPayload(PortList, PolicyListId): - pass - - -class PortListInfo(PortList, PolicyListInfo): - pass - - class ConfigurationPolicyPortList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/port") def create_policy_list(self, payload: PortList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/preferred_color_group.py b/catalystwan/endpoints/configuration/policy/list/preferred_color_group.py index 3cf8aa3a..8902bf4d 100644 --- a/catalystwan/endpoints/configuration/policy/list/preferred_color_group.py +++ b/catalystwan/endpoints/configuration/policy/list/preferred_color_group.py @@ -4,25 +4,16 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import PreferredColorGroupList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.preferred_color_group import ( + PreferredColorGroupList, + PreferredColorGroupListEditPayload, + PreferredColorGroupListInfo, ) +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class PreferredColorGroupListEditPayload(PreferredColorGroupList, PolicyListId): - pass - - -class PreferredColorGroupListInfo(PreferredColorGroupList, PolicyListInfo): - pass - - class ConfigurationPreferredColorGroupList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/preferredcolorgroup") def create_policy_list(self, payload: PreferredColorGroupList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/prefix.py b/catalystwan/endpoints/configuration/policy/list/prefix.py index 64f6c584..f31ea541 100644 --- a/catalystwan/endpoints/configuration/policy/list/prefix.py +++ b/catalystwan/endpoints/configuration/policy/list/prefix.py @@ -3,26 +3,14 @@ # mypy: disable-error-code="empty-body" from uuid import UUID +from catalystwan.api.templates.models.cisco_vpn_model import PrefixList from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import PrefixList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.prefix import PrefixListEditPayload, PrefixListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class PrefixListEditPayload(PrefixList, PolicyListId): - pass - - -class PrefixListInfo(PrefixList, PolicyListInfo): - pass - - class ConfigurationPolicyPrefixList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/prefix") def create_policy_list(self, payload: PrefixList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/protocol_name.py b/catalystwan/endpoints/configuration/policy/list/protocol_name.py index e5835f96..76e7a837 100644 --- a/catalystwan/endpoints/configuration/policy/list/protocol_name.py +++ b/catalystwan/endpoints/configuration/policy/list/protocol_name.py @@ -4,25 +4,16 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import ProtocolNameList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.protocol_name import ( + ProtocolNameList, + ProtocolNameListEditPayload, + ProtocolNameListInfo, ) +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class ProtocolNameListEditPayload(ProtocolNameList, PolicyListId): - pass - - -class ProtocolNameListInfo(ProtocolNameList, PolicyListInfo): - pass - - class ConfigurationPolicyProtocolNameList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/protocolname") def create_policy_list(self, payload: ProtocolNameList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/region.py b/catalystwan/endpoints/configuration/policy/list/region.py index e55cbddd..a711446b 100644 --- a/catalystwan/endpoints/configuration/policy/list/region.py +++ b/catalystwan/endpoints/configuration/policy/list/region.py @@ -4,19 +4,11 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import RegionList -from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListInfo, PolicyListPreview +from catalystwan.models.policy.list.region import RegionList, RegionListEditPayload, RegionListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class RegionListEditPayload(RegionList, PolicyListId): - pass - - -class RegionListInfo(RegionList, PolicyListInfo): - pass - - class ConfigurationPolicyRegionList(APIEndpoints): @post("/template/policy/list/region") def create_policy_list(self, payload: RegionList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/site.py b/catalystwan/endpoints/configuration/policy/list/site.py index 00472136..8dd1b458 100644 --- a/catalystwan/endpoints/configuration/policy/list/site.py +++ b/catalystwan/endpoints/configuration/policy/list/site.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import SiteList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.site import SiteList, SiteListEditPayload, SiteListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class SiteListEditPayload(SiteList, PolicyListId): - pass - - -class SiteListInfo(SiteList, PolicyListInfo): - pass - - class ConfigurationPolicySiteList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/site/defaultsite") def create_default_site_list(self, payload: SiteList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/sla.py b/catalystwan/endpoints/configuration/policy/list/sla.py index 5764aa0f..6dd6833f 100644 --- a/catalystwan/endpoints/configuration/policy/list/sla.py +++ b/catalystwan/endpoints/configuration/policy/list/sla.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import SLAClassList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.sla import SLAClassList, SLAClassListEditPayload, SLAClassListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class SLAClassListEditPayload(SLAClassList, PolicyListId): - pass - - -class SLAClassListInfo(SLAClassList, PolicyListInfo): - pass - - class ConfigurationPolicySLAClassList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/sla") def create_policy_list(self, payload: SLAClassList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/tloc.py b/catalystwan/endpoints/configuration/policy/list/tloc.py index 82619705..ad9b47d1 100644 --- a/catalystwan/endpoints/configuration/policy/list/tloc.py +++ b/catalystwan/endpoints/configuration/policy/list/tloc.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import TLOCList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.tloc import TLOCList, TLOCListEditPayload, TLOCListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class TLOCListEditPayload(TLOCList, PolicyListId): - pass - - -class TLOCListInfo(TLOCList, PolicyListInfo): - pass - - class ConfigurationPolicyTLOCList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/tloc") def create_policy_list(self, payload: TLOCList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/url_allow_list.py b/catalystwan/endpoints/configuration/policy/list/url_allow_list.py index 32d5c803..1e235908 100644 --- a/catalystwan/endpoints/configuration/policy/list/url_allow_list.py +++ b/catalystwan/endpoints/configuration/policy/list/url_allow_list.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import URLAllowList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.url import URLAllowList, URLAllowListEditPayload, URLAllowListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class URLAllowListEditPayload(URLAllowList, PolicyListId): - pass - - -class URLAllowListInfo(URLAllowList, PolicyListInfo): - pass - - class ConfigurationPolicyURLAllowList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/urlwhitelist") def create_policy_list(self, payload: URLAllowList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/url_block_list.py b/catalystwan/endpoints/configuration/policy/list/url_block_list.py index 96c17153..41258d27 100644 --- a/catalystwan/endpoints/configuration/policy/list/url_block_list.py +++ b/catalystwan/endpoints/configuration/policy/list/url_block_list.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import URLBlockList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.url import URLBlockList, URLBlockListEditPayload, URLBlockListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class URLBlockListEditPayload(URLBlockList, PolicyListId): - pass - - -class URLBlockListInfo(URLBlockList, PolicyListInfo): - pass - - class ConfigurationPolicyURLBlockList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/urlblacklist") def create_policy_list(self, payload: URLBlockList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/vpn.py b/catalystwan/endpoints/configuration/policy/list/vpn.py index 0b1f50fa..e945b8e1 100644 --- a/catalystwan/endpoints/configuration/policy/list/vpn.py +++ b/catalystwan/endpoints/configuration/policy/list/vpn.py @@ -6,25 +6,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import VPNList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.vpn import VPNList, VPNListEditPayload, VPNListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class VPNListEditPayload(VPNList, PolicyListId): - pass - - -class VPNListInfo(VPNList, PolicyListInfo): - pass - - class ConfigurationPolicyVPNList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/vpn") def create_policy_list(self, payload: VPNList) -> PolicyListId: diff --git a/catalystwan/endpoints/configuration/policy/list/zone.py b/catalystwan/endpoints/configuration/policy/list/zone.py index 96464e5c..995643e6 100644 --- a/catalystwan/endpoints/configuration/policy/list/zone.py +++ b/catalystwan/endpoints/configuration/policy/list/zone.py @@ -4,25 +4,12 @@ from uuid import UUID from catalystwan.endpoints import APIEndpoints, delete, get, post, put -from catalystwan.models.policy.lists import ZoneList -from catalystwan.models.policy.policy_list import ( - InfoTag, - PolicyListEndpoints, - PolicyListId, - PolicyListInfo, - PolicyListPreview, -) +from catalystwan.endpoints.configuration.policy.abstractions import PolicyListEndpoints +from catalystwan.models.policy.list.zone import ZoneList, ZoneListEditPayload, ZoneListInfo +from catalystwan.models.policy.policy_list import InfoTag, PolicyListId, PolicyListPreview from catalystwan.typed_list import DataSequence -class ZoneListEditPayload(ZoneList, PolicyListId): - pass - - -class ZoneListInfo(ZoneList, PolicyListInfo): - pass - - class ConfigurationPolicyZoneList(APIEndpoints, PolicyListEndpoints): @post("/template/policy/list/zone") def create_policy_list(self, payload: ZoneList) -> PolicyListId: diff --git a/catalystwan/models/common.py b/catalystwan/models/common.py index d01e9006..9feafaff 100644 --- a/catalystwan/models/common.py +++ b/catalystwan/models/common.py @@ -101,6 +101,12 @@ def str_as_str_list(val: Union[str, Sequence[str]]) -> Sequence[str]: return val +EncapType = Literal[ + "ipsec", + "gre", +] + + InterfaceType = Literal[ "Ethernet", "FastEthernet", diff --git a/catalystwan/models/configuration/config_migration.py b/catalystwan/models/configuration/config_migration.py index df785c2c..7e67bdc7 100644 --- a/catalystwan/models/configuration/config_migration.py +++ b/catalystwan/models/configuration/config_migration.py @@ -1,6 +1,6 @@ # Copyright 2024 Cisco Systems, Inc. and its affiliates -from typing import List, Literal, Union +from typing import List, Union from pydantic import BaseModel, ConfigDict, Field from typing_extensions import Annotated @@ -12,7 +12,7 @@ from catalystwan.models.configuration.feature_profile.sdwan.policy_object import AnyPolicyObjectParcel from catalystwan.models.configuration.feature_profile.sdwan.system import AnySystemParcel from catalystwan.models.configuration.topology_group import TopologyGroup -from catalystwan.models.policy import AnyPolicyDefinition, AnyPolicyList +from catalystwan.models.policy import AnyPolicyDefinitionInfo, AnyPolicyListInfo from catalystwan.models.policy.centralized import CentralizedPolicyInfo from catalystwan.models.policy.localized import LocalizedPolicyInfo from catalystwan.models.policy.security import AnySecurityPolicyInfo @@ -37,10 +37,10 @@ class UX1Policies(BaseModel): security_policies: List[AnySecurityPolicyInfo] = Field( default=[], serialization_alias="securityPolicies", validation_alias="securityPolicies" ) - policy_definitions: List[AnyPolicyDefinition] = Field( + policy_definitions: List[AnyPolicyDefinitionInfo] = Field( default=[], serialization_alias="policyDefinitions", validation_alias="policyDefinitions" ) - policy_lists: List[AnyPolicyList] = Field( + policy_lists: List[AnyPolicyListInfo] = Field( default=[], serialization_alias="policyLists", validation_alias="policyLists" ) @@ -54,14 +54,6 @@ class UX1Templates(BaseModel): ) -class ConfigGroupPreset(BaseModel): - config_group_name: str = Field(serialization_alias="name", validation_alias="name") - solution: Literal["sdwan"] = "sdwan" - profile_parcels: List[AnyParcel] = Field( - default=[], serialization_alias="profileParcels", validation_alias="profileParcels" - ) - - class UX1Config(BaseModel): # All UX1 Configuration items - Mega Model model_config = ConfigDict(populate_by_name=True) diff --git a/catalystwan/models/policy/__init__.py b/catalystwan/models/policy/__init__.py index 0dfa4b3a..9ab002d3 100644 --- a/catalystwan/models/policy/__init__.py +++ b/catalystwan/models/policy/__init__.py @@ -6,53 +6,54 @@ from pydantic import Field from typing_extensions import Annotated -from .centralized import CentralizedPolicy, TrafficDataDirection -from .definitions.access_control_list import AclPolicy -from .definitions.access_control_list_ipv6 import AclIPv6Policy -from .definitions.control import ControlPolicy -from .definitions.device_access import DeviceAccessPolicy -from .definitions.device_access_ipv6 import DeviceAccessIPv6Policy -from .definitions.hub_and_spoke import HubAndSpokePolicy -from .definitions.mesh import MeshPolicy -from .definitions.qos_map import QoSDropType, QoSMapPolicy -from .definitions.rewrite import RewritePolicy -from .definitions.rule_set import RuleSet -from .definitions.security_group import SecurityGroup -from .definitions.traffic_data import TrafficDataPolicy -from .definitions.vpn_membership import VPNMembershipPolicy -from .definitions.zone_based_firewall import ZoneBasedFWPolicy -from .lists import ( - AppList, - AppProbeClassList, - ASPathList, - ClassMapList, - ColorList, +from catalystwan.models.policy.list.app import AppList, AppListInfo +from catalystwan.models.policy.list.app_probe import AppProbeClassList, AppProbeClassListInfo +from catalystwan.models.policy.list.as_path import ASPathList, ASPathListInfo +from catalystwan.models.policy.list.class_map import ClassMapList, ClassMapListInfo +from catalystwan.models.policy.list.color import ColorList, ColorListInfo +from catalystwan.models.policy.list.communities import ( CommunityList, - DataIPv6PrefixList, - DataPrefixList, + CommunityListInfo, ExpandedCommunityList, - FQDNList, - GeoLocationList, - IPSSignatureList, - IPv6PrefixList, - LocalAppList, - LocalDomainList, - MirrorList, - PolicerList, - PortList, - PreferredColorGroupList, - PrefixList, - ProtocolNameList, - RegionList, - SiteList, - SLAClassList, - TLOCList, - URLAllowList, - URLBlockList, - VPNList, - ZoneList, + ExpandedCommunityListInfo, ) -from .lists_entries import EncapType, PathPreference, PolicerExceedAction +from catalystwan.models.policy.list.data_ipv6_prefix import DataIPv6PrefixList, DataIPv6PrefixListInfo +from catalystwan.models.policy.list.data_prefix import DataPrefixList, DataPrefixListInfo +from catalystwan.models.policy.list.fqdn import FQDNList, FQDNListInfo +from catalystwan.models.policy.list.geo_location import GeoLocationList, GeoLocationListInfo +from catalystwan.models.policy.list.ips_signature import IPSSignatureList, IPSSignatureListInfo +from catalystwan.models.policy.list.ipv6_prefix import IPv6PrefixList, IPv6PrefixListInfo +from catalystwan.models.policy.list.local_app import LocalAppList, LocalAppListInfo +from catalystwan.models.policy.list.local_domain import LocalDomainList, LocalDomainListInfo +from catalystwan.models.policy.list.mirror import MirrorList, MirrorListInfo +from catalystwan.models.policy.list.policer import PolicerList, PolicerListInfo +from catalystwan.models.policy.list.port import PortList, PortListInfo +from catalystwan.models.policy.list.preferred_color_group import PreferredColorGroupList, PreferredColorGroupListInfo +from catalystwan.models.policy.list.prefix import PrefixList, PrefixListInfo +from catalystwan.models.policy.list.protocol_name import ProtocolNameList, ProtocolNameListInfo +from catalystwan.models.policy.list.region import RegionList, RegionListInfo +from catalystwan.models.policy.list.site import SiteList, SiteListInfo +from catalystwan.models.policy.list.sla import SLAClassList, SLAClassListInfo +from catalystwan.models.policy.list.tloc import TLOCList, TLOCListInfo +from catalystwan.models.policy.list.url import URLAllowList, URLAllowListInfo, URLBlockList, URLBlockListInfo +from catalystwan.models.policy.list.vpn import VPNList, VPNListInfo +from catalystwan.models.policy.list.zone import ZoneList, ZoneListInfo + +from .centralized import CentralizedPolicy, TrafficDataDirection +from .definition.access_control_list import AclPolicy, AclPolicyGetResponse +from .definition.access_control_list_ipv6 import AclIPv6Policy, AclIPv6PolicyGetResponse +from .definition.control import ControlPolicy, ControlPolicyGetResponse +from .definition.device_access import DeviceAccessPolicy, DeviceAccessPolicyGetResponse +from .definition.device_access_ipv6 import DeviceAccessIPv6Policy, DeviceAccessIPv6PolicyGetResponse +from .definition.hub_and_spoke import HubAndSpokePolicy, HubAndSpokePolicyGetResponse +from .definition.mesh import MeshPolicy, MeshPolicyGetResponse +from .definition.qos_map import QoSDropType, QoSMapPolicy, QoSMapPolicyGetResponse +from .definition.rewrite import RewritePolicy, RewritePolicyGetResponse +from .definition.rule_set import RuleSet, RuleSetGetResponse +from .definition.security_group import SecurityGroup, SecurityGroupGetResponse +from .definition.traffic_data import TrafficDataPolicy, TrafficDataPolicyGetResponse +from .definition.vpn_membership import VPNMembershipPolicy, VPNMembershipPolicyGetResponse +from .definition.zone_based_firewall import ZoneBasedFWPolicy, ZoneBasedFWPolicyGetResponse from .localized import LocalizedPolicy from .policy_definition import ( Carrier, @@ -69,20 +70,20 @@ AnyPolicyDefinition = Annotated[ Union[ + AclIPv6Policy, + AclPolicy, + ControlPolicy, + DeviceAccessIPv6Policy, + DeviceAccessPolicy, + HubAndSpokePolicy, + MeshPolicy, + QoSMapPolicy, + RewritePolicy, RuleSet, SecurityGroup, - ZoneBasedFWPolicy, TrafficDataPolicy, - QoSMapPolicy, - RewritePolicy, - ControlPolicy, VPNMembershipPolicy, - HubAndSpokePolicy, - MeshPolicy, - AclPolicy, - AclIPv6Policy, - DeviceAccessPolicy, - DeviceAccessIPv6Policy, + ZoneBasedFWPolicy, ], Field(discriminator="type"), ] @@ -122,12 +123,67 @@ Field(discriminator="type"), ] +AnyPolicyListInfo = Annotated[ + Union[ + AppListInfo, + AppProbeClassListInfo, + ASPathListInfo, + ClassMapListInfo, + ColorListInfo, + CommunityListInfo, + DataIPv6PrefixListInfo, + DataPrefixListInfo, + ExpandedCommunityListInfo, + FQDNListInfo, + GeoLocationListInfo, + IPSSignatureListInfo, + IPv6PrefixListInfo, + LocalAppListInfo, + LocalDomainListInfo, + MirrorListInfo, + PolicerListInfo, + PortListInfo, + PreferredColorGroupListInfo, + PrefixListInfo, + ProtocolNameListInfo, + RegionListInfo, + SiteListInfo, + SLAClassListInfo, + TLOCListInfo, + URLAllowListInfo, + URLBlockListInfo, + VPNListInfo, + ZoneListInfo, + ], + Field(discriminator="type"), +] + +AnyPolicyDefinitionInfo = Annotated[ + Union[ + AclIPv6PolicyGetResponse, + AclPolicyGetResponse, + ControlPolicyGetResponse, + DeviceAccessIPv6PolicyGetResponse, + DeviceAccessPolicyGetResponse, + HubAndSpokePolicyGetResponse, + MeshPolicyGetResponse, + QoSMapPolicyGetResponse, + RewritePolicyGetResponse, + RuleSetGetResponse, + SecurityGroupGetResponse, + TrafficDataPolicyGetResponse, + VPNMembershipPolicyGetResponse, + ZoneBasedFWPolicyGetResponse, + ], + Field(discriminator="type"), +] + __all__ = ( "AclIPv6Policy", "AclPolicy", "AnyPolicyList", - "AnyPolicyList", + "AnyPolicyDefinitionInfo", "AppList", "AppProbeClassList", "ASPathList", @@ -142,7 +198,6 @@ "DeviceAccessIPv6Policy", "DeviceAccessPolicy", "DNSTypeEntryType", - "EncapType", "ExpandedCommunityList", "FQDNList", "GeoLocationList", @@ -156,10 +211,8 @@ "MirrorList", "MultiRegionRole", "OriginProtocol", - "PathPreference", "PathType", "PLPEntryType", - "PolicerExceedAction", "PolicerList", "PolicyActionType", "PortList", diff --git a/catalystwan/models/policy/definitions/access_control_list.py b/catalystwan/models/policy/definition/access_control_list.py similarity index 96% rename from catalystwan/models/policy/definitions/access_control_list.py rename to catalystwan/models/policy/definition/access_control_list.py index 1fab4280..121bf6aa 100644 --- a/catalystwan/models/policy/definitions/access_control_list.py +++ b/catalystwan/models/policy/definition/access_control_list.py @@ -26,6 +26,8 @@ PolicerAction, PolicyActionType, PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, PolicyDefinitionSequenceBase, ProtocolEntry, Reference, @@ -161,3 +163,11 @@ def add_acl_sequence( ) self.add(seq) return seq + + +class AclPolicyEditPayload(AclPolicy, PolicyDefinitionId): + pass + + +class AclPolicyGetResponse(AclPolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/access_control_list_ipv6.py b/catalystwan/models/policy/definition/access_control_list_ipv6.py similarity index 96% rename from catalystwan/models/policy/definitions/access_control_list_ipv6.py rename to catalystwan/models/policy/definition/access_control_list_ipv6.py index 66fcbf47..29e14f1d 100644 --- a/catalystwan/models/policy/definitions/access_control_list_ipv6.py +++ b/catalystwan/models/policy/definition/access_control_list_ipv6.py @@ -26,6 +26,8 @@ PolicerAction, PolicyActionType, PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, PolicyDefinitionSequenceBase, Reference, SourceDataIPv6PrefixListEntry, @@ -161,3 +163,11 @@ def add_acl_sequence( ) self.add(seq) return seq + + +class AclIPv6PolicyEditPayload(AclIPv6Policy, PolicyDefinitionId): + pass + + +class AclIPv6PolicyGetResponse(AclIPv6Policy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/control.py b/catalystwan/models/policy/definition/control.py similarity index 97% rename from catalystwan/models/policy/definitions/control.py rename to catalystwan/models/policy/definition/control.py index c86e176b..b2800bb7 100644 --- a/catalystwan/models/policy/definitions/control.py +++ b/catalystwan/models/policy/definition/control.py @@ -7,8 +7,7 @@ from pydantic import ConfigDict, Field from typing_extensions import Annotated -from catalystwan.models.common import TLOCColor -from catalystwan.models.policy.lists_entries import EncapType +from catalystwan.models.common import EncapType, TLOCColor from catalystwan.models.policy.policy_definition import ( AffinityEntry, Carrier, @@ -33,6 +32,8 @@ PathTypeEntry, PolicyActionType, PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, PolicyDefinitionSequenceBase, PreferenceEntry, PrefixListEntry, @@ -341,3 +342,11 @@ def add_tloc_sequence( ) self.add(seq) return seq + + +class ControlPolicyEditPayload(ControlPolicy, PolicyDefinitionId): + pass + + +class ControlPolicyGetResponse(ControlPolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/device_access.py b/catalystwan/models/policy/definition/device_access.py similarity index 94% rename from catalystwan/models/policy/definitions/device_access.py rename to catalystwan/models/policy/definition/device_access.py index 817c0803..d5ba1456 100644 --- a/catalystwan/models/policy/definitions/device_access.py +++ b/catalystwan/models/policy/definition/device_access.py @@ -18,6 +18,8 @@ Match, PolicyActionType, PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, PolicyDefinitionSequenceBase, SourceDataPrefixListEntry, SourceIPEntry, @@ -104,3 +106,11 @@ def add_acl_sequence( seq.match_device_access_protocol(port=device_access_protocol) self.add(seq) return seq + + +class DeviceAccessPolicyEditPayload(DeviceAccessPolicy, PolicyDefinitionId): + pass + + +class DeviceAccessPolicyGetResponse(DeviceAccessPolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/device_access_ipv6.py b/catalystwan/models/policy/definition/device_access_ipv6.py similarity index 93% rename from catalystwan/models/policy/definitions/device_access_ipv6.py rename to catalystwan/models/policy/definition/device_access_ipv6.py index 6fe2f75f..853dd49b 100644 --- a/catalystwan/models/policy/definitions/device_access_ipv6.py +++ b/catalystwan/models/policy/definition/device_access_ipv6.py @@ -18,6 +18,8 @@ Match, PolicyActionType, PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, PolicyDefinitionSequenceBase, SourceDataIPv6PrefixListEntry, SourceIPv6Entry, @@ -104,3 +106,11 @@ def add_acl_sequence( seq.match_device_access_protocol(port=device_access_protocol) self.add(seq) return seq + + +class DeviceAccessIPv6PolicyEditPayload(DeviceAccessIPv6Policy, PolicyDefinitionId): + pass + + +class DeviceAccessIPv6PolicyGetResponse(DeviceAccessIPv6Policy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/hub_and_spoke.py b/catalystwan/models/policy/definition/hub_and_spoke.py similarity index 90% rename from catalystwan/models/policy/definitions/hub_and_spoke.py rename to catalystwan/models/policy/definition/hub_and_spoke.py index 058eeaec..75689c19 100644 --- a/catalystwan/models/policy/definitions/hub_and_spoke.py +++ b/catalystwan/models/policy/definition/hub_and_spoke.py @@ -5,7 +5,11 @@ from pydantic import BaseModel, ConfigDict, Field -from catalystwan.models.policy.policy_definition import PolicyDefinitionBase +from catalystwan.models.policy.policy_definition import ( + PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, +) class Hub(BaseModel): @@ -71,3 +75,11 @@ def add_hub_and_spoke( ) self.definition.sub_definitions.append(sub_definition) return sub_definition + + +class HubAndSpokePolicyEditPayload(HubAndSpokePolicy, PolicyDefinitionId): + pass + + +class HubAndSpokePolicyGetResponse(HubAndSpokePolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/mesh.py b/catalystwan/models/policy/definition/mesh.py similarity index 78% rename from catalystwan/models/policy/definitions/mesh.py rename to catalystwan/models/policy/definition/mesh.py index 291b161a..92449365 100644 --- a/catalystwan/models/policy/definitions/mesh.py +++ b/catalystwan/models/policy/definition/mesh.py @@ -5,7 +5,11 @@ from pydantic import BaseModel, ConfigDict, Field -from catalystwan.models.policy.policy_definition import PolicyDefinitionBase +from catalystwan.models.policy.policy_definition import ( + PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, +) class Region(BaseModel): @@ -33,3 +37,11 @@ def add_region(self, name: str, site_lists: List[UUID]) -> Region: region = Region(name=name, site_lists=site_lists) self.definition.regions.append(region) return region + + +class MeshPolicyEditPayload(MeshPolicy, PolicyDefinitionId): + pass + + +class MeshPolicyGetResponse(MeshPolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/qos_map.py b/catalystwan/models/policy/definition/qos_map.py similarity index 91% rename from catalystwan/models/policy/definitions/qos_map.py rename to catalystwan/models/policy/definition/qos_map.py index 2576b62b..6201ffe8 100644 --- a/catalystwan/models/policy/definitions/qos_map.py +++ b/catalystwan/models/policy/definition/qos_map.py @@ -6,7 +6,11 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from catalystwan.models.common import IntStr -from catalystwan.models.policy.policy_definition import PolicyDefinitionBase +from catalystwan.models.policy.policy_definition import ( + PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, +) QoSScheduling = Literal[ "llq", @@ -97,3 +101,11 @@ def generate_default_control_scheduler(self): # Only when creating (not when value obtained from remote is present) self.definition = QoSMapDefinition(qos_schedulers=[QoSScheduler.get_default_control_scheduler()]) return self + + +class QoSMapPolicyEditPayload(QoSMapPolicy, PolicyDefinitionId): + pass + + +class QoSMapPolicyGetResponse(QoSMapPolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/rewrite.py b/catalystwan/models/policy/definition/rewrite.py similarity index 84% rename from catalystwan/models/policy/definitions/rewrite.py rename to catalystwan/models/policy/definition/rewrite.py index 41087903..a85b8c9a 100644 --- a/catalystwan/models/policy/definitions/rewrite.py +++ b/catalystwan/models/policy/definition/rewrite.py @@ -9,6 +9,8 @@ DefinitionWithSequencesCommonBase, PLPEntryType, PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, ) @@ -35,3 +37,11 @@ def add_rule(self, class_map_ref: UUID, dscp: int, l2cos: int, plp: PLPEntryType self.definition.rules.append(RewritePolicyRule(class_=class_map_ref, plp=plp, dscp=str(dscp), l2cos=str(l2cos))) model_config = ConfigDict(populate_by_name=True) + + +class RewritePolicyEditPayload(RewritePolicy, PolicyDefinitionId): + pass + + +class RewritePolicyGetResponse(RewritePolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/rule_set.py b/catalystwan/models/policy/definition/rule_set.py similarity index 97% rename from catalystwan/models/policy/definitions/rule_set.py rename to catalystwan/models/policy/definition/rule_set.py index 2fdd5ff8..eff41632 100644 --- a/catalystwan/models/policy/definitions/rule_set.py +++ b/catalystwan/models/policy/definition/rule_set.py @@ -8,7 +8,13 @@ from typing_extensions import Annotated from catalystwan.models.common import check_fields_exclusive -from catalystwan.models.policy.policy_definition import PolicyDefinitionBase, Reference, VariableName +from catalystwan.models.policy.policy_definition import ( + PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, + Reference, + VariableName, +) class RuleBase(BaseModel): @@ -254,3 +260,11 @@ def add_ipv4_rule( protocol_name_list=Reference(ref=protocol_name_list_id) if protocol_name_list_id else None, ) self.add(ipv4_rule) + + +class RuleSetEditPayload(RuleSet, PolicyDefinitionId): + pass + + +class RuleSetGetResponse(RuleSet, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/security_group.py b/catalystwan/models/policy/definition/security_group.py similarity index 89% rename from catalystwan/models/policy/definitions/security_group.py rename to catalystwan/models/policy/definition/security_group.py index 68c9214e..3ecc56d3 100644 --- a/catalystwan/models/policy/definitions/security_group.py +++ b/catalystwan/models/policy/definition/security_group.py @@ -6,7 +6,13 @@ from pydantic import BaseModel, ConfigDict, Field, model_validator from catalystwan.models.common import check_any_of_exclusive_field_sets, check_fields_exclusive -from catalystwan.models.policy.policy_definition import PolicyDefinitionBase, Reference, VariableName +from catalystwan.models.policy.policy_definition import ( + PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, + Reference, + VariableName, +) SequenceIPType = Literal[ "ipv4", @@ -67,3 +73,11 @@ def validate_by_sequence_ip_type(self): ): raise ValueError(f"Incompatible definition for {self.sequence_ip_type} sequence") return self + + +class SecurityGroupEditPayload(SecurityGroup, PolicyDefinitionId): + pass + + +class SecurityGroupGetResponse(SecurityGroup, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/traffic_data.py b/catalystwan/models/policy/definition/traffic_data.py similarity index 97% rename from catalystwan/models/policy/definitions/traffic_data.py rename to catalystwan/models/policy/definition/traffic_data.py index 2d3ffbee..c13b173e 100644 --- a/catalystwan/models/policy/definitions/traffic_data.py +++ b/catalystwan/models/policy/definition/traffic_data.py @@ -7,8 +7,7 @@ from pydantic import ConfigDict, Field from typing_extensions import Annotated -from catalystwan.models.common import ICMPMessageType, ServiceChainNumber, TLOCColor -from catalystwan.models.policy.lists_entries import EncapType +from catalystwan.models.common import EncapType, ICMPMessageType, ServiceChainNumber, TLOCColor from catalystwan.models.policy.policy_definition import ( AppListEntry, CFlowDAction, @@ -43,6 +42,8 @@ PolicerListEntry, PolicyActionType, PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, PolicyDefinitionSequenceBase, PrefferedColorGroupListEntry, ProtocolEntry, @@ -376,3 +377,11 @@ def add_ipv4_sequence( ) self.add(seq) return seq + + +class TrafficDataPolicyEditPayload(TrafficDataPolicy, PolicyDefinitionId): + pass + + +class TrafficDataPolicyGetResponse(TrafficDataPolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/vpn_membership.py b/catalystwan/models/policy/definition/vpn_membership.py similarity index 75% rename from catalystwan/models/policy/definitions/vpn_membership.py rename to catalystwan/models/policy/definition/vpn_membership.py index 769848dd..1b1aead8 100644 --- a/catalystwan/models/policy/definitions/vpn_membership.py +++ b/catalystwan/models/policy/definition/vpn_membership.py @@ -5,7 +5,11 @@ from pydantic import BaseModel, ConfigDict, Field -from catalystwan.models.policy.policy_definition import PolicyDefinitionBase +from catalystwan.models.policy.policy_definition import ( + PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, +) class Site(BaseModel): @@ -28,3 +32,11 @@ def add_site(self, site_list: UUID, vpn_lists: List[UUID]) -> Site: site = Site(site_list=site_list, vpn_list=vpn_lists) self.definition.sites.append(site) return site + + +class VPNMembershipPolicyEditPayload(VPNMembershipPolicy, PolicyDefinitionId): + pass + + +class VPNMembershipPolicyGetResponse(VPNMembershipPolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/definitions/zone_based_firewall.py b/catalystwan/models/policy/definition/zone_based_firewall.py similarity index 97% rename from catalystwan/models/policy/definitions/zone_based_firewall.py rename to catalystwan/models/policy/definition/zone_based_firewall.py index cd2500bf..feb1b4c1 100644 --- a/catalystwan/models/policy/definitions/zone_based_firewall.py +++ b/catalystwan/models/policy/definition/zone_based_firewall.py @@ -25,6 +25,8 @@ Match, PolicyActionType, PolicyDefinitionBase, + PolicyDefinitionGetResponse, + PolicyDefinitionId, PolicyDefinitionSequenceBase, ProtocolEntry, ProtocolNameEntry, @@ -251,3 +253,11 @@ def add_zone_pair(self, source_zone_id: UUID, destination_zone_id: UUID) -> None destination_zone_id=destination_zone_id, ) self.definition.entries.append(entry) + + +class ZoneBasedFWPolicyEditPayload(ZoneBasedFWPolicy, PolicyDefinitionId): + pass + + +class ZoneBasedFWPolicyGetResponse(ZoneBasedFWPolicy, PolicyDefinitionGetResponse): + pass diff --git a/catalystwan/models/policy/list/app.py b/catalystwan/models/policy/list/app.py new file mode 100644 index 00000000..5ded9988 --- /dev/null +++ b/catalystwan/models/policy/list/app.py @@ -0,0 +1,37 @@ +from typing import List, Literal, Optional + +from pydantic import BaseModel, ConfigDict, Field, model_validator + +from catalystwan.models.common import check_fields_exclusive +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class AppListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + app_family: Optional[str] = Field(default=None, serialization_alias="appFamily", validation_alias="appFamily") + app: Optional[str] = None + + @model_validator(mode="after") + def check_app_xor_appfamily(self): + check_fields_exclusive(self.__dict__, {"app", "app_family"}, True) + return self + + +class AppList(PolicyListBase): + type: Literal["app"] = "app" + entries: List[AppListEntry] = [] + + def add_app(self, app: str) -> None: + self._add_entry(AppListEntry(app=app)) + + def add_app_family(self, app_family: str) -> None: + self._add_entry(AppListEntry(app_family=app_family)) + + +class AppListEditPayload(AppList, PolicyListId): + pass + + +class AppListInfo(AppList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/app_probe.py b/catalystwan/models/policy/list/app_probe.py new file mode 100644 index 00000000..cb788fd6 --- /dev/null +++ b/catalystwan/models/policy/list/app_probe.py @@ -0,0 +1,42 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.common import TLOCColor +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class ColorDSCPMap(BaseModel): + color: TLOCColor + dscp: int = Field(ge=0, le=63) + + +class AppProbeClassListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + forwarding_class: str = Field(serialization_alias="forwardingClass", validation_alias="forwardingClass") + map: List[ColorDSCPMap] = [] + + def add_color_mapping(self, color: TLOCColor, dscp: int) -> None: + self.map.append(ColorDSCPMap(color=color, dscp=dscp)) + + +class AppProbeClassList(PolicyListBase): + type: Literal["appProbe"] = "appProbe" + entries: List[AppProbeClassListEntry] = [] + + def assign_forwarding_class(self, name: str) -> AppProbeClassListEntry: + # App probe class list must have only one entry! + entry = AppProbeClassListEntry(forwarding_class=name) + self._add_entry(entry, single=True) + return entry + + +class AppProbeClassListEditPayload(AppProbeClassList, PolicyListId): + pass + + +class AppProbeClassListInfo(AppProbeClassList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/as_path.py b/catalystwan/models/policy/list/as_path.py new file mode 100644 index 00000000..b263b7a2 --- /dev/null +++ b/catalystwan/models/policy/list/as_path.py @@ -0,0 +1,26 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class ASPathListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + as_path: str = Field(serialization_alias="asPath", validation_alias="asPath") + + +class ASPathList(PolicyListBase): + type: Literal["asPath"] = "asPath" + entries: List[ASPathListEntry] = [] + + +class ASPathListEditPayload(ASPathList, PolicyListId): + pass + + +class ASPathListInfo(ASPathList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/class_map.py b/catalystwan/models/policy/list/class_map.py new file mode 100644 index 00000000..cf2bd462 --- /dev/null +++ b/catalystwan/models/policy/list/class_map.py @@ -0,0 +1,30 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, Field + +from catalystwan.models.common import IntStr +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class ClassMapListEntry(BaseModel): + queue: IntStr = Field(ge=0, le=7) + + +class ClassMapList(PolicyListBase): + type: Literal["class"] = "class" + entries: List[ClassMapListEntry] = [] + + def assign_queue(self, queue: int) -> None: + # Class map list must have only one entry! + entry = ClassMapListEntry(queue=queue) + self._add_entry(entry, single=True) + + +class ClassMapListEditPayload(ClassMapList, PolicyListId): + pass + + +class ClassMapListInfo(ClassMapList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/color.py b/catalystwan/models/policy/list/color.py new file mode 100644 index 00000000..358cf8e6 --- /dev/null +++ b/catalystwan/models/policy/list/color.py @@ -0,0 +1,28 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel + +from catalystwan.models.common import TLOCColor +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class ColorListEntry(BaseModel): + color: TLOCColor + + +class ColorList(PolicyListBase): + type: Literal["color"] = "color" + entries: List[ColorListEntry] = [] + + def add_color(self, color: TLOCColor) -> None: + self._add_entry(ColorListEntry(color=color)) + + +class ColorListEditPayload(ColorList, PolicyListId): + pass + + +class ColorListInfo(ColorList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/communities.py b/catalystwan/models/policy/list/communities.py new file mode 100644 index 00000000..798916e7 --- /dev/null +++ b/catalystwan/models/policy/list/communities.py @@ -0,0 +1,48 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.common import WellKnownBGPCommunities +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class CommunityListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + community: str = Field(examples=["1000:10000", "internet", "local-AS"]) + + +class CommunityListBase(PolicyListBase): + entries: List[CommunityListEntry] = [] + + def add_well_known_community(self, community: WellKnownBGPCommunities) -> None: + self._add_entry(CommunityListEntry(community=community)) + + def add_community(self, as_number: int, community_number: int) -> None: + self._add_entry(CommunityListEntry(community=f"{as_number}:{community_number}")) + + +class CommunityList(CommunityListBase): + type: Literal["community"] = "community" + + +class CommunityListEditPayload(CommunityList, PolicyListId): + pass + + +class CommunityListInfo(CommunityList, PolicyListInfo): + pass + + +class ExpandedCommunityList(CommunityListBase): + type: Literal["expandedCommunity"] = "expandedCommunity" + + +class ExpandedCommunityListEditPayload(ExpandedCommunityList, PolicyListId): + pass + + +class ExpandedCommunityListInfo(ExpandedCommunityList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/data_ipv6_prefix.py b/catalystwan/models/policy/list/data_ipv6_prefix.py new file mode 100644 index 00000000..db326ff4 --- /dev/null +++ b/catalystwan/models/policy/list/data_ipv6_prefix.py @@ -0,0 +1,30 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from ipaddress import IPv6Interface +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class DataIPv6PrefixListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + ipv6_prefix: IPv6Interface = Field(serialization_alias="ipv6Prefix", validation_alias="ipv6Prefix") + + +class DataIPv6PrefixList(PolicyListBase): + type: Literal["dataIpv6Prefix"] = "dataIpv6Prefix" + entries: List[DataIPv6PrefixListEntry] = [] + + def add_prefix(self, ipv6_prefix: IPv6Interface) -> None: + self._add_entry(DataIPv6PrefixListEntry(ipv6_prefix=ipv6_prefix)) + + +class DataIPv6PrefixListEditPayload(DataIPv6PrefixList, PolicyListId): + pass + + +class DataIPv6PrefixListInfo(DataIPv6PrefixList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/data_prefix.py b/catalystwan/models/policy/list/data_prefix.py new file mode 100644 index 00000000..98ba2fe3 --- /dev/null +++ b/catalystwan/models/policy/list/data_prefix.py @@ -0,0 +1,30 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from ipaddress import IPv4Network +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class DataPrefixListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + ip_prefix: IPv4Network = Field(serialization_alias="ipPrefix", validation_alias="ipPrefix") + + +class DataPrefixList(PolicyListBase): + type: Literal["dataPrefix"] = "dataPrefix" + entries: List[DataPrefixListEntry] = [] + + def add_prefix(self, ip_prefix: IPv4Network) -> None: + self._add_entry(DataPrefixListEntry(ip_prefix=ip_prefix)) + + +class DataPrefixListEditPayload(DataPrefixList, PolicyListId): + pass + + +class DataPrefixListInfo(DataPrefixList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/fqdn.py b/catalystwan/models/policy/list/fqdn.py new file mode 100644 index 00000000..4bcc3e88 --- /dev/null +++ b/catalystwan/models/policy/list/fqdn.py @@ -0,0 +1,24 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class FQDNListEntry(BaseModel): + pattern: str + + +class FQDNList(PolicyListBase): + type: Literal["fqdn"] = "fqdn" + entries: List[FQDNListEntry] = [] + + +class FQDNListEditPayload(FQDNList, PolicyListId): + pass + + +class FQDNListInfo(FQDNList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/geo_location.py b/catalystwan/models/policy/list/geo_location.py new file mode 100644 index 00000000..eff5831e --- /dev/null +++ b/catalystwan/models/policy/list/geo_location.py @@ -0,0 +1,33 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal, Optional + +from pydantic import BaseModel, Field, model_validator + +from catalystwan.models.common import check_fields_exclusive +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class GeoLocationListEntry(BaseModel): + country: Optional[str] = Field(default=None, description="ISO-3166 alpha-3 country code eg: FRA") + continent: Optional[str] = Field( + default=None, description="One of 2-letter continent codes: AF, NA, OC, AN, AS, EU, SA" + ) + + @model_validator(mode="after") + def check_country_xor_continent(self): + check_fields_exclusive(self.__dict__, {"country", "continent"}, True) + return self + + +class GeoLocationList(PolicyListBase): + type: Literal["geoLocation"] = "geoLocation" + entries: List[GeoLocationListEntry] = [] + + +class GeoLocationListEditPayload(GeoLocationList, PolicyListId): + pass + + +class GeoLocationListInfo(GeoLocationList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/ips_signature.py b/catalystwan/models/policy/list/ips_signature.py new file mode 100644 index 00000000..08dbe371 --- /dev/null +++ b/catalystwan/models/policy/list/ips_signature.py @@ -0,0 +1,27 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class IPSSignatureListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + generator_id: str = Field(serialization_alias="generatorId", validation_alias="generatorId") + signature_id: str = Field(serialization_alias="signatureId", validation_alias="signatureId") + + +class IPSSignatureList(PolicyListBase): + type: Literal["ipsSignature"] = "ipsSignature" + entries: List[IPSSignatureListEntry] = [] + + +class IPSSignatureListEditPayload(IPSSignatureList, PolicyListId): + pass + + +class IPSSignatureListInfo(IPSSignatureList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/ipv6_prefix.py b/catalystwan/models/policy/list/ipv6_prefix.py new file mode 100644 index 00000000..8b5c59ee --- /dev/null +++ b/catalystwan/models/policy/list/ipv6_prefix.py @@ -0,0 +1,33 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from ipaddress import IPv6Interface +from typing import List, Literal, Optional + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.common import IntStr +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class IPv6PrefixListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + ipv6_prefix: IPv6Interface = Field(serialization_alias="ipv6Prefix", validation_alias="ipv6Prefix") + ge: Optional[IntStr] = Field(default=None, ge=0, le=128) + le: Optional[IntStr] = Field(default=None, ge=0, le=128) + + +class IPv6PrefixList(PolicyListBase): + type: Literal["ipv6prefix"] = "ipv6prefix" + entries: List[IPv6PrefixListEntry] = [] + + def add_prefix(self, prefix: IPv6Interface, ge: Optional[int] = None, le: Optional[int] = None) -> None: + self._add_entry(IPv6PrefixListEntry(ipv6_prefix=prefix, ge=ge, le=le)) + + +class IPv6PrefixListEditPayload(IPv6PrefixList, PolicyListId): + pass + + +class IPv6PrefixListInfo(IPv6PrefixList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/local_app.py b/catalystwan/models/policy/list/local_app.py new file mode 100644 index 00000000..d0fe37ed --- /dev/null +++ b/catalystwan/models/policy/list/local_app.py @@ -0,0 +1,33 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal, Optional + +from pydantic import BaseModel, ConfigDict, Field, model_validator + +from catalystwan.models.common import check_fields_exclusive +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class LocalAppListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + app_family: Optional[str] = Field(default=None, serialization_alias="appFamily", validation_alias="appFamily") + app: Optional[str] = None + + @model_validator(mode="after") + def check_app_xor_appfamily(self): + check_fields_exclusive(self.__dict__, {"app", "app_family"}, True) + return self + + +class LocalAppList(PolicyListBase): + type: Literal["localApp"] = "localApp" + entries: List[LocalAppListEntry] = [] + + +class LocalAppListEditPayload(LocalAppList, PolicyListId): + pass + + +class LocalAppListInfo(LocalAppList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/local_domain.py b/catalystwan/models/policy/list/local_domain.py new file mode 100644 index 00000000..9fbe5679 --- /dev/null +++ b/catalystwan/models/policy/list/local_domain.py @@ -0,0 +1,33 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class LocalDomainListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + name_server: str = Field( + pattern="^[^*+].*", + serialization_alias="nameServer", + validation_alias="nameServer", + max_length=240, + description="Must be valid std regex." + "String cannot start with a '*' or a '+', be empty, or be more than 240 characters", + ) + + +class LocalDomainList(PolicyListBase): + type: Literal["localDomain"] = "localDomain" + entries: List[LocalDomainListEntry] = [] + + +class LocalDomainListEditPayload(LocalDomainList, PolicyListId): + pass + + +class LocalDomainListInfo(LocalDomainList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/mirror.py b/catalystwan/models/policy/list/mirror.py new file mode 100644 index 00000000..03a84250 --- /dev/null +++ b/catalystwan/models/policy/list/mirror.py @@ -0,0 +1,27 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field, IPvAnyAddress + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class MirrorListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + remote_dest: IPvAnyAddress = Field(serialization_alias="remoteDest", validation_alias="remoteDest") + source: IPvAnyAddress + + +class MirrorList(PolicyListBase): + type: Literal["mirror"] = "mirror" + entries: List[MirrorListEntry] = [] + + +class MirrorListEditPayload(MirrorList, PolicyListId): + pass + + +class MirrorListInfo(MirrorList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/policer.py b/catalystwan/models/policy/list/policer.py new file mode 100644 index 00000000..502bae19 --- /dev/null +++ b/catalystwan/models/policy/list/policer.py @@ -0,0 +1,39 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.common import IntStr +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + +PolicerExceedAction = Literal[ + "drop", + "remark", +] + + +class PolicerListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + burst: IntStr = Field(description="bytes", ge=15_000, le=10_000_000) + exceed: PolicerExceedAction = "drop" + rate: IntStr = Field(description="bps", ge=8, le=100_000_000_000) + + +class PolicerList(PolicyListBase): + type: Literal["policer"] = "policer" + entries: List[PolicerListEntry] = [] + + def police(self, burst: int, rate: int, exceed: PolicerExceedAction = "drop") -> None: + # Policer list must have only single entry! + entry = PolicerListEntry(burst=burst, exceed=exceed, rate=rate) + self._add_entry(entry, single=True) + + +class PolicerListEditPayload(PolicerList, PolicyListId): + pass + + +class PolicerListInfo(PolicerList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/port.py b/catalystwan/models/policy/list/port.py new file mode 100644 index 00000000..e7759ab4 --- /dev/null +++ b/catalystwan/models/policy/list/port.py @@ -0,0 +1,33 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, field_validator + +from catalystwan.models.common import IntRangeStr +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class PortListEntry(BaseModel): + port: IntRangeStr + + @field_validator("port") + @classmethod + def check_port(cls, port: IntRangeStr): + for i in port: + if i is not None: + assert 0 <= i <= 65_535 + return port + + +class PortList(PolicyListBase): + type: Literal["port"] = "port" + entries: List[PortListEntry] = [] + + +class PortListEditPayload(PortList, PolicyListId): + pass + + +class PortListInfo(PortList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/preferred_color_group.py b/catalystwan/models/policy/list/preferred_color_group.py new file mode 100644 index 00000000..e5fd2ae2 --- /dev/null +++ b/catalystwan/models/policy/list/preferred_color_group.py @@ -0,0 +1,80 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal, Optional, Set, Tuple + +from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator + +from catalystwan.models.common import TLOCColor, str_as_str_list +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + +PathPreference = Literal[ + "direct-path", + "multi-hop-path", + "all-paths", +] + + +class ColorGroupPreference(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + color_preference: Set[TLOCColor] = Field(serialization_alias="colorPreference", validation_alias="colorPreference") + path_preference: PathPreference = Field(serialization_alias="pathPreference", validation_alias="pathPreference") + + _color_pref = field_validator("color_preference", mode="before")(str_as_str_list) + + @staticmethod + def from_color_set_and_path( + color_preference: Set[TLOCColor], path_preference: PathPreference + ) -> "ColorGroupPreference": + return ColorGroupPreference(color_preference=color_preference, path_preference=path_preference) + + +class PreferredColorGroupListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + primary_preference: ColorGroupPreference = Field( + serialization_alias="primaryPreference", validation_alias="primaryPreference" + ) + secondary_preference: Optional[ColorGroupPreference] = Field( + default=None, serialization_alias="secondaryPreference", validation_alias="secondaryPreference" + ) + tertiary_preference: Optional[ColorGroupPreference] = Field( + default=None, serialization_alias="tertiaryPreference", validation_alias="tertiaryPreference" + ) + + @model_validator(mode="after") + def check_optional_preferences_order(self): + assert not (self.secondary_preference is None and self.tertiary_preference is not None) + return self + + +class PreferredColorGroupList(PolicyListBase): + type: Literal["preferredColorGroup"] = "preferredColorGroup" + entries: List[PreferredColorGroupListEntry] = [] + + def assign_color_groups( + self, + primary: Tuple[Set[TLOCColor], PathPreference], + secondary: Optional[Tuple[Set[TLOCColor], PathPreference]] = None, + tertiary: Optional[Tuple[Set[TLOCColor], PathPreference]] = None, + ) -> PreferredColorGroupListEntry: + primary_preference = ColorGroupPreference.from_color_set_and_path(*primary) + secondary_preference = ( + ColorGroupPreference.from_color_set_and_path(*secondary) if secondary is not None else None + ) + tertiary_preference = ColorGroupPreference.from_color_set_and_path(*tertiary) if tertiary is not None else None + entry = PreferredColorGroupListEntry( + primary_preference=primary_preference, + secondary_preference=secondary_preference, + tertiary_preference=tertiary_preference, + ) + self._add_entry(entry=entry, single=True) + return entry + + +class PreferredColorGroupListEditPayload(PreferredColorGroupList, PolicyListId): + pass + + +class PreferredColorGroupListInfo(PreferredColorGroupList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/prefix.py b/catalystwan/models/policy/list/prefix.py new file mode 100644 index 00000000..32823176 --- /dev/null +++ b/catalystwan/models/policy/list/prefix.py @@ -0,0 +1,33 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from ipaddress import IPv4Network +from typing import List, Literal, Optional + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.common import IntStr +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class PrefixListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + ip_prefix: IPv4Network = Field(serialization_alias="ipPrefix", validation_alias="ipPrefix") + ge: Optional[IntStr] = Field(default=None, ge=0, le=32) + le: Optional[IntStr] = Field(default=None, ge=0, le=32) + + +class PrefixList(PolicyListBase): + type: Literal["prefix"] = "prefix" + entries: List[PrefixListEntry] = [] + + def add_prefix(self, prefix: IPv4Network, ge: Optional[int] = None, le: Optional[int] = None) -> None: + self._add_entry(PrefixListEntry(ip_prefix=prefix, ge=ge, le=le)) + + +class PrefixListEditPayload(PrefixList, PolicyListId): + pass + + +class PrefixListInfo(PrefixList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/protocol_name.py b/catalystwan/models/policy/list/protocol_name.py new file mode 100644 index 00000000..667c544c --- /dev/null +++ b/catalystwan/models/policy/list/protocol_name.py @@ -0,0 +1,26 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class ProtocolNameListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + protocol_name: str = Field(serialization_alias="protocolName", validation_alias="protocolName") + + +class ProtocolNameList(PolicyListBase): + type: Literal["protocolName"] = "protocolName" + entries: List[ProtocolNameListEntry] = [] + + +class ProtocolNameListEditPayload(ProtocolNameList, PolicyListId): + pass + + +class ProtocolNameListInfo(ProtocolNameList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/region.py b/catalystwan/models/policy/list/region.py new file mode 100644 index 00000000..bb6b9d06 --- /dev/null +++ b/catalystwan/models/policy/list/region.py @@ -0,0 +1,45 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal, Set, Tuple + +from pydantic import BaseModel, ConfigDict, Field, field_validator + +from catalystwan.models.common import IntRangeStr +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class RegionListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + region_id: IntRangeStr = Field( + serialization_alias="regionId", validation_alias="regionId", description="Number in range 0-63" + ) + + @field_validator("region_id") + @classmethod + def check_region_range(cls, region_ids: IntRangeStr): + for i in region_ids: + if i is not None: + assert 0 <= i <= 63 + return region_ids + + +class RegionList(PolicyListBase): + type: Literal["region"] = "region" + entries: List[RegionListEntry] = [] + + def add_regions(self, regions: Set[int]): + for region in regions: + self._add_entry(RegionListEntry(region_id=(region, None))) + + def add_region_range(self, region_range: Tuple[int, int]): + entry = RegionListEntry(region_id=region_range) + self._add_entry(entry) + + +class RegionListEditPayload(RegionList, PolicyListId): + pass + + +class RegionListInfo(RegionList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/site.py b/catalystwan/models/policy/list/site.py new file mode 100644 index 00000000..346a2e2f --- /dev/null +++ b/catalystwan/models/policy/list/site.py @@ -0,0 +1,34 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal, Set, Tuple + +from pydantic import BaseModel, ConfigDict, Field + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class SiteListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + site_id: str = Field(serialization_alias="siteId", validation_alias="siteId") + + +class SiteList(PolicyListBase): + type: Literal["site"] = "site" + entries: List[SiteListEntry] = [] + + def add_sites(self, sites: Set[int]): + for site in sites: + self._add_entry(SiteListEntry(site_id=str(site))) + + def add_site_range(self, site_range: Tuple[int, int]): + entry = SiteListEntry(site_id=f"{site_range[0]}-{site_range[1]}") + self._add_entry(entry) + + +class SiteListEditPayload(SiteList, PolicyListId): + pass + + +class SiteListInfo(SiteList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/sla.py b/catalystwan/models/policy/list/sla.py new file mode 100644 index 00000000..3a79f754 --- /dev/null +++ b/catalystwan/models/policy/list/sla.py @@ -0,0 +1,177 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal, Optional +from uuid import UUID + +from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +def check_jitter_ms(jitter_str: Optional[str]) -> Optional[str]: + if jitter_str is not None: + assert 1 <= int(jitter_str) <= 1000 + return jitter_str + + +def check_latency_ms(latency_str: Optional[str]) -> Optional[str]: + if latency_str is not None: + assert 1 <= int(latency_str) <= 1000 + return latency_str + + +def check_loss_percent(loss_str: Optional[str]) -> Optional[str]: + if loss_str is not None: + assert 0 <= int(loss_str) <= 100 + return loss_str + + +class FallbackBestTunnel(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + criteria: str + jitter_variance: Optional[str] = Field( + default=None, + serialization_alias="jitterVariance", + validation_alias="jitterVariance", + description="jitter variance in ms", + ) + latency_variance: Optional[str] = Field( + default=None, + serialization_alias="latencyVariance", + validation_alias="latencyVariance", + description="latency variance in ms", + ) + loss_variance: Optional[str] = Field( + default=None, + serialization_alias="lossVariance", + validation_alias="lossVariance", + description="loss variance as percentage", + ) + _criteria_priority: List[Literal["jitter", "latency", "loss"]] = [] + + # validators + _jitter_validator = field_validator("jitter_variance")(check_jitter_ms) + _latency_validator = field_validator("latency_variance")(check_latency_ms) + _loss_validator = field_validator("loss_variance")(check_loss_percent) + + @model_validator(mode="after") + def check_criteria(self): + expected_criteria = set() + if self.jitter_variance is not None: + expected_criteria.add("jitter") + if self.latency_variance is not None: + expected_criteria.add("latency") + if self.loss_variance is not None: + expected_criteria.add("loss") + assert expected_criteria, "At least one variance type needs to be present" + self._criteria_priority = str(self.criteria).split("-") + observed_criteria = set(self._criteria_priority) + assert expected_criteria == observed_criteria + return self + + def _update_criteria_field(self) -> None: + self.criteria = f"{'-'.join(self._criteria_priority)}" + + def add_jitter_criteria(self, jitter_variance: int) -> None: + if self.jitter_variance is None: + self._criteria_priority.append("jitter") + self.jitter_variance = str(jitter_variance) + self._update_criteria_field() + self.check_criteria + + def add_latency_criteria(self, latency_variance: int) -> None: + if self.latency_variance is None: + self._criteria_priority.append("latency") + self.latency_variance = str(latency_variance) + self._update_criteria_field() + self.check_criteria + + def add_loss_criteria(self, loss_variance: int) -> None: + if self.loss_variance is None: + self._criteria_priority.append("loss") + self.loss_variance = str(loss_variance) + self._update_criteria_field() + self.check_criteria + + +class SLAClassListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + latency: Optional[str] = None + loss: Optional[str] = None + jitter: Optional[str] = None + app_probe_class: Optional[UUID] = Field( + default=None, serialization_alias="appProbeClass", validation_alias="appProbeClass" + ) + fallback_best_tunnel: Optional[FallbackBestTunnel] = Field( + default=None, serialization_alias="fallbackBestTunnel", validation_alias="fallbackBestTunnel" + ) + + # validators + _jitter_validator = field_validator("jitter")(check_jitter_ms) + _latency_validator = field_validator("latency")(check_latency_ms) + _loss_validator = field_validator("loss")(check_loss_percent) + + @model_validator(mode="after") + def check_at_least_one_criteria_is_set(self): + assert any([self.latency, self.loss, self.jitter]) + return self + + def add_fallback_jitter_criteria(self, jitter_variance: int) -> None: + if self.fallback_best_tunnel: + self.fallback_best_tunnel.add_jitter_criteria(jitter_variance) + else: + self.fallback_best_tunnel = FallbackBestTunnel(criteria="jitter", jitter_variance=str(jitter_variance)) + + def add_fallback_latency_criteria(self, latency_variance: int) -> None: + if self.fallback_best_tunnel: + self.fallback_best_tunnel.add_latency_criteria(latency_variance) + else: + self.fallback_best_tunnel = FallbackBestTunnel(criteria="latency", latency_variance=str(latency_variance)) + + def add_fallback_loss_criteria(self, loss_variance: int) -> None: + if self.fallback_best_tunnel: + self.fallback_best_tunnel.add_loss_criteria(loss_variance) + else: + self.fallback_best_tunnel = FallbackBestTunnel(criteria="loss", loss_variance=str(loss_variance)) + + +class SLAClassList(PolicyListBase): + type: Literal["sla"] = "sla" + entries: List[SLAClassListEntry] = [] + + def assign_app_probe_class( + self, + app_probe_class_id: UUID, + latency: Optional[int] = None, + loss: Optional[int] = None, + jitter: Optional[int] = None, + ) -> SLAClassListEntry: + # SLA class list must have only one entry! + _latency = str(latency) if latency is not None else None + _loss = str(loss) if loss is not None else None + _jitter = str(jitter) if jitter is not None else None + entry = SLAClassListEntry(latency=_latency, loss=_loss, jitter=_jitter, app_probe_class=app_probe_class_id) + self._add_entry(entry, single=True) + return entry + + def add_fallback_jitter_criteria(self, jitter_variance: int) -> None: + assert self.entries, "Assign app probe class before configuring best fallback tunnel" + self.entries[0].add_fallback_jitter_criteria(jitter_variance) + + def add_fallback_latency_criteria(self, latency_variance: int) -> None: + assert self.entries, "Assign app probe class before configuring best fallback tunnel" + self.entries[0].add_fallback_latency_criteria(latency_variance) + + def add_fallback_loss_criteria(self, loss_variance: int) -> None: + assert self.entries, "Assign app probe class before configuring best fallback tunnel" + self.entries[0].add_fallback_loss_criteria(loss_variance) + + +class SLAClassListEditPayload(SLAClassList, PolicyListId): + pass + + +class SLAClassListInfo(SLAClassList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/tloc.py b/catalystwan/models/policy/list/tloc.py new file mode 100644 index 00000000..7cb13de0 --- /dev/null +++ b/catalystwan/models/policy/list/tloc.py @@ -0,0 +1,32 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from ipaddress import IPv4Address +from typing import List, Literal, Optional + +from pydantic import BaseModel, Field + +from catalystwan.models.common import EncapType, IntStr, TLOCColor +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class TLOCListEntry(BaseModel): + tloc: IPv4Address + color: TLOCColor + encap: EncapType + preference: Optional[IntStr] = Field(default=None, ge=0, le=2**32 - 1) + + +class TLOCList(PolicyListBase): + type: Literal["tloc"] = "tloc" + entries: List[TLOCListEntry] = [] + + def add_tloc(self, tloc: IPv4Address, color: TLOCColor, encap: EncapType, preference: Optional[int] = None) -> None: + self.entries.append(TLOCListEntry(tloc=tloc, color=color, encap=encap, preference=preference)) + + +class TLOCListEditPayload(TLOCList, PolicyListId): + pass + + +class TLOCListInfo(TLOCList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/url.py b/catalystwan/models/policy/list/url.py new file mode 100644 index 00000000..9b4367ee --- /dev/null +++ b/catalystwan/models/policy/list/url.py @@ -0,0 +1,39 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal + +from pydantic import BaseModel, ConfigDict + +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class URLListEntry(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + pattern: str + + +class URLAllowList(PolicyListBase): + type: Literal["urlWhiteList"] = "urlWhiteList" + entries: List[URLListEntry] = [] + + +class URLAllowListEditPayload(URLAllowList, PolicyListId): + pass + + +class URLAllowListInfo(URLAllowList, PolicyListInfo): + pass + + +class URLBlockList(PolicyListBase): + type: Literal["urlBlackList"] = "urlBlackList" + entries: List[URLListEntry] = [] + + +class URLBlockListEditPayload(URLBlockList, PolicyListId): + pass + + +class URLBlockListInfo(URLBlockList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/vpn.py b/catalystwan/models/policy/list/vpn.py new file mode 100644 index 00000000..0812677d --- /dev/null +++ b/catalystwan/models/policy/list/vpn.py @@ -0,0 +1,40 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal, Set, Tuple + +from pydantic import BaseModel, Field, field_validator + +from catalystwan.models.common import IntRangeStr +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class VPNListEntry(BaseModel): + vpn: IntRangeStr = Field(description="0-65530 range or single number") + + @field_validator("vpn") + @classmethod + def check_vpn_range(cls, vpn: IntRangeStr): + for i in vpn: + if i is not None: + assert 0 <= i <= 65_530 + return vpn + + +class VPNList(PolicyListBase): + type: Literal["vpn"] = "vpn" + entries: List[VPNListEntry] = [] + + def add_vpns(self, vpns: Set[int]): + for vpn in vpns: + self._add_entry(VPNListEntry(vpn=(vpn, None))) + + def add_vpn_range(self, vpn_range: Tuple[int, int]): + self._add_entry(VPNListEntry(vpn=vpn_range)) + + +class VPNListEditPayload(VPNList, PolicyListId): + pass + + +class VPNListInfo(VPNList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/list/zone.py b/catalystwan/models/policy/list/zone.py new file mode 100644 index 00000000..c0c1688c --- /dev/null +++ b/catalystwan/models/policy/list/zone.py @@ -0,0 +1,45 @@ +# Copyright 2022 Cisco Systems, Inc. and its affiliates + +from typing import List, Literal, Optional, Set + +from pydantic import BaseModel, Field, field_validator, model_validator + +from catalystwan.models.common import InterfaceType, IntRangeStr, check_fields_exclusive +from catalystwan.models.policy.policy_list import PolicyListBase, PolicyListId, PolicyListInfo + + +class ZoneListEntry(BaseModel): + vpn: Optional[IntRangeStr] = Field(default=None, description="0-65530 single number") + interface: Optional[InterfaceType] = None + + @field_validator("vpn") + @classmethod + def check_vpn_range(cls, vpn: IntRangeStr): + for i in vpn: + if i is not None: + assert 0 <= i <= 65_530 + return vpn + + @model_validator(mode="after") + def check_vpn_xor_interface(self): + check_fields_exclusive(self.__dict__, {"vpn", "interface"}, True) + return self + + +class ZoneList(PolicyListBase): + type: Literal["zone"] = "zone" + entries: List[ZoneListEntry] = [] + + def assign_vpns(self, vpns: Set[int]) -> None: + self.entries = [ZoneListEntry(vpn=(vpn, None)) for vpn in vpns] + + def assign_interfaces(self, ifs: Set[InterfaceType]) -> None: + self.entries = [ZoneListEntry(interface=interface) for interface in ifs] + + +class ZoneListEditPayload(ZoneList, PolicyListId): + pass + + +class ZoneListInfo(ZoneList, PolicyListInfo): + pass diff --git a/catalystwan/models/policy/lists.py b/catalystwan/models/policy/lists.py deleted file mode 100644 index f3584114..00000000 --- a/catalystwan/models/policy/lists.py +++ /dev/null @@ -1,330 +0,0 @@ -# Copyright 2023 Cisco Systems, Inc. and its affiliates - -from ipaddress import IPv4Address, IPv4Network, IPv6Interface -from typing import Any, List, Literal, Optional, Set, Tuple -from uuid import UUID - -from pydantic import BaseModel, Field - -from catalystwan.models.common import InterfaceType, TLOCColor, WellKnownBGPCommunities -from catalystwan.models.policy.lists_entries import ( - AppListEntry, - AppProbeClassListEntry, - ASPathListEntry, - ClassMapListEntry, - ColorGroupPreference, - ColorListEntry, - CommunityListEntry, - DataIPv6PrefixListEntry, - DataPrefixListEntry, - EncapType, - FQDNListEntry, - GeoLocationListEntry, - IPSSignatureListEntry, - IPv6PrefixListEntry, - LocalAppListEntry, - LocalDomainListEntry, - MirrorListEntry, - PathPreference, - PolicerExceedAction, - PolicerListEntry, - PortListEntry, - PreferredColorGroupListEntry, - PrefixListEntry, - ProtocolNameListEntry, - RegionListEntry, - SiteListEntry, - SLAClassListEntry, - TLOCListEntry, - URLListEntry, - VPNListEntry, - ZoneListEntry, -) - - -class PolicyListBase(BaseModel): - name: str = Field( - pattern="^[a-zA-Z0-9_-]{1,32}$", - description="Can include only alpha-numeric characters, hyphen '-' or underscore '_'; maximum 32 characters", - ) - description: Optional[str] = "Desc Not Required" - entries: List[Any] - - def _add_entry(self, entry: Any, single: bool = False) -> None: - if self.entries and single: - self.entries[0] = entry - del self.entries[1:] - else: - self.entries.append(entry) - - -class DataPrefixList(PolicyListBase): - type: Literal["dataPrefix"] = "dataPrefix" - entries: List[DataPrefixListEntry] = [] - - def add_prefix(self, ip_prefix: IPv4Network) -> None: - self._add_entry(DataPrefixListEntry(ip_prefix=ip_prefix)) - - -class SiteList(PolicyListBase): - type: Literal["site"] = "site" - entries: List[SiteListEntry] = [] - - def add_sites(self, sites: Set[int]): - for site in sites: - self._add_entry(SiteListEntry(site_id=str(site))) - - def add_site_range(self, site_range: Tuple[int, int]): - entry = SiteListEntry(site_id=f"{site_range[0]}-{site_range[1]}") - self._add_entry(entry) - - -class VPNList(PolicyListBase): - type: Literal["vpn"] = "vpn" - entries: List[VPNListEntry] = [] - - def add_vpns(self, vpns: Set[int]): - for vpn in vpns: - self._add_entry(VPNListEntry(vpn=(vpn, None))) - - def add_vpn_range(self, vpn_range: Tuple[int, int]): - self._add_entry(VPNListEntry(vpn=vpn_range)) - - -class ZoneList(PolicyListBase): - type: Literal["zone"] = "zone" - entries: List[ZoneListEntry] = [] - - def assign_vpns(self, vpns: Set[int]) -> None: - self.entries = [ZoneListEntry(vpn=(vpn, None)) for vpn in vpns] - - def assign_interfaces(self, ifs: Set[InterfaceType]) -> None: - self.entries = [ZoneListEntry(interface=interface) for interface in ifs] - - -class FQDNList(PolicyListBase): - type: Literal["fqdn"] = "fqdn" - entries: List[FQDNListEntry] = [] - - -class GeoLocationList(PolicyListBase): - type: Literal["geoLocation"] = "geoLocation" - entries: List[GeoLocationListEntry] = [] - - -class PortList(PolicyListBase): - type: Literal["port"] = "port" - entries: List[PortListEntry] = [] - - -class ProtocolNameList(PolicyListBase): - type: Literal["protocolName"] = "protocolName" - entries: List[ProtocolNameListEntry] = [] - - -class LocalAppList(PolicyListBase): - type: Literal["localApp"] = "localApp" - entries: List[LocalAppListEntry] = [] - - -class AppList(PolicyListBase): - type: Literal["app"] = "app" - entries: List[AppListEntry] = [] - - def add_app(self, app: str) -> None: - self._add_entry(AppListEntry(app=app)) - - def add_app_family(self, app_family: str) -> None: - self._add_entry(AppListEntry(app_family=app_family)) - - -class ColorList(PolicyListBase): - type: Literal["color"] = "color" - entries: List[ColorListEntry] = [] - - def add_color(self, color: TLOCColor) -> None: - self._add_entry(ColorListEntry(color=color)) - - -class DataIPv6PrefixList(PolicyListBase): - type: Literal["dataIpv6Prefix"] = "dataIpv6Prefix" - entries: List[DataIPv6PrefixListEntry] = [] - - def add_prefix(self, ipv6_prefix: IPv6Interface) -> None: - self._add_entry(DataIPv6PrefixListEntry(ipv6_prefix=ipv6_prefix)) - - -class LocalDomainList(PolicyListBase): - type: Literal["localDomain"] = "localDomain" - entries: List[LocalDomainListEntry] = [] - - -class IPSSignatureList(PolicyListBase): - type: Literal["ipsSignature"] = "ipsSignature" - entries: List[IPSSignatureListEntry] = [] - - -class URLAllowList(PolicyListBase): - type: Literal["urlWhiteList"] = "urlWhiteList" - entries: List[URLListEntry] = [] - - -class URLBlockList(PolicyListBase): - type: Literal["urlBlackList"] = "urlBlackList" - entries: List[URLListEntry] = [] - - -class _CommunityListBase(PolicyListBase): - entries: List[CommunityListEntry] = [] - - def add_well_known_community(self, community: WellKnownBGPCommunities) -> None: - self._add_entry(CommunityListEntry(community=community)) - - def add_community(self, as_number: int, community_number: int) -> None: - self._add_entry(CommunityListEntry(community=f"{as_number}:{community_number}")) - - -class CommunityList(_CommunityListBase): - type: Literal["community"] = "community" - - -class ExpandedCommunityList(_CommunityListBase): - type: Literal["expandedCommunity"] = "expandedCommunity" - - -class PolicerList(PolicyListBase): - type: Literal["policer"] = "policer" - entries: List[PolicerListEntry] = [] - - def police(self, burst: int, rate: int, exceed: PolicerExceedAction = "drop") -> None: - # Policer list must have only single entry! - entry = PolicerListEntry(burst=burst, exceed=exceed, rate=rate) - self._add_entry(entry, single=True) - - -class ASPathList(PolicyListBase): - type: Literal["asPath"] = "asPath" - entries: List[ASPathListEntry] = [] - - -class ClassMapList(PolicyListBase): - type: Literal["class"] = "class" - entries: List[ClassMapListEntry] = [] - - def assign_queue(self, queue: int) -> None: - # Class map list must have only one entry! - entry = ClassMapListEntry(queue=queue) - self._add_entry(entry, single=True) - - -class MirrorList(PolicyListBase): - type: Literal["mirror"] = "mirror" - entries: List[MirrorListEntry] = [] - - -class AppProbeClassList(PolicyListBase): - type: Literal["appProbe"] = "appProbe" - entries: List[AppProbeClassListEntry] = [] - - def assign_forwarding_class(self, name: str) -> AppProbeClassListEntry: - # App probe class list must have only one entry! - entry = AppProbeClassListEntry(forwarding_class=name) - self._add_entry(entry, single=True) - return entry - - -class SLAClassList(PolicyListBase): - type: Literal["sla"] = "sla" - entries: List[SLAClassListEntry] = [] - - def assign_app_probe_class( - self, - app_probe_class_id: UUID, - latency: Optional[int] = None, - loss: Optional[int] = None, - jitter: Optional[int] = None, - ) -> SLAClassListEntry: - # SLA class list must have only one entry! - _latency = str(latency) if latency is not None else None - _loss = str(loss) if loss is not None else None - _jitter = str(jitter) if jitter is not None else None - entry = SLAClassListEntry(latency=_latency, loss=_loss, jitter=_jitter, app_probe_class=app_probe_class_id) - self._add_entry(entry, single=True) - return entry - - def add_fallback_jitter_criteria(self, jitter_variance: int) -> None: - assert self.entries, "Assign app probe class before configuring best fallback tunnel" - self.entries[0].add_fallback_jitter_criteria(jitter_variance) - - def add_fallback_latency_criteria(self, latency_variance: int) -> None: - assert self.entries, "Assign app probe class before configuring best fallback tunnel" - self.entries[0].add_fallback_latency_criteria(latency_variance) - - def add_fallback_loss_criteria(self, loss_variance: int) -> None: - assert self.entries, "Assign app probe class before configuring best fallback tunnel" - self.entries[0].add_fallback_loss_criteria(loss_variance) - - -class TLOCList(PolicyListBase): - type: Literal["tloc"] = "tloc" - entries: List[TLOCListEntry] = [] - - def add_tloc(self, tloc: IPv4Address, color: TLOCColor, encap: EncapType, preference: Optional[int] = None) -> None: - _preference = str(preference) if preference is not None else None - self.entries.append(TLOCListEntry(tloc=tloc, color=color, encap=encap, preference=_preference)) - - -class PreferredColorGroupList(PolicyListBase): - type: Literal["preferredColorGroup"] = "preferredColorGroup" - entries: List[PreferredColorGroupListEntry] = [] - - def assign_color_groups( - self, - primary: Tuple[Set[TLOCColor], PathPreference], - secondary: Optional[Tuple[Set[TLOCColor], PathPreference]] = None, - tertiary: Optional[Tuple[Set[TLOCColor], PathPreference]] = None, - ) -> PreferredColorGroupListEntry: - primary_preference = ColorGroupPreference.from_color_set_and_path(*primary) - secondary_preference = ( - ColorGroupPreference.from_color_set_and_path(*secondary) if secondary is not None else None - ) - tertiary_preference = ColorGroupPreference.from_color_set_and_path(*tertiary) if tertiary is not None else None - entry = PreferredColorGroupListEntry( - primary_preference=primary_preference, - secondary_preference=secondary_preference, - tertiary_preference=tertiary_preference, - ) - if self.entries: - self.entries[0] = entry - else: - self.entries.append(entry) - return entry - - -class PrefixList(PolicyListBase): - type: Literal["prefix"] = "prefix" - entries: List[PrefixListEntry] = [] - - def add_prefix(self, prefix: IPv4Network, ge: Optional[int] = None, le: Optional[int] = None) -> None: - self._add_entry(PrefixListEntry(ip_prefix=prefix, ge=ge, le=le)) - - -class IPv6PrefixList(PolicyListBase): - type: Literal["ipv6prefix"] = "ipv6prefix" - entries: List[IPv6PrefixListEntry] = [] - - def add_prefix(self, prefix: IPv6Interface, ge: Optional[int] = None, le: Optional[int] = None) -> None: - self._add_entry(IPv6PrefixListEntry(ipv6_prefix=prefix, ge=ge, le=le)) - - -class RegionList(PolicyListBase): - type: Literal["region"] = "region" - entries: List[RegionListEntry] = [] - - def add_regions(self, regions: Set[int]): - for region in regions: - self._add_entry(RegionListEntry(region_id=str(region))) - - def add_region_range(self, region_range: Tuple[int, int]): - entry = RegionListEntry(region_id=f"{region_range[0]}-{region_range[1]}") - self._add_entry(entry) diff --git a/catalystwan/models/policy/lists_entries.py b/catalystwan/models/policy/lists_entries.py deleted file mode 100644 index 7ee837ad..00000000 --- a/catalystwan/models/policy/lists_entries.py +++ /dev/null @@ -1,427 +0,0 @@ -# Copyright 2023 Cisco Systems, Inc. and its affiliates - -from ipaddress import IPv4Address, IPv4Network, IPv6Interface -from typing import List, Literal, Optional, Set -from uuid import UUID - -from pydantic import BaseModel, ConfigDict, Field, IPvAnyAddress, field_validator, model_validator - -from catalystwan.models.common import ( - InterfaceType, - IntRangeStr, - IntStr, - TLOCColor, - check_fields_exclusive, - str_as_str_list, -) - - -def check_jitter_ms(jitter_str: Optional[str]) -> Optional[str]: - if jitter_str is not None: - assert 1 <= int(jitter_str) <= 1000 - return jitter_str - - -def check_latency_ms(latency_str: Optional[str]) -> Optional[str]: - if latency_str is not None: - assert 1 <= int(latency_str) <= 1000 - return latency_str - - -def check_loss_percent(loss_str: Optional[str]) -> Optional[str]: - if loss_str is not None: - assert 0 <= int(loss_str) <= 100 - return loss_str - - -PolicerExceedAction = Literal[ - "drop", - "remark", -] - -EncapType = Literal[ - "ipsec", - "gre", -] - -PathPreference = Literal[ - "direct-path", - "multi-hop-path", - "all-paths", -] - - -class ColorDSCPMap(BaseModel): - color: TLOCColor - dscp: int = Field(ge=0, le=63) - - -class ColorGroupPreference(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - color_preference: Set[TLOCColor] = Field(serialization_alias="colorPreference", validation_alias="colorPreference") - path_preference: PathPreference = Field(serialization_alias="pathPreference", validation_alias="pathPreference") - - _color_pref = field_validator("color_preference", mode="before")(str_as_str_list) - - @staticmethod - def from_color_set_and_path( - color_preference: Set[TLOCColor], path_preference: PathPreference - ) -> "ColorGroupPreference": - return ColorGroupPreference(color_preference=color_preference, path_preference=path_preference) - - -class FallbackBestTunnel(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - criteria: str - jitter_variance: Optional[str] = Field( - default=None, - serialization_alias="jitterVariance", - validation_alias="jitterVariance", - description="jitter variance in ms", - ) - latency_variance: Optional[str] = Field( - default=None, - serialization_alias="latencyVariance", - validation_alias="latencyVariance", - description="latency variance in ms", - ) - loss_variance: Optional[str] = Field( - default=None, - serialization_alias="lossVariance", - validation_alias="lossVariance", - description="loss variance as percentage", - ) - _criteria_priority: List[Literal["jitter", "latency", "loss"]] = [] - - # validators - _jitter_validator = field_validator("jitter_variance")(check_jitter_ms) - _latency_validator = field_validator("latency_variance")(check_latency_ms) - _loss_validator = field_validator("loss_variance")(check_loss_percent) - - @model_validator(mode="after") - def check_criteria(self): - expected_criteria = set() - if self.jitter_variance is not None: - expected_criteria.add("jitter") - if self.latency_variance is not None: - expected_criteria.add("latency") - if self.loss_variance is not None: - expected_criteria.add("loss") - assert expected_criteria, "At least one variance type needs to be present" - self._criteria_priority = str(self.criteria).split("-") - observed_criteria = set(self._criteria_priority) - assert expected_criteria == observed_criteria - return self - - def _update_criteria_field(self) -> None: - self.criteria = f"{'-'.join(self._criteria_priority)}" - - def add_jitter_criteria(self, jitter_variance: int) -> None: - if self.jitter_variance is None: - self._criteria_priority.append("jitter") - self.jitter_variance = str(jitter_variance) - self._update_criteria_field() - self.check_criteria - - def add_latency_criteria(self, latency_variance: int) -> None: - if self.latency_variance is None: - self._criteria_priority.append("latency") - self.latency_variance = str(latency_variance) - self._update_criteria_field() - self.check_criteria - - def add_loss_criteria(self, loss_variance: int) -> None: - if self.loss_variance is None: - self._criteria_priority.append("loss") - self.loss_variance = str(loss_variance) - self._update_criteria_field() - self.check_criteria - - -class DataPrefixListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - ip_prefix: IPv4Network = Field(serialization_alias="ipPrefix", validation_alias="ipPrefix") - - -class SiteListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - site_id: str = Field(serialization_alias="siteId", validation_alias="siteId") - - -class VPNListEntry(BaseModel): - vpn: IntRangeStr = Field(description="0-65530 range or single number") - - @field_validator("vpn") - @classmethod - def check_vpn_range(cls, vpn: IntRangeStr): - for i in vpn: - if i is not None: - assert 0 <= i <= 65_530 - return vpn - - -class ZoneListEntry(BaseModel): - vpn: Optional[IntRangeStr] = Field(default=None, description="0-65530 single number") - interface: Optional[InterfaceType] = None - - @field_validator("vpn") - @classmethod - def check_vpn_range(cls, vpn: IntRangeStr): - for i in vpn: - if i is not None: - assert 0 <= i <= 65_530 - return vpn - - @model_validator(mode="after") - def check_vpn_xor_interface(self): - check_fields_exclusive(self.__dict__, {"vpn", "interface"}, True) - return self - - -class FQDNListEntry(BaseModel): - pattern: str - - -class GeoLocationListEntry(BaseModel): - country: Optional[str] = Field(default=None, description="ISO-3166 alpha-3 country code eg: FRA") - continent: Optional[str] = Field( - default=None, description="One of 2-letter continent codes: AF, NA, OC, AN, AS, EU, SA" - ) - - @model_validator(mode="after") - def check_country_xor_continent(self): - check_fields_exclusive(self.__dict__, {"country", "continent"}, True) - return self - - -class PortListEntry(BaseModel): - port: IntRangeStr - - @field_validator("port") - @classmethod - def check_port(cls, port: IntRangeStr): - for i in port: - if i is not None: - assert 0 <= i <= 65_535 - return port - - -class ProtocolNameListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - protocol_name: str = Field(serialization_alias="protocolName", validation_alias="protocolName") - - -class LocalAppListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - app_family: Optional[str] = Field(default=None, serialization_alias="appFamily", validation_alias="appFamily") - app: Optional[str] = None - - @model_validator(mode="after") - def check_app_xor_appfamily(self): - check_fields_exclusive(self.__dict__, {"app", "app_family"}, True) - return self - - -class AppListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - app_family: Optional[str] = Field(default=None, serialization_alias="appFamily", validation_alias="appFamily") - app: Optional[str] = None - - @model_validator(mode="after") - def check_app_xor_appfamily(self): - check_fields_exclusive(self.__dict__, {"app", "app_family"}, True) - return self - - -class ColorListEntry(BaseModel): - color: TLOCColor - - -class DataIPv6PrefixListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - ipv6_prefix: IPv6Interface = Field(serialization_alias="ipv6Prefix", validation_alias="ipv6Prefix") - - -class LocalDomainListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - name_server: str = Field( - pattern="^[^*+].*", - serialization_alias="nameServer", - validation_alias="nameServer", - max_length=240, - description="Must be valid std regex." - "String cannot start with a '*' or a '+', be empty, or be more than 240 characters", - ) - - -class IPSSignatureListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - generator_id: str = Field(serialization_alias="generatorId", validation_alias="generatorId") - signature_id: str = Field(serialization_alias="signatureId", validation_alias="signatureId") - - -class URLListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - pattern: str - - -class CommunityListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - community: str = Field(description="Example: 1000:10000 or internet or local-AS or no advertise or no-export") - - -class PolicerListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - burst: IntStr = Field(description="bytes", ge=15_000, le=10_000_000) - exceed: PolicerExceedAction = "drop" - rate: IntStr = Field(description="bps", ge=8, le=100_000_000_000) - - -class ASPathListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - as_path: str = Field(serialization_alias="asPath", validation_alias="asPath") - - -class ClassMapListEntry(BaseModel): - queue: IntStr = Field(ge=0, le=7) - - -class MirrorListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - remote_dest: IPvAnyAddress = Field(serialization_alias="remoteDest", validation_alias="remoteDest") - source: IPvAnyAddress - - -class AppProbeClassListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - forwarding_class: str = Field(serialization_alias="forwardingClass", validation_alias="forwardingClass") - map: List[ColorDSCPMap] = [] - - def add_color_mapping(self, color: TLOCColor, dscp: int) -> None: - self.map.append(ColorDSCPMap(color=color, dscp=dscp)) - - -class SLAClassListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - latency: Optional[str] = None - loss: Optional[str] = None - jitter: Optional[str] = None - app_probe_class: Optional[UUID] = Field( - default=None, serialization_alias="appProbeClass", validation_alias="appProbeClass" - ) - fallback_best_tunnel: Optional[FallbackBestTunnel] = Field( - default=None, serialization_alias="fallbackBestTunnel", validation_alias="fallbackBestTunnel" - ) - - # validators - _jitter_validator = field_validator("jitter")(check_jitter_ms) - _latency_validator = field_validator("latency")(check_latency_ms) - _loss_validator = field_validator("loss")(check_loss_percent) - - @model_validator(mode="after") - def check_at_least_one_criteria_is_set(self): - assert any([self.latency, self.loss, self.jitter]) - return self - - def add_fallback_jitter_criteria(self, jitter_variance: int) -> None: - if self.fallback_best_tunnel: - self.fallback_best_tunnel.add_jitter_criteria(jitter_variance) - else: - self.fallback_best_tunnel = FallbackBestTunnel(criteria="jitter", jitter_variance=str(jitter_variance)) - - def add_fallback_latency_criteria(self, latency_variance: int) -> None: - if self.fallback_best_tunnel: - self.fallback_best_tunnel.add_latency_criteria(latency_variance) - else: - self.fallback_best_tunnel = FallbackBestTunnel(criteria="latency", latency_variance=str(latency_variance)) - - def add_fallback_loss_criteria(self, loss_variance: int) -> None: - if self.fallback_best_tunnel: - self.fallback_best_tunnel.add_loss_criteria(loss_variance) - else: - self.fallback_best_tunnel = FallbackBestTunnel(criteria="loss", loss_variance=str(loss_variance)) - - -class TLOCListEntry(BaseModel): - tloc: IPv4Address - color: TLOCColor - encap: EncapType - preference: Optional[str] = None - - @field_validator("preference") - @classmethod - def check_preference(cls, preference_str: str): - if preference_str is not None: - assert 0 <= int(preference_str) <= 2**32 - 1 - return preference_str - - -class PreferredColorGroupListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - primary_preference: ColorGroupPreference = Field( - serialization_alias="primaryPreference", validation_alias="primaryPreference" - ) - secondary_preference: Optional[ColorGroupPreference] = Field( - default=None, serialization_alias="secondaryPreference", validation_alias="secondaryPreference" - ) - tertiary_preference: Optional[ColorGroupPreference] = Field( - default=None, serialization_alias="tertiaryPreference", validation_alias="tertiaryPreference" - ) - - @model_validator(mode="after") - def check_optional_preferences_order(self): - assert not (self.secondary_preference is None and self.tertiary_preference is not None) - return self - - -class PrefixListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - ip_prefix: IPv4Network = Field(serialization_alias="ipPrefix", validation_alias="ipPrefix") - ge: Optional[IntStr] = Field(default=None, ge=0, le=32) - le: Optional[IntStr] = Field(default=None, ge=0, le=32) - - -class IPv6PrefixListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - ipv6_prefix: IPv6Interface = Field(serialization_alias="ipv6Prefix", validation_alias="ipv6Prefix") - ge: Optional[IntStr] = Field(default=None, ge=0, le=128) - le: Optional[IntStr] = Field(default=None, ge=0, le=128) - - -class RegionListEntry(BaseModel): - model_config = ConfigDict(populate_by_name=True) - - region_id: str = Field( - serialization_alias="regionId", validation_alias="regionId", description="Number in range 0-63" - ) - - @field_validator("region_id") - @classmethod - def check_region_id(cls, region_id_str: str): - regions = [int(region_id) for region_id in region_id_str.split("-")] - assert len(regions) <= 2 - for region in regions: - assert 0 <= region <= 63 - if len(regions) == 2: - assert regions[0] <= regions[1] - return region_id_str diff --git a/catalystwan/models/policy/policy_definition.py b/catalystwan/models/policy/policy_definition.py index dcdcd339..7a0d0715 100644 --- a/catalystwan/models/policy/policy_definition.py +++ b/catalystwan/models/policy/policy_definition.py @@ -3,13 +3,14 @@ import datetime from functools import wraps from ipaddress import IPv4Address, IPv4Network, IPv6Network -from typing import Any, Dict, List, MutableSequence, Optional, Protocol, Sequence, Set, Tuple, Union +from typing import Any, Dict, List, MutableSequence, Optional, Sequence, Set, Tuple, Union from uuid import UUID from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from typing_extensions import Annotated, Literal from catalystwan.models.common import ( + EncapType, ICMPMessageType, ServiceChainNumber, TLOCColor, @@ -18,8 +19,6 @@ str_as_uuid_list, ) from catalystwan.models.misc.application_protocols import ApplicationProtocol -from catalystwan.models.policy.lists_entries import EncapType -from catalystwan.typed_list import DataSequence def port_set_and_ranges_to_str(ports: Set[int] = set(), port_ranges: List[Tuple[int, int]] = []) -> str: @@ -1146,20 +1145,3 @@ class PolicyDefinitionEditResponse(BaseModel): class PolicyDefinitionPreview(BaseModel): preview: str - - -class PolicyDefinitionEndpoints(Protocol): - def create_policy_definition(self, payload: BaseModel) -> PolicyDefinitionId: - ... - - def delete_policy_definition(self, id: UUID) -> None: - ... - - def edit_policy_definition(self, id: UUID, payload: BaseModel) -> PolicyDefinitionEditResponse: - ... - - def get_definitions(self) -> DataSequence[PolicyDefinitionInfo]: - ... - - def get_policy_definition(self, id: UUID) -> PolicyDefinitionGetResponse: - ... diff --git a/catalystwan/models/policy/policy_list.py b/catalystwan/models/policy/policy_list.py index 2b790a9e..0397c5d1 100644 --- a/catalystwan/models/policy/policy_list.py +++ b/catalystwan/models/policy/policy_list.py @@ -1,49 +1,47 @@ # Copyright 2023 Cisco Systems, Inc. and its affiliates import datetime -from typing import List, Optional, Protocol +from typing import Any, List, Optional from uuid import UUID from pydantic import BaseModel, Field -from catalystwan.models.policy import AnyPolicyList -from catalystwan.typed_list import DataSequence + +class PolicyListBase(BaseModel): + name: str = Field( + pattern="^[a-zA-Z0-9_-]{1,32}$", + description="Can include only alpha-numeric characters, hyphen '-' or underscore '_'; maximum 32 characters", + ) + description: Optional[str] = "Desc Not Required" + entries: List[Any] + + def _add_entry(self, entry: Any, single: bool = False) -> None: + if self.entries and single: + self.entries[0] = entry + del self.entries[1:] + else: + self.entries.append(entry) class InfoTag(BaseModel): - info_tag: Optional[str] = Field("", alias="infoTag") + info_tag: Optional[str] = Field("", serialization_alias="infoTag", validation_alias="infoTag") class PolicyListId(BaseModel): - list_id: UUID = Field(alias="listId") + list_id: UUID = Field(serialization_alias="listId", validation_alias="listId") class PolicyListInfo(PolicyListId, InfoTag): - last_updated: datetime.datetime = Field(alias="lastUpdated") + last_updated: datetime.datetime = Field(serialization_alias="lastUpdated", validation_alias="lastUpdated") owner: str - read_only: bool = Field(alias="readOnly") + read_only: bool = Field(serialization_alias="readOnly", validation_alias="readOnly") version: str - reference_count: int = Field(alias="referenceCount") + reference_count: int = Field(serialization_alias="referenceCount", validation_alias="referenceCount") references: List - is_activated_by_vsmart: Optional[bool] = Field(None, alias="isActivatedByVsmart") + is_activated_by_vsmart: Optional[bool] = Field( + None, serialization_alias="isActivatedByVsmart", validation_alias="isActivatedByVsmart" + ) class PolicyListPreview(BaseModel): preview: str - - -class PolicyListEndpoints(Protocol): - def create_policy_list(self, payload: AnyPolicyList) -> PolicyListId: - ... - - def delete_policy_list(self, id: UUID) -> None: - ... - - def edit_policy_list(self, id: UUID, payload: AnyPolicyList) -> None: - ... - - def get_lists_by_id(self, id: UUID) -> PolicyListInfo: - ... - - def get_policy_lists(self) -> DataSequence[PolicyListInfo]: - ... diff --git a/catalystwan/utils/config_migration/converters/policy/policy_lists.py b/catalystwan/utils/config_migration/converters/policy/policy_lists.py index 0ead146f..4d668273 100644 --- a/catalystwan/utils/config_migration/converters/policy/policy_lists.py +++ b/catalystwan/utils/config_migration/converters/policy/policy_lists.py @@ -216,7 +216,8 @@ def sla_class(in_: SLAClassList) -> SLAClassParcel: def tloc(in_: TLOCList) -> TlocParcel: out = TlocParcel(**_get_parcel_name_desc(in_)) for entry in in_.entries: - out.add_entry(tloc=entry.tloc, color=entry.color, encapsulation=entry.encap, preference=entry.preference) + _preference = str(entry.preference) if entry.preference is not None else None + out.add_entry(tloc=entry.tloc, color=entry.color, encapsulation=entry.encap, preference=_preference) return out @@ -281,8 +282,15 @@ class ConvertAllResult(NamedTuple): } +def _find_converter(in_: Input) -> Optional[Callable[[Any], Output]]: + for key in CONVERTERS.keys(): + if isinstance(in_, key): + return CONVERTERS[key] + return None + + def convert(in_: Input) -> Optional[Output]: - if converter := CONVERTERS.get(type(in_)): + if converter := _find_converter(in_): return converter(in_) return None