diff --git a/ENDPOINTS.md b/ENDPOINTS.md index be7d8fe5..7dc043d1 100644 --- a/ENDPOINTS.md +++ b/ENDPOINTS.md @@ -1,6 +1,6 @@ **THIS FILE WAS AUTO-GENERATED DO NOT EDIT** -Generated for: catalystwan-0.35.4.dev0 +Generated for: catalystwan-0.33.4.dev0 All URIs are relative to */dataservice* HTTP request | Supported Versions | Method | Payload Type | Return Type | Tenancy Mode @@ -60,98 +60,103 @@ POST /disasterrecovery/unpause||[**ConfigurationDisasterRecovery.unpause_dr**](h GET /v1/feature-profile/sdwan/cli||[**CliFeatureProfile.get_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L21)|Optional[[**GetFeatureProfilesParams**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L128)]|DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| POST /v1/feature-profile/sdwan/cli||[**CliFeatureProfile.create_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L26)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| DELETE /v1/feature-profile/sdwan/cli/{profile_id}||[**CliFeatureProfile.delete_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L31)||None| -GET /v1/feature-profile/sdwan/cli/{profile_id}/config||[**CliFeatureProfile.get_all**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L36)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/cli/{profile_id}/config/{parcel_id}||[**CliFeatureProfile.get_by_id**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L41)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -POST /v1/feature-profile/sdwan/cli/{profile_id}/config||[**CliFeatureProfile.create**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L46)|[**ConfigParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/cli/config.py#L10)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| +GET /v1/feature-profile/sdwan/cli/{profile_id}/config||[**CliFeatureProfile.get_all**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L36)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/cli/{profile_id}/config/{parcel_id}||[**CliFeatureProfile.get_by_id**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L41)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +POST /v1/feature-profile/sdwan/cli/{profile_id}/config||[**CliFeatureProfile.create**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L46)|[**ConfigParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/cli/config.py#L10)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| PUT /v1/feature-profile/sdwan/cli/{profile_id}/config/{parcel_id}||[**CliFeatureProfile.update**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L51)|[**ConfigParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/cli/config.py#L10)|None| DELETE /v1/feature-profile/sdwan/cli/{profile_id}/config/{parcel_id}||[**CliFeatureProfile.delete**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py#L56)||None| GET /v1/feature-profile/sdwan/policy-object|>=20.12|[**PolicyObjectFeatureProfile.get_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L19)||DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| POST /v1/feature-profile/sdwan/policy-object|>=20.12|[**PolicyObjectFeatureProfile.create_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L26)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| DELETE /v1/feature-profile/sdwan/policy-object/{profile_id}|>=20.12|[**PolicyObjectFeatureProfile.delete_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L31)||None| -POST /v1/feature-profile/sdwan/policy-object/{profile_id}/{policy_object_list_type}|>=20.12|[**PolicyObjectFeatureProfile.create**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L36)|[**AdvancedInspectionProfileParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/aip.py#L15), [**AdvancedMalwareProtectionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/amp.py#L19), [**ApplicationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/application_list.py#L20), [**AppProbeParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/app_probe.py#L28), [**AsPathParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/as_path.py#L15), [**ColorParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/color_list.py#L15), [**DataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/data_prefix.py#L24), [**ExpandedCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/expanded_community_list.py#L10), [**ExtendedCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/extended_community.py#L20), [**FowardingClassParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/fowarding_class.py#L20), [**FQDNDomainParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/fqdn.py#L17), [**GeoLocationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/geolocation_list.py#L23), [**IdentityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/identity.py#L15), [**IntrusionPreventionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/intrusion_prevention.py#L16), [**IPSSignatureParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ips_signature.py#L32), [**IPv6DataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_data_prefix.py#L17), [**IPv6PrefixListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_prefix_list.py#L25), [**LocalDomainParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/local_domain.py#L17), [**MirrorParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/mirror.py#L17), [**PolicerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/policer.py#L30), [**PreferredColorGroupParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefered_group_color.py#L54), [**PrefixListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefix_list.py#L17), [**ProtocolListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/protocol_list.py#L15), [**ScalableGroupTagParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/scalable_group_tag.py#L13), [**SecurityApplicationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/application_list.py#L20), [**SecurityDataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/data_prefix.py#L16), [**SecurityPortParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/security_port.py#L31), [**SecurityZoneListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/zone.py#L27), [**SLAClassParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/sla_class.py#L95), [**SslDecryptionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption.py#L41), [**SslDecryptionProfileParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption_profile.py#L100), [**StandardCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/standard_community.py#L18), [**TlocParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/tloc_list.py#L29), [**UrlFilteringParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url_filtering.py#L102), [**URLParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url.py#L15)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| +POST /v1/feature-profile/sdwan/policy-object/{profile_id}/{policy_object_list_type}|>=20.12|[**PolicyObjectFeatureProfile.create**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L36)|[**AdvancedInspectionProfileParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/aip.py#L15), [**AdvancedMalwareProtectionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/amp.py#L19), [**ApplicationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/application_list.py#L20), [**AppProbeParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/app_probe.py#L28), [**AsPathParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/as_path.py#L15), [**ColorParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/color_list.py#L15), [**DataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/data_prefix.py#L24), [**ExpandedCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/expanded_community_list.py#L10), [**ExtendedCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/extended_community.py#L20), [**FowardingClassParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/fowarding_class.py#L20), [**FQDNDomainParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/fqdn.py#L17), [**GeoLocationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/geolocation_list.py#L23), [**IdentityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/identity.py#L15), [**IntrusionPreventionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/intrusion_prevention.py#L16), [**IPSSignatureParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ips_signature.py#L32), [**IPv6DataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_data_prefix.py#L17), [**IPv6PrefixListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_prefix_list.py#L25), [**LocalDomainParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/local_domain.py#L17), [**MirrorParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/mirror.py#L17), [**PolicerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/policer.py#L30), [**PreferredColorGroupParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefered_group_color.py#L54), [**PrefixListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefix_list.py#L17), [**ProtocolListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/protocol_list.py#L15), [**ScalableGroupTagParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/scalable_group_tag.py#L13), [**SecurityApplicationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/application_list.py#L20), [**SecurityDataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/data_prefix.py#L16), [**SecurityPortParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/security_port.py#L31), [**SecurityZoneListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/zone.py#L27), [**SLAClassParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/sla_class.py#L95), [**SslDecryptionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption.py#L41), [**SslDecryptionProfileParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption_profile.py#L100), [**StandardCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/standard_community.py#L18), [**TlocParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/tloc_list.py#L29), [**UrlFilteringParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url_filtering.py#L102), [**URLParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url.py#L15)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| DELETE /v1/feature-profile/sdwan/policy-object/{profile_id}/{policy_object_list_type}/{list_object_id}|>=20.12|[**PolicyObjectFeatureProfile.delete**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L48)||None| -PUT /v1/feature-profile/sdwan/policy-object/{profile_id}/{policy_object_list_type}/{list_object_id}|>=20.12|[**PolicyObjectFeatureProfile.update**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L62)|[**AdvancedInspectionProfileParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/aip.py#L15), [**AdvancedMalwareProtectionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/amp.py#L19), [**ApplicationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/application_list.py#L20), [**AppProbeParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/app_probe.py#L28), [**AsPathParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/as_path.py#L15), [**ColorParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/color_list.py#L15), [**DataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/data_prefix.py#L24), [**ExpandedCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/expanded_community_list.py#L10), [**ExtendedCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/extended_community.py#L20), [**FowardingClassParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/fowarding_class.py#L20), [**FQDNDomainParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/fqdn.py#L17), [**GeoLocationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/geolocation_list.py#L23), [**IdentityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/identity.py#L15), [**IntrusionPreventionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/intrusion_prevention.py#L16), [**IPSSignatureParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ips_signature.py#L32), [**IPv6DataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_data_prefix.py#L17), [**IPv6PrefixListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_prefix_list.py#L25), [**LocalDomainParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/local_domain.py#L17), [**MirrorParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/mirror.py#L17), [**PolicerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/policer.py#L30), [**PreferredColorGroupParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefered_group_color.py#L54), [**PrefixListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefix_list.py#L17), [**ProtocolListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/protocol_list.py#L15), [**ScalableGroupTagParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/scalable_group_tag.py#L13), [**SecurityApplicationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/application_list.py#L20), [**SecurityDataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/data_prefix.py#L16), [**SecurityPortParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/security_port.py#L31), [**SecurityZoneListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/zone.py#L27), [**SLAClassParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/sla_class.py#L95), [**SslDecryptionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption.py#L41), [**SslDecryptionProfileParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption_profile.py#L100), [**StandardCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/standard_community.py#L18), [**TlocParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/tloc_list.py#L29), [**UrlFilteringParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url_filtering.py#L102), [**URLParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url.py#L15)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| -GET /v1/feature-profile/sdwan/policy-object/{profile_id}/{policy_object_list_type}/{list_object_id}|>=20.12|[**PolicyObjectFeatureProfile.get_by_id**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L78)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/policy-object/{profile_id}/{policy_object_list_type}|>=20.12|[**PolicyObjectFeatureProfile.get_all**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L83)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| +PUT /v1/feature-profile/sdwan/policy-object/{profile_id}/{policy_object_list_type}/{list_object_id}|>=20.12|[**PolicyObjectFeatureProfile.update**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L62)|[**AdvancedInspectionProfileParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/aip.py#L15), [**AdvancedMalwareProtectionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/amp.py#L19), [**ApplicationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/application_list.py#L20), [**AppProbeParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/app_probe.py#L28), [**AsPathParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/as_path.py#L15), [**ColorParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/color_list.py#L15), [**DataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/data_prefix.py#L24), [**ExpandedCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/expanded_community_list.py#L10), [**ExtendedCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/extended_community.py#L20), [**FowardingClassParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/fowarding_class.py#L20), [**FQDNDomainParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/fqdn.py#L17), [**GeoLocationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/geolocation_list.py#L23), [**IdentityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/identity.py#L15), [**IntrusionPreventionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/intrusion_prevention.py#L16), [**IPSSignatureParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ips_signature.py#L32), [**IPv6DataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_data_prefix.py#L17), [**IPv6PrefixListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_prefix_list.py#L25), [**LocalDomainParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/local_domain.py#L17), [**MirrorParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/mirror.py#L17), [**PolicerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/policer.py#L30), [**PreferredColorGroupParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefered_group_color.py#L54), [**PrefixListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefix_list.py#L17), [**ProtocolListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/protocol_list.py#L15), [**ScalableGroupTagParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/scalable_group_tag.py#L13), [**SecurityApplicationListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/application_list.py#L20), [**SecurityDataPrefixParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/data_prefix.py#L16), [**SecurityPortParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/security_port.py#L31), [**SecurityZoneListParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/zone.py#L27), [**SLAClassParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/sla_class.py#L95), [**SslDecryptionParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption.py#L41), [**SslDecryptionProfileParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption_profile.py#L100), [**StandardCommunityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/standard_community.py#L18), [**TlocParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/tloc_list.py#L29), [**UrlFilteringParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url_filtering.py#L102), [**URLParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url.py#L15)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +GET /v1/feature-profile/sdwan/policy-object/{profile_id}/{policy_object_list_type}/{list_object_id}|>=20.12|[**PolicyObjectFeatureProfile.get_by_id**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L78)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/policy-object/{profile_id}/{policy_object_list_type}|>=20.12|[**PolicyObjectFeatureProfile.get_all**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py#L83)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| GET /v1/feature-profile/sdwan/sig-security/sig/schema|>=20.12|[**SIGSecurity.get_sig_security_parcel_schema**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L27)||None| GET /v1/feature-profile/sdwan/sig-security|>=20.12|[**SIGSecurity.get_sig_security_feature_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L32)||DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| POST /v1/feature-profile/sdwan/sig-security|>=20.12|[**SIGSecurity.create_sig_security_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L39)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| GET /v1/feature-profile/sdwan/sig-security/{profile_id}|>=20.12|[**SIGSecurity.get_sig_security_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L46)||[**FeatureProfileDetail**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L74)| PUT /v1/feature-profile/sdwan/sig-security/{profile_id}|>=20.12|[**SIGSecurity.edit_sig_security_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L53)|[**FeatureProfileEditPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L108)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| DELETE /v1/feature-profile/sdwan/sig-security/{profile_id}|>=20.12|[**SIGSecurity.delete_sig_security_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L60)||None| -GET /v1/feature-profile/sdwan/sig-security/{profile_id}/sig|>=20.12|[**SIGSecurity.get_sig_security_parcels**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L65)||[**ParcelSequence**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L183)| -POST /v1/feature-profile/sdwan/sig-security/{profile_id}/sig|>=20.12|[**SIGSecurity.create_sig_security_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L70)|[**SIGParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/sig_security/sig_security.py#L359)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| -GET /v1/feature-profile/sdwan/sig-security/{profile_id}/sig/{parcel_id}|>=20.12|[**SIGSecurity.get_sig_security_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L75)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -PUT /v1/feature-profile/sdwan/sig-security/{profile_id}/sig/{parcel_id}|>=20.12|[**SIGSecurity.edit_sig_security_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L80)|[**SIGParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/sig_security/sig_security.py#L359)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| +GET /v1/feature-profile/sdwan/sig-security/{profile_id}/sig|>=20.12|[**SIGSecurity.get_sig_security_parcels**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L65)||[**ParcelSequence**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L186)| +POST /v1/feature-profile/sdwan/sig-security/{profile_id}/sig|>=20.12|[**SIGSecurity.create_sig_security_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L70)|[**SIGParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/sig_security/sig_security.py#L359)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +GET /v1/feature-profile/sdwan/sig-security/{profile_id}/sig/{parcel_id}|>=20.12|[**SIGSecurity.get_sig_security_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L75)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +PUT /v1/feature-profile/sdwan/sig-security/{profile_id}/sig/{parcel_id}|>=20.12|[**SIGSecurity.edit_sig_security_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L80)|[**SIGParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/sig_security/sig_security.py#L359)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| DELETE /v1/feature-profile/sdwan/sig-security/{profile_id}/sig/{parcel_id}|>=20.12|[**SIGSecurity.delete_sig_security_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py#L85)||None| GET /v1/feature-profile/sdwan/system/{parcel_type}/schema|>=20.9|[**SystemFeatureProfile.get_schema**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L33)||None| GET /v1/feature-profile/sdwan/system|>=20.9|[**SystemFeatureProfile.get_sdwan_system_feature_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L38)|Optional[[**GetFeatureProfilesParams**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L128)]|DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| POST /v1/feature-profile/sdwan/system|>=20.9|[**SystemFeatureProfile.create_sdwan_system_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L45)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| DELETE /v1/feature-profile/sdwan/system/{profile_id}|>=20.9|[**SystemFeatureProfile.delete_sdwan_system_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L52)||None| -POST /v1/feature-profile/sdwan/system/{profile_id}/aaa|>=20.9|[**SystemFeatureProfile.create_aaa_profile_parcel_for_system**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L57)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| -PUT /v1/feature-profile/sdwan/system/{profile_id}/aaa/{parcel_id}|>=20.9|[**SystemFeatureProfile.edit_aaa_profile_parcel_for_system**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L62)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| -GET /v1/feature-profile/sdwan/system/{profile_id}/{parcel_type}|>=20.9|[**SystemFeatureProfile.get_all**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L67)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/{parcel_type}/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L72)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/aaa|>=20.9|[**SystemFeatureProfile.get_all_aaa**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L77)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/aaa/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_aaa**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L82)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/banner|>=20.9|[**SystemFeatureProfile.get_all_banner**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L87)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/banner/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_banner**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L92)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/basic|>=20.9|[**SystemFeatureProfile.get_all_basic**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L97)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/basic/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_basic**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L102)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/bfd|>=20.9|[**SystemFeatureProfile.get_all_bfd**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L107)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/bfd/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_bfd**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L112)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/global|>=20.9|[**SystemFeatureProfile.get_all_global**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L117)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/global/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_global**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L122)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/logging|>=20.9|[**SystemFeatureProfile.get_all_logging**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L127)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/logging/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_logging**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L132)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/mrf|>=20.9|[**SystemFeatureProfile.get_all_mrf**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L137)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/mrf/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_mrf**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L142)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/ntp|>=20.9|[**SystemFeatureProfile.get_all_ntp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L147)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/ntp/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_ntp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L152)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/omp|>=20.9|[**SystemFeatureProfile.get_all_omp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L157)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/omp/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_omp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L162)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/security|>=20.9|[**SystemFeatureProfile.get_all_security**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L167)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/security/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_security**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L172)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -GET /v1/feature-profile/sdwan/system/{profile_id}/snmp|>=20.9|[**SystemFeatureProfile.get_all_snmp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L177)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/system/{profile_id}/snmp/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_snmp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L182)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -PUT /v1/feature-profile/sdwan/system/{profile_id}/{parcel_type}/{parcel_id}|>=20.9|[**SystemFeatureProfile.update**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L187)|[**AAAParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/aaa.py#L264), [**BFDParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/bfd.py#L22), [**LoggingParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/logging_parcel.py#L74), [**BannerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/banner.py#L12), [**BasicParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/basic.py#L116), [**DeviceAccessIPv4Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/device_access.py#L127), [**DeviceAccessIPv6Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/device_access_ipv6.py#L127), [**GlobalParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/global_parcel.py#L140), [**NtpParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/ntp.py#L90), [**MRFParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/mrf.py#L38), [**OMPParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/omp.py#L34), [**SecurityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/security.py#L144), [**SNMPParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/snmp.py#L137)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| +POST /v1/feature-profile/sdwan/system/{profile_id}/aaa|>=20.9|[**SystemFeatureProfile.create_aaa_profile_parcel_for_system**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L57)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| +PUT /v1/feature-profile/sdwan/system/{profile_id}/aaa/{parcel_id}|>=20.9|[**SystemFeatureProfile.edit_aaa_profile_parcel_for_system**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L62)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| +GET /v1/feature-profile/sdwan/system/{profile_id}/{parcel_type}|>=20.9|[**SystemFeatureProfile.get_all**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L67)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/{parcel_type}/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L72)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/aaa|>=20.9|[**SystemFeatureProfile.get_all_aaa**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L77)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/aaa/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_aaa**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L82)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/banner|>=20.9|[**SystemFeatureProfile.get_all_banner**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L87)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/banner/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_banner**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L92)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/basic|>=20.9|[**SystemFeatureProfile.get_all_basic**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L97)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/basic/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_basic**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L102)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/bfd|>=20.9|[**SystemFeatureProfile.get_all_bfd**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L107)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/bfd/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_bfd**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L112)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/global|>=20.9|[**SystemFeatureProfile.get_all_global**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L117)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/global/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_global**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L122)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/logging|>=20.9|[**SystemFeatureProfile.get_all_logging**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L127)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/logging/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_logging**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L132)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/mrf|>=20.9|[**SystemFeatureProfile.get_all_mrf**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L137)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/mrf/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_mrf**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L142)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/ntp|>=20.9|[**SystemFeatureProfile.get_all_ntp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L147)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/ntp/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_ntp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L152)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/omp|>=20.9|[**SystemFeatureProfile.get_all_omp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L157)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/omp/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_omp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L162)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/security|>=20.9|[**SystemFeatureProfile.get_all_security**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L167)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/security/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_security**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L172)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/system/{profile_id}/snmp|>=20.9|[**SystemFeatureProfile.get_all_snmp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L177)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/system/{profile_id}/snmp/{parcel_id}|>=20.9|[**SystemFeatureProfile.get_by_id_snmp**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L182)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +PUT /v1/feature-profile/sdwan/system/{profile_id}/{parcel_type}/{parcel_id}|>=20.9|[**SystemFeatureProfile.update**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L187)|[**AAAParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/aaa.py#L264), [**BFDParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/bfd.py#L22), [**LoggingParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/logging_parcel.py#L74), [**BannerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/banner.py#L12), [**BasicParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/basic.py#L116), [**DeviceAccessIPv4Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/device_access.py#L127), [**DeviceAccessIPv6Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/device_access_ipv6.py#L127), [**GlobalParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/global_parcel.py#L140), [**NtpParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/ntp.py#L90), [**MRFParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/mrf.py#L38), [**OMPParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/omp.py#L34), [**SecurityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/security.py#L144), [**SNMPParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/snmp.py#L137)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| DELETE /v1/feature-profile/sdwan/system/{profile_id}/{parcel_type}/{parcel_id}|>=20.9|[**SystemFeatureProfile.delete**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L192)||None| -POST /v1/feature-profile/sdwan/system/{system_id}/bfd|>=20.9|[**SystemFeatureProfile.create_bfd_profile_parcel_for_system**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L197)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| -POST /v1/feature-profile/sdwan/system/{profile_id}/{parcel_type}|>=20.9|[**SystemFeatureProfile.create**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L202)|[**AAAParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/aaa.py#L264), [**BFDParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/bfd.py#L22), [**LoggingParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/logging_parcel.py#L74), [**BannerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/banner.py#L12), [**BasicParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/basic.py#L116), [**DeviceAccessIPv4Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/device_access.py#L127), [**DeviceAccessIPv6Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/device_access_ipv6.py#L127), [**GlobalParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/global_parcel.py#L140), [**NtpParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/ntp.py#L90), [**MRFParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/mrf.py#L38), [**OMPParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/omp.py#L34), [**SecurityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/security.py#L144), [**SNMPParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/snmp.py#L137)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| +POST /v1/feature-profile/sdwan/system/{system_id}/bfd|>=20.9|[**SystemFeatureProfile.create_bfd_profile_parcel_for_system**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L197)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| +POST /v1/feature-profile/sdwan/system/{profile_id}/{parcel_type}|>=20.9|[**SystemFeatureProfile.create**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/system.py#L202)|[**AAAParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/aaa.py#L264), [**BFDParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/bfd.py#L22), [**LoggingParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/logging_parcel.py#L74), [**BannerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/banner.py#L12), [**BasicParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/basic.py#L116), [**DeviceAccessIPv4Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/device_access.py#L127), [**DeviceAccessIPv6Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/device_access_ipv6.py#L127), [**GlobalParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/global_parcel.py#L140), [**NtpParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/ntp.py#L90), [**MRFParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/mrf.py#L38), [**OMPParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/omp.py#L34), [**SecurityParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/security.py#L144), [**SNMPParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/system/snmp.py#L137)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| POST /v1/feature-profile/sdwan/topology|>=20.12|[**TopologyFeatureProfile.create_topology_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L23)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| GET /v1/feature-profile/sdwan/topology|>=20.12|[**TopologyFeatureProfile.get_topology_feature_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L28)||DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| GET /v1/feature-profile/sdwan/topology/{profile_id}|>=20.12|[**TopologyFeatureProfile.get_topology_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L33)||[**FeatureProfileDetail**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L74)| PUT /v1/feature-profile/sdwan/topology/{profile_id}|>=20.12|[**TopologyFeatureProfile.edit_topology_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L38)|[**FeatureProfileEditPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L108)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| DELETE /v1/feature-profile/sdwan/topology/{profile_id}|>=20.12|[**TopologyFeatureProfile.delete_topology_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L45)||None| -POST /v1/feature-profile/sdwan/topology/{profile_id}/{parcel_type}|>=20.12|[**TopologyFeatureProfile.create_any_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L54)|[**MeshParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/topology/mesh.py#L12), [**HubSpokeParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/topology/hubspoke.py#L43), [**CustomControlParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/topology/custom_control.py#L369)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| +POST /v1/feature-profile/sdwan/topology/{profile_id}/{parcel_type}|>=20.12|[**TopologyFeatureProfile.create_any_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L54)|[**MeshParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/topology/mesh.py#L12), [**HubSpokeParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/topology/hubspoke.py#L43), [**CustomControlParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/topology/custom_control.py#L369)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| DELETE /v1/feature-profile/sdwan/topology/{profile_id}/{parcel_type}/{parcel_id}|>=20.9|[**TopologyFeatureProfile.delete_any_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L61)||None| -GET /v1/feature-profile/sdwan/topology/{profile_id}/{parcel_type}/{parcel_id}|>=20.9|[**TopologyFeatureProfile.get_any_parcel_by_id**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L66)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| +GET /v1/feature-profile/sdwan/topology/{profile_id}/{parcel_type}/{parcel_id}|>=20.9|[**TopologyFeatureProfile.get_any_parcel_by_id**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L66)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| GET /v1/feature-profile/sdwan/topology/mesh/schema|>=20.9|[**TopologyFeatureProfile.get_mesh_parcel_schema**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L74)||None| GET /v1/feature-profile/sdwan/topology/hubspoke/schema|>=20.9|[**TopologyFeatureProfile.get_hubspoke_parcel_schema**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L82)||None| GET /v1/feature-profile/sdwan/topology/custom-control/schema|>=20.9|[**TopologyFeatureProfile.get_custom_control_parcel_schema**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py#L90)||None| -POST /v1/feature-profile/sdwan/transport|>=20.12|[**TransportFeatureProfile.create_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L33)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| -GET /v1/feature-profile/sdwan/transport|>=20.12|[**TransportFeatureProfile.get_transport_feature_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L40)||DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| -GET /v1/feature-profile/sdwan/transport/{profile_id}|>=20.12|[**TransportFeatureProfile.get_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L45)||[**FeatureProfileDetail**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L74)| -PUT /v1/feature-profile/sdwan/transport/{profile_id}|>=20.12|[**TransportFeatureProfile.edit_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L50)|[**FeatureProfileEditPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L108)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| -DELETE /v1/feature-profile/sdwan/transport/{profile_id}|>=20.12|[**TransportFeatureProfile.delete_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L57)||None| -POST /v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}|>=20.12|[**TransportFeatureProfile.create_transport_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L62)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| -POST /v1/feature-profile/sdwan/transport/{profile_id}/wan/vpn/{vpn_id}/{parcel_type}|>=20.12|[**TransportFeatureProfile.create_transport_vpn_sub_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L69)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| -POST /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{vpn_id}/{parcel_type}|>=20.12|[**TransportFeatureProfile.create_management_vpn_sub_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L76)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| -GET /v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}|>=20.12|[**TransportFeatureProfile.get_transport_parcels**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L83)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| -GET /v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}/{parcel_id}|>=20.12|[**TransportFeatureProfile.get_transport_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L88)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)| -POST /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn|>=20.12|[**TransportFeatureProfile.create_management_vpn_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L96)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| -PUT /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{parcel_id}|>=20.12|[**TransportFeatureProfile.edit_management_vpn_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L111)|[**ManagementVpnParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/transport/vpn.py#L166)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| -DELETE /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{parcel_id}|>=20.12|[**TransportFeatureProfile.delete_management_vpn_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L118)||None| -GET /v1/feature-profile/sdwan/transport|>=20.9|[**TransportFeatureProfile.get_sdwan_transport_feature_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L123)|Optional[[**GetFeatureProfilesParams**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L128)]|DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| -GET /v1/feature-profile/sdwan/transport/cellular-controller/schema|>=20.9|[**TransportFeatureProfile.get_sdwan_transport_cellular_controller_parcel_schema**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L130)||None| -POST /v1/feature-profile/sdwan/transport|>=20.9|[**TransportFeatureProfile.create_sdwan_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L135)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| -DELETE /v1/feature-profile/sdwan/transport/{transport_id}|>=20.9|[**TransportFeatureProfile.delete_sdwan_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L142)||None| -POST /v1/feature-profile/sdwan/transport/{transport_id}/cellular-controller|>=20.9|[**TransportFeatureProfile.create_cellular_controller_profile_parcel_for_transport**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L147)|[**CellularControllerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/transport/cellular_controller.py#L38)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| -POST /v1/feature-profile/sdwan/transport/{profile_id}/cellular-controller/{cellular_controler_id}/{parcel_type}|>=20.9|[**TransportFeatureProfile.associate_with_cellular_controller**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L158)|[**ParcelAssociationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L196)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| -POST /v1/feature-profile/sdwan/transport/{profile_id}/wan/vpn/{vpn_id}/{parcel_type}|>=20.9|[**TransportFeatureProfile.associate_with_vpn**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L169)|[**ParcelAssociationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L196)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| +POST /v1/feature-profile/sdwan/transport|>=20.12|[**TransportFeatureProfile.create_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L34)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| +GET /v1/feature-profile/sdwan/transport|>=20.12|[**TransportFeatureProfile.get_transport_feature_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L41)||DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| +GET /v1/feature-profile/sdwan/transport/{profile_id}|>=20.12|[**TransportFeatureProfile.get_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L46)||[**FeatureProfileDetail**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L74)| +PUT /v1/feature-profile/sdwan/transport/{profile_id}|>=20.12|[**TransportFeatureProfile.edit_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L51)|[**FeatureProfileEditPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L108)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| +DELETE /v1/feature-profile/sdwan/transport/{profile_id}|>=20.12|[**TransportFeatureProfile.delete_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L58)||None| +POST /v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}|>=20.12|[**TransportFeatureProfile.create_transport_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L63)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +POST /v1/feature-profile/sdwan/transport/{profile_id}/wan/vpn/{vpn_id}/{parcel_type}|>=20.12|[**TransportFeatureProfile.create_transport_vpn_sub_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L70)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +POST /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{vpn_id}/{parcel_type}|>=20.12|[**TransportFeatureProfile.create_management_vpn_sub_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L77)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +GET /v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}|>=20.12|[**TransportFeatureProfile.get_transport_parcels**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L84)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| +GET /v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}/{parcel_id}|>=20.12|[**TransportFeatureProfile.get_transport_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L91)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +PUT /v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}/{parcel_id}|>=20.12|[**TransportFeatureProfile.update_transport_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L98)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +GET /v1/feature-profile/sdwan/transport/{profile_id}/wan/vpn/{vpn_id}/{parcel_type}/{parcel_id}|>=20.12|[**TransportFeatureProfile.get_transport_vpn_sub_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L105)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +GET /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{vpn_id}/{parcel_type}/{parcel_id}|>=20.12|[**TransportFeatureProfile.get_management_vpn_sub_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L112)||[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)| +PUT /v1/feature-profile/sdwan/transport/{profile_id}/wan/vpn/{vpn_id}/{parcel_type}/{parcel_id}|>=20.12|[**TransportFeatureProfile.update_transport_vpn_sub_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L119)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +PUT /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{vpn_id}/{parcel_type}/{parcel_id}|>=20.12|[**TransportFeatureProfile.update_management_vpn_sub_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L126)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +POST /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn|>=20.12|[**TransportFeatureProfile.create_management_vpn_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L136)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +PUT /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{parcel_id}|>=20.12|[**TransportFeatureProfile.edit_management_vpn_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L151)|[**ManagementVpnParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/transport/vpn.py#L166)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +DELETE /v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{parcel_id}|>=20.12|[**TransportFeatureProfile.delete_management_vpn_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L158)||None| +GET /v1/feature-profile/sdwan/transport|>=20.9|[**TransportFeatureProfile.get_sdwan_transport_feature_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L163)|Optional[[**GetFeatureProfilesParams**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L128)]|DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| +GET /v1/feature-profile/sdwan/transport/cellular-controller/schema|>=20.9|[**TransportFeatureProfile.get_sdwan_transport_cellular_controller_parcel_schema**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L170)||None| +POST /v1/feature-profile/sdwan/transport|>=20.9|[**TransportFeatureProfile.create_sdwan_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L175)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| +DELETE /v1/feature-profile/sdwan/transport/{transport_id}|>=20.9|[**TransportFeatureProfile.delete_sdwan_transport_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L182)||None| +POST /v1/feature-profile/sdwan/transport/{transport_id}/cellular-controller|>=20.9|[**TransportFeatureProfile.create_cellular_controller_profile_parcel_for_transport**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L187)|[**CellularControllerParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/sdwan/transport/cellular_controller.py#L38)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| +POST /v1/feature-profile/sdwan/transport/{profile_id}/cellular-controller/{cellular_controler_id}/{parcel_type}|>=20.9|[**TransportFeatureProfile.associate_with_cellular_controller**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L198)|[**ParcelAssociationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L199)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| +POST /v1/feature-profile/sdwan/transport/{profile_id}/wan/vpn/{vpn_id}/{parcel_type}|>=20.9|[**TransportFeatureProfile.associate_with_vpn**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py#L209)|[**ParcelAssociationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L199)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| GET /v1/network-hierarchy|>=20.10|[**NetworkHierarchy.list_nodes**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/network_hierarchy.py#L14)||DataSequence[[**NodeInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/network_hierarchy/node.py#L78)]| -POST /v1/network-hierarchy/{node_id}/network-settings/cflowd|>20.12|[**NetworkHierarchy.create_cflowd**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/network_hierarchy.py#L19)|[**CflowdParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/network_hierarchy/cflowd.py#L43)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L190)| -GET /v1/network-hierarchy/{node_id}/network-settings/cflowd|>20.12|[**NetworkHierarchy.get_cflowd**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/network_hierarchy.py#L24)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L143)]| +POST /v1/network-hierarchy/{node_id}/network-settings/cflowd|>20.12|[**NetworkHierarchy.create_cflowd**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/network_hierarchy.py#L19)|[**CflowdParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/network_hierarchy/cflowd.py#L43)|[**ParcelCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L193)| +GET /v1/network-hierarchy/{node_id}/network-settings/cflowd|>20.12|[**NetworkHierarchy.get_cflowd**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/network_hierarchy.py#L24)||DataSequence[[**Parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L146)]| DELETE /v1/network-hierarchy/{node_id}/network-settings/cflowd/{parcel_id}|>20.12|[**NetworkHierarchy.delete_cflowd**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/network_hierarchy.py#L29)||None| POST /template/policy/definition/acl||[**ConfigurationPolicyAclDefinition.create_policy_definition**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/policy/definition/access_control_list.py#L23)|[**AclPolicy**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/policy/definition/access_control_list.py#L157)|[**PolicyDefinitionId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/policy/policy_definition.py#L1285)| DELETE /template/policy/definition/acl/{id}||[**ConfigurationPolicyAclDefinition.delete_policy_definition**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration/policy/definition/access_control_list.py#L27)||None| @@ -607,11 +612,11 @@ DELETE /v1/feature-profile/sdwan/transport/{transport_id}|>=20.9|[**Configuratio GET /v1/feature-profile/sdwan/system|>=20.9|[**ConfigurationFeatureProfile.get_sdwan_system_feature_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L67)|Optional[[**GetFeatureProfilesPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L32)]|DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| POST /v1/feature-profile/sdwan/system|>=20.9|[**ConfigurationFeatureProfile.create_sdwan_system_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L74)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| DELETE /v1/feature-profile/sdwan/system/{system_id}|>=20.9|[**ConfigurationFeatureProfile.delete_sdwan_system_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L81)||None| -POST /v1/feature-profile/sdwan/system/{system_id}/aaa|>=20.9|[**ConfigurationFeatureProfile.create_aaa_profile_parcel_for_system**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L86)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| -POST /v1/feature-profile/sdwan/transport/{transport_id}/cellular-controller|>=20.9|[**ConfigurationFeatureProfile.create_cellular_controller_profile_parcel_for_transport**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L91)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| +POST /v1/feature-profile/sdwan/system/{system_id}/aaa|>=20.9|[**ConfigurationFeatureProfile.create_aaa_profile_parcel_for_system**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L86)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| +POST /v1/feature-profile/sdwan/transport/{transport_id}/cellular-controller|>=20.9|[**ConfigurationFeatureProfile.create_cellular_controller_profile_parcel_for_transport**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L91)|[**_ParcelBase**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/configuration_groups/parcel.py#L24)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| GET /v1/feature-profile/sdwan|>=20.9|[**ConfigurationFeatureProfile.get_sdwan_feature_profiles**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L98)||DataSequence[[**FeatureProfileInfo**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L59)]| POST /v1/feature-profile/sd-routing/cli|>=20.12|[**SDRoutingConfigurationFeatureProfile.create_cli_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L105)|[**FeatureProfileCreationPayload**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L100)|[**FeatureProfileCreationResponse**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/common.py#L113)| -POST /v1/feature-profile/sd-routing/cli/{cli_fp_id}/full-config|>=20.12|[**SDRoutingConfigurationFeatureProfile.create_cli_full_config_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L110)|[**FullConfigParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/feature_profile_parcel.py#L12)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L201)| +POST /v1/feature-profile/sd-routing/cli/{cli_fp_id}/full-config|>=20.12|[**SDRoutingConfigurationFeatureProfile.create_cli_full_config_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L110)|[**FullConfigParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/feature_profile_parcel.py#L12)|[**ParcelId**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/configuration/feature_profile/parcel.py#L204)| DELETE /v1/feature-profile/sd-routing/cli/{cli_fp_id}|>=20.12|[**SDRoutingConfigurationFeatureProfile.delete_cli_feature_profile**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L115)||None| DELETE /v1/feature-profile/sd-routing/cli/{cli_fp_id}/full-config/{parcel_id}|>=20.12|[**SDRoutingConfigurationFeatureProfile.delete_cli_full_config_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L120)||None| PUT /v1/feature-profile/sd-routing/cli/{cli_fp_id}/full-config/{parcel_id}|>=20.12|[**SDRoutingConfigurationFeatureProfile.edit_cli_full_config_parcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/endpoints/configuration_feature_profile.py#L125)|[**FullConfigParcel**](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/models/feature_profile_parcel.py#L12)|None| diff --git a/catalystwan/api/configuration_groups/parcel.py b/catalystwan/api/configuration_groups/parcel.py index 78bc182a..4be1822d 100644 --- a/catalystwan/api/configuration_groups/parcel.py +++ b/catalystwan/api/configuration_groups/parcel.py @@ -1,6 +1,5 @@ # Copyright 2024 Cisco Systems, Inc. and its affiliates -from enum import Enum from typing import Any, Dict, Generic, List, Literal, Optional, Tuple, TypeVar from pydantic import ( @@ -13,6 +12,7 @@ SerializerFunctionWrapHandler, model_serializer, ) +from pydantic.alias_generators import to_camel from typing_extensions import get_origin from catalystwan.exceptions import CatalystwanException @@ -81,24 +81,11 @@ def _get_parcel_type(cls) -> str: raise CatalystwanException(f"{cls.__name__} field parcel type is not set.") -class OptionType(str, Enum): - GLOBAL = "global" - DEFAULT = "default" - VARIABLE = "variable" - - -class ParcelAttribute(BaseModel): - model_config = ConfigDict(extra="forbid") - option_type: OptionType = Field(serialization_alias="optionType", validation_alias="optionType") - - # https://github.com/pydantic/pydantic/discussions/6090 # Usage: Global[str](value="test") -class Global(ParcelAttribute, Generic[T]): - model_config = ConfigDict(populate_by_name=True) - option_type: OptionType = Field( - default=OptionType.GLOBAL, serialization_alias="optionType", validation_alias="optionType" - ) +class Global(BaseModel, Generic[T]): + model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel) + option_type: Literal["global"] = "global" value: T def __bool__(self) -> bool: @@ -121,17 +108,15 @@ def __le__(self, other: Any) -> bool: return False -class Variable(ParcelAttribute): - option_type: OptionType = Field( - default=OptionType.VARIABLE, serialization_alias="optionType", validation_alias="optionType" - ) +class Variable(BaseModel): + model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel) + option_type: Literal["variable"] = "variable" value: str = Field(pattern=r"^\{\{[.\/\[\]a-zA-Z0-9_-]+\}\}$", min_length=1, max_length=64) -class Default(ParcelAttribute, Generic[T]): - option_type: OptionType = Field( - default=OptionType.DEFAULT, serialization_alias="optionType", validation_alias="optionType" - ) +class Default(BaseModel, Generic[T]): + model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel) + option_type: Literal["default"] = "default" value: Optional[T] = None diff --git a/catalystwan/api/feature_profile_api.py b/catalystwan/api/feature_profile_api.py index b98167fc..8a9113c5 100644 --- a/catalystwan/api/feature_profile_api.py +++ b/catalystwan/api/feature_profile_api.py @@ -14,7 +14,7 @@ from catalystwan.endpoints.configuration.feature_profile.sdwan.system import SystemFeatureProfile from catalystwan.endpoints.configuration.feature_profile.sdwan.topology import TopologyFeatureProfile from catalystwan.endpoints.configuration.feature_profile.sdwan.transport import TransportFeatureProfile -from catalystwan.exceptions import ManagerHTTPError +from catalystwan.exceptions import CatalystwanException, ManagerHTTPError from catalystwan.models.configuration.feature_profile.sdwan.acl.ipv4acl import Ipv4AclParcel from catalystwan.models.configuration.feature_profile.sdwan.acl.ipv6acl import Ipv6AclParcel from catalystwan.models.configuration.feature_profile.sdwan.application_priority import ( @@ -43,10 +43,33 @@ SslDecryptionProfileParcel, ) from catalystwan.models.configuration.feature_profile.sdwan.policy_object.security.url import URLParcel -from catalystwan.models.configuration.feature_profile.sdwan.routing import AnyRoutingParcel, RoutingBgpParcel +from catalystwan.models.configuration.feature_profile.sdwan.routing import ( + AnyRoutingParcel, + RoutingBgpParcel, + RoutingOspfParcel, + RoutingOspfv3IPv4Parcel, + RoutingOspfv3IPv6Parcel, +) from catalystwan.models.configuration.feature_profile.sdwan.service import AnyServiceParcel +from catalystwan.models.configuration.feature_profile.sdwan.service.eigrp import EigrpParcel +from catalystwan.models.configuration.feature_profile.sdwan.service.lan.ethernet import ( + InterfaceEthernetParcel as LanInterfaceEthernetParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.service.lan.gre import ( + InterfaceGreParcel as LanInterfaceGreParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.service.lan.ipsec import ( + InterfaceIpsecParcel as LanInterfaceIpsecParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.service.lan.multilink import ( + InterfaceMultilinkParcel as LanInterfaceMultilinkParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.service.lan.svi import InterfaceSviParcel +from catalystwan.models.configuration.feature_profile.sdwan.service.lan.vpn import LanVpnParcel from catalystwan.models.configuration.feature_profile.sdwan.service.multicast import MulticastParcel from catalystwan.models.configuration.feature_profile.sdwan.service.route_policy import RoutePolicyParcel +from catalystwan.models.configuration.feature_profile.sdwan.service.switchport import SwitchportParcel +from catalystwan.models.configuration.feature_profile.sdwan.service.wireless_lan import WirelessLanParcel from catalystwan.models.configuration.feature_profile.sdwan.sig_security.sig_security import SIGParcel from catalystwan.models.configuration.feature_profile.sdwan.topology import AnyTopologyParcel from catalystwan.models.configuration.feature_profile.sdwan.topology.custom_control import CustomControlParcel @@ -56,8 +79,33 @@ from catalystwan.models.configuration.feature_profile.sdwan.transport.cellular_controller import ( CellularControllerParcel, ) +from catalystwan.models.configuration.feature_profile.sdwan.transport.management.ethernet import ( + InterfaceEthernetParcel as ManagementInterfaceEthernetParcel, +) from catalystwan.models.configuration.feature_profile.sdwan.transport.t1e1controller import T1E1ControllerParcel from catalystwan.models.configuration.feature_profile.sdwan.transport.vpn import ManagementVpnParcel, TransportVpnParcel +from catalystwan.models.configuration.feature_profile.sdwan.transport.wan.interface.cellular import ( + InterfaceCellularParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.transport.wan.interface.ethernet import ( + InterfaceEthernetParcel as WanInterfaceEthernetParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.transport.wan.interface.gre import ( + InterfaceGreParcel as WanInterfaceGreParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.transport.wan.interface.ipsec import ( + InterfaceIpsecParcel as WanInterfaceIpsecParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.transport.wan.interface.multilink import ( + InterfaceMultilinkParcel as WanInterfaceMultilinkParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.transport.wan.interface.protocol_over import ( + InterfaceDslIPoEParcel, + InterfaceDslPPPoAParcel, + InterfaceDslPPPoEParcel, + InterfaceEthPPPoEParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.transport.wan.interface.t1e1serial import T1E1SerialParcel from catalystwan.typed_list import DataSequence if TYPE_CHECKING: @@ -132,6 +180,12 @@ ) +def removeprefix(s: str, prefix: str) -> str: + if s.startswith(prefix): + return s[len(prefix) :] + return s + + class SDRoutingFeatureProfilesAPI: def __init__(self, session: ManagerSession): self.cli = SDRoutingCLIFeatureProfileAPI(session=session) @@ -267,7 +321,11 @@ def _get_vpn_parcel( try: return self.endpoint.get_transport_parcel(profile_id, TransportVpnParcel._get_parcel_type(), vpn_uuid) except ManagerHTTPError: + pass + try: return self.endpoint.get_transport_parcel(profile_id, ManagementVpnParcel._get_parcel_type(), vpn_uuid) + except ManagerHTTPError: + raise CatalystwanException(f"VPN parcel wih uuid: {vpn_uuid} is not found") @overload def get_parcel( @@ -281,12 +339,6 @@ def get_parcel( ) -> Parcel[T1E1ControllerParcel]: ... - @overload - def get_parcel( - self, profile_id: UUID, parcel_type: Type[RoutingBgpParcel], parcel_id: UUID - ) -> Parcel[RoutingBgpParcel]: - ... - @overload def get_parcel( self, profile_id: UUID, parcel_type: Type[TransportVpnParcel], parcel_id: UUID @@ -313,14 +365,150 @@ def get_parcel( ) -> Parcel[RoutePolicyParcel]: ... + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[WanInterfaceMultilinkParcel], parcel_id: UUID, vpn_uuid: UUID + ) -> Parcel[WanInterfaceMultilinkParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[InterfaceEthPPPoEParcel], parcel_id: UUID, vpn_uuid: UUID + ) -> Parcel[InterfaceEthPPPoEParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[InterfaceDslPPPoEParcel], parcel_id: UUID, vpn_uuid: UUID + ) -> Parcel[InterfaceDslPPPoEParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[InterfaceDslPPPoAParcel], parcel_id: UUID, vpn_uuid: UUID + ) -> Parcel[InterfaceDslPPPoAParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[InterfaceDslIPoEParcel], parcel_id: UUID, vpn_uuid: UUID + ) -> Parcel[InterfaceDslIPoEParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[WanInterfaceGreParcel], parcel_id: UUID, vpn_uuid: UUID + ) -> Parcel[WanInterfaceGreParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[WanInterfaceEthernetParcel], parcel_id: UUID, vpn_uuid: UUID + ) -> Parcel[WanInterfaceEthernetParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[ManagementInterfaceEthernetParcel], parcel_id: UUID, vpn_uuid: UUID + ) -> Parcel[ManagementInterfaceEthernetParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[RoutingBgpParcel], parcel_id: UUID + ) -> Parcel[RoutingBgpParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[RoutingOspfParcel], parcel_id: UUID + ) -> Parcel[RoutingOspfParcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[RoutingOspfv3IPv6Parcel], parcel_id: UUID + ) -> Parcel[RoutingOspfv3IPv6Parcel]: + ... + + @overload + def get_parcel( + self, profile_id: UUID, parcel_type: Type[RoutingOspfv3IPv4Parcel], parcel_id: UUID + ) -> Parcel[RoutingOspfv3IPv4Parcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[InterfaceCellularParcel], + parcel_id: UUID, + vpn_uuid: UUID, + ) -> Parcel[InterfaceCellularParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[T1E1SerialParcel], + parcel_id: UUID, + vpn_uuid: UUID, + ) -> Parcel[T1E1SerialParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[WanInterfaceIpsecParcel], + parcel_id: UUID, + vpn_uuid: UUID, + ) -> Parcel[WanInterfaceIpsecParcel]: + ... + def get_parcel( - self, profile_id: UUID, parcel_type: Type[Union[AnyTransportParcel, AnyRoutingParcel]], parcel_id: UUID + self, + profile_id: UUID, + parcel_type: Type[Union[AnyTransportParcel, AnyRoutingParcel]], + parcel_id: UUID, + vpn_uuid: Optional[UUID] = None, ) -> Parcel: """ Get one Transport Parcel given profile id, parcel type and parcel id """ + if vpn_uuid is not None: + vpn_parcel = self._get_vpn_parcel(profile_id, vpn_uuid).payload + parcel_type_str = parcel_type._get_parcel_type() + parcel_type_str = removeprefix(parcel_type_str, "wan/vpn/") + parcel_type_str = removeprefix(parcel_type_str, "management/vpn/") + if vpn_parcel._get_parcel_type() == TransportVpnParcel._get_parcel_type(): + return self.endpoint.get_transport_vpn_sub_parcel(profile_id, vpn_uuid, parcel_type_str, parcel_id) + else: + return self.endpoint.get_management_vpn_sub_parcel(profile_id, vpn_uuid, parcel_type_str, parcel_id) return self.endpoint.get_transport_parcel(profile_id, parcel_type._get_parcel_type(), parcel_id) + def update_parcel( + self, profile_id: UUID, payload: AnyTransportParcel, parcel_id: UUID, vpn_uuid: Optional[UUID] = None + ) -> ParcelCreationResponse: + """ + Update Transport Parcel for selected profile_id based on payload type + """ + if vpn_uuid is not None: + vpn_parcel = self._get_vpn_parcel(profile_id, vpn_uuid).payload + parcel_type = payload._get_parcel_type() + parcel_type = removeprefix(parcel_type, "wan/vpn/") + parcel_type = removeprefix(parcel_type, "management/vpn/") + if vpn_parcel._get_parcel_type() == TransportVpnParcel._get_parcel_type(): + return self.endpoint.update_transport_vpn_sub_parcel( + profile_id, vpn_uuid, parcel_type, parcel_id, payload + ) + else: + return self.endpoint.update_management_vpn_sub_parcel( + profile_id, vpn_uuid, parcel_type, parcel_id, payload + ) + return self.endpoint.update_transport_parcel(profile_id, payload._get_parcel_type(), parcel_id, payload) + class OtherFeatureProfileAPI: """ @@ -454,12 +642,287 @@ def create_parcel( return self.endpoint.create_lan_vpn_sub_parcel(profile_id, vpn_uuid, parcel_type, payload) return self.endpoint.create_service_parcel(profile_id, payload._get_parcel_type(), payload) - def delete_parcel(self, profile_uuid: UUID, parcel_type: Type[AnyServiceParcel], parcel_uuid: UUID) -> None: + def delete_parcel( + self, + profile_uuid: UUID, + parcel_type: Type[AnyServiceParcel], + parcel_uuid: UUID, + vpn_uuid: Optional[UUID] = None, + ) -> None: """ Delete Service Parcel for selected profile_uuid based on payload type """ + if vpn_uuid is not None: + return self.endpoint.delete_lan_vpn_sub_parcel( + profile_uuid, vpn_uuid, removeprefix(parcel_type._get_parcel_type(), "lan/vpn/"), parcel_uuid + ) return self.endpoint.delete_service_parcel(profile_uuid, parcel_type._get_parcel_type(), parcel_uuid) + @overload + def get_parcels( + self, + profile_id: UUID, + parcel_type: Type[RoutePolicyParcel], + ) -> DataSequence[Parcel[RoutePolicyParcel]]: + ... + + @overload + def get_parcels( + self, + profile_id: UUID, + parcel_type: Type[Ipv4AclParcel], + ) -> DataSequence[Parcel[Ipv4AclParcel]]: + ... + + @overload + def get_parcels( + self, + profile_id: UUID, + parcel_type: Type[Ipv6AclParcel], + ) -> DataSequence[Parcel[Ipv6AclParcel]]: + ... + + @overload + def get_parcels( + self, + profile_id: UUID, + parcel_type: Type[LanVpnParcel], + ) -> DataSequence[Parcel[LanVpnParcel]]: + ... + + @overload + def get_parcels( + self, + profile_id: UUID, + parcel_type: Type[MulticastParcel], + ) -> DataSequence[Parcel[MulticastParcel]]: + ... + + @overload + def get_parcels( + self, + profile_id: UUID, + parcel_type: Type[EigrpParcel], + ) -> DataSequence[Parcel[EigrpParcel]]: + ... + + @overload + def get_parcels( + self, + profile_id: UUID, + parcel_type: Type[SwitchportParcel], + ) -> DataSequence[Parcel[SwitchportParcel]]: + ... + + @overload + def get_parcels( + self, + profile_id: UUID, + parcel_type: Type[WirelessLanParcel], + ) -> DataSequence[Parcel[WirelessLanParcel]]: + ... + + def get_parcels( + self, + profile_id: UUID, + parcel_type: Type[AnyServiceParcel], + ) -> DataSequence: + """ + Get all Service Parcels given profile id and parcel type + """ + return self.endpoint.get_all(profile_id, parcel_type._get_parcel_type()) + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[RoutePolicyParcel], + parcel_id: UUID, + ) -> Parcel[RoutePolicyParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[Ipv4AclParcel], + parcel_id: UUID, + ) -> Parcel[Ipv4AclParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[Ipv6AclParcel], + parcel_id: UUID, + ) -> Parcel[Ipv6AclParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[LanVpnParcel], + parcel_id: UUID, + ) -> Parcel[LanVpnParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[MulticastParcel], + parcel_id: UUID, + ) -> Parcel[MulticastParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[EigrpParcel], + parcel_id: UUID, + ) -> Parcel[EigrpParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[SwitchportParcel], + parcel_id: UUID, + ) -> Parcel[SwitchportParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[WirelessLanParcel], + parcel_id: UUID, + ) -> Parcel[WirelessLanParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[LanInterfaceEthernetParcel], + parcel_id: UUID, + vpn_uuid: UUID, + ) -> Parcel[LanInterfaceEthernetParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[LanInterfaceGreParcel], + parcel_id: UUID, + vpn_uuid: UUID, + ) -> Parcel[LanInterfaceGreParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[LanInterfaceIpsecParcel], + parcel_id: UUID, + vpn_uuid: UUID, + ) -> Parcel[LanInterfaceIpsecParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[InterfaceSviParcel], + parcel_id: UUID, + vpn_uuid: UUID, + ) -> Parcel[InterfaceSviParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[LanInterfaceMultilinkParcel], + parcel_id: UUID, + vpn_uuid: UUID, + ) -> Parcel[LanInterfaceMultilinkParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[RoutingBgpParcel], + parcel_id: UUID, + ) -> Parcel[RoutingBgpParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[RoutingOspfv3IPv6Parcel], + parcel_id: UUID, + ) -> Parcel[RoutingOspfv3IPv6Parcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[RoutingOspfParcel], + parcel_id: UUID, + ) -> Parcel[RoutingOspfParcel]: + ... + + @overload + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[RoutingOspfv3IPv4Parcel], + parcel_id: UUID, + ) -> Parcel[RoutingOspfv3IPv4Parcel]: + ... + + def get_parcel( + self, + profile_id: UUID, + parcel_type: Type[AnyServiceParcel], + parcel_id: UUID, + vpn_uuid: Optional[UUID] = None, + ) -> Parcel: + """ + Get one Service Parcel given profile id, parcel type and parcel id + """ + if vpn_uuid is not None: + return self.endpoint.get_lan_vpn_sub_parcel( + profile_id, vpn_uuid, removeprefix(parcel_type._get_parcel_type(), "lan/vpn/"), parcel_id + ) + return self.endpoint.get_by_id(profile_id, parcel_type._get_parcel_type(), parcel_id) + + def update_parcel( + self, + profile_id: UUID, + parcel_type: Type[AnyServiceParcel], + parcel_id: UUID, + payload: AnyServiceParcel, + vpn_uuid: Optional[UUID] = None, + ) -> ParcelCreationResponse: + """ + Update Service Parcel for selected profile_id based on payload type + """ + if vpn_uuid is not None: + return self.endpoint.update_lan_vpn_sub_parcel( + profile_id, vpn_uuid, removeprefix(parcel_type._get_parcel_type(), "lan/vpn/"), parcel_id, payload + ) + return self.endpoint.update(profile_id, parcel_type._get_parcel_type(), parcel_id, payload) + class SystemFeatureProfileAPI: """ @@ -853,7 +1316,7 @@ def get_profiles(self) -> DataSequence[FeatureProfileInfo]: return self.endpoint.get_profiles() def create_profile(self, profile: FeatureProfileCreationPayload) -> FeatureProfileCreationResponse: - return self.endpoint.create_profile() + return self.endpoint.create_profile(profile) def delete_profile(self, profile_id: UUID) -> None: return self.endpoint.delete_profile(profile_id=profile_id) diff --git a/catalystwan/endpoints/configuration/feature_profile/sdwan/service.py b/catalystwan/endpoints/configuration/feature_profile/sdwan/service.py index a8dfe840..94148e31 100644 --- a/catalystwan/endpoints/configuration/feature_profile/sdwan/service.py +++ b/catalystwan/endpoints/configuration/feature_profile/sdwan/service.py @@ -1,19 +1,25 @@ # Copyright 2024 Cisco Systems, Inc. and its affiliates # mypy: disable-error-code="empty-body" -from typing import Optional +from typing import Optional, Union from uuid import UUID -from catalystwan.endpoints import APIEndpoints, delete, get, post, versions +from catalystwan.endpoints import APIEndpoints, delete, get, post, put, versions from catalystwan.models.configuration.feature_profile.common import ( FeatureProfileCreationPayload, FeatureProfileCreationResponse, FeatureProfileInfo, GetFeatureProfilesParams, ) -from catalystwan.models.configuration.feature_profile.parcel import ParcelAssociationPayload, ParcelCreationResponse +from catalystwan.models.configuration.feature_profile.parcel import ( + Parcel, + ParcelAssociationPayload, + ParcelCreationResponse, +) +from catalystwan.models.configuration.feature_profile.sdwan.routing import AnyRoutingParcel from catalystwan.models.configuration.feature_profile.sdwan.service import ( AnyLanVpnInterfaceParcel, + AnyServiceParcel, AnyTopLevelServiceParcel, ) from catalystwan.typed_list import DataSequence @@ -42,7 +48,7 @@ def delete_sdwan_service_feature_profile(self, profile_uuid: UUID) -> None: @versions(supported_versions=(">=20.9"), raises=False) @post("/v1/feature-profile/sdwan/service/{profile_uuid}/{parcel_type}") def create_service_parcel( - self, profile_uuid: UUID, parcel_type: str, payload: AnyTopLevelServiceParcel + self, profile_uuid: UUID, parcel_type: str, payload: Union[AnyTopLevelServiceParcel, AnyRoutingParcel] ) -> ParcelCreationResponse: ... @@ -51,6 +57,13 @@ def create_service_parcel( def delete_service_parcel(self, profile_uuid: UUID, parcel_type: str, parcel_uuid: UUID) -> None: ... + @versions(supported_versions=(">=20.9"), raises=False) + @delete("/v1/feature-profile/sdwan/service/{profile_uuid}/lan/vpn/{vpn_uuid}/{parcel_type}/{parcel_uuid}") + def delete_lan_vpn_sub_parcel( + self, profile_uuid: UUID, vpn_uuid: UUID, parcel_type: str, parcel_uuid: UUID + ) -> None: + ... + @versions(supported_versions=(">=20.9"), raises=False) @post("/v1/feature-profile/sdwan/service/{profile_uuid}/lan/vpn/{vpn_uuid}/{parcel_type}") def create_lan_vpn_sub_parcel( @@ -87,3 +100,38 @@ def associate_with_vpn( self, profile_id: UUID, vpn_id: UUID, parcel_type: str, payload: ParcelAssociationPayload ) -> ParcelCreationResponse: ... + + @versions(supported_versions=(">=20.9"), raises=False) + @put("/v1/feature-profile/sdwan/service/{profile_id}/{parcel_type}/{parcel_id}") + def update( + self, profile_id: UUID, parcel_type: str, parcel_id: UUID, payload: AnyTopLevelServiceParcel + ) -> ParcelCreationResponse: + ... + + @versions(supported_versions=(">=20.9"), raises=False) + @put("/v1/feature-profile/sdwan/service/{profile_id}/lan/vpn/{vpn_id}/{parcel_type}/{parcel_id}") + def update_lan_vpn_sub_parcel( + self, profile_id: UUID, vpn_id: UUID, parcel_type: str, parcel_id: UUID, payload: AnyLanVpnInterfaceParcel + ) -> ParcelCreationResponse: + ... + + @versions(supported_versions=(">=20.9"), raises=False) + @get("/v1/feature-profile/sdwan/service/{profile_id}/{parcel_type}/{parcel_id}") + def get_by_id( + self, profile_id: UUID, parcel_type: str, parcel_id: UUID + ) -> Parcel[Union[AnyServiceParcel, AnyRoutingParcel]]: + ... + + @versions(supported_versions=(">=20.9"), raises=False) + @get("/v1/feature-profile/sdwan/service/{profile_id}/{parcel_type}") + def get_all( + self, profile_id: UUID, parcel_type: str + ) -> DataSequence[Parcel[Union[AnyServiceParcel, AnyRoutingParcel]]]: + ... + + @versions(supported_versions=(">=20.9"), raises=False) + @get("/v1/feature-profile/sdwan/service/{profile_id}/lan/vpn/{vpn_id}/{parcel_type}/{parcel_id}") + def get_lan_vpn_sub_parcel( + self, profile_id: UUID, vpn_id: UUID, parcel_type: str, parcel_id: UUID + ) -> Parcel[AnyLanVpnInterfaceParcel]: + ... diff --git a/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py b/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py index a31ba997..884081ad 100644 --- a/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py +++ b/catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py @@ -1,7 +1,7 @@ # Copyright 2024 Cisco Systems, Inc. and its affiliates # mypy: disable-error-code="empty-body" -from typing import Optional +from typing import Optional, Union from uuid import UUID from catalystwan.api.configuration_groups.parcel import _ParcelBase @@ -21,6 +21,7 @@ ParcelCreationResponse, ParcelId, ) +from catalystwan.models.configuration.feature_profile.sdwan.routing import AnyRoutingParcel from catalystwan.models.configuration.feature_profile.sdwan.transport import ( AnyTransportParcel, CellularControllerParcel, @@ -82,12 +83,51 @@ def create_management_vpn_sub_parcel( @versions(supported_versions=(">=20.12"), raises=False) @get("/v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}") - def get_transport_parcels(self, profile_id: UUID, parcel_type: str) -> DataSequence[Parcel[AnyTransportParcel]]: + def get_transport_parcels( + self, profile_id: UUID, parcel_type: str + ) -> DataSequence[Parcel[Union[AnyTransportParcel, AnyRoutingParcel]]]: ... @versions(supported_versions=(">=20.12"), raises=False) @get("/v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}/{parcel_id}") - def get_transport_parcel(self, profile_id: UUID, parcel_type: str, parcel_id: UUID) -> Parcel[AnyTransportParcel]: + def get_transport_parcel( + self, profile_id: UUID, parcel_type: str, parcel_id: UUID + ) -> Parcel[Union[AnyTransportParcel, AnyRoutingParcel]]: + ... + + @versions(supported_versions=(">=20.12"), raises=False) + @put("/v1/feature-profile/sdwan/transport/{profile_id}/{parcel_type}/{parcel_id}") + def update_transport_parcel( + self, profile_id: UUID, parcel_type: str, parcel_id: UUID, payload: _ParcelBase + ) -> ParcelCreationResponse: + ... + + @versions(supported_versions=(">=20.12"), raises=False) + @get("/v1/feature-profile/sdwan/transport/{profile_id}/wan/vpn/{vpn_id}/{parcel_type}/{parcel_id}") + def get_transport_vpn_sub_parcel( + self, profile_id: UUID, vpn_id: UUID, parcel_type: str, parcel_id: UUID + ) -> Parcel[AnyTransportParcel]: + ... + + @versions(supported_versions=(">=20.12"), raises=False) + @get("/v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{vpn_id}/{parcel_type}/{parcel_id}") + def get_management_vpn_sub_parcel( + self, profile_id: UUID, vpn_id: UUID, parcel_type: str, parcel_id: UUID + ) -> Parcel[AnyTransportParcel]: + ... + + @versions(supported_versions=(">=20.12"), raises=False) + @put("/v1/feature-profile/sdwan/transport/{profile_id}/wan/vpn/{vpn_id}/{parcel_type}/{parcel_id}") + def update_transport_vpn_sub_parcel( + self, profile_id: UUID, vpn_id: UUID, parcel_type: str, parcel_id: UUID, payload: _ParcelBase + ) -> ParcelCreationResponse: + ... + + @versions(supported_versions=(">=20.12"), raises=False) + @put("/v1/feature-profile/sdwan/transport/{profile_id}/management/vpn/{vpn_id}/{parcel_type}/{parcel_id}") + def update_management_vpn_sub_parcel( + self, profile_id: UUID, vpn_id: UUID, parcel_type: str, parcel_id: UUID, payload: _ParcelBase + ) -> ParcelCreationResponse: ... # diff --git a/catalystwan/integration_tests/feature_profile/sdwan/test_service.py b/catalystwan/integration_tests/feature_profile/sdwan/test_service.py index 7b847bbc..40a4811e 100644 --- a/catalystwan/integration_tests/feature_profile/sdwan/test_service.py +++ b/catalystwan/integration_tests/feature_profile/sdwan/test_service.py @@ -4,6 +4,7 @@ from uuid import UUID from catalystwan.api.configuration_groups.parcel import Default, Global, Variable, as_global, as_variable +from catalystwan.api.feature_profile_api import ServiceFeatureProfileAPI from catalystwan.integration_tests.base import TestCaseBase, create_name_with_run_id from catalystwan.models.common import ( CableLengthLongValue, @@ -122,12 +123,35 @@ class TestServiceFeatureProfileModels(TestCaseBase): + api: ServiceFeatureProfileAPI + @classmethod def setUpClass(cls) -> None: super().setUpClass() cls.api = cls.session.api.sdwan_feature_profiles.service cls.profile_uuid = cls.api.create_profile(create_name_with_run_id("TestProfileService"), "Description").id + def test_update(self): + dhcp_server_parcel = LanVpnDhcpServerParcel( + parcel_name="DhcpServerDefault_TestUpdate", + parcel_description="Dhcp Server Parcel", + address_pool=AddressPool( + network_address=Global[IPv4Address](value=IPv4Address("10.0.0.2")), + subnet_mask=Global[SubnetMask](value="255.255.255.255"), + ), + ) + parcel_id = self.api.create_parcel(self.profile_uuid, dhcp_server_parcel).id + parcel = self.api.get_parcel(self.profile_uuid, LanVpnDhcpServerParcel, parcel_id) + assert isinstance(parcel.payload, LanVpnDhcpServerParcel) + assert parcel.payload == dhcp_server_parcel + + dhcp_server_parcel.address_pool.network_address = Global[IPv4Address](value=IPv4Address("10.3.2.1")) + dhcp_server_parcel.address_pool.subnet_mask = Global[SubnetMask](value="248.0.0.0") + parcel_id = self.api.update_parcel(self.profile_uuid, LanVpnDhcpServerParcel, parcel_id, dhcp_server_parcel).id + parcel = self.api.get_parcel(self.profile_uuid, LanVpnDhcpServerParcel, parcel_id) + assert isinstance(parcel.payload, LanVpnDhcpServerParcel) + assert parcel.payload == dhcp_server_parcel + def test_when_default_values_dhcp_server_parcel_expect_successful_post(self): # Arrange dhcp_server_parcel = LanVpnDhcpServerParcel( @@ -141,7 +165,9 @@ def test_when_default_values_dhcp_server_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, dhcp_server_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, LanVpnDhcpServerParcel, parcel_id) + assert isinstance(parcel.payload, LanVpnDhcpServerParcel) + assert parcel.payload == dhcp_server_parcel def test_when_default_values_service_vpn_parcel_expect_successful_post(self): # Arrange @@ -187,7 +213,9 @@ def test_when_default_values_service_vpn_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, vpn_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, LanVpnParcel, parcel_id) + assert isinstance(parcel.payload, LanVpnParcel) + assert parcel.payload == vpn_parcel def test_when_default_values_ospf_parcel_expect_successful_post(self): # Arrange @@ -198,7 +226,9 @@ def test_when_default_values_ospf_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, ospf_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, RoutingOspfParcel, parcel_id) + assert isinstance(parcel.payload, RoutingOspfParcel) + assert parcel.payload == ospf_parcel def test_when_default_ospfv3_ipv4_expect_successful_post(self): # Arrange @@ -215,7 +245,9 @@ def test_when_default_ospfv3_ipv4_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, ospfv3ipv4_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, RoutingOspfv3IPv4Parcel, parcel_id) + assert isinstance(parcel.payload, RoutingOspfv3IPv4Parcel) + assert parcel.payload == ospfv3ipv4_parcel def test_when_default_ospfv3_ipv6_expect_successful_post(self): # Arrange @@ -232,7 +264,9 @@ def test_when_default_ospfv3_ipv6_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, ospfv3ipv6_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, RoutingOspfv3IPv6Parcel, parcel_id) + assert isinstance(parcel.payload, RoutingOspfv3IPv6Parcel) + assert parcel.payload == ospfv3ipv6_parcel def test_when_default_values_eigrp_parcel_expect_successful_post(self): eigrp_parcel = EigrpParcel( @@ -253,7 +287,9 @@ def test_when_default_values_eigrp_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, eigrp_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, EigrpParcel, parcel_id) + assert isinstance(parcel.payload, EigrpParcel) + assert parcel.payload == eigrp_parcel def test_when_default_values_route_policy_parcel_expect_successful_post(self): # Arrange @@ -264,7 +300,9 @@ def test_when_default_values_route_policy_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, route_policy_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, RoutePolicyParcel, parcel_id) + assert isinstance(parcel.payload, RoutePolicyParcel) + assert parcel.payload == route_policy_parcel def test_when_default_values_acl_ipv4_expect_successful_post(self): # Arrange @@ -275,7 +313,9 @@ def test_when_default_values_acl_ipv4_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, acl_ipv4_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, Ipv4AclParcel, parcel_id) + assert isinstance(parcel.payload, Ipv4AclParcel) + assert parcel.payload == acl_ipv4_parcel def test_when_fully_specified_acl_ipv4_expect_successful_post(self): # Arrange @@ -300,7 +340,9 @@ def test_when_fully_specified_acl_ipv4_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, acl_ipv4_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, Ipv4AclParcel, parcel_id) + assert isinstance(parcel.payload, Ipv4AclParcel) + assert parcel.payload == acl_ipv4_parcel def test_when_default_values_acl_ipv6_expect_successful_post(self): # Arrange @@ -311,7 +353,9 @@ def test_when_default_values_acl_ipv6_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, acl_ipv6_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, Ipv6AclParcel, parcel_id) + assert isinstance(parcel.payload, Ipv6AclParcel) + assert parcel.payload == acl_ipv6_parcel def test_when_fully_specified_acl_ipv6_expect_successful_post(self): # Arrange @@ -333,7 +377,9 @@ def test_when_fully_specified_acl_ipv6_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, acl_ipv6_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, Ipv6AclParcel, parcel_id) + assert isinstance(parcel.payload, Ipv6AclParcel) + assert parcel.payload == acl_ipv6_parcel def test_when_fully_specified_routing_bgp_expect_successful_post(self): # Arrange @@ -368,7 +414,7 @@ def test_when_fully_specified_routing_bgp_expect_successful_post(self): send_community=Global[bool](value=True), send_ext_community=Global[bool](value=False), ebgp_multihop=Global[int](value=147), - password=Global[str](value="Qzxpq"), + password=None, send_label=Global[bool](value=True), as_override=Global[bool](value=False), as_number=Variable(value="{{lbgp_1_ipv4_conf_1_asNumber}}"), @@ -399,7 +445,7 @@ def test_when_fully_specified_routing_bgp_expect_successful_post(self): send_community=Global[bool](value=True), send_ext_community=Global[bool](value=False), ebgp_multihop=Global[int](value=21), - password=Global[str](value="vaPsP"), + password=None, as_override=Global[bool](value=True), as_number=Global[int](value=10), address_family=[ @@ -457,7 +503,9 @@ def test_when_fully_specified_routing_bgp_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, bgp_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, RoutingBgpParcel, parcel_id) + assert isinstance(parcel.payload, RoutingBgpParcel) + assert parcel.payload == bgp_parcel def test_when_correct_values_switchport_parcel_expect_successful_post(self): # Arrange @@ -503,7 +551,10 @@ def test_when_correct_values_switchport_parcel_expect_successful_post(self): with self.subTest(switchport_parcel=switchport_parcel.parcel_name): parcel_id = self.api.create_parcel(self.profile_uuid, switchport_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, SwitchportParcel, parcel_id) + assert isinstance(parcel.payload, SwitchportParcel) + assert parcel.payload == switchport_parcel + # Cleanup self.api.delete_parcel(self.profile_uuid, SwitchportParcel, parcel_id) @@ -517,7 +568,9 @@ def test_when_default_values_multicast_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, multicast_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, MulticastParcel, parcel_id) + assert isinstance(parcel.payload, MulticastParcel) + assert parcel.payload == multicast_parcel def test_when_fully_specified_values_multicast_expect_successful_post(self): # Arrange @@ -597,7 +650,7 @@ def test_when_fully_specified_values_multicast_expect_successful_post(self): peer_ip=Global[IPv4Address](value=IPv4Address("5.5.5.5")), connect_source_intf=as_global("GigabitEthernet0/0/0"), remote_as=as_global(10), - password=as_global("TestPassword"), + password=None, keepalive_holdtime=as_global(20), keepalive_interval=as_global(10), sa_limit=as_global(10), @@ -610,7 +663,9 @@ def test_when_fully_specified_values_multicast_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, multicast_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, MulticastParcel, parcel_id) + assert isinstance(parcel.payload, MulticastParcel) + assert parcel.payload == multicast_parcel def test_when_fully_specified_values_wireless_lan_expect_successful_post(self): # Arrange @@ -650,7 +705,9 @@ def test_when_fully_specified_values_wireless_lan_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, wireless_lan_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, WirelessLanParcel, parcel_id) + assert isinstance(parcel.payload, WirelessLanParcel) + assert parcel.payload == wireless_lan_parcel @classmethod def tearDownClass(cls) -> None: @@ -673,6 +730,31 @@ def setUpClass(cls) -> None: ), ).id + def test_update_interface(self): + # Arrange + svi_parcel = InterfaceSviParcel( + parcel_name="TestSviParcel_ToUpdate", + parcel_description="Test Svi Parcel", + interface_name=as_global("Vlan1"), + svi_description=as_global("Test Svi Description"), + ) + # Act + parcel_id = self.api.create_parcel(self.profile_uuid, svi_parcel, self.vpn_parcel_uuid).id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceSviParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid) + assert isinstance(parcel.payload, InterfaceSviParcel) + assert parcel.payload == svi_parcel + # Assert + svi_parcel.svi_description = as_global("Updated Svi Description") + parcel_id = self.api.update_parcel( + self.profile_uuid, InterfaceSviParcel, parcel_id, svi_parcel, vpn_uuid=self.vpn_parcel_uuid + ).id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceSviParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid) + assert isinstance(parcel.payload, InterfaceSviParcel) + assert parcel.payload == svi_parcel + + # Cleanup + self.api.delete_parcel(self.profile_uuid, InterfaceSviParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid) + def test_when_default_values_gre_parcel_expect_successful_post(self): # Arrange gre_parcel = InterfaceGreParcel( @@ -690,7 +772,9 @@ def test_when_default_values_gre_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, gre_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceGreParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid) + assert isinstance(parcel.payload, InterfaceGreParcel) + assert parcel.payload == gre_parcel def test_when_default_values_svi_parcel_expect_successful_post(self): # Arrange @@ -703,7 +787,9 @@ def test_when_default_values_svi_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, svi_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceSviParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid) + assert isinstance(parcel.payload, InterfaceSviParcel) + assert parcel.payload == svi_parcel def test_when_default_values_ethernet_parcel_expect_successful_post(self): # Arrange @@ -716,7 +802,11 @@ def test_when_default_values_ethernet_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel( + self.profile_uuid, InterfaceEthernetParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid + ) + assert isinstance(parcel.payload, InterfaceEthernetParcel) + assert parcel.payload == ethernet_parcel def test_set_dynamic_interface_ip_address_for_ethernet_parcel(self): # Arrange @@ -729,7 +819,11 @@ def test_set_dynamic_interface_ip_address_for_ethernet_parcel(self): parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel( + self.profile_uuid, InterfaceEthernetParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid + ) + assert isinstance(parcel.payload, InterfaceEthernetParcel) + assert parcel.payload == ethernet_parcel def test_set_dynamic_interface_ip_address_as_variable_for_ethernet_parcel(self): # Arrange @@ -742,7 +836,11 @@ def test_set_dynamic_interface_ip_address_as_variable_for_ethernet_parcel(self): parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel( + self.profile_uuid, InterfaceEthernetParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid + ) + assert isinstance(parcel.payload, InterfaceEthernetParcel) + assert parcel.payload == ethernet_parcel def test_set_primary_static_interface_ip_address_for_ethernet_parcel(self): # Arrange @@ -755,7 +853,11 @@ def test_set_primary_static_interface_ip_address_for_ethernet_parcel(self): parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel( + self.profile_uuid, InterfaceEthernetParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid + ) + assert isinstance(parcel.payload, InterfaceEthernetParcel) + assert parcel.payload == ethernet_parcel def test_set_primary_static_interface_ip_address_as_variable_for_ethernet_parcel(self): # Arrange @@ -768,7 +870,11 @@ def test_set_primary_static_interface_ip_address_as_variable_for_ethernet_parcel parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel( + self.profile_uuid, InterfaceEthernetParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid + ) + assert isinstance(parcel.payload, InterfaceEthernetParcel) + assert parcel.payload == ethernet_parcel def test_set_primary_static_with_mask_interface_ip_address_for_ethernet_parcel(self): # Arrange @@ -782,7 +888,11 @@ def test_set_primary_static_with_mask_interface_ip_address_for_ethernet_parcel(s parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel( + self.profile_uuid, InterfaceEthernetParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid + ) + assert isinstance(parcel.payload, InterfaceEthernetParcel) + assert parcel.payload == ethernet_parcel def test_set_primary_static_with_mask_interface_ip_address_as_varialbles_for_ethernet_parcel(self): # Arrange @@ -798,7 +908,11 @@ def test_set_primary_static_with_mask_interface_ip_address_as_varialbles_for_eth parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel( + self.profile_uuid, InterfaceEthernetParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid + ) + assert isinstance(parcel.payload, InterfaceEthernetParcel) + assert parcel.payload == ethernet_parcel def test_when_default_values_ipsec_parcel_expect_successful_post(self): # Arrange @@ -818,7 +932,9 @@ def test_when_default_values_ipsec_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, ipsec_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceIpsecParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid) + assert isinstance(parcel.payload, InterfaceIpsecParcel) + assert parcel.payload == ipsec_parcel def test_when_routing_parcel_and_vpn_uuid_present_expect_create_then_assign_to_vpn(self): # Arrange @@ -830,7 +946,9 @@ def test_when_routing_parcel_and_vpn_uuid_present_expect_create_then_assign_to_v # Act parcel_id = self.api.create_parcel(self.profile_uuid, multicast_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, MulticastParcel, parcel_id) + assert isinstance(parcel.payload, MulticastParcel) + assert parcel.payload == multicast_parcel def test_when_fully_specified_multilink_interface_parcel_expect_successful_post(self): nim_list = [ @@ -925,7 +1043,11 @@ def test_when_fully_specified_multilink_interface_parcel_expect_successful_post( parcel_id = self.api.create_parcel(self.profile_uuid, multilink_parcel, self.vpn_parcel_uuid).id - assert parcel_id + parcel = self.api.get_parcel( + self.profile_uuid, InterfaceMultilinkParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid + ) + assert isinstance(parcel.payload, InterfaceMultilinkParcel) + assert parcel.payload == multilink_parcel def test_when_default_values_ethernet_interface_expect_successful_post(self): # For 20.13 when we send "advanced.intfruMtu" as Default 1500 @@ -944,7 +1066,11 @@ def test_when_default_values_ethernet_interface_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.vpn_parcel_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel( + self.profile_uuid, InterfaceEthernetParcel, parcel_id, vpn_uuid=self.vpn_parcel_uuid + ) + assert isinstance(parcel.payload, InterfaceEthernetParcel) + assert parcel.payload == ethernet_parcel @classmethod def tearDownClass(cls) -> None: diff --git a/catalystwan/integration_tests/feature_profile/sdwan/test_transport.py b/catalystwan/integration_tests/feature_profile/sdwan/test_transport.py index a2e17846..c0f9376b 100644 --- a/catalystwan/integration_tests/feature_profile/sdwan/test_transport.py +++ b/catalystwan/integration_tests/feature_profile/sdwan/test_transport.py @@ -6,6 +6,7 @@ from packaging.version import Version # type: ignore from catalystwan.api.configuration_groups.parcel import Default, Global, Variable, as_global +from catalystwan.api.feature_profile_api import TransportFeatureProfileAPI from catalystwan.integration_tests.base import TestCaseBase, create_name_with_run_id from catalystwan.integration_tests.test_data import cellular_controller_parcel, cellular_profile_parcel, gps_parcel from catalystwan.models.common import ( @@ -26,10 +27,7 @@ T1Linecode, TLOCColor, ) -from catalystwan.models.configuration.feature_profile.common import AclQos -from catalystwan.models.configuration.feature_profile.common import AddressWithMask -from catalystwan.models.configuration.feature_profile.common import AddressWithMask as CommonPrefix -from catalystwan.models.configuration.feature_profile.common import AdvancedGre, AllowService +from catalystwan.models.configuration.feature_profile.common import AclQos, AddressWithMask, AdvancedGre, AllowService from catalystwan.models.configuration.feature_profile.common import Arp as CommonArp from catalystwan.models.configuration.feature_profile.common import ChannelGroup, DNSIPv4, DNSIPv6 from catalystwan.models.configuration.feature_profile.common import ( @@ -71,6 +69,13 @@ RedistributeItem, RoutingBgpParcel, ) +from catalystwan.models.configuration.feature_profile.sdwan.routing.ospf import RoutingOspfParcel +from catalystwan.models.configuration.feature_profile.sdwan.service.route_policy import RoutePolicyParcel +from catalystwan.models.configuration.feature_profile.sdwan.transport.cellular_controller import ( + CellularControllerParcel, +) +from catalystwan.models.configuration.feature_profile.sdwan.transport.cellular_profile import CellularProfileParcel +from catalystwan.models.configuration.feature_profile.sdwan.transport.gps import GpsParcel from catalystwan.models.configuration.feature_profile.sdwan.transport.management.ethernet import ( Advanced as ManagementEthernetAdvanced, ) @@ -111,7 +116,6 @@ Advanced as AdvancedCellular, ) from catalystwan.models.configuration.feature_profile.sdwan.transport.wan.interface.cellular import ( - Arp, InterfaceCellularParcel, NatAttributesIpv4, ) @@ -177,12 +181,42 @@ class TestTransportFeatureProfileModels(TestCaseBase): + api: TransportFeatureProfileAPI + @classmethod def setUpClass(cls) -> None: super().setUpClass() cls.api = cls.session.api.sdwan_feature_profiles.transport cls.profile_uuid = cls.api.create_profile(create_name_with_run_id("TestTransportModels"), "Description").id + def test_update(self): + # Arrange + parcel = RoutePolicyParcel( + parcel_name="TestRoutePolicyParcel_ToUpdate", + parcel_description="Description", + ) + parcel_id = self.api.create_parcel(self.profile_uuid, parcel).id + # Act + parcel.parcel_name = "TestRoutePolicyParcel_Updated" + parcel_id = self.api.update_parcel(self.profile_uuid, parcel, parcel_id).id + # Assert + updated_parcel = self.api.get_parcel(self.profile_uuid, RoutePolicyParcel, parcel_id) + assert isinstance(updated_parcel.payload, RoutePolicyParcel) + assert updated_parcel.payload == parcel + + def test_when_default_values_ospf_expect_successful_post(self): + # Arrange + ospf_parcel = RoutingOspfParcel( + parcel_name="TestOspfParcel-Defaults", + parcel_description="Test Ospf Parcel", + ) + # Act + parcel_id = self.api.create_parcel(self.profile_uuid, ospf_parcel).id + # Assert + parcel = self.api.get_parcel(self.profile_uuid, RoutingOspfParcel, parcel_id) + assert isinstance(parcel.payload, RoutingOspfParcel) + assert parcel.payload == ospf_parcel + def test_when_fully_specified_management_vpn_parcel_expect_successful_post(self): # Arrange management_vpn_parcel = ManagementVpnParcel( @@ -230,7 +264,9 @@ def test_when_fully_specified_management_vpn_parcel_expect_successful_post(self) # Act parcel_id = self.api.create_parcel(self.profile_uuid, management_vpn_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, ManagementVpnParcel, parcel_id) + assert isinstance(parcel.payload, ManagementVpnParcel) + assert parcel.payload == management_vpn_parcel def test_when_fully_specified_t1e1controller_type_e1_parcel_expect_successful_post(self): # Arrange @@ -262,7 +298,9 @@ def test_when_fully_specified_t1e1controller_type_e1_parcel_expect_successful_po # Act parcel_id = self.api.create_parcel(self.profile_uuid, t1e1controller).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, T1E1ControllerParcel, parcel_id) + assert isinstance(parcel.payload, T1E1ControllerParcel) + assert parcel.payload == t1e1controller def test_when_fully_specified_t1e1controller_type_t1_parcel_expect_successful_post(self): # Arrange @@ -298,25 +336,33 @@ def test_when_fully_specified_t1e1controller_type_t1_parcel_expect_successful_po # Act parcel_id = self.api.create_parcel(self.profile_uuid, t1e1controller).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, T1E1ControllerParcel, parcel_id) + assert isinstance(parcel.payload, T1E1ControllerParcel) + assert parcel.payload == t1e1controller def test_when_fully_specifed_gps_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, gps_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, GpsParcel, parcel_id) + assert isinstance(parcel.payload, GpsParcel) + assert parcel.payload == gps_parcel def test_when_fully_specifed_cellular_controller_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, cellular_controller_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, CellularControllerParcel, parcel_id) + assert isinstance(parcel.payload, CellularControllerParcel) + assert parcel.payload == cellular_controller_parcel def test_when_fully_specifed_cellular_profile_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, cellular_profile_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, CellularProfileParcel, parcel_id) + assert isinstance(parcel.payload, CellularProfileParcel) + assert parcel.payload == cellular_profile_parcel def test_when_default_values_acl_ipv4_expect_successful_post(self): # Arrange @@ -326,9 +372,10 @@ def test_when_default_values_acl_ipv4_expect_successful_post(self): ) # Act parcel_id = self.api.create_parcel(self.profile_uuid, acl_ipv4_parcel).id - self.api.get_parcel(self.profile_uuid, Ipv4AclParcel, parcel_id) # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, Ipv4AclParcel, parcel_id) + assert isinstance(parcel.payload, Ipv4AclParcel) + assert parcel.payload == acl_ipv4_parcel def test_when_fully_specified_acl_ipv4_expect_successful_post(self): # Arrange @@ -352,9 +399,10 @@ def test_when_fully_specified_acl_ipv4_expect_successful_post(self): seq2.match_source_ports([1, 3, (10, 100), (50, 200), 600]) # Act parcel_id = self.api.create_parcel(self.profile_uuid, acl_ipv4_parcel).id - self.api.get_parcel(self.profile_uuid, Ipv4AclParcel, parcel_id) # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, Ipv4AclParcel, parcel_id) + assert isinstance(parcel.payload, Ipv4AclParcel) + assert parcel.payload == acl_ipv4_parcel def test_when_default_values_acl_ipv6_expect_successful_post(self): # Arrange @@ -364,9 +412,10 @@ def test_when_default_values_acl_ipv6_expect_successful_post(self): ) # Act parcel_id = self.api.create_parcel(self.profile_uuid, acl_ipv6_parcel).id - self.api.get_parcel(self.profile_uuid, Ipv6AclParcel, parcel_id) # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, Ipv6AclParcel, parcel_id) + assert isinstance(parcel.payload, Ipv6AclParcel) + assert parcel.payload == acl_ipv6_parcel def test_when_fully_specified_acl_ipv6_expect_successful_post(self): # Arrange @@ -387,9 +436,10 @@ def test_when_fully_specified_acl_ipv6_expect_successful_post(self): seq2.match_source_ports([1, 3, (10, 100), (50, 200), 600]) # Act parcel_id = self.api.create_parcel(self.profile_uuid, acl_ipv6_parcel).id - self.api.get_parcel(self.profile_uuid, Ipv6AclParcel, parcel_id) # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, Ipv6AclParcel, parcel_id) + assert isinstance(parcel.payload, Ipv6AclParcel) + assert parcel.payload == acl_ipv6_parcel def test_when_fully_specified_routing_bgp_expect_successful_post(self): # Arrange @@ -424,7 +474,7 @@ def test_when_fully_specified_routing_bgp_expect_successful_post(self): send_community=Global[bool](value=True), send_ext_community=Global[bool](value=False), ebgp_multihop=Global[int](value=147), - password=Global[str](value="Qzxpq"), + password=None, send_label=Global[bool](value=True), as_override=Global[bool](value=False), as_number=Variable(value="{{lbgp_1_ipv4_conf_1_asNumber}}"), @@ -455,7 +505,7 @@ def test_when_fully_specified_routing_bgp_expect_successful_post(self): send_community=Global[bool](value=True), send_ext_community=Global[bool](value=False), ebgp_multihop=Global[int](value=21), - password=Global[str](value="vaPsP"), + password=None, as_override=Global[bool](value=True), as_number=Global[int](value=10), address_family=[ @@ -513,7 +563,9 @@ def test_when_fully_specified_routing_bgp_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, bgp_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, RoutingBgpParcel, parcel_id) + assert isinstance(parcel.payload, RoutingBgpParcel) + assert parcel.payload == bgp_parcel @classmethod def tearDownClass(cls) -> None: @@ -538,7 +590,9 @@ def test_when_minimal_specifed_transport_vpn_parcel_expect_successful_post(self) # Act parcel_id = self.api.create_parcel(self.profile_uuid, transport_vpn_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, TransportVpnParcel, parcel_id) + assert isinstance(parcel.payload, TransportVpnParcel) + assert parcel.payload == transport_vpn_parcel def test_when_set_dns_address_specifed_transport_vpn_parcel_expect_successful_post(self): # Arrange @@ -551,7 +605,9 @@ def test_when_set_dns_address_specifed_transport_vpn_parcel_expect_successful_po parcel_id = self.api.create_parcel(self.profile_uuid, transport_vpn_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, TransportVpnParcel, parcel_id) + assert isinstance(parcel.payload, TransportVpnParcel) + assert parcel.payload == transport_vpn_parcel def test_when_add_ipv4_route_specifed_transport_vpn_parcel_expect_successful_post(self): # Arrange @@ -571,7 +627,9 @@ def test_when_add_ipv4_route_specifed_transport_vpn_parcel_expect_successful_pos parcel_id = self.api.create_parcel(self.profile_uuid, transport_vpn_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, TransportVpnParcel, parcel_id) + assert isinstance(parcel.payload, TransportVpnParcel) + assert parcel.payload == transport_vpn_parcel def test_when_fully_specifed_transport_vpn_parcel_expect_successful_post(self): # Arrange @@ -625,7 +683,9 @@ def test_when_fully_specifed_transport_vpn_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, transport_vpn_parcel).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, TransportVpnParcel, parcel_id) + assert isinstance(parcel.payload, TransportVpnParcel) + assert parcel.payload == transport_vpn_parcel def tearDown(self) -> None: self.session.api.config_group.delete(self.config_id) @@ -634,6 +694,7 @@ def tearDown(self) -> None: class TestTransportFeatureProfileWanInterfaceModels(TestCaseBase): wan_uuid: UUID + api: TransportFeatureProfileAPI @classmethod def setUpClass(cls) -> None: @@ -664,7 +725,9 @@ def test_when_fully_specified_t1e1serial_interface_parcel_expect_successfull_pos parcel_name="T1E1FullySpecifiedParcel", parcel_description="Description", interface_name=Global[str](value="Serial3"), - address_v4=CommonPrefix(address=Global[str](value="1.1.1.1"), mask=Variable(value="{{NQokHq}}")), + address_v4=AddressWithMask( + address=Global[IPv4Address](value=IPv4Address("1.1.1.1")), mask=Variable(value="{{NQokHq}}") + ), address_v6=Variable(value="{{i4i}}"), advanced=Advanced( ip_mtu=Global[int](value=1500), @@ -737,7 +800,9 @@ def test_when_fully_specified_t1e1serial_interface_parcel_expect_successfull_pos # Act parcel_id = self.api.create_parcel(self.profile_uuid, t1e1serial, self.wan_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, T1E1SerialParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, T1E1SerialParcel) + assert parcel.payload == t1e1serial def test_when_fully_specified_ethpppoe_interface_parcel_expect_successfull_post(self): # Arrange @@ -840,7 +905,9 @@ def test_when_fully_specified_ethpppoe_interface_parcel_expect_successfull_post( # Act parcel_id = self.api.create_parcel(self.profile_uuid, ethpppoe_parcel, self.wan_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceEthPPPoEParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceEthPPPoEParcel) + assert parcel.payload == ethpppoe_parcel def test_when_fully_specified_dslpppoe_interface_parcel_expect_successfull_post(self): # Arrange @@ -947,7 +1014,9 @@ def test_when_fully_specified_dslpppoe_interface_parcel_expect_successfull_post( # Act parcel_id = self.api.create_parcel(self.profile_uuid, ethpppoe_parcel, self.wan_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceDslPPPoEParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceDslPPPoEParcel) + assert parcel.payload == ethpppoe_parcel def test_when_correct_values_dlspppoa_interface_parcel_expect_successfull_post(self): """This test case don't cover all fields because the models @@ -974,7 +1043,9 @@ def test_when_correct_values_dlspppoa_interface_parcel_expect_successfull_post(s # Act parcel_id = self.api.create_parcel(self.profile_uuid, dslpppoa_parcel, self.wan_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceDslPPPoAParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceDslPPPoAParcel) + assert parcel.payload == dslpppoa_parcel def test_when_correct_values_dlsipoe_interface_parcel_expect_successfull_post(self): """This test case don't cover all fields because the models @@ -998,7 +1069,9 @@ def test_when_correct_values_dlsipoe_interface_parcel_expect_successfull_post(se # Act parcel_id = self.api.create_parcel(self.profile_uuid, dslipoe_parcel, self.wan_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceDslIPoEParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceDslIPoEParcel) + assert parcel.payload == dslipoe_parcel def test_when_fully_specified_gre_interface_parcel_expect_successful_post(self): # Arrange @@ -1006,7 +1079,7 @@ def test_when_fully_specified_gre_interface_parcel_expect_successful_post(self): parcel_name="InterfaceGreParcel", parcel_description="Description", basic=Basic( - address=CommonPrefix( + address=AddressWithMask( address=Global[IPv4Address](value=IPv4Address("39.5.0.97")), mask=Variable(value="{{QPg11165441vY1}}"), ), @@ -1029,13 +1102,15 @@ def test_when_fully_specified_gre_interface_parcel_expect_successful_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, gre_parcel, self.wan_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceGreParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceGreParcel) + assert parcel.payload == gre_parcel def test_when_fully_specified_ipsec_interface_parcel_expect_successful_post(self): ipsec_parcel = InterfaceIpsecParcel( parcel_name="InterfaceIpsecParcel", parcel_description="Description", - address=CommonPrefix( + address=AddressWithMask( address=Global[IPv4Address](value=IPv4Address("127.211.176.149")), mask=Global[SubnetMask](value="255.255.255.0"), ), @@ -1059,10 +1134,10 @@ def test_when_fully_specified_ipsec_interface_parcel_expect_successful_post(self pre_shared_secret=Global[str](value="iEKeBeVb"), shutdown=Default[bool](value=True), tcp_mss_adjust=Default[None](value=None), - tunnel_destination=CommonPrefix( + tunnel_destination=AddressWithMask( address=Global[IPv4Address](value=IPv4Address("192.0.0.171")), mask=Variable(value="{{Dr}}") ), - tunnel_source=CommonPrefix( + tunnel_source=AddressWithMask( address=Global[IPv4Address](value=IPv4Address("192.52.193.221")), mask=Global[SubnetMask](value="255.255.254.0"), ), @@ -1073,7 +1148,9 @@ def test_when_fully_specified_ipsec_interface_parcel_expect_successful_post(self # Act parcel_id = self.api.create_parcel(self.profile_uuid, ipsec_parcel, self.wan_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceIpsecParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceIpsecParcel) + assert parcel.payload == ipsec_parcel def test_when_fully_specified_cellular_interface_parcel_expect_successful_post(self): # Arrange @@ -1136,12 +1213,15 @@ def test_when_fully_specified_cellular_interface_parcel_expect_successful_post(s stun=Global[bool](value=True), ), arp=[ - Arp( + CommonArp( ip_address=Global[IPv4Address](value=IPv4Address("203.0.113.2")), mac_address=Global[str](value="DC:F1:17:22:FA:3D"), ), - Arp(ip_address=Global[str](value="3.2.1.1"), mac_address=Global[str](value="BF:DB:A1:F0:4B:C8")), - Arp( + CommonArp( + ip_address=Global[IPv4Address](value=IPv4Address("3.2.1.1")), + mac_address=Global[str](value="BF:DB:A1:F0:4B:C8"), + ), + CommonArp( ip_address=Global[IPv4Address](value=IPv4Address("192.0.0.170")), mac_address=Global[str](value="1B:5A:0F:AB:9E:CE"), ), @@ -1179,7 +1259,9 @@ def test_when_fully_specified_cellular_interface_parcel_expect_successful_post(s # Act parcel_id = self.api.create_parcel(self.profile_uuid, cellular_parcel, self.wan_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceCellularParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceCellularParcel) + assert parcel.payload == cellular_parcel def test_when_fully_specified_ethernet_interface_expect_successfull_post(self): # Arrange @@ -1250,7 +1332,10 @@ def test_when_fully_specified_ethernet_interface_expect_successfull_post(self): ip_address=Global[IPv4Address](value=IPv4Address("203.0.113.2")), mac_address=Global[str](value="DC:F1:17:22:FA:3D"), ), - CommonArp(ip_address=Global[str](value="3.2.1.1"), mac_address=Global[str](value="BF:DB:A1:F0:4B:C8")), + CommonArp( + ip_address=Global[IPv4Address](value=IPv4Address("3.2.1.1")), + mac_address=Global[str](value="BF:DB:A1:F0:4B:C8"), + ), CommonArp( ip_address=Global[IPv4Address](value=IPv4Address("192.0.0.170")), mac_address=Global[str](value="1B:5A:0F:AB:9E:CE"), @@ -1275,7 +1360,7 @@ def test_when_fully_specified_ethernet_interface_expect_successfull_post(self): source_vpn=Global[int](value=422), ), StaticNat( - source_ip=Global[str](value="hWhYrEZZ"), + source_ip=Global[IPv4Address](value=IPv4Address("10.0.2.1")), translate_ip=Variable(value="{{xskEgr6}}"), static_nat_direction=Default[Literal["inside", "outside"]](value="inside"), source_vpn=Default[int](value=0), @@ -1330,7 +1415,9 @@ def test_when_fully_specified_ethernet_interface_expect_successfull_post(self): # Act parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.wan_uuid).id # Assert - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceEthernetParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceEthernetParcel) + assert parcel.payload == ethernet_parcel def test_when_fully_specified_multilink_interface_parcel_expect_successful_post(self): # Arrange @@ -1452,7 +1539,7 @@ def test_when_fully_specified_multilink_interface_parcel_expect_successful_post( ospf=Global[bool](value=True), password=Global[str](value="hyBBiuDgO"), port_hop=Global[bool](value=False), - ppp_auth_password=Global[str](value="aCBBBxnzsw"), + ppp_auth_password=None, restrict=Global[bool](value=False), shaping_rate=Global[int](value=294), shutdown=Global[bool](value=False), @@ -1471,7 +1558,56 @@ def test_when_fully_specified_multilink_interface_parcel_expect_successful_post( parcel_id = self.api.create_parcel(self.profile_uuid, multilink_parcel, self.wan_uuid).id - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceMultilinkParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceMultilinkParcel) + assert parcel.payload == multilink_parcel + + @classmethod + def tearDownClass(cls) -> None: + cls.api.delete_profile(cls.profile_uuid) + super().tearDownClass() + + +class TestTransportFeatureProfileWanInterfaceModelsUpdate(TestCaseBase): + wan_uuid: UUID + api: TransportFeatureProfileAPI + + @classmethod + def setUpClass(cls) -> None: + super().setUpClass() + cls.api = cls.session.api.sdwan_feature_profiles.transport + cls.profile_uuid = cls.api.create_profile(create_name_with_run_id("TestTransportInterface"), "Description").id + cls.wan_uuid = cls.api.create_parcel( + cls.profile_uuid, + TransportVpnParcel( + parcel_name="TestTransportVpnParcel", + parcel_description="Description", + ), + ).id + + def test_update(self): + gre_parcel = InterfaceGreParcel( + parcel_name="InterfaceGreParcel", + parcel_description="Description", + basic=Basic( + if_name=Global[str](value="gre23"), + tunnel_destination=Global[IPv4Address](value=IPv4Address("5.5.2.1")), + address=AddressWithMask( + address=Global[IPv4Address](value=IPv4Address("30.2.1.1")), + mask=Variable(value="{{QPg111654}}"), + ), + ), + ) + parcel_id = self.api.create_parcel(self.profile_uuid, gre_parcel, self.wan_uuid).id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceGreParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceGreParcel) + assert parcel.payload == gre_parcel + + gre_parcel.basic.address.address = as_global(IPv4Address("20.3.2.1")) + parcel_id = self.api.update_parcel(self.profile_uuid, gre_parcel, parcel_id, self.wan_uuid).id + parcel = self.api.get_parcel(self.profile_uuid, InterfaceGreParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, InterfaceGreParcel) + assert parcel.payload == gre_parcel @classmethod def tearDownClass(cls) -> None: @@ -1514,7 +1650,10 @@ def test_when_fully_specified_ethernet_parcel_expect_successful_post(self): ip_address=Global[IPv4Address](value=IPv4Address("203.0.113.2")), mac_address=Global[str](value="DC:F1:17:22:FA:3D"), ), - CommonArp(ip_address=Global[str](value="3.2.1.1"), mac_address=Global[str](value="BF:DB:A1:F0:4B:C8")), + CommonArp( + ip_address=Global[IPv4Address](value=IPv4Address("3.2.1.1")), + mac_address=Global[str](value="BF:DB:A1:F0:4B:C8"), + ), CommonArp( ip_address=Global[IPv4Address](value=IPv4Address("192.0.0.170")), mac_address=Global[str](value="1B:5A:0F:AB:9E:CE"), @@ -1551,7 +1690,9 @@ def test_when_fully_specified_ethernet_parcel_expect_successful_post(self): parcel_id = self.api.create_parcel(self.profile_uuid, ethernet_parcel, self.wan_uuid).id - assert parcel_id + parcel = self.api.get_parcel(self.profile_uuid, ManagementEthernetParcel, parcel_id, self.wan_uuid) + assert isinstance(parcel.payload, ManagementEthernetParcel) + assert parcel.payload == ethernet_parcel @classmethod def tearDownClass(cls) -> None: diff --git a/catalystwan/integration_tests/test_data/__init__.py b/catalystwan/integration_tests/test_data/__init__.py index bf8ed745..49b31993 100644 --- a/catalystwan/integration_tests/test_data/__init__.py +++ b/catalystwan/integration_tests/test_data/__init__.py @@ -2,7 +2,7 @@ from ipaddress import IPv4Address from typing import List, Literal -from catalystwan.api.configuration_groups.parcel import Default, Global, as_global +from catalystwan.api.configuration_groups.parcel import Default, Global, Variable, as_global from catalystwan.models.configuration.feature_profile.sdwan.routing.bgp import RoutingBgpParcel from catalystwan.models.configuration.feature_profile.sdwan.routing.ospf import RoutingOspfParcel from catalystwan.models.configuration.feature_profile.sdwan.routing.ospfv3 import ( @@ -46,7 +46,7 @@ apn=Global[str](value="KvqJrCD"), authentication=Authentication( need_authentication=NeedAuthentication( - password=Global[str](value="HfBBBHZlFH"), + password=Variable(value="{{HfBBBHZlFH}}"), type=Global[Literal["chap", "pap", "pap_chap"]](value="chap"), username=Global[str](value="BABBBBBBV"), ) diff --git a/catalystwan/models/configuration/config_migration.py b/catalystwan/models/configuration/config_migration.py deleted file mode 100644 index 0e89aaf9..00000000 --- a/catalystwan/models/configuration/config_migration.py +++ /dev/null @@ -1,721 +0,0 @@ -# Copyright 2024 Cisco Systems, Inc. and its affiliates - -from dataclasses import dataclass, field -from typing import Any, Dict, Generic, List, Literal, Optional, Sequence, Set, Tuple, TypeVar, Union, cast -from uuid import UUID, uuid4 - -from packaging.version import Version -from pydantic import AliasGenerator, BaseModel, ConfigDict, Field, model_validator -from pydantic.alias_generators import to_camel - -from catalystwan import PACKAGE_VERSION -from catalystwan.api.builders.feature_profiles.report import ( - FailedParcel, - FailedRequestDetails, - FeatureProfileBuildReport, -) -from catalystwan.api.templates.device_template.device_template import DeviceTemplate, GeneralTemplate, str_to_uuid -from catalystwan.endpoints.configuration_group import ConfigGroupCreationPayload -from catalystwan.endpoints.configuration_settings import CloudCredentials -from catalystwan.exceptions import ManagerHTTPError -from catalystwan.models.common import IntStr, VpnId -from catalystwan.models.configuration.feature_profile.common import FeatureProfileCreationPayload, ProfileType -from catalystwan.models.configuration.feature_profile.parcel import AnyParcel, list_types -from catalystwan.models.configuration.feature_profile.sdwan.policy_object import AnyPolicyObjectParcel -from catalystwan.models.configuration.feature_profile.sdwan.service.lan.vpn import LanVpnParcel -from catalystwan.models.configuration.network_hierarchy.cflowd import CflowdParcel -from catalystwan.models.configuration.network_hierarchy.node import NodeInfo -from catalystwan.models.configuration.policy_group import PolicyGroup -from catalystwan.models.configuration.topology_group import TopologyGroup -from catalystwan.models.policy import AnyPolicyDefinitionInfo, AnyPolicyListInfo, URLAllowListInfo, URLBlockListInfo -from catalystwan.models.policy.centralized import CentralizedPolicyInfo -from catalystwan.models.policy.definition.ssl_decryption import NetworkDecryptionRuleSequence, UrlProfile -from catalystwan.models.policy.definition.zone_based_firewall import ZoneBasedFWPolicyEntry -from catalystwan.models.policy.localized import LocalizedPolicyInfo -from catalystwan.models.policy.security import ( - AnySecurityPolicyInfo, - HighSpeedLoggingEntry, - HighSpeedLoggingList, - LoggingEntry, - ZoneToNoZoneInternet, -) -from catalystwan.models.settings import ThreatGridApi -from catalystwan.models.templates import FeatureTemplateInformation, TemplateInformation -from catalystwan.version import NullVersion, parse_api_version - -T = TypeVar("T", bound=AnyParcel) -TO = TypeVar("TO") - -ConvertOutputStatus = Literal["complete", "partial"] -ConvertAbortStatus = Literal["failed", "unsupported"] -ConvertStatus = Literal[ConvertOutputStatus, ConvertAbortStatus] - -camel = AliasGenerator( - serialization_alias=to_camel, - validation_alias=to_camel, -) - - -class VersionInfo(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - platform: str = "unknown" - sdk: str = PACKAGE_VERSION - - @property - def platform_api(self) -> Version: - return parse_api_version(self.platform) - - def is_compatible(self, other: "VersionInfo"): - return True if (self.sdk == other.sdk and self.platform_api == other.platform_api) else False - - -class DeviceTemplateWithInfo(DeviceTemplate): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - template_id: str - devices_attached: int - - @staticmethod - def from_merged(template: DeviceTemplate, info: TemplateInformation) -> "DeviceTemplateWithInfo": - info_dict = template.model_dump() - return DeviceTemplateWithInfo( - template_id=info.id, - devices_attached=info.devices_attached, - **info_dict, - ) - - def get_sig_template_uuid(self) -> Optional[UUID]: - """SIG template is part of a PolicyGroup in UX2.0""" - - def __traverse_general_templates(general_templates: List[GeneralTemplate]) -> Optional[str]: - """Traverse the general templates to find the SIG template uuid""" - for general_template in general_templates: - if general_template.template_type == "cisco_secure_internet_gateway": - return general_template.template_id - if general_template.sub_templates: - if result := __traverse_general_templates(general_template.sub_templates): - return result - return None - - result = __traverse_general_templates(self.general_templates) - return str_to_uuid(result) if result else None - - def get_flattened_general_templates(self) -> List[GeneralTemplate]: - """ - Flatten the representation but leave cisco vpn templates and - cellular cedge controller as they are, because they have subtemplates - that need to have the same parent template in UX2.0. For example cisco_system - also have subtemplates but they have flat structure in UX2.0. - - Returns: - A list of GeneralTemplate objects representing the flattened templates list. - """ - result = [] - for template in self.general_templates: - subtemplates = template.sub_templates - if subtemplates and template.template_type not in ["cisco_vpn", "vpn-vedge", "cellular-cedge-controller"]: - template.sub_templates = [] - for subtemplate in subtemplates: - result.append(subtemplate) - result.append(template) - - return result - - -class UX1Policies(BaseModel): - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - centralized_policies: List[CentralizedPolicyInfo] = Field(default_factory=list) - localized_policies: List[LocalizedPolicyInfo] = Field(default_factory=list) - security_policies: List[AnySecurityPolicyInfo] = Field(default_factory=list) - policy_definitions: List[AnyPolicyDefinitionInfo] = Field(default_factory=list) - policy_lists: List[AnyPolicyListInfo] = Field(default_factory=list) - - def get_centralized_policy_by_id(self, policy_id: UUID) -> Optional[CentralizedPolicyInfo]: - return next((p for p in self.centralized_policies if p.policy_id == policy_id), None) - - def get_localized_policy_by_id(self, policy_id: UUID) -> Optional[LocalizedPolicyInfo]: - return next((p for p in self.localized_policies if p.policy_id == policy_id), None) - - def get_security_policy_by_id(self, policy_id: UUID) -> Optional[AnySecurityPolicyInfo]: - return next((p for p in self.security_policies if p.policy_id == policy_id), None) - - -class UX1Templates(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - feature_templates: List[FeatureTemplateInformation] = Field(default_factory=list) - device_templates: List[DeviceTemplateWithInfo] = Field(default_factory=list) - - def create_device_template_by_policy_id_lookup(self) -> Dict[Literal["policy", "security"], Dict[UUID, UUID]]: - lookup: Dict[Literal["policy", "security"], Dict[UUID, UUID]] = {"policy": {}, "security": {}} - for dt in self.device_templates: - policy_id = dt.get_policy_uuid() - security_policy_id = dt.get_security_policy_uuid() - if policy_id is not None: - lookup["policy"][policy_id] = UUID(dt.template_id) - if security_policy_id is not None: - lookup["security"][security_policy_id] = UUID(dt.template_id) - return lookup - - def pop_cloud_credential_templates(self) -> List[FeatureTemplateInformation]: - cloud_credential_templates = [] - for template in self.feature_templates: - if template.name in ["Cisco-Zscaler-Global-Credentials", "Cisco-Umbrella-Global-Credentials"]: - cloud_credential_templates.append(template) - for t in cloud_credential_templates: - self.feature_templates.remove(t) - return cloud_credential_templates - - -class UX1Config(BaseModel): - # All UX1 Configuration items - Mega Model - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - version: VersionInfo = VersionInfo() - policies: UX1Policies = UX1Policies() - templates: UX1Templates = UX1Templates() - network_hierarchy: List[NodeInfo] = Field(default_factory=list) - - -class TransformHeader(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - type: str = Field( - description="Needed to push item to specific endpoint." - "Type discriminator is not present in many UX2 item payloads" - ) - origin: UUID = Field(description="Original UUID of converted item") - origname: Optional[str] = None - subelements: Set[UUID] = Field(default_factory=set) - localized_policy_subelements: Optional[Set[UUID]] = Field(default=None) - status: ConvertOutputStatus = Field(default="complete") - info: List[str] = Field(default_factory=list) - - def add_localized_policy_subelement(self, subelement: UUID) -> None: - if self.localized_policy_subelements is None: - self.localized_policy_subelements = {subelement} - else: - self.localized_policy_subelements.add(subelement) - - -class TransformedTopologyGroup(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - header: TransformHeader - topology_group: TopologyGroup - - -class TransformedConfigGroup(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - header: TransformHeader - config_group: ConfigGroupCreationPayload - - -class TransformedPolicyGroup(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - header: TransformHeader - policy_group: PolicyGroup - - -class TransformedFeatureProfile(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - header: TransformHeader - feature_profile: FeatureProfileCreationPayload - - -class TransformedParcel(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - header: TransformHeader - parcel: AnyParcel - - -class FailedConversionItem(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - feature_template: Optional[FeatureTemplateInformation] = Field(default=None) - policy: Optional[ - Union[ - CentralizedPolicyInfo, - LocalizedPolicyInfo, - AnySecurityPolicyInfo, - AnyPolicyDefinitionInfo, - AnyPolicyListInfo, - ] - ] = Field(default=None) - exception_message: str - - -class UnsupportedConversionItem(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - name: str - uuid: UUID - type: Optional[str] = None - - -class UX2Config(BaseModel): - # All UX2 Configuration items - Mega Model - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - version: VersionInfo = VersionInfo() - topology_groups: List[TransformedTopologyGroup] = Field(default_factory=list) - config_groups: List[TransformedConfigGroup] = Field(default_factory=list) - policy_groups: List[TransformedPolicyGroup] = Field(default_factory=list) - feature_profiles: List[TransformedFeatureProfile] = Field(default_factory=list) - profile_parcels: List[TransformedParcel] = Field(default_factory=list) - cloud_credentials: Optional[CloudCredentials] = Field(default=None) - thread_grid_api: Optional[ThreatGridApi] = Field(default=None) - cflowd: Optional[CflowdParcel] = None - - @model_validator(mode="before") - @classmethod - def insert_parcel_type_from_headers(cls, values: Dict[str, Any]): - if not isinstance(values, dict): - return values - profile_parcels = values.get("profileParcels", []) - if not profile_parcels: - profile_parcels = values.get("profile_parcels", []) - for profile_parcel in profile_parcels: - if not isinstance(profile_parcel, dict): - break - profile_parcel["parcel"]["type_"] = profile_parcel["header"]["type"] - return values - - def list_transformed_parcels_with_origin(self, origin: Set[UUID]) -> List[TransformedParcel]: - return [p for p in self.profile_parcels if p.header.origin in origin] - - def remove_transformed_parcels_with_origin(self, origin: Set[UUID]): - self.profile_parcels = [p for p in self.profile_parcels if p.header.origin not in origin] - - def add_subelement_in_config_group( - self, profile_types: List[ProfileType], device_template_id: UUID, subelement: UUID - ) -> bool: - profile_ids: Set[UUID] = set() - added = False - for config_group in self.config_groups: - if config_group.header.origin == device_template_id: - profile_ids = config_group.header.subelements - break - if not profile_ids: - return added - for feature_profile in self.feature_profiles: - if feature_profile.header.type in profile_types and feature_profile.header.origin in profile_ids: - head = feature_profile.header - if head.localized_policy_subelements is None: - head.localized_policy_subelements = {subelement} - else: - head.localized_policy_subelements.add(subelement) - added = True - return added - - def set_cloud_credentials_from_merged( - self, source_template: Optional[CloudCredentials] = None, source_policy: Optional[CloudCredentials] = None - ) -> None: - if source_template is None and source_policy is None: - self.cloud_credentials = None - elif source_template and source_policy: - cloud_credentials = source_template.model_copy(deep=True) - cloud_credentials.umbrella_sig_auth_key = source_policy.umbrella_sig_auth_key - cloud_credentials.umbrella_sig_auth_secret = source_policy.umbrella_sig_auth_secret - self.cloud_credentials = cloud_credentials - elif source_template: - self.cloud_credentials = source_template - else: - self.cloud_credentials = source_policy - - -class ConfigTransformResult(BaseModel): - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - uuid: UUID = Field(default_factory=uuid4) - ux2_config: UX2Config = Field(default_factory=UX2Config) - failed_items: List[FailedConversionItem] = Field(default_factory=list) - unsupported_items: List[UnsupportedConversionItem] = Field(default_factory=list) - - @property - def policy_object_parcel_maxlen(self) -> int: - return 32 - - @property - def suffix(self) -> str: - return f"_{str(self.uuid)[:5]}" - - def create_policy_object_parcel_name_lookup( - self, use_suffix: bool = False - ) -> Dict[str, List[AnyPolicyObjectParcel]]: - namelen = ( - self.policy_object_parcel_maxlen - len(self.suffix) - if use_suffix - else (self.policy_object_parcel_maxlen - 2) - ) - lookup: Dict[str, List[AnyPolicyObjectParcel]] = {} - # parcel rename only for policy groups-of-interest which share global profile - for profile_parcel in self.ux2_config.profile_parcels: - profile_parcel.header.origname = profile_parcel.parcel.parcel_name - if profile_parcel.header.type in [t._get_parcel_type() for t in list_types(AnyPolicyObjectParcel)]: - # build lookup by parcel name to find duplicates - # if suffix is added we need to take into consideration shortened names - parcel = cast(AnyPolicyObjectParcel, profile_parcel.parcel) - name = profile_parcel.header.origname[:namelen] - if not lookup.get(name): - lookup[name] = [parcel] - else: - lookup[name].append(parcel) - return lookup - - def add_suffix_to_names(self) -> None: - for config_group in self.ux2_config.config_groups: - config_group.header.origname = config_group.config_group.name - config_group.config_group.name += self.suffix - for topology_group in self.ux2_config.topology_groups: - topology_group.header.origname = topology_group.topology_group.name - topology_group.topology_group.name += self.suffix - for feature_profile in self.ux2_config.feature_profiles: - feature_profile.header.origname = feature_profile.feature_profile.name - feature_profile.feature_profile.name += self.suffix - - def resolve_conflicts_on_policy_object_parcel_names(self, use_suffix: bool = False) -> None: - # policy object parcel names are restricted to 32 characters and needs to be unique - # TODO: cleanup, also this works only for suffix len = 6 (eg. "_1afc9") - assert len(self.suffix) == 6 - for name, parcels in self.create_policy_object_parcel_name_lookup().items(): - maxlen = self.policy_object_parcel_maxlen - if use_suffix: - # dedicated conflict resolving when suffix is used (we increment suffix digit) - for i, parcel in enumerate(parcels): - if i > 0: - # replace last 3-digit of suffix (can handle 4096 duplicates) - suffix_num = int(self.suffix[1:], 16) + i - parcel.parcel_name = name[:-3] + hex(suffix_num)[-3:] - continue - # add suffix - if len(name) >= (maxlen - 6): - name = name[: maxlen - 7] - name = name + self.suffix - parcel.parcel_name = name - else: - for i, parcel in enumerate(parcels): - if i > 0: - suffix_str = f"_{hex(i)[-1]}" - if len(name) > (maxlen - 2): - parcel.parcel_name = name[:-2] + suffix_str - else: - parcel.parcel_name = name + suffix_str - - def add_failed_conversion_parcel( - self, - exception_message: str, - feature_template: Optional[FeatureTemplateInformation] = None, - policy: Optional[ - Union[ - CentralizedPolicyInfo, - LocalizedPolicyInfo, - AnySecurityPolicyInfo, - AnyPolicyDefinitionInfo, - AnyPolicyListInfo, - ] - ] = None, - ): - self.failed_items.append( - FailedConversionItem( - feature_template=feature_template, - policy=policy, - exception_message=exception_message, - ) - ) - - def add_unsupported_item(self, name: str, uuid: UUID, type: Optional[str] = None): - item = UnsupportedConversionItem( - name=name, - uuid=uuid, - type=type, - ) - self.unsupported_items.append(item) - - -GroupTypes = Literal["config", "topology", "policy", "base"] - - -class GroupReportBase(BaseModel): - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - type_: GroupTypes = Field(default="base", exclude=True) - name: str - uuid: UUID - feature_profiles: List[FeatureProfileBuildReport] = Field(default_factory=list) - - -class ConfigGroupReport(GroupReportBase): - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - type_: GroupTypes = Field(default="config", exclude=True) - - -class TopologyGroupReport(GroupReportBase): - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - type_: GroupTypes = Field(default="topology", exclude=True) - - -class PolicyGroupReport(GroupReportBase): - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - type_: GroupTypes = Field(default="policy", exclude=True) - - -class DefaultPolicyObjectProfileReport(BaseModel): - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - present_before_migration: Optional[bool] = None - created_by: Optional[str] = None - creation_failed: Optional[bool] = None - - -class GroupsOfInterestBuildReport(BaseModel): - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - default_policy_object_profile: DefaultPolicyObjectProfileReport = Field( - default_factory=DefaultPolicyObjectProfileReport - ) - created_parcels: List[Tuple[str, UUID]] = Field(default_factory=list) - failed_parcels: List[FailedParcel] = Field(default_factory=list) - - def add_created(self, name: str, id: UUID): - self.created_parcels.append((name, id)) - - def add_failed(self, parcel: AnyParcel, error: ManagerHTTPError): - failed_parcel = FailedParcel( - parcel_name=parcel.parcel_name, - parcel_type=parcel._get_parcel_type(), - error_info=error.info, - request_details=FailedRequestDetails.from_response(error.response), - ) - self.failed_parcels.append(failed_parcel) - - -class UX2ConfigPushReport(BaseModel): - model_config = ConfigDict(populate_by_name=True, extra="forbid", alias_generator=camel) - config_groups: List[ConfigGroupReport] = Field(default_factory=list) - policy_groups: List[PolicyGroupReport] = Field(default_factory=list) - topology_groups: List[TopologyGroupReport] = Field(default_factory=list) - standalone_feature_profiles: List[FeatureProfileBuildReport] = Field(default_factory=list) - groups_of_interest: GroupsOfInterestBuildReport = Field(default_factory=GroupsOfInterestBuildReport) - security_policies: List[FeatureProfileBuildReport] = Field(default_factory=list) - failed_push_parcels: List[FailedParcel] = Field(default_factory=list) - - @property - def groups(self) -> Sequence[GroupReportBase]: - groups: List[GroupReportBase] = list() - groups.extend(self.config_groups) - groups.extend(self.policy_groups) - groups.extend(self.topology_groups) - return groups - - def add_report(self, name: str, uuid: UUID, feature_profiles: List[FeatureProfileBuildReport]) -> None: - self.config_groups.append(ConfigGroupReport(name=name, uuid=uuid, feature_profiles=feature_profiles)) - - def add_pg_report(self, name: str, uuid: UUID, feature_profiles: List[FeatureProfileBuildReport]) -> None: - self.policy_groups.append(PolicyGroupReport(name=name, uuid=uuid, feature_profiles=feature_profiles)) - - def add_standalone_feature_profiles(self, feature_profiles: List[FeatureProfileBuildReport]) -> None: - """This happends when parent config group failes to create or profile don't have config group""" - self.standalone_feature_profiles.extend(feature_profiles) - - def get_standalone_feature_profiles_by_ids(self, uuids: Set[UUID]) -> List[FeatureProfileBuildReport]: - return [f for f in self.standalone_feature_profiles + self.security_policies if f.profile_uuid in uuids] - - def set_failed_push_parcels_flat_list(self): - for group in self.groups: - for feature_profile in group.feature_profiles: - for failed_parcel in feature_profile.failed_parcels: - self.failed_push_parcels.append(failed_parcel) - - for s_feature_profile in self.standalone_feature_profiles: - for failed_parcel in s_feature_profile.failed_parcels: - self.failed_push_parcels.append(failed_parcel) - - for failed_parcel in self.groups_of_interest.failed_parcels: - self.failed_push_parcels.append(failed_parcel) - - @property - def get_summary(self) -> str: - created_parcels = 0 - failed_parcels = 0 - - for group in self.groups: - for feature_profile in group.feature_profiles: - created_parcels += len(feature_profile.created_parcels) - failed_parcels += len(feature_profile.failed_parcels) - all_parcels = created_parcels + failed_parcels - success_rate_message = ( - f"{created_parcels}/{all_parcels} " - f"({int((created_parcels / all_parcels) * 100)}%)" - " parcels created successfully." - ) - return success_rate_message - - -class DefaultPolicyObjectProfile(BaseModel): - model_config = ConfigDict(populate_by_name=True) - profile_id: UUID - parcels: List[Tuple[UUID, str]] = Field(default_factory=list) - - def add_parcel(self, parcel_type: str, parcel_id: UUID): - self.parcels.append((parcel_id, parcel_type)) - - -class UX2RollbackInfo(BaseModel): - model_config = ConfigDict(populate_by_name=True, validate_assignment=True, alias_generator=camel) - config_group_ids: List[UUID] = Field(default_factory=list) - policy_group_ids: List[UUID] = Field(default_factory=list) - topology_group_ids: List[UUID] = Field(default_factory=list) - feature_profile_ids: List[Tuple[UUID, ProfileType]] = Field(default_factory=list) - default_policy_object_profile: Optional[DefaultPolicyObjectProfile] = Field( - default=None, - description="Do not delete this profile! only selected parcel contents for which profile id is provided", - ) - - def add_config_group(self, config_group_id: UUID) -> None: - self.config_group_ids.append(config_group_id) - - def add_feature_profile(self, feature_profile_id: UUID, profile_type: ProfileType) -> None: - self.feature_profile_ids.append((feature_profile_id, profile_type)) - - def add_default_policy_object_profile_id(self, profile_id: UUID) -> DefaultPolicyObjectProfile: - # do not delete this profile! only selected parcel contents - self.default_policy_object_profile = DefaultPolicyObjectProfile(profile_id=profile_id) - return self.default_policy_object_profile - - def add_policy_group(self, group_id: UUID) -> None: - self.policy_group_ids.append(group_id) - - def add_topology_group(self, topology_id: UUID) -> None: - self.topology_group_ids.append(topology_id) - - -class UX2ConfigPushResult(BaseModel): - model_config = ConfigDict(populate_by_name=True, alias_generator=camel) - rollback: UX2RollbackInfo = UX2RollbackInfo() - report: UX2ConfigPushReport = UX2ConfigPushReport() - - def set_groups_rollback(self): - for group in self.report.groups: - if group.type_ == "config": - self.rollback.add_config_group(group.uuid) - elif group.type_ == "policy": - self.rollback.add_policy_group(group.uuid) - elif group.type_ == "topology": - self.rollback.add_topology_group(group.uuid) - - -@dataclass -class SslProfileResidues: - filtered_url_black_list: List[URLBlockListInfo] - filtered_url_white_list: List[URLAllowListInfo] - - -@dataclass -class SslDecryptioneResidues: - sequences: List[NetworkDecryptionRuleSequence] - profiles: List[UrlProfile] - - -@dataclass -class SecurityPolicyResidues: - high_speed_logging_setting: Optional[Union[HighSpeedLoggingEntry, HighSpeedLoggingList]] - logging_setting: Optional[List[LoggingEntry]] = None - zone_to_no_zone_internet_setting: Optional[ZoneToNoZoneInternet] = None - platform_match_setting: Optional[str] = None - - -@dataclass -class QoSMapResidues: - buffer_percent: IntStr - burst: Optional[IntStr] = None - temp_key_values: Optional[str] = None - - -@dataclass -class PolicyConvertContext: - # conversion input - platform_version: Version = NullVersion() - region_map: Dict[str, int] = field(default_factory=dict) - site_map: Dict[str, int] = field(default_factory=dict) - lan_vpn_map: Dict[str, Union[int, str]] = field(default_factory=dict) - activated_centralized_policy_item_ids: Set[UUID] = field(default_factory=set) - # emited during conversion - regions_by_list_id: Dict[UUID, List[str]] = field(default_factory=dict) - sites_by_list_id: Dict[UUID, List[str]] = field(default_factory=dict) - lan_vpns_by_list_id: Dict[UUID, List[str]] = field(default_factory=dict) - amp_target_vpns_id: Dict[UUID, List[VpnId]] = field(default_factory=dict) - dns_security_umbrella_data: Dict[UUID, UUID] = field(default_factory=dict) - intrusion_prevention_target_vpns_id: Dict[UUID, List[VpnId]] = field(default_factory=dict) - ssl_decryption_residues: Dict[UUID, SslDecryptioneResidues] = field(default_factory=dict) - ssl_profile_residues: Dict[UUID, SslProfileResidues] = field(default_factory=dict) - url_filtering_target_vpns: Dict[UUID, List[VpnId]] = field(default_factory=dict) - zone_based_firewall_residues: Dict[UUID, List[ZoneBasedFWPolicyEntry]] = field(default_factory=dict) - security_policy_residues: Dict[UUID, SecurityPolicyResidues] = field(default_factory=dict) - qos_map_residues: Dict[UUID, List[QoSMapResidues]] = field(default_factory=dict) - as_path_list_num_mapping: Dict[str, int] = field(default_factory=dict) - threat_grid_api: Optional[ThreatGridApi] = None - cflowd: Optional[CflowdParcel] = None - cloud_credentials: Optional[CloudCredentials] = None - fwclass_id_by_name: Dict[str, UUID] = field(default_factory=dict) - - def get_vpn_id_to_vpn_name_map(self) -> Dict[Union[str, int], List[str]]: - vpn_map: Dict[Union[str, int], List[str]] = {} - for k, v in self.lan_vpn_map.items(): - vpn_map[v] = vpn_map.get(v, []) - vpn_map[v].append(k) - return vpn_map - - def generate_as_path_list_num_from_name(self, name: str) -> int: - """The UX1 and UX2 intersection in AS Path list name and ID but only for the ISR Edge router (number 1 to 500). - If there is number we can insert the value in as_path_list_num field otherwise we will - generate the value and keep track of it in the context.""" - number = len(self.as_path_list_num_mapping) + 1 - self.as_path_list_num_mapping[name] = number - return number - - @staticmethod - def from_configs( - network_hierarchy: List[NodeInfo], - transformed_parcels: List[TransformedParcel], - platform_version: Version, - ) -> "PolicyConvertContext": - context = PolicyConvertContext(platform_version=platform_version) - for node in network_hierarchy: - if node.data.hierarchy_id is not None: - if node.data.label == "SITE" and node.data.hierarchy_id.site_id is not None: - context.site_map[node.name] = node.data.hierarchy_id.site_id - if node.data.label == "REGION" and node.data.hierarchy_id.region_id is not None: - context.region_map[node.name] = node.data.hierarchy_id.region_id - for parcel in [p.parcel for p in transformed_parcels]: - if isinstance(parcel, LanVpnParcel): - if parcel.vpn_id.value is not None: - context.lan_vpn_map[parcel.parcel_name] = parcel.vpn_id.value - - return context - - def populate_activated_centralized_policy_item_ids(self, centralized_policies: List[CentralizedPolicyInfo]) -> None: - """For Cflowd - only convert and push the active policy""" - active_policy = next((policy for policy in centralized_policies if policy.is_policy_activated), None) - if active_policy is None or isinstance(active_policy.policy_definition, str): - return - self.activated_centralized_policy_item_ids = set( - [a.definition_id for a in active_policy.policy_definition.assembly] - ) - - def find_any_service_vpn(self) -> List[str]: - vpns: List[str] = list() - for vpn_list in self.lan_vpns_by_list_id.values(): - vpns.extend(vpn_list) # all of these could be empty - return vpns[:1] - - -@dataclass -class PushContext: - default_policy_object_profile_id: Optional[UUID] = None - id_lookup: Dict[UUID, UUID] = field( - default_factory=dict - ) # universal lookup for finding pushed item id by origin id - policy_group_feature_profiles_id_lookup: Dict[UUID, UUID] = field(default_factory=dict) - - -@dataclass -class ConvertResult(Generic[TO]): - status: ConvertStatus = "complete" - output: Optional[TO] = None - info: List[str] = field(default_factory=list) - - def update_status(self, status: ConvertStatus, message: str): - self.status = status - self.info.append(message) - - def get_info(self) -> str: - return "\n".join(self.info) diff --git a/catalystwan/models/configuration/feature_profile/common.py b/catalystwan/models/configuration/feature_profile/common.py index b8dddca0..c050af63 100644 --- a/catalystwan/models/configuration/feature_profile/common.py +++ b/catalystwan/models/configuration/feature_profile/common.py @@ -115,8 +115,8 @@ class FeatureProfileCreationResponse(BaseModel): class AddressWithMask(BaseModel): - address: Union[Variable, Global[str], Global[IPv4Address], Global[IPv6Address]] - mask: Union[Variable, Global[str], Global[SubnetMask]] + address: Union[Variable, Global[IPv4Address], Global[IPv6Address]] + mask: Union[Variable, Global[SubnetMask]] class SchemaTypeQuery(BaseModel): @@ -141,12 +141,12 @@ class DNSIPv4(BaseModel): extra="forbid", populate_by_name=True, ) - primary_dns_address_ipv4: Union[Default[None], Global[str], Global[IPv4Address], Variable] = Field( + primary_dns_address_ipv4: Union[Default[None], Global[IPv4Address], Variable] = Field( default=Default[None](value=None), serialization_alias="primaryDnsAddressIpv4", validation_alias="primaryDnsAddressIpv4", ) - secondary_dns_address_ipv4: Optional[Union[Default[None], Global[str], Global[IPv4Address], Variable]] = Field( + secondary_dns_address_ipv4: Optional[Union[Default[None], Global[IPv4Address], Variable]] = Field( default=None, serialization_alias="secondaryDnsAddressIpv4", validation_alias="secondaryDnsAddressIpv4", @@ -158,12 +158,12 @@ class DNSIPv6(BaseModel): extra="forbid", populate_by_name=True, ) - primary_dns_address_ipv6: Union[Default[None], Global[str], Global[IPv6Address], Variable] = Field( + primary_dns_address_ipv6: Union[Default[None], Global[IPv6Address], Variable] = Field( default=Default[None](value=None), serialization_alias="primaryDnsAddressIpv6", validation_alias="primaryDnsAddressIpv6", ) - secondary_dns_address_ipv6: Optional[Union[Default[None], Global[str], Global[IPv6Address], Variable]] = Field( + secondary_dns_address_ipv6: Optional[Union[Default[None], Global[IPv6Address], Variable]] = Field( default=None, serialization_alias="secondaryDnsAddressIpv6", validation_alias="secondaryDnsAddressIpv6", @@ -518,7 +518,7 @@ class AllowService(BaseModel): class Arp(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid") - ip_address: Union[Variable, Global[str], Global[IPv4Address], Default[None]] = Field( + ip_address: Union[Variable, Global[IPv4Address], Default[None]] = Field( serialization_alias="ipAddress", validation_alias="ipAddress", default=Default[None](value=None) ) mac_address: Union[Global[str], Variable] = Field(serialization_alias="macAddress", validation_alias="macAddress") @@ -542,11 +542,9 @@ class EthernetNatPool(BaseModel): class StaticNat(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid") - source_ip: Union[Global[str], Global[IPv4Address], Variable] = Field( - serialization_alias="sourceIp", validation_alias="sourceIp" - ) + source_ip: Union[Global[IPv4Address], Variable] = Field(serialization_alias="sourceIp", validation_alias="sourceIp") - translate_ip: Union[Global[str], Global[IPv4Address], Variable] = Field( + translate_ip: Union[Global[IPv4Address], Variable] = Field( serialization_alias="translateIp", validation_alias="translateIp" ) static_nat_direction: Union[Global[EthernetDirection], Default[EthernetDirection]] = Field( diff --git a/catalystwan/models/configuration/feature_profile/parcel.py b/catalystwan/models/configuration/feature_profile/parcel.py index ed6f4224..c30982b1 100644 --- a/catalystwan/models/configuration/feature_profile/parcel.py +++ b/catalystwan/models/configuration/feature_profile/parcel.py @@ -25,6 +25,7 @@ "aaa", "app-list", "app-probe", + "wan/vpn/interface/ipsec", "appqoe", "as-path", "banner", @@ -70,6 +71,7 @@ "preferred-color-group", "prefix", "qos-policy", + "route-policy", "routing/bgp", "routing/eigrp", "routing/multicast", @@ -93,6 +95,7 @@ "snmp", "standard-community", "switchport", + "t1-e1-controller", "tloc", "tracker", "trackergroup", diff --git a/catalystwan/models/configuration/feature_profile/sdwan/routing/bgp.py b/catalystwan/models/configuration/feature_profile/sdwan/routing/bgp.py index 806945f2..5851599e 100644 --- a/catalystwan/models/configuration/feature_profile/sdwan/routing/bgp.py +++ b/catalystwan/models/configuration/feature_profile/sdwan/routing/bgp.py @@ -407,9 +407,7 @@ class Ipv6AggregateAddres(BaseModel): extra="forbid", populate_by_name=True, ) - prefix: Union[Global[str], Global[IPv6Interface], Variable] = Field( - ..., description="Configure the IPv6 prefixes to aggregate" - ) + prefix: Union[Global[IPv6Interface], Variable] = Field(..., description="Configure the IPv6 prefixes to aggregate") as_set: Optional[Union[Variable, Global[bool], Default[Literal[False]]]] = Field( default=None, serialization_alias="asSet", validation_alias="asSet", description="Set AS set path information" ) @@ -426,7 +424,7 @@ class Ipv6NetworkItem(BaseModel): extra="forbid", populate_by_name=True, ) - prefix: Union[Global[str], Global[IPv6Interface], Variable] = Field( + prefix: Union[Global[IPv6Interface], Variable] = Field( ..., description="Configure the prefixes for BGP to announce" ) diff --git a/catalystwan/models/configuration/feature_profile/sdwan/service/__init__.py b/catalystwan/models/configuration/feature_profile/sdwan/service/__init__.py index 0a802167..646c0cfe 100644 --- a/catalystwan/models/configuration/feature_profile/sdwan/service/__init__.py +++ b/catalystwan/models/configuration/feature_profile/sdwan/service/__init__.py @@ -4,6 +4,8 @@ from pydantic import Field from typing_extensions import Annotated +from catalystwan.models.configuration.feature_profile.sdwan.routing import AnyRoutingParcel + from ..acl import AnyAclParcel from .appqoe import AppqoeParcel from .dhcp_server import LanVpnDhcpServerParcel @@ -56,7 +58,7 @@ ] AnyServiceParcel = Annotated[ - Union[AnyAclParcel, AnyTopLevelServiceParcel, AnyLanVpnInterfaceParcel], + Union[AnyAclParcel, AnyTopLevelServiceParcel, AnyLanVpnInterfaceParcel, AnyRoutingParcel], Field(discriminator="type_"), ] diff --git a/catalystwan/models/configuration/feature_profile/sdwan/service/dhcp_server.py b/catalystwan/models/configuration/feature_profile/sdwan/service/dhcp_server.py index c045ee4e..c5f014fa 100644 --- a/catalystwan/models/configuration/feature_profile/sdwan/service/dhcp_server.py +++ b/catalystwan/models/configuration/feature_profile/sdwan/service/dhcp_server.py @@ -89,7 +89,7 @@ class LanVpnDhcpServerParcel(_ParcelBase): validation_alias=AliasPath("data", "exclude"), description="Configure IPv4 address to exclude from DHCP address pool", ) - lease_time: Union[Global[int], Variable, Default[int]] = Field( + lease_time: Union[Default[int], Global[int], Variable] = Field( default=Default[int](value=86400), validation_alias=AliasPath("data", "leaseTime"), description="Configure how long a DHCP-assigned IP address is valid", diff --git a/catalystwan/models/configuration/feature_profile/sdwan/service/lan/gre.py b/catalystwan/models/configuration/feature_profile/sdwan/service/lan/gre.py index a46b926a..dabf833b 100644 --- a/catalystwan/models/configuration/feature_profile/sdwan/service/lan/gre.py +++ b/catalystwan/models/configuration/feature_profile/sdwan/service/lan/gre.py @@ -55,10 +55,10 @@ class BasicGre(BaseModel): tunnel_source_type: Optional[Union[TunnelSourceType, GreSourceIPv6]] = Field( serialization_alias="tunnelSourceType", validation_alias="tunnelSourceType", default=None ) - tunnel_destination: Union[Global[str], Global[IPv4Address], Variable] = Field( + tunnel_destination: Union[Global[IPv4Address], Variable] = Field( serialization_alias="tunnelDestination", validation_alias="tunnelDestination" ) - tunnel_destination_v6: Optional[Union[Global[str], Global[IPv6Address], Variable]] = Field( + tunnel_destination_v6: Optional[Union[Global[IPv6Address], Variable]] = Field( default=None, serialization_alias="tunnelDestinationV6", validation_alias="tunnelDestinationV6" ) mtu: Optional[Union[Global[int], Variable, Default[int]]] = Default[int](value=1500) diff --git a/catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py b/catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py index 3e45606f..95f970ca 100644 --- a/catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py +++ b/catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py @@ -351,7 +351,7 @@ class ServiceRoute(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True) prefix: RoutePrefix - service: Union[Variable, Global[ServiceRouteType], Default[ServiceRouteType]] = Default[ServiceRouteType]( + service: Union[Default[ServiceRouteType], Variable, Global[ServiceRouteType]] = Default[ServiceRouteType]( value="SIG" ) vpn: Global[int] = Global[int](value=0) diff --git a/catalystwan/models/configuration/feature_profile/sdwan/transport/vpn.py b/catalystwan/models/configuration/feature_profile/sdwan/transport/vpn.py index 714a74c7..8aeb5453 100644 --- a/catalystwan/models/configuration/feature_profile/sdwan/transport/vpn.py +++ b/catalystwan/models/configuration/feature_profile/sdwan/transport/vpn.py @@ -40,7 +40,7 @@ class NextHopItem(BaseModel): extra="forbid", populate_by_name=True, ) - address: Union[Variable, Global[IPv4Address], Global[str]] = Field(..., description="Variable") + address: Union[Variable, Global[IPv4Address]] = Field(..., description="Variable") distance: Union[Variable, Global[int], Default[int]] = Field(as_default(1), description="Administrative distance") diff --git a/catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/cellular.py b/catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/cellular.py index 349a0fea..19b06f0e 100644 --- a/catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/cellular.py +++ b/catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/cellular.py @@ -1,7 +1,6 @@ # Copyright 2024 Cisco Systems, Inc. and its affiliates from __future__ import annotations -from ipaddress import IPv4Address from typing import List, Literal, Optional, Union from pydantic import AliasPath, BaseModel, ConfigDict, Field @@ -11,6 +10,7 @@ from catalystwan.models.configuration.feature_profile.common import ( AclQos, AllowService, + Arp, Encapsulation, MultiRegionFabric, ) @@ -85,19 +85,6 @@ class NatAttributesIpv4(BaseModel): ) -class Arp(BaseModel): - model_config = ConfigDict( - extra="forbid", - populate_by_name=True, - ) - ip_address: Union[Global[str], Global[IPv4Address], Default[None], Variable] = Field( - default=as_default(None), validation_alias="ipAddress", serialization_alias="ipAddress" - ) - mac_address: Union[Global[str], Default[None], Variable] = Field( - default=as_default(None), validation_alias="macAddress", serialization_alias="macAddress" - ) - - class Advanced(BaseModel): model_config = ConfigDict( extra="forbid", diff --git a/catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/t1e1serial.py b/catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/t1e1serial.py index c9441016..9403934b 100644 --- a/catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/t1e1serial.py +++ b/catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/t1e1serial.py @@ -129,7 +129,7 @@ class T1E1SerialParcel(_ParcelBase): extra="forbid", populate_by_name=True, ) - type_: Literal["interface/serial"] = Field(default="interface/serial", exclude=True) + type_: Literal["wan/vpn/interface/serial"] = Field(default="wan/vpn/interface/serial", exclude=True) interface_name: Union[Global[str], Variable] = Field(validation_alias=AliasPath("data", "interfaceName")) acl_qos: Optional[AclQos] = Field( default=None, diff --git a/pyproject.toml b/pyproject.toml index 07c42fb1..f09aa4ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "catalystwan" -version = "0.35.4dev1" +version = "0.35.4dev2" description = "Cisco Catalyst WAN SDK for Python" authors = ["kagorski "] readme = "README.md"