From 4844e843eba0c083b3cdc9ff013aec8b61b57eac Mon Sep 17 00:00:00 2001 From: ravindra-h <127876293+ravindra-h@users.noreply.github.com> Date: Tue, 19 Sep 2023 17:45:09 +0530 Subject: [PATCH 1/5] Policy: Added new class for creation of centralized policy lists and vSmart policy (#222) * Policy: Added new class for creation of centralized policy with following API support - Create, get all, get details, delete -- Data prefix list -- Site list -- VPN list -- Data / traffic policy - Create, activate, deactivate -- vSmart policy -- vSmart CLI policy * define common models for policy list builder endpoints * add: dataprefix policy list builder endpoints * update: ENDPOINTS.md after rebase * add: site policy list builder endpoints * add validation of name field, description is optional * add: vpn policy list builder endpoints * remove reused fields in policy_list common model * wip: data policy definition builder endpoints * add: traffic-policy model (Sequence can be reused) * update: data policy definition builder endpoints and models * fix: ipPrefix is IPv4 only * fix validators * fix: request decorator was not using default arguments values * add: vsmart template (centralized) policy endpoints * remove: policy list api prototype --------- Co-authored-by: sbasan --- ENDPOINTS.md | 44 + vmngclient/endpoints/__init__.py | 6 +- ...guration_policy_data_definition_builder.py | 262 +++++ ...uration_policy_data_prefix_list_builder.py | 92 ++ .../configuration_policy_site_list_builder.py | 87 ++ .../configuration_policy_vpn_list_builder.py | 95 ++ .../configuration_vsmart_template_policy.py | 118 +++ vmngclient/endpoints/endpoints_container.py | 10 + vmngclient/model/policy.py | 42 + vmngclient/model/policy_definition.py | 47 + vmngclient/model/policy_list.py | 40 + .../model/profileparcel/traffic_policy.py | 938 ++++++++++++++++++ vmngclient/tests/test_endpoints.py | 51 + 13 files changed, 1831 insertions(+), 1 deletion(-) create mode 100644 vmngclient/endpoints/configuration_policy_data_definition_builder.py create mode 100644 vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py create mode 100644 vmngclient/endpoints/configuration_policy_site_list_builder.py create mode 100644 vmngclient/endpoints/configuration_policy_vpn_list_builder.py create mode 100644 vmngclient/endpoints/configuration_vsmart_template_policy.py create mode 100644 vmngclient/model/policy.py create mode 100644 vmngclient/model/policy_definition.py create mode 100644 vmngclient/model/policy_list.py create mode 100644 vmngclient/model/profileparcel/traffic_policy.py diff --git a/ENDPOINTS.md b/ENDPOINTS.md index 1cefd5d1a..e4cbf5e04 100644 --- a/ENDPOINTS.md +++ b/ENDPOINTS.md @@ -45,6 +45,41 @@ PUT /v1/feature-profile/sdwan/system/{system_id}/aaa/{parcel_id}|>=20.9|[**Confi POST /v1/config-group|>=20.9|[**ConfigurationGroup.create_config_group**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_group.py#L49)|[**ConfigGroupCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_group.py#L21)|[**ConfigGroupCreationResponse**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_group.py#L35)| DELETE /v1/config-group/{config_group_id}|>=20.9|[**ConfigurationGroup.delete_config_group**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_group.py#L54)||None| PUT /v1/config-group/{config_group_id}|>=20.9|[**ConfigurationGroup.edit_config_group**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_group.py#L59)|[**ConfigGroupEditPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_group.py#L28)|[**ConfigGroupEditResponse**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_group.py#L43)| +POST /template/policy/definition/data||[**ConfigurationPolicyDataDefinitionBuilder.create_policy_definition**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L228)|[**DataDefinitionCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L215)|[**PolicyDefinitionId**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_definition.py#L11)| +DELETE /template/policy/definition/data/{id}||[**ConfigurationPolicyDataDefinitionBuilder.delete_policy_definition**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L232)||None| +PUT /template/policy/definition/data/{id}||[**ConfigurationPolicyDataDefinitionBuilder.edit_policy_definition**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L240)|[**DataDefinitionEditPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L219)|[**PolicyDefinitionEditResponse**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_definition.py#L33)| +GET /template/policy/definition/data||[**ConfigurationPolicyDataDefinitionBuilder.get_definitions**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L244)||DataSequence[[**PolicyDefinition**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_definition.py#L37)]| +GET /template/policy/definition/data/{id}||[**ConfigurationPolicyDataDefinitionBuilder.get_policy_definition**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L248)||[**DataDefinition**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L223)| +POST /template/policy/definition/data/preview||[**ConfigurationPolicyDataDefinitionBuilder.preview_policy_definition**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L252)|[**DataDefinitionCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L215)|[**PolicyDefinitionPreview**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_definition.py#L46)| +GET /template/policy/definition/data/preview/{id}||[**ConfigurationPolicyDataDefinitionBuilder.preview_policy_definition_by_id**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_definition_builder.py#L256)||[**PolicyDefinitionPreview**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_definition.py#L46)| +POST /template/policy/list/dataprefix||[**ConfigurationPolicyDataPrefixListBuilder.create_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L51)|[**DataPrefixListCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L38)|[**PolicyListId**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L11)| +DELETE /template/policy/list/dataprefix/{id}||[**ConfigurationPolicyDataPrefixListBuilder.delete_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L55)||None| +DELETE /template/policy/list/dataprefix||[**ConfigurationPolicyDataPrefixListBuilder.delete_policy_lists_with_info_tag**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L59)||None| +PUT /template/policy/list/dataprefix/{id}||[**ConfigurationPolicyDataPrefixListBuilder.edit_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L66)|[**DataPrefixListEditPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L42)|None| +GET /template/policy/list/dataprefix/{id}||[**ConfigurationPolicyDataPrefixListBuilder.get_lists_by_id**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L70)||[**DataPrefixList**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L46)| +GET /template/policy/list/dataprefix||[**ConfigurationPolicyDataPrefixListBuilder.get_policy_lists**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L74)||DataSequence[[**DataPrefixList**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L46)]| +GET /template/policy/list/dataprefix/filtered||[**ConfigurationPolicyDataPrefixListBuilder.get_policy_lists_with_info_tag**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L78)||DataSequence[[**DataPrefixList**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L46)]| +POST /template/policy/list/dataprefix/preview||[**ConfigurationPolicyDataPrefixListBuilder.preview_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L85)|[**DataPrefixListCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L38)|[**PolicyListPreview**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L39)| +GET /template/policy/list/dataprefix/preview/{id}||[**ConfigurationPolicyDataPrefixListBuilder.preview_policy_list_by_id**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py#L90)||[**PolicyListPreview**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L39)| +POST /template/policy/list/site/defaultsite||[**ConfigurationPolicySiteListBuilder.create_default_site_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L43)|[**SiteListCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L30)|[**PolicyListId**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L11)| +POST /template/policy/list/site||[**ConfigurationPolicySiteListBuilder.create_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L47)|[**SiteListCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L30)|[**PolicyListId**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L11)| +DELETE /template/policy/list/site/{id}||[**ConfigurationPolicySiteListBuilder.delete_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L51)||None| +DELETE /template/policy/list/site||[**ConfigurationPolicySiteListBuilder.delete_policy_lists_with_info_tag**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L55)||None| +PUT /template/policy/list/site/{id}||[**ConfigurationPolicySiteListBuilder.edit_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L62)|[**SiteListEditPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L34)|None| +GET /template/policy/list/site/{id}||[**ConfigurationPolicySiteListBuilder.get_lists_by_id**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L66)||[**SiteList**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L38)| +GET /template/policy/list/site||[**ConfigurationPolicySiteListBuilder.get_policy_lists**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L70)||DataSequence[[**SiteList**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L38)]| +GET /template/policy/list/site/filtered||[**ConfigurationPolicySiteListBuilder.get_policy_lists_with_info_tag**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L74)||DataSequence[[**SiteList**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L38)]| +POST /template/policy/list/site/preview||[**ConfigurationPolicySiteListBuilder.preview_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L81)|[**SiteListCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L30)|[**PolicyListPreview**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L39)| +GET /template/policy/list/site/preview/{id}||[**ConfigurationPolicySiteListBuilder.preview_policy_list_by_id**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_site_list_builder.py#L85)||[**PolicyListPreview**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L39)| +POST /template/policy/list/vpn||[**ConfigurationPolicyVPNListBuilder.create_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L55)|[**VPNListCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L42)|[**PolicyListId**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L11)| +DELETE /template/policy/list/vpn/{id}||[**ConfigurationPolicyVPNListBuilder.delete_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L59)||None| +DELETE /template/policy/list/vpn||[**ConfigurationPolicyVPNListBuilder.delete_policy_lists_with_info_tag**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L63)||None| +PUT /template/policy/list/vpn/{id}||[**ConfigurationPolicyVPNListBuilder.edit_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L70)|[**VPNListEditPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L46)|None| +GET /template/policy/list/vpn/{id}||[**ConfigurationPolicyVPNListBuilder.get_lists_by_id**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L74)||[**VPNList**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L50)| +GET /template/policy/list/vpn||[**ConfigurationPolicyVPNListBuilder.get_policy_lists**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L78)||DataSequence[[**VPNList**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L50)]| +GET /template/policy/list/vpn/filtered||[**ConfigurationPolicyVPNListBuilder.get_policy_lists_with_info_tag**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L82)||DataSequence[[**VPNList**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L50)]| +POST /template/policy/list/vpn/preview||[**ConfigurationPolicyVPNListBuilder.preview_policy_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L89)|[**VPNListCreationPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L42)|[**PolicyListPreview**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L39)| +GET /template/policy/list/vpn/preview/{id}||[**ConfigurationPolicyVPNListBuilder.preview_policy_list_by_id**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_policy_vpn_list_builder.py#L93)||[**PolicyListPreview**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy_list.py#L39)| GET /settings/configuration/{setting_type}||[**ConfigurationSettings.get_configuration_by_setting_type**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L208)||dict| GET /settings/configuration/organization||[**ConfigurationSettings.get_organizations**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L212)||DataSequence[[**Organization**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L29)]| GET /settings/configuration/device||[**ConfigurationSettings.get_devices**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L216)||DataSequence[[**Device**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L35)]| @@ -77,6 +112,15 @@ GET /settings/configuration/smartaccountcredentials||[**ConfigurationSettings.ge GET /settings/configuration/pnpConnectSync||[**ConfigurationSettings.get_pnp_connect_sync**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L324)||DataSequence[[**PnPConnectSync**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L174)]| GET /settings/configuration/claimDevice||[**ConfigurationSettings.get_claim_device**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L328)||DataSequence[[**ClaimDevice**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L178)]| GET /settings/configuration/walkme||[**ConfigurationSettings.get_walkme**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L332)||DataSequence[[**WalkMe**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_settings.py#L182)]| +POST /template/policy/vsmart/activate/{id}||[**ConfigurationVSmartTemplatePolicy.activate_policy**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L72)|None|[**ActivateDeactivateTaskId**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L67)| +GET /template/policy/vsmart/connectivity/status||[**ConfigurationVSmartTemplatePolicy.check_vsmart_connectivity_status**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L82)||DataSequence[[**VSmartConnectivityStatus**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L55)]| +POST /template/policy/vsmart||[**ConfigurationVSmartTemplatePolicy.create_vsmart_template**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L86)|[**VSmartTemplate**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L33)|[**PolicyId**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/model/policy.py#L7)| +POST /template/policy/vsmart/deactivate/{id}||[**ConfigurationVSmartTemplatePolicy.deactivate_policy**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L90)|None|[**ActivateDeactivateTaskId**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L67)| +DELETE /template/policy/vsmart/{id}||[**ConfigurationVSmartTemplatePolicy.delete_vsmart_template**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L96)||None| +PUT /template/policy/vsmart/central/{id}||[**ConfigurationVSmartTemplatePolicy.edit_template_without_lock_checks**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L100)|[**VSmartTemplateEditPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L46)|None| +PUT /template/policy/vsmart/{id}||[**ConfigurationVSmartTemplatePolicy.edit_vsmart_template**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L104)|[**VSmartTemplateEditPayload**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L46)|None| +GET /template/policy/vsmart||[**ConfigurationVSmartTemplatePolicy.generate_vsmart_policy_template_list**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L108)||DataSequence[[**VSmartTemplateInfo**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L51)]| +GET /template/policy/vsmart/definition/{id}||[**ConfigurationVSmartTemplatePolicy.get_template_by_policy_id**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L112)||[**VSmartTemplate**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/configuration_vsmart_template_policy.py#L33)| GET /device/tier||[**MonitoringDeviceDetails.get_tiers**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/monitoring_device_details.py#L116)||DataSequence[[**Tier**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/monitoring_device_details.py#L15)]| GET /statistics/settings/status||[**MonitoringStatus.get_statistics_settings**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/monitoring_status.py#L32)||DataSequence[[**Status**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/monitoring_status.py#L17)]| GET /sdavc/cloudconnector||[**SDAVCCloudConnector.get_cloud_connector**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/sdavc_cloud_connector.py#L28)||[**CloudConnector**](https://github.com/CiscoDevNet/vManage-client/blob/main/vmngclient/endpoints/sdavc_cloud_connector.py#L10)| diff --git a/vmngclient/endpoints/__init__.py b/vmngclient/endpoints/__init__.py index ca8411760..8fe554b78 100644 --- a/vmngclient/endpoints/__init__.py +++ b/vmngclient/endpoints/__init__.py @@ -519,7 +519,8 @@ def merge_args(self, positional_args: Tuple, keyword_args: Dict[str, Any]) -> Di Returns: Dict[str, Any]: all passed args as keyword arguments (excluding "self") """ all_args_names = [key for key in self.sig.parameters.keys()] - all_args_dict = dict(zip(all_args_names, positional_args)) + all_args_dict = dict(self.defaults) + all_args_dict.update(dict(zip(all_args_names, positional_args))) all_args_dict.update(keyword_args) all_args_dict.pop("self", None) return all_args_dict @@ -527,6 +528,9 @@ def merge_args(self, positional_args: Tuple, keyword_args: Dict[str, Any]) -> Di def __call__(self, func): original_func = getattr(func, "_ofunc", func) # grab original function self.sig = signature(original_func) + self.defaults = { + key: value.default for (key, value) in self.sig.parameters.items() if value.default is not _empty + } self.return_spec = self.specify_return_type() self.payload_spec = self.specify_payload_type() self.check_params() diff --git a/vmngclient/endpoints/configuration_policy_data_definition_builder.py b/vmngclient/endpoints/configuration_policy_data_definition_builder.py new file mode 100644 index 000000000..92d75fc12 --- /dev/null +++ b/vmngclient/endpoints/configuration_policy_data_definition_builder.py @@ -0,0 +1,262 @@ +# mypy: disable-error-code="empty-body" +from enum import Enum +from typing import Any, List, Optional, Union + +from pydantic import BaseModel, Field, IPvAnyNetwork +from typing_extensions import Annotated, Literal + +from vmngclient.endpoints import APIEndpoints, delete, get, post, put +from vmngclient.model.policy_definition import ( + PolicyDefinition, + PolicyDefinitionCreationPayload, + PolicyDefinitionEditPayload, + PolicyDefinitionEditResponse, + PolicyDefinitionId, + PolicyDefinitionPreview, +) +from vmngclient.typed_list import DataSequence + +# TODO: add validators for custom strings (eg.: port ranges, space separated networks) +# TODO: model actions + + +class DefaultActionType(str, Enum): + DROP = "drop" + ACCEPT = "accept" + + +class PLPEntryValues(str, Enum): + LOW = "low" + HIGH = "high" + + +class DNSEntryValues(str, Enum): + REQUEST = "request" + RESPONSE = "response" + + +class TrafficToEntryValues(str, Enum): + ACCESS = "access" + CORE = "core" + SERVICE = "service" + + +class DestinationRegionEntryValues(str, Enum): + PRIMARY = "primary-region" + SECONDARY = "secondary-region" + OTHER = "other-region" + + +class SequenceIpType(str, Enum): + IPV4 = "ipv4" + IPV6 = "ipv6" + ALL = "all" + + +class BaseAction(str, Enum): + DROP = "drop" + ACCEPT = "accept" + + +class SequenceType(str, Enum): + APPLICATION_FIREWALL = "applicationFirewall" + DATA = "data" + SERVICE_CHAINING = "serviceChaining" + TRAFFIC_ENGINEERING = "trafficEngineering" + QOS = "qos" + + +class PacketLengthEntry(BaseModel): + field: Literal["packetLength"] + value: str = Field(description="0-65536 range or single number") + + +class PLPEntry(BaseModel): + field: Literal["plp"] + value: PLPEntryValues + + +class ProtocolEntry(BaseModel): + field: Literal["protocol"] + value: str = Field(description="0-255 single numbers separate by space") + + +class DSCPEntry(BaseModel): + field: Literal["dscp"] + value: str = Field(description="0-63 single numbers separate by space") + + +class SourceIPEntry(BaseModel): + field: Literal["sourceIp"] + value: str = Field(description="IP network specifier separate by space") + + +class SourcePortEntry(BaseModel): + field: Literal["sourcePort"] + value: str = Field(description="0-65535 range or separate by space") + + +class DestinationIPEntry(BaseModel): + field: Literal["destinationIp"] + value: IPvAnyNetwork + + +class DestinationPortEntry(BaseModel): + field: Literal["destinationPort"] + value: str = Field(description="0-65535 range or separate by space") + + +class TCPEntry(BaseModel): + field: Literal["tcp"] + value: Literal["syn"] + + +class DNSEntry(BaseModel): + field: Literal["dns"] + value: DNSEntryValues + + +class TrafficToEntry(BaseModel): + field: Literal["trafficTo"] + value: TrafficToEntryValues + + +class DestinationRegionEntry(BaseModel): + field: Literal["destinationRegion"] + value: DestinationRegionEntryValues + + +class SourceDataPrefixListEntry(BaseModel): + field: Literal["sourceDataPrefixList"] + ref: str + + +class DestinationDataPrefixListEntry(BaseModel): + field: Literal["destinationDataPrefixList"] + ref: str + + +class SourceDataIPv6PrefixListEntry(BaseModel): + field: Literal["sourceDataIpv6PrefixList"] + ref: str + + +class DestinationDataIPv6PrefixListEntry(BaseModel): + field: Literal["destinationDataIpv6PrefixList"] + ref: str + + +class DNSAppListEntry(BaseModel): + field: Literal["dnsAppList"] + ref: str + + +class AppListEntry(BaseModel): + field: Literal["appList"] + ref: str + + +Entry = Annotated[ + Union[ + PacketLengthEntry, + PLPEntry, + ProtocolEntry, + DSCPEntry, + SourceIPEntry, + SourcePortEntry, + DestinationIPEntry, + DestinationPortEntry, + TCPEntry, + DNSEntry, + TrafficToEntry, + SourceDataPrefixListEntry, + DestinationDataPrefixListEntry, + SourceDataIPv6PrefixListEntry, + DestinationDataIPv6PrefixListEntry, + DestinationRegionEntry, + DNSAppListEntry, + AppListEntry, + ], + Field(discriminator="field"), +] + + +class Match(BaseModel): + entries: List[Entry] + + +class Action(BaseModel): + pass + + +class Sequence(BaseModel): + sequence_id: int = Field(alias="sequenceId") + sequence_name: str = Field(alias="sequenceName") + base_action: BaseAction = Field(alias="baseAction") + sequence_type: SequenceType = Field(alias="sequenceType") + sequence_ip_type: SequenceIpType = Field(alias="sequenceIpType") + match: Match + actions: List[Any] + + +class DefaultAction(BaseModel): + type: DefaultActionType + + +class Data(BaseModel): + type: str = Field(default="data", const=True) + default_action: Optional[DefaultAction] = Field( + default=DefaultAction(type=DefaultActionType.DROP), alias="defaultAction" + ) + is_activated_by_vsmart: Optional[bool] = Field(default=False, alias="isActivatedByVsmart") + sequences: List[Sequence] = [] + + +class DataDefinitionCreationPayload(Data, PolicyDefinitionCreationPayload): + pass + + +class DataDefinitionEditPayload(Data, PolicyDefinitionEditPayload): + pass + + +class DataDefinition(Data, PolicyDefinition): + pass + + +class ConfigurationPolicyDataDefinitionBuilder(APIEndpoints): + @post("/template/policy/definition/data") + def create_policy_definition(self, payload: DataDefinitionCreationPayload) -> PolicyDefinitionId: + ... + + @delete("/template/policy/definition/data/{id}") + def delete_policy_definition(self, id: str) -> None: + ... + + def edit_multiple_policy_definition(self): + # PUT /template/policy/definition/data/multiple/{id} + ... + + @put("/template/policy/definition/data/{id}") + def edit_policy_definition(self, id: str, payload: DataDefinitionEditPayload) -> PolicyDefinitionEditResponse: + ... + + @get("/template/policy/definition/data", "data") + def get_definitions(self) -> DataSequence[PolicyDefinition]: + ... + + @get("/template/policy/definition/data/{id}") + def get_policy_definition(self, id: str) -> DataDefinition: + ... + + @post("/template/policy/definition/data/preview") + def preview_policy_definition(self, payload: DataDefinitionCreationPayload) -> PolicyDefinitionPreview: + ... + + @get("/template/policy/definition/data/preview/{id}") + def preview_policy_definition_by_id(self, id: str) -> PolicyDefinitionPreview: + ... + + def save_policy_definition_in_bulk(self): + # PUT /template/policy/definition/data/bulk + ... diff --git a/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py b/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py new file mode 100644 index 000000000..58ae9f97e --- /dev/null +++ b/vmngclient/endpoints/configuration_policy_data_prefix_list_builder.py @@ -0,0 +1,92 @@ +# mypy: disable-error-code="empty-body" +from ipaddress import IPv4Network +from typing import List + +from pydantic import BaseModel, Field, validator + +from vmngclient.endpoints import APIEndpoints, delete, get, post, put +from vmngclient.model.policy_list import ( + InfoTag, + PolicyList, + PolicyListCreationPayload, + PolicyListEditPayload, + PolicyListId, + PolicyListPreview, +) +from vmngclient.typed_list import DataSequence + + +class DataPrefixListEntry(BaseModel): + class Config: + allow_population_by_field_name = True + + ip_prefix: str = Field(alias="ipPrefix", description="IP4 network prefixes separated by comma") + + @validator("ip_prefix") + def check_network_prefixes(cls, ip_prefix: str): + nets = [IPv4Network(net.strip()) for net in ip_prefix.split(",")] + if len(nets) < 1: + raise ValueError("No network prefix provided") + return ip_prefix + + +class DataPrefixPayload(BaseModel): + entries: List[DataPrefixListEntry] + type: str = Field(default="dataPrefix", const=True) + + +class DataPrefixListCreationPayload(DataPrefixPayload, PolicyListCreationPayload): + pass + + +class DataPrefixListEditPayload(DataPrefixPayload, PolicyListEditPayload): + pass + + +class DataPrefixList(DataPrefixPayload, PolicyList): + pass + + +class ConfigurationPolicyDataPrefixListBuilder(APIEndpoints): + @post("/template/policy/list/dataprefix") + def create_policy_list(self, payload: DataPrefixListCreationPayload) -> PolicyListId: + ... + + @delete("/template/policy/list/dataprefix/{id}") + def delete_policy_list(self, id: str) -> None: + ... + + @delete("/template/policy/list/dataprefix") + def delete_policy_lists_with_info_tag(self, params: InfoTag) -> None: + # TODO: dont know how to assing tags to check if filter works + # (it is present in GET response but cannot be added to POST, PUT payload) + # for now it was tested with default info tag value == "" + ... + + @put("/template/policy/list/dataprefix/{id}") + def edit_policy_list(self, id: str, payload: DataPrefixListEditPayload) -> None: + ... + + @get("/template/policy/list/dataprefix/{id}") + def get_lists_by_id(self, id: str) -> DataPrefixList: + ... + + @get("/template/policy/list/dataprefix", "data") + def get_policy_lists(self) -> DataSequence[DataPrefixList]: + ... + + @get("/template/policy/list/dataprefix/filtered", "data") + def get_policy_lists_with_info_tag(self, params: InfoTag) -> DataSequence[DataPrefixList]: + # TODO: dont know how to assing tags to check if filter works + # (it is present in GET response but cannot be added to POST, PUT payload) + # for now it was tested with default info tag value == "" + ... + + @post("/template/policy/list/dataprefix/preview") + def preview_policy_list(self, payload: DataPrefixListCreationPayload) -> PolicyListPreview: + # TODO: not working for some reason + ... + + @get("/template/policy/list/dataprefix/preview/{id}") + def preview_policy_list_by_id(self, id: str) -> PolicyListPreview: + ... diff --git a/vmngclient/endpoints/configuration_policy_site_list_builder.py b/vmngclient/endpoints/configuration_policy_site_list_builder.py new file mode 100644 index 000000000..2949b2b94 --- /dev/null +++ b/vmngclient/endpoints/configuration_policy_site_list_builder.py @@ -0,0 +1,87 @@ +# mypy: disable-error-code="empty-body" +from typing import List + +from pydantic import BaseModel, Field + +from vmngclient.endpoints import APIEndpoints, delete, get, post, put +from vmngclient.model.policy_list import ( + InfoTag, + PolicyList, + PolicyListCreationPayload, + PolicyListEditPayload, + PolicyListId, + PolicyListPreview, +) +from vmngclient.typed_list import DataSequence + + +class SiteListEntry(BaseModel): + class Config: + allow_population_by_field_name = True + + site_id: str = Field(alias="siteId") + + +class SitePayload(BaseModel): + entries: List[SiteListEntry] + type: str = Field(default="site", const=True) + + +class SiteListCreationPayload(SitePayload, PolicyListCreationPayload): + pass + + +class SiteListEditPayload(SitePayload, PolicyListEditPayload): + pass + + +class SiteList(SitePayload, PolicyList): + pass + + +class ConfigurationPolicySiteListBuilder(APIEndpoints): + @post("/template/policy/list/site/defaultsite") + def create_default_site_list(self, payload: SiteListCreationPayload) -> PolicyListId: + ... + + @post("/template/policy/list/site") + def create_policy_list(self, payload: SiteListCreationPayload) -> PolicyListId: + ... + + @delete("/template/policy/list/site/{id}") + def delete_policy_list(self, id: str) -> None: + ... + + @delete("/template/policy/list/site") + def delete_policy_lists_with_info_tag(self, params: InfoTag) -> None: + # TODO: dont know how to assing tags to check if filter works + # (it is present in GET response but cannot be added to POST, PUT payload) + # for now it was tested with default info tag value == "" + ... + + @put("/template/policy/list/site/{id}") + def edit_policy_list(self, id: str, payload: SiteListEditPayload) -> None: + ... + + @get("/template/policy/list/site/{id}") + def get_lists_by_id(self, id: str) -> SiteList: + ... + + @get("/template/policy/list/site", "data") + def get_policy_lists(self) -> DataSequence[SiteList]: + ... + + @get("/template/policy/list/site/filtered", "data") + def get_policy_lists_with_info_tag(self, params: InfoTag) -> DataSequence[SiteList]: + # TODO: dont know how to assing tags to check if filter works + # (it is present in GET response but cannot be added to POST, PUT payload) + # for now it was tested with default info tag value == "" + ... + + @post("/template/policy/list/site/preview") + def preview_policy_list(self, payload: SiteListCreationPayload) -> PolicyListPreview: + ... + + @get("/template/policy/list/site/preview/{id}") + def preview_policy_list_by_id(self, id: str) -> PolicyListPreview: + ... diff --git a/vmngclient/endpoints/configuration_policy_vpn_list_builder.py b/vmngclient/endpoints/configuration_policy_vpn_list_builder.py new file mode 100644 index 000000000..4dba42b9b --- /dev/null +++ b/vmngclient/endpoints/configuration_policy_vpn_list_builder.py @@ -0,0 +1,95 @@ +# mypy: disable-error-code="empty-body" +from typing import List + +from pydantic import BaseModel, Field, validator + +from vmngclient.endpoints import APIEndpoints, delete, get, post, put +from vmngclient.model.policy_list import ( + InfoTag, + PolicyList, + PolicyListCreationPayload, + PolicyListEditPayload, + PolicyListId, + PolicyListPreview, +) +from vmngclient.typed_list import DataSequence + + +class VPNListEntry(BaseModel): + class Config: + allow_population_by_field_name = True + + vpn: str = Field(alias="vpn", description="0-65530 range or single number") + + @validator("vpn") + def check_vpn_range(cls, vpns_str: str): + vpns = [int(vpn) for vpn in vpns_str.split("-")] + if len(vpns) > 2: + raise ValueError("VPN range should consist two integers separated by hyphen") + for vpn in vpns: + if vpn < 0 or vpn > 65530: + raise ValueError("VPN should be in range 0-65530") + if len(vpns) == 2 and vpns[0] >= vpns[1]: + raise ValueError("Second VPN in range should be greater than first") + return vpns_str + + +class VPNPayload(BaseModel): + entries: List[VPNListEntry] + type: str = Field(default="vpn", const=True) + + +class VPNListCreationPayload(VPNPayload, PolicyListCreationPayload): + pass + + +class VPNListEditPayload(VPNPayload, PolicyListEditPayload): + pass + + +class VPNList(VPNPayload, PolicyList): + pass + + +class ConfigurationPolicyVPNListBuilder(APIEndpoints): + @post("/template/policy/list/vpn") + def create_policy_list(self, payload: VPNListCreationPayload) -> PolicyListId: + ... + + @delete("/template/policy/list/vpn/{id}") + def delete_policy_list(self, id: str) -> None: + ... + + @delete("/template/policy/list/vpn") + def delete_policy_lists_with_info_tag(self, params: InfoTag) -> None: + # TODO: dont know how to assing tags to check if filter works + # (it is present in GET response but cannot be added to POST, PUT payload) + # for now it was tested with default info tag value == "" + ... + + @put("/template/policy/list/vpn/{id}") + def edit_policy_list(self, id: str, payload: VPNListEditPayload) -> None: + ... + + @get("/template/policy/list/vpn/{id}") + def get_lists_by_id(self, id: str) -> VPNList: + ... + + @get("/template/policy/list/vpn", "data") + def get_policy_lists(self) -> DataSequence[VPNList]: + ... + + @get("/template/policy/list/vpn/filtered", "data") + def get_policy_lists_with_info_tag(self, params: InfoTag) -> DataSequence[VPNList]: + # TODO: dont know how to assing tags to check if filter works + # (it is present in GET response but cannot be added to POST, PUT payload) + # for now it was tested with default info tag value == "" + ... + + @post("/template/policy/list/vpn/preview") + def preview_policy_list(self, payload: VPNListCreationPayload) -> PolicyListPreview: + ... + + @get("/template/policy/list/vpn/preview/{id}") + def preview_policy_list_by_id(self, id: str) -> PolicyListPreview: + ... diff --git a/vmngclient/endpoints/configuration_vsmart_template_policy.py b/vmngclient/endpoints/configuration_vsmart_template_policy.py new file mode 100644 index 000000000..23e8b8414 --- /dev/null +++ b/vmngclient/endpoints/configuration_vsmart_template_policy.py @@ -0,0 +1,118 @@ +# mypy: disable-error-code="empty-body" +from typing import List, Optional + +from pydantic import BaseModel, Field, IPvAnyAddress, validator + +from vmngclient.endpoints import JSON, APIEndpoints, delete, get, post, put +from vmngclient.model.policy import ( + AssemblyItem, + PolicyCreationPayload, + PolicyDefinition, + PolicyEditPayload, + PolicyId, + PolicyInfo, +) +from vmngclient.typed_list import DataSequence + + +class Entry(BaseModel): + site_lists: Optional[List[str]] = Field(alias="siteLists") + vpn_lists: Optional[List[str]] = Field(None, alias="vpnLists") + direction: Optional[str] = None + + +class VSmartAssemblyItem(AssemblyItem): + entries: Optional[List[Entry]] = None + + +class VSmartPolicyDefinition(PolicyDefinition): + assembly: List[AssemblyItem] + region_role_assembly: List = Field(alias="regionRoleAssembly") + + +class VSmartTemplate(PolicyCreationPayload): + policy_definition: VSmartPolicyDefinition = Field(alias="policyDefinition") + + @validator("policy_definition", pre=True) + def try_parse(cls, policy_definition): + # this is needed because GET /template/policy/vsmart contains string in policyDefinition field + # while POST /template/policy/vsmart requires a regular object + # it makes sense to reuse that model for both requests and present parsed data to the user + if isinstance(policy_definition, str): + return VSmartPolicyDefinition.parse_raw(policy_definition) + return policy_definition + + +class VSmartTemplateEditPayload(PolicyEditPayload, VSmartTemplate): + rid: Optional[str] = Field(default=None, alias="@rid") + pass + + +class VSmartTemplateInfo(PolicyInfo, VSmartTemplateEditPayload): + pass + + +class VSmartConnectivityStatus(BaseModel): + device_uuid: str = Field(alias="deviceUUID") + operation_mode: str = Field(alias="operationMode") + device_ip: IPvAnyAddress = Field(alias="deviceIp") + local_system_ip: IPvAnyAddress = Field(alias="local-system-ip") + is_online: bool = Field(alias="isOnline") + + +class AutoConfirm(BaseModel): + confirm: str = Field(default="true", const=True) + + +class ActivateDeactivateTaskId(BaseModel): + id: str + + +class ConfigurationVSmartTemplatePolicy(APIEndpoints): + @post("/template/policy/vsmart/activate/{id}") + def activate_policy( + self, id: str, params: AutoConfirm = AutoConfirm(), payload: JSON = {} + ) -> ActivateDeactivateTaskId: + ... + + def activate_policy_for_cloud_services(self): + # POST /template/policy/vsmart/activate/central/{policyId} + ... + + @get("/template/policy/vsmart/connectivity/status", "data") + def check_vsmart_connectivity_status(self) -> DataSequence[VSmartConnectivityStatus]: + ... + + @post("/template/policy/vsmart") + def create_vsmart_template(self, payload: VSmartTemplate) -> PolicyId: + ... + + @post("/template/policy/vsmart/deactivate/{id}") + def deactivate_policy( + self, id: str, params: AutoConfirm = AutoConfirm(), payload: JSON = {} + ) -> ActivateDeactivateTaskId: + ... + + @delete("/template/policy/vsmart/{id}") + def delete_vsmart_template(self, id: str) -> None: + ... + + @put("/template/policy/vsmart/central/{id}") + def edit_template_without_lock_checks(self, id: str, payload: VSmartTemplateEditPayload) -> JSON: + ... + + @put("/template/policy/vsmart/{id}") + def edit_vsmart_template(self, id: str, payload: VSmartTemplateEditPayload) -> JSON: + ... + + @get("/template/policy/vsmart", "data") + def generate_vsmart_policy_template_list(self) -> DataSequence[VSmartTemplateInfo]: + ... + + @get("/template/policy/vsmart/definition/{id}") + def get_template_by_policy_id(self, id: str) -> VSmartTemplate: + ... + + def qosmos_nbar_migration_warning(self): + # GET /template/policy/vsmart/qosmos_nbar_migration_warning + ... diff --git a/vmngclient/endpoints/endpoints_container.py b/vmngclient/endpoints/endpoints_container.py index 1ad3b841e..84f71a2e1 100644 --- a/vmngclient/endpoints/endpoints_container.py +++ b/vmngclient/endpoints/endpoints_container.py @@ -12,7 +12,12 @@ from vmngclient.endpoints.configuration_device_template import ConfigurationDeviceTemplate from vmngclient.endpoints.configuration_feature_profile import ConfigurationFeatureProfile from vmngclient.endpoints.configuration_group import ConfigurationGroup +from vmngclient.endpoints.configuration_policy_data_definition_builder import ConfigurationPolicyDataDefinitionBuilder +from vmngclient.endpoints.configuration_policy_data_prefix_list_builder import ConfigurationPolicyDataPrefixListBuilder +from vmngclient.endpoints.configuration_policy_site_list_builder import ConfigurationPolicySiteListBuilder +from vmngclient.endpoints.configuration_policy_vpn_list_builder import ConfigurationPolicyVPNListBuilder from vmngclient.endpoints.configuration_settings import ConfigurationSettings +from vmngclient.endpoints.configuration_vsmart_template_policy import ConfigurationVSmartTemplatePolicy from vmngclient.endpoints.monitoring_device_details import MonitoringDeviceDetails from vmngclient.endpoints.monitoring_status import MonitoringStatus from vmngclient.endpoints.sdavc_cloud_connector import SDAVCCloudConnector @@ -34,6 +39,11 @@ def __init__(self, session: vManageSession): self.configuration_device_actions = ConfigurationDeviceActions(session) self.configuration_device_software_update = ConfigurationDeviceSoftwareUpdate(session) self.configuration_device_template = ConfigurationDeviceTemplate(session) + self.configuration_policy_data_definition_builder = ConfigurationPolicyDataDefinitionBuilder(session) + self.configuration_policy_data_prefix_list_builder = ConfigurationPolicyDataPrefixListBuilder(session) + self.configuration_policy_site_list_builder = ConfigurationPolicySiteListBuilder(session) + self.configuration_policy_vpn_list_builder = ConfigurationPolicyVPNListBuilder(session) + self.configuration_vsmart_template_policy = ConfigurationVSmartTemplatePolicy(session) self.configuration_settings = ConfigurationSettings(session) self.monitoring_device_details = MonitoringDeviceDetails(session) self.monitoring_status = MonitoringStatus(session) diff --git a/vmngclient/model/policy.py b/vmngclient/model/policy.py new file mode 100644 index 000000000..c365823ec --- /dev/null +++ b/vmngclient/model/policy.py @@ -0,0 +1,42 @@ +import datetime +from typing import Any, List, Optional + +from pydantic import BaseModel, Field + + +class PolicyId(BaseModel): + policy_id: str = Field(alias="policyId") + + +class AssemblyItem(BaseModel): + definition_id: str = Field(alias="definitionId") + type: str + entries: Optional[List[Any]] = [] + + +class PolicyDefinition(BaseModel): + assembly: List[AssemblyItem] + + +class PolicyCreationPayload(BaseModel): + policy_name: str = Field( + alias="policyName", + regex="^[a-zA-Z0-9_-]{1,127}$", + description="Can include only alpha-numeric characters, hyphen '-' or underscore '_'; maximum 127 characters", + ) + policy_description: str = Field(alias="policyDescription") + policy_type: str = Field(alias="policyType") + policy_definition: PolicyDefinition = Field(alias="policyDefinition") + is_policy_activated: bool = Field(default=False, alias="isPolicyActivated") + + +class PolicyEditPayload(PolicyCreationPayload, PolicyId): + pass + + +class PolicyInfo(PolicyEditPayload): + created_by: str = Field(alias="createdBy") + created_on: datetime.datetime = Field(alias="createdOn") + last_updated_by: str = Field(alias="lastUpdatedBy") + last_updated_on: datetime.datetime = Field(alias="lastUpdatedOn") + policy_version: str = Field(alias="policyVersion") diff --git a/vmngclient/model/policy_definition.py b/vmngclient/model/policy_definition.py new file mode 100644 index 000000000..13113338f --- /dev/null +++ b/vmngclient/model/policy_definition.py @@ -0,0 +1,47 @@ +import datetime +from typing import List, Optional + +from pydantic import BaseModel, Field + + +class InfoTag(BaseModel): + info_tag: Optional[str] = Field("", alias="infoTag") + + +class PolicyDefinitionId(BaseModel): + definition_id: str = Field(alias="definitionId") + + +class PolicyReference(BaseModel): + id: str + property: str + + +class PolicyDefinitionCreationPayload(BaseModel): + name: str = Field( + regex="^[a-zA-Z0-9_-]{1,128}$", + description="Can include only alpha-numeric characters, hyphen '-' or underscore '_'; maximum 128 characters", + ) + description: str + type: str + + +class PolicyDefinitionEditPayload(PolicyDefinitionCreationPayload, PolicyDefinitionId): + pass + + +class PolicyDefinitionEditResponse(BaseModel): + master_templates_affected: List[str] = Field(default=[], alias="masterTemplatesAffected") + + +class PolicyDefinition(PolicyDefinitionEditPayload, InfoTag): + last_updated: datetime.datetime = Field(alias="lastUpdated") + owner: str + mode: str + optimized: str + reference_count: int = Field(alias="referenceCount") + references: List[PolicyReference] + + +class PolicyDefinitionPreview(BaseModel): + preview: str diff --git a/vmngclient/model/policy_list.py b/vmngclient/model/policy_list.py new file mode 100644 index 000000000..91b6e83f7 --- /dev/null +++ b/vmngclient/model/policy_list.py @@ -0,0 +1,40 @@ +import datetime +from typing import List, Optional + +from pydantic import BaseModel, Field + + +class InfoTag(BaseModel): + info_tag: Optional[str] = Field("", alias="infoTag") + + +class PolicyListId(BaseModel): + list_id: str = Field(alias="listId") + + +class PolicyListCreationPayload(BaseModel): + name: str = Field( + regex="^[a-zA-Z0-9_-]{1,32}$", + description="Can include only alpha-numeric characters, hyphen '-' or underscore '_'; maximum 32 characters", + ) + description: Optional[str] = "Desc Not Required" + type: str + entries: List + + +class PolicyListEditPayload(PolicyListCreationPayload, PolicyListId): + pass + + +class PolicyList(PolicyListEditPayload, InfoTag): + last_updated: datetime.datetime = Field(alias="lastUpdated") + owner: str + read_only: bool = Field(alias="readOnly") + version: str + reference_count: int = Field(alias="referenceCount") + references: List + is_activated_by_vsmart: bool = Field(alias="isActivatedByVsmart") + + +class PolicyListPreview(BaseModel): + preview: str diff --git a/vmngclient/model/profileparcel/traffic_policy.py b/vmngclient/model/profileparcel/traffic_policy.py new file mode 100644 index 000000000..dbbd218b0 --- /dev/null +++ b/vmngclient/model/profileparcel/traffic_policy.py @@ -0,0 +1,938 @@ +# mypy: disable-error-code="valid-type" +# generated by datamodel-codegen: +# filename: app-traffic-policy.json +# timestamp: 2023-09-07T08:34:35+00:00 + +from __future__ import annotations + +from enum import Enum +from ipaddress import IPv4Address, IPv6Address +from typing import List, Optional, Union + +from pydantic import BaseModel, Extra, Field, conint, constr + + +class Entries(BaseModel): + pass + + +class SlaClass(BaseModel): + pass + + +class Set(BaseModel): + pass + + +class Actions(BaseModel): + pass + + +class CgFpPpNameDef(BaseModel): + __root__: constr(regex=r'^[^&<>! "]+$', min_length=1, max_length=128) # noqa: F722 + + +class GlobalOptionTypeDef(Enum): + global_ = "global" + + +class UuidDef(BaseModel): + __root__: constr(regex=r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}") # noqa: F722 + + +class BooleanDef(BaseModel): + __root__: bool + + +class Ipv4PrefixDef(BaseModel): + __root__: constr( + regex=r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\/)([0-2]?[0-9]$|[3]?[0-2])" # noqa: F722, E501 + ) + + +class Ipv6PrefixDef(BaseModel): + __root__: constr( + regex=r"((^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*(\/)(\b([0-9]{1,2}|1[01][0-9]|12[0-8])\b)$))" # noqa: F722, E501 + ) + + +class OneOfMatchEntriesSourceIpv6OptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: Ipv6PrefixDef + + +class OneOfMatchEntriesSourceIpv6OptionsDef(BaseModel): + __root__: OneOfMatchEntriesSourceIpv6OptionsDefItem + + +class ColorDef(Enum): + field_3g = "3g" + biz_internet = "biz-internet" + blue = "blue" + bronze = "bronze" + custom1 = "custom1" + custom2 = "custom2" + custom3 = "custom3" + default = "default" + gold = "gold" + green = "green" + lte = "lte" + metro_ethernet = "metro-ethernet" + mpls = "mpls" + private1 = "private1" + private2 = "private2" + private3 = "private3" + private4 = "private4" + private5 = "private5" + private6 = "private6" + public_internet = "public-internet" + red = "red" + silver = "silver" + + +class Count(BaseModel): + __root__: constr(min_length=1, max_length=20) + + +class DestinationRegion(Enum): + primary_region = "primary-region" + secondary_region = "secondary-region" + other_region = "other-region" + + +class Dns(Enum): + request = "request" + response = "response" + + +class Ipv4AddressDef(BaseModel): + class Config: + extra = Extra.forbid + + __root__: IPv4Address + + +class Ipv6AddressDef(BaseModel): + class Config: + extra = Extra.forbid + + __root__: IPv6Address + + +class MatchEntriesDscpDef(BaseModel): + __root__: conint(ge=0, le=63) + + +class MatchEntriesIcmp6MessageDef(Enum): + beyond_scope = "beyond-scope" + cp_advertisement = "cp-advertisement" + cp_solicitation = "cp-solicitation" + destination_unreachable = "destination-unreachable" + dhaad_reply = "dhaad-reply" + dhaad_request = "dhaad-request" + echo_reply = "echo-reply" + echo_request = "echo-request" + header = "header" + hop_limit = "hop-limit" + ind_advertisement = "ind-advertisement" + ind_solicitation = "ind-solicitation" + mld_query = "mld-query" + mld_reduction = "mld-reduction" + mld_report = "mld-report" + mldv2_report = "mldv2-report" + mpd_advertisement = "mpd-advertisement" + mpd_solicitation = "mpd-solicitation" + mr_advertisement = "mr-advertisement" + mr_solicitation = "mr-solicitation" + mr_termination = "mr-termination" + nd_na = "nd-na" + nd_ns = "nd-ns" + next_header_type = "next-header-type" + ni_query = "ni-query" + ni_query_name = "ni-query-name" + ni_query_v4_address = "ni-query-v4-address" + ni_query_v6_address = "ni-query-v6-address" + ni_response = "ni-response" + ni_response_qtype_unknown = "ni-response-qtype-unknown" + ni_response_refuse = "ni-response-refuse" + ni_response_success = "ni-response-success" + no_admin = "no-admin" + no_route = "no-route" + packet_too_big = "packet-too-big" + parameter_option = "parameter-option" + parameter_problem = "parameter-problem" + port_unreachable = "port-unreachable" + reassembly_timeout = "reassembly-timeout" + redirect = "redirect" + reject_route = "reject-route" + renum_command = "renum-command" + renum_result = "renum-result" + renum_seq_number = "renum-seq-number" + router_advertisement = "router-advertisement" + router_renumbering = "router-renumbering" + router_solicitation = "router-solicitation" + rpl_control = "rpl-control" + source_policy = "source-policy" + source_route_header = "source-route-header" + time_exceeded = "time-exceeded" + unreachable = "unreachable" + + +class MatchEntriesIcmpMessageDef(Enum): + administratively_prohibited = "administratively-prohibited" + dod_host_prohibited = "dod-host-prohibited" + dod_net_prohibited = "dod-net-prohibited" + echo = "echo" + echo_reply = "echo-reply" + echo_reply_no_error = "echo-reply-no-error" + extended_echo = "extended-echo" + extended_echo_reply = "extended-echo-reply" + general_parameter_problem = "general-parameter-problem" + host_isolated = "host-isolated" + host_precedence_unreachable = "host-precedence-unreachable" + host_redirect = "host-redirect" + host_tos_redirect = "host-tos-redirect" + host_tos_unreachable = "host-tos-unreachable" + host_unknown = "host-unknown" + host_unreachable = "host-unreachable" + interface_error = "interface-error" + malformed_query = "malformed-query" + multiple_interface_match = "multiple-interface-match" + net_redirect = "net-redirect" + net_tos_redirect = "net-tos-redirect" + net_tos_unreachable = "net-tos-unreachable" + net_unreachable = "net-unreachable" + network_unknown = "network-unknown" + no_room_for_option = "no-room-for-option" + option_missing = "option-missing" + packet_too_big = "packet-too-big" + parameter_problem = "parameter-problem" + photuris = "photuris" + port_unreachable = "port-unreachable" + precedence_unreachable = "precedence-unreachable" + protocol_unreachable = "protocol-unreachable" + reassembly_timeout = "reassembly-timeout" + redirect = "redirect" + router_advertisement = "router-advertisement" + router_solicitation = "router-solicitation" + source_route_failed = "source-route-failed" + table_entry_error = "table-entry-error" + time_exceeded = "time-exceeded" + timestamp_reply = "timestamp-reply" + timestamp_request = "timestamp-request" + ttl_exceeded = "ttl-exceeded" + unreachable = "unreachable" + + +class MatchEntriesTcpDef(Enum): + syn = "syn" + + +class MatchEntriesTrafficClassOptionsDef(Enum): + gold_voip_telephony = "gold-voip-telephony" + gold_broadcast_video = "gold-broadcast-video" + gold_real_time_interactive = "gold-real-time-interactive" + gold_multimedia_conferencing = "gold-multimedia-conferencing" + gold_multimedia_streaming = "gold-multimedia-streaming" + gold_network_control = "gold-network-control" + gold_signaling = "gold-signaling" + gold_ops_admin_mgmt = "gold-ops-admin-mgmt" + gold_transactional_data = "gold-transactional-data" + gold_bulk_data = "gold-bulk-data" + silver = "silver" + bronze = "bronze" + + +class NatPool(BaseModel): + __root__: conint(ge=1, le=31) + + +class ProtocolDef(BaseModel): + __root__: constr(regex=r"^(0|[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$") # noqa: F722, E501 + + +class RedirectDn(Enum): + umbrella = "umbrella" + host = "host" + + +class RedirectDns(BaseModel): + __root__: Union[RedirectDn, Ipv4AddressDef] + + +class RedirectDnsTypes(Enum): + ip_address = "ipAddress" + dns_host = "dnsHost" + + +class SequencesBaseActionDef(Enum): + drop = "drop" + accept = "accept" + + +class SequencesSequenceIdDef(BaseModel): + __root__: conint(ge=1, le=65536) + + +class SequencesSequenceIpTypeDef(Enum): + ipv4 = "ipv4" + ipv6 = "ipv6" + all = "all" + + +class SequencesSequenceNameDef(BaseModel): + __root__: str + + +class TargetDirectionDef(Enum): + service = "service" + tunnel = "tunnel" + all = "all" + + +class TargetVpnDef(BaseModel): + __root__: str + + +class TrafficTo(Enum): + core = "core" + service = "service" + access = "access" + + +class VpnDef(BaseModel): + class Config: + extra = Extra.forbid + + __root__: conint(ge=0, le=65530) + + +class Encap(Enum): + ipsec = "ipsec" + gre = "gre" + + +class EncapDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: Encap + + +class PortNoDef(BaseModel): + __root__: constr( + regex=r"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$" # noqa: F722, E501 + ) + + +class PortRangeDef(BaseModel): + __root__: constr( + regex=r"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])\-(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$" # noqa: F722, E501 + ) + + +class SequencesMatchEntriesPacketLengthDef(BaseModel): + __root__: constr( + regex=r"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$" # noqa: F722, E501 + ) + + +class SequencesMatchEntriesPacketLengthRangeDef(BaseModel): + __root__: constr( + regex=r"^([0-9]|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])\-([1-9]|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$" # noqa: F722, E501 + ) + + +class TypeDefinition(Enum): + fw = "FW" + ids = "IDS" + idp = "IDP" + netsvc1 = "netsvc1" + netsvc2 = "netsvc2" + netsvc3 = "netsvc3" + netsvc4 = "netsvc4" + appqoe = "appqoe" + + +class RefId(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: UuidDef + + +class ParcelReferenceDef(BaseModel): + class Config: + extra = Extra.forbid + + ref_id: RefId = Field(..., alias="refId") + + +class BooleanDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: BooleanDef + + +class BooleanDefModel(BaseModel): + __root__: BooleanDefItem + + +class ColorMatchListDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: List[ColorDef] = Field(..., min_items=1, unique_items=True) + + +class CountDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: Count + + +class DestinationRegionDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: DestinationRegion + + +class DnsDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: Dns + + +class Ipv4PrefixDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: Ipv4PrefixDef + + +class Ipv4PrefixDefModel(BaseModel): + __root__: Ipv4PrefixDefItem + + +class UseVpn(BaseModel): + option_type: Optional[GlobalOptionTypeDef] = Field(None, alias="optionType") + value: Optional[BooleanDefModel] = None + + +class NatDef(BaseModel): + class Config: + extra = Extra.forbid + + use_vpn: UseVpn = Field(..., alias="useVpn") + fallback: Optional[BooleanDefModel] = None + + +class NatPoolDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: NatPool + + +class OneOfMatchEntriesDestinationIpv6OptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: Ipv6PrefixDef + + +class OneOfMatchEntriesDestinationIpv6OptionsDef(BaseModel): + __root__: OneOfMatchEntriesDestinationIpv6OptionsDefItem + + +class OneOfMatchEntriesDscpOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: MatchEntriesDscpDef + + +class OneOfMatchEntriesDscpOptionsDef(BaseModel): + __root__: OneOfMatchEntriesDscpOptionsDefItem + + +class OneOfMatchEntriesIcmp6MessageOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: List[MatchEntriesIcmp6MessageDef] = Field(..., min_items=1, unique_items=True) + + +class OneOfMatchEntriesIcmp6MessageOptionsDef(BaseModel): + __root__: OneOfMatchEntriesIcmp6MessageOptionsDefItem + + +class OneOfMatchEntriesIcmpMessageOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: List[MatchEntriesIcmpMessageDef] = Field(..., min_items=1, unique_items=True) + + +class OneOfMatchEntriesIcmpMessageOptionsDef(BaseModel): + __root__: OneOfMatchEntriesIcmpMessageOptionsDefItem + + +class OneOfMatchEntriesProtocolOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: List[ProtocolDef] = Field(..., min_items=1, unique_items=True) + + +class OneOfMatchEntriesProtocolOptionsDef(BaseModel): + __root__: OneOfMatchEntriesProtocolOptionsDefItem + + +class OneOfMatchEntriesTcpOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: MatchEntriesTcpDef + + +class OneOfMatchEntriesTcpOptionsDef(BaseModel): + __root__: OneOfMatchEntriesTcpOptionsDefItem + + +class OneOfMatchEntriesTrafficClassOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: MatchEntriesTrafficClassOptionsDef + + +class OneOfMatchEntriesTrafficClassOptionsDef(BaseModel): + __root__: OneOfMatchEntriesTrafficClassOptionsDefItem + + +class FieldModel(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: RedirectDnsTypes + + +class Value(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: RedirectDns + + +class OneOfRedirectDnsDef(BaseModel): + field: Optional[FieldModel] = None + value: Optional[Value] = None + + +class OneOfSequencesBaseActionOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: SequencesBaseActionDef + + +class OneOfSequencesBaseActionOptionsDef(BaseModel): + __root__: OneOfSequencesBaseActionOptionsDefItem + + +class OneOfSequencesSequenceIdOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: SequencesSequenceIdDef + + +class OneOfSequencesSequenceIdOptionsDef(BaseModel): + __root__: OneOfSequencesSequenceIdOptionsDefItem + + +class OneOfSequencesSequenceIpTypeOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: SequencesSequenceIpTypeDef + + +class OneOfSequencesSequenceIpTypeOptionsDef(BaseModel): + __root__: OneOfSequencesSequenceIpTypeOptionsDefItem + + +class OneOfSequencesSequenceNameOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: SequencesSequenceNameDef + + +class OneOfSequencesSequenceNameOptionsDef(BaseModel): + __root__: OneOfSequencesSequenceNameOptionsDefItem + + +class OneOfTargetDirectionOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: TargetDirectionDef + + +class OneOfTargetDirectionOptionsDef(BaseModel): + __root__: OneOfTargetDirectionOptionsDefItem + + +class OneOfTargetVpnOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: List[TargetVpnDef] = Field(..., min_items=1, unique_items=True) + + +class OneOfTargetVpnOptionsDef(BaseModel): + __root__: OneOfTargetVpnOptionsDefItem + + +class SlaClassDef(BaseModel): + class Config: + extra = Extra.forbid + + sla_name: Optional[ParcelReferenceDef] = Field(None, alias="slaName") + preferred_color: Optional[ColorMatchListDef] = Field(None, alias="preferredColor") + preferred_color_group: Optional[ParcelReferenceDef] = Field(None, alias="preferredColorGroup") + strict: Optional[BooleanDefModel] = None + fallback_to_best_path: Optional[BooleanDefModel] = Field(None, alias="fallbackToBestPath") + + +class TrafficToDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: TrafficTo + + +class EncapListDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: List[Encap] = Field(..., min_items=1, unique_items=True) + + +class Ipv4AddressDefModel(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: Ipv4AddressDef + + +class Ipv6AddressDefModel(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: Ipv6AddressDef + + +class OneOfSequencesMatchEntriesPacketLengthValueDef(BaseModel): + __root__: Union[SequencesMatchEntriesPacketLengthDef, SequencesMatchEntriesPacketLengthRangeDef] + + +class PortValueDef(BaseModel): + __root__: Union[PortNoDef, PortRangeDef] + + +class TlocDef(BaseModel): + class Config: + extra = Extra.forbid + + color: ColorMatchListDef + encap: EncapDef + ip: Ipv4AddressDefModel + + +class TypeDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: TypeDefinition + + +class VpnDefModel(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: VpnDef + + +class Restrict(BaseModel): + __root__: BooleanDefModel + + +class Target(BaseModel): + class Config: + extra = Extra.forbid + + vpn: Optional[OneOfTargetVpnOptionsDef] = Field(None, description="") + direction: Optional[OneOfTargetDirectionOptionsDef] = Field(None, description="") + + +class OneOfMatchEntriesDestinationPortOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: List[PortValueDef] = Field(..., min_items=1) + + +class OneOfMatchEntriesDestinationPortOptionsDef(BaseModel): + __root__: OneOfMatchEntriesDestinationPortOptionsDefItem + + +class OneOfMatchEntriesPacketLengthOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: OneOfSequencesMatchEntriesPacketLengthValueDef + + +class OneOfMatchEntriesPacketLengthOptionsDef(BaseModel): + __root__: OneOfMatchEntriesPacketLengthOptionsDefItem + + +class OneOfMatchEntriesSourcePortOptionsDefItem(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: List[PortValueDef] = Field(..., min_items=1) + + +class OneOfMatchEntriesSourcePortOptionsDef(BaseModel): + __root__: OneOfMatchEntriesSourcePortOptionsDefItem + + +class ServiceItem(BaseModel): + class Config: + extra = Extra.forbid + + tloc: TlocDef + vpn: VpnDefModel + type: TypeDef + + +class ServiceItem1(BaseModel): + class Config: + extra = Extra.forbid + + tloc_list: ParcelReferenceDef = Field(..., alias="tlocList") + vpn: VpnDefModel + type: TypeDef + + +class RestrictDef(BaseModel): + class Config: + extra = Extra.forbid + + option_type: GlobalOptionTypeDef = Field(..., alias="optionType") + value: Restrict + + +class Entry(BaseModel): + class Config: + extra = Extra.forbid + + app_list: Optional[ParcelReferenceDef] = Field(None, alias="appList", description="App list Reference") + saas_app_list: Optional[ParcelReferenceDef] = Field( + None, alias="saasAppList", description="Saas App list Reference" + ) + dns_app_list: Optional[ParcelReferenceDef] = Field(None, alias="dnsAppList", description="dns App list Reference") + traffic_class: Optional[OneOfMatchEntriesTrafficClassOptionsDef] = Field( + None, alias="trafficClass", description="Traffic Class" + ) + dscp: Optional[OneOfMatchEntriesDscpOptionsDef] = Field(None, description="DSCP number") + packet_length: Optional[OneOfMatchEntriesPacketLengthOptionsDef] = Field( + None, alias="packetLength", description="Packet Length" + ) + protocol: Optional[OneOfMatchEntriesProtocolOptionsDef] = Field( + None, + description="protocol (0-255) range or individual number separated by space", + ) + icmp_message: Optional[OneOfMatchEntriesIcmpMessageOptionsDef] = Field( + None, alias="icmpMessage", description="ICMP Message" + ) + icmp6_message: Optional[OneOfMatchEntriesIcmp6MessageOptionsDef] = Field( + None, alias="icmp6Message", description="ICMP6 Message" + ) + source_data_prefix_list: Optional[ParcelReferenceDef] = Field( + None, alias="sourceDataPrefixList", description="Source Data Prefix Parcel UUID" + ) + source_data_ipv6_prefix_list: Optional[ParcelReferenceDef] = Field( + None, + alias="sourceDataIpv6PrefixList", + description="Source Data Prefix Parcel UUID", + ) + source_ip: Optional[Ipv4PrefixDefModel] = Field(None, alias="sourceIp", description="Source Data IP Prefix") + source_ipv6: Optional[OneOfMatchEntriesSourceIpv6OptionsDef] = Field( + None, alias="sourceIpv6", description="Source Data IP Prefix" + ) + source_port: Optional[OneOfMatchEntriesSourcePortOptionsDef] = Field( + None, + alias="sourcePort", + description="Source Port (0-65535) range or individual number separated by space", + ) + destination_data_prefix_list: Optional[ParcelReferenceDef] = Field( + None, + alias="destinationDataPrefixList", + description="Destination Data Prefix Parcel UUID", + ) + destination_data_ipv6_prefix_list: Optional[ParcelReferenceDef] = Field( + None, + alias="destinationDataIpv6PrefixList", + description="Destination Data Prefix Parcel UUID", + ) + destination_ip: Optional[Ipv4PrefixDefModel] = Field( + None, alias="destinationIp", description="Destination Data IP Prefix" + ) + destination_ipv6: Optional[OneOfMatchEntriesDestinationIpv6OptionsDef] = Field( + None, alias="destinationIpv6", description="Destination Data IP Prefix" + ) + destination_port: Optional[OneOfMatchEntriesDestinationPortOptionsDef] = Field( + None, + alias="destinationPort", + description="Destination Port (0-65535) range or individual number separated by space", + ) + tcp: Optional[OneOfMatchEntriesTcpOptionsDef] = Field(None, description="TCP States") + destination_region: Optional[DestinationRegionDef] = Field( + None, alias="destinationRegion", description="Destination Region" + ) + traffic_to: Optional[TrafficToDef] = Field(None, alias="trafficTo", description="Traffic to") + dns: Optional[DnsDef] = Field(None, description="Dns") + + +class Match(BaseModel): + class Config: + extra = Extra.forbid + + entries: Union[List[Entry], Entries] = Field(..., unique_items=True) + + +class LocalTlocList(BaseModel): + class Config: + extra = Extra.forbid + + color: ColorMatchListDef + restrict: Optional[RestrictDef] = None + encap: EncapListDef + + +class SetProperties(BaseModel): + class Config: + extra = Extra.forbid + + dscp: Optional[OneOfMatchEntriesDscpOptionsDef] = None + policer: Optional[ParcelReferenceDef] = None + preferred_color_group: Optional[ParcelReferenceDef] = Field(None, alias="preferredColorGroup") + forwarding_class: Optional[ParcelReferenceDef] = Field(None, alias="forwardingClass") + local_tloc_list: Optional[LocalTlocList] = Field(None, alias="localTlocList") + tloc: Optional[TlocDef] = None + tloc_list: Optional[ParcelReferenceDef] = Field(None, alias="tlocList") + service: Optional[Union[ServiceItem, ServiceItem1]] = None + next_hop: Optional[Ipv4AddressDefModel] = Field(None, alias="nextHop") + next_hop_ipv6: Optional[Ipv6AddressDefModel] = Field(None, alias="nextHopIpv6") + next_hop_loose: Optional[BooleanDefModel] = Field(None, alias="nextHopLoose") + vpn: Optional[VpnDefModel] = None + + +class Action(BaseModel): + class Config: + extra = Extra.forbid + + sla_class: Optional[Union[List[SlaClassDef], SlaClass]] = Field(None, alias="slaClass", description="slaClass") + backup_sla_preferred_color: Optional[ColorMatchListDef] = Field( + None, alias="backupSlaPreferredColor", description="Backup SLA perferred color" + ) + set: Optional[Union[List[SetProperties], Set]] = None + redirect_dns: Optional[OneOfRedirectDnsDef] = Field(None, alias="redirectDns") + count: Optional[CountDef] = None + log: Optional[BooleanDefModel] = None + cloud_saas: Optional[BooleanDefModel] = Field(None, alias="cloudSaas") + cflowd: Optional[BooleanDefModel] = None + nat_pool: Optional[NatPoolDef] = Field(None, alias="natPool") + nat: Optional[NatDef] = None + sig: Optional[BooleanDefModel] = None + fallback_to_routing: Optional[BooleanDefModel] = Field(None, alias="fallbackToRouting") + + +class Sequence(BaseModel): + class Config: + extra = Extra.forbid + + sequence_id: Optional[OneOfSequencesSequenceIdOptionsDef] = Field( + None, alias="sequenceId", description="Sequence Id" + ) + sequence_name: Optional[OneOfSequencesSequenceNameOptionsDef] = Field( + None, alias="sequenceName", description="Sequence Name" + ) + base_action: Optional[OneOfSequencesBaseActionOptionsDef] = Field( + None, alias="baseAction", description="Base Action" + ) + sequence_ip_type: Optional[OneOfSequencesSequenceIpTypeOptionsDef] = Field( + None, alias="sequenceIpType", description="Sequence IP Type" + ) + match: Optional[Match] = None + actions: Optional[Union[List[Action], Actions]] = None + + +class Data(BaseModel): + class Config: + extra = Extra.forbid + + simple_flow: Optional[BooleanDefModel] = Field(None, alias="simpleFlow") + target: Optional[Target] = Field(None, description="Target vpn and direction") + sequences: Optional[List[Sequence]] = Field(None, description="Traffic policy sequence list", unique_items=True) + + +class TrafficPolicyParcelSchema(BaseModel): + name: Optional[CgFpPpNameDef] = None + description: Optional[str] = None + data: Data diff --git a/vmngclient/tests/test_endpoints.py b/vmngclient/tests/test_endpoints.py index e73a07ec7..f3b3e3d3c 100644 --- a/vmngclient/tests/test_endpoints.py +++ b/vmngclient/tests/test_endpoints.py @@ -698,6 +698,57 @@ def get_data( ) self.session_mock.reset_mock() + def test_request_decorator_call_with_defaults_arguments(self): + # Arrange + class TestAPI(APIEndpoints): + @request("GET", "/v2/{category}/items") + def get_data( + self, + payload: BaseModelExample = self.basemodel_payload, + category: str = "default-category", + params: ParamsExample = self.basemodel_params, + ) -> None: # type: ignore [empty-body] + ... + + api = TestAPI(self.session_mock) + # Act + api.get_data() + # Assert + self.session_mock.request.assert_called_once_with( + "GET", + self.base_path + "/v2/default-category/items", + data=self.json_payload, + headers={"content-type": "application/json"}, + params=self.basemodel_params, + ) + + def test_request_decorator_call_with_defaults_arguments_override(self): + # Arrange + class TestAPI(APIEndpoints): + @request("GET", "/v2/{category}/items") + def get_data( + self, + payload: BaseModelExample = self.basemodel_payload, + category: str = "default", + params: ParamsExample = self.basemodel_params, + ) -> None: # type: ignore [empty-body] + ... + + api = TestAPI(self.session_mock) + # Act + payload_override = BaseModelExample(id="override-id", size=500, capacity=9.0001, active=False) + category_override = "override-category!" + params_override = ParamsExample(name="override-Name", color="override with orange!") + api.get_data(payload_override, category_override, params_override) + # Assert + self.session_mock.request.assert_called_once_with( + "GET", + self.base_path + f"/v2/{category_override}/items", + data=payload_override.json(), + headers={"content-type": "application/json"}, + params=params_override, + ) + def test_decorator_chaining_order(self): # Expected @request can access original function signature (it will raise otherwise) class TestAPIMixedOrder1(APIEndpoints): From df8664749012d01a5ad5eaf78fe2a5abb2781e60 Mon Sep 17 00:00:00 2001 From: dariuszniedzielski-codilime <112850296+dariuszniedzielski-codilime@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:49:42 +0200 Subject: [PATCH 2/5] Precommit secrets (#370) * pre-commit secrets scan * remove unused file * fixed typo --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .pre-commit-config.yaml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a207039a0..d50bbcd03 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -5,7 +5,7 @@ [Add more in depth analysis of what changed, provide logs, examples of usage] # Checklist: -- [ ] Make sure to run pre-commit before commiting changes +- [ ] Make sure to run pre-commit before committing changes - [ ] Make sure all checks have passed - [ ] PR description is clear and comprehensive - [ ] Mentioned the issue that this PR solves (if applicable) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5cbcf1002..6ced5483a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -65,3 +65,8 @@ repos: language: system types: [python] fail_fast: true + + - repo: https://github.com/Yelp/detect-secrets + rev: v1.4.0 + hooks: + - id: detect-secrets From 6471cc15a7baa3cc02622f9e0c353522426fa3c0 Mon Sep 17 00:00:00 2001 From: "Renuka Mohan Channapatna (rchannap)" <17580723+renukavinay@users.noreply.github.com> Date: Fri, 15 Sep 2023 17:27:06 -0700 Subject: [PATCH 3/5] updated payload --- vmngclient/model/tenant.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vmngclient/model/tenant.py b/vmngclient/model/tenant.py index 933775514..5d3464a61 100644 --- a/vmngclient/model/tenant.py +++ b/vmngclient/model/tenant.py @@ -47,3 +47,7 @@ class Tenant(BaseModel): class Config: allow_population_by_field_name = True + + +class MigrationTenant(Tenant): + is_destination_overlay_mt: Optional[bool] = Field(alias="isDestinationOverlayMT") From e16d05696efe62df40442f6edc55e1abf63f741a Mon Sep 17 00:00:00 2001 From: "Renuka Mohan Channapatna (rchannap)" <17580723+renukavinay@users.noreply.github.com> Date: Sat, 16 Sep 2023 00:16:59 -0700 Subject: [PATCH 4/5] unit test->MigrationTenant --- vmngclient/tests/test_tenant_migration_api.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/vmngclient/tests/test_tenant_migration_api.py b/vmngclient/tests/test_tenant_migration_api.py index b20355868..610220dfd 100644 --- a/vmngclient/tests/test_tenant_migration_api.py +++ b/vmngclient/tests/test_tenant_migration_api.py @@ -6,7 +6,7 @@ from vmngclient.api.task_status_api import Task from vmngclient.api.tenant_migration_api import ImportTask, TenantMigrationAPI from vmngclient.endpoints.tenant_migration import ImportInfo, MigrationInfo -from vmngclient.model.tenant import Tenant +from vmngclient.model.tenant import MigrationTenant, Tenant class TestTenantMigrationAPI(unittest.TestCase): @@ -20,6 +20,17 @@ def test_export_tenant(self): task = self.api.export_tenant(tenant=tenant) self.assertIsInstance(task, Task) + def test_export_migration_tenant(self): + tenant = MigrationTenant( + desc="Test Tenant", + name="test_tenant", + subdomain="test_subdomain", + org_name="test_org", + is_destination_overlay_mt=False, + ) + task = self.api.export_tenant(tenant=tenant) + self.assertIsInstance(task, Task) + def test_download(self): content = b"\xFFtest_data" with tempfile.TemporaryDirectory() as tmpdir: From 1183c5cbec3d7e1d2427bc1528ca95c13edc44fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20G=C3=B3rski?= <33100242+tehAgitto@users.noreply.github.com> Date: Tue, 19 Sep 2023 18:30:32 +0200 Subject: [PATCH 5/5] Add logo to README (#353) * add logo * blank * add transparency * blank * blank * blank * Change logo * rename * resize --- README.md | 7 ++++-- docs/vManage-client_LOGO.svg | 47 ++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 docs/vManage-client_LOGO.svg diff --git a/README.md b/README.md index fd2afe105..3af4a003f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ -# vManage-client +

+ vManage-client logo +

+ [![Python-Supported](https://img.shields.io/static/v1?label=Python&logo=Python&color=3776AB&message=3.8%20|%203.9%20|%203.10%20|%203.11)](https://www.python.org/) -vManage client is a package for creating simple and parallel automatic requests via official vManageAPI. It is intended to serve as a multiple session handler (provider, provider as a tenant, tenant). The library is not dependent on environment which is being run in, you just need a connection to any vManage. +vManage client is a package for creating simple and parallel automatic requests via official vManage API. It is intended to serve as a multiple session handler (provider, provider as a tenant, tenant). The library is not dependent on environment which is being run in, you just need a connection to any vManage. ## Installation ```console diff --git a/docs/vManage-client_LOGO.svg b/docs/vManage-client_LOGO.svg new file mode 100644 index 000000000..e414c2b9d --- /dev/null +++ b/docs/vManage-client_LOGO.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file