catalystwan 0.40.2.dev1__py3-none-any.whl → 2.0.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- catalystwan/core/__init__.py +2 -0
- catalystwan/core/abstractions.py +26 -0
- catalystwan/{apigw_auth.py → core/apigw_auth.py} +27 -14
- catalystwan/core/client.py +71 -0
- catalystwan/core/encoder.py +12 -0
- catalystwan/{exceptions.py → core/exceptions.py} +29 -9
- catalystwan/core/loader.py +37 -0
- catalystwan/{__init__.py → core/metadata.py} +9 -22
- catalystwan/core/models/deserialize.py +204 -0
- catalystwan/core/models/serialize.py +137 -0
- catalystwan/core/request_adapter.py +246 -0
- catalystwan/{request_limiter.py → core/request_limiter.py} +1 -2
- catalystwan/{response.py → core/response.py} +41 -88
- catalystwan/{session.py → core/session.py} +84 -101
- catalystwan/core/types.py +33 -0
- catalystwan/{version.py → core/version.py} +3 -5
- catalystwan/{vmanage_auth.py → core/vmanage_auth.py} +46 -21
- catalystwan-2.0.0a1.dist-info/METADATA +239 -0
- catalystwan-2.0.0a1.dist-info/RECORD +24 -0
- {catalystwan-0.40.2.dev1.dist-info → catalystwan-2.0.0a1.dist-info}/WHEEL +2 -1
- catalystwan-2.0.0a1.dist-info/top_level.txt +1 -0
- catalystwan/abstractions.py +0 -77
- catalystwan/api/admin_tech_api.py +0 -176
- catalystwan/api/administration.py +0 -434
- catalystwan/api/alarms_api.py +0 -186
- catalystwan/api/api_container.py +0 -73
- catalystwan/api/basic_api.py +0 -338
- catalystwan/api/builders/__init__.py +0 -14
- catalystwan/api/builders/feature_profiles/application_priority.py +0 -58
- catalystwan/api/builders/feature_profiles/builder_factory.py +0 -59
- catalystwan/api/builders/feature_profiles/cli.py +0 -76
- catalystwan/api/builders/feature_profiles/other.py +0 -79
- catalystwan/api/builders/feature_profiles/report.py +0 -137
- catalystwan/api/builders/feature_profiles/service.py +0 -213
- catalystwan/api/builders/feature_profiles/system.py +0 -80
- catalystwan/api/builders/feature_profiles/transport.py +0 -214
- catalystwan/api/builders/feature_profiles/uc_voice.py +0 -287
- catalystwan/api/config_device_inventory_api.py +0 -58
- catalystwan/api/config_group_api.py +0 -150
- catalystwan/api/configuration_groups/parcel.py +0 -206
- catalystwan/api/dashboard_api.py +0 -215
- catalystwan/api/device_action_api.py +0 -216
- catalystwan/api/feature_profile_api.py +0 -2401
- catalystwan/api/logs_api.py +0 -63
- catalystwan/api/monitoring_status_api.py +0 -76
- catalystwan/api/mtt_aaa_api.py +0 -197
- catalystwan/api/omp_api.py +0 -124
- catalystwan/api/packet_capture_api.py +0 -152
- catalystwan/api/parcel_api.py +0 -42
- catalystwan/api/partition_manager_api.py +0 -143
- catalystwan/api/policy_api.py +0 -1163
- catalystwan/api/resource_pool_api.py +0 -74
- catalystwan/api/software_action_api.py +0 -269
- catalystwan/api/speedtest_api.py +0 -153
- catalystwan/api/task_status_api.py +0 -171
- catalystwan/api/template_api.py +0 -761
- catalystwan/api/templates/README.md +0 -101
- catalystwan/api/templates/bool_str.py +0 -6
- catalystwan/api/templates/cli_template.py +0 -236
- catalystwan/api/templates/device_template/device_template.py +0 -189
- catalystwan/api/templates/device_variable.py +0 -7
- catalystwan/api/templates/feature_template.py +0 -133
- catalystwan/api/templates/feature_template_field.py +0 -175
- catalystwan/api/templates/feature_template_payload.py +0 -17
- catalystwan/api/templates/models/aaa_model.py +0 -387
- catalystwan/api/templates/models/cisco_aaa_model.py +0 -331
- catalystwan/api/templates/models/cisco_banner_model.py +0 -27
- catalystwan/api/templates/models/cisco_bfd_model.py +0 -61
- catalystwan/api/templates/models/cisco_bgp_model.py +0 -510
- catalystwan/api/templates/models/cisco_logging_model.py +0 -122
- catalystwan/api/templates/models/cisco_ntp_model.py +0 -60
- catalystwan/api/templates/models/cisco_omp_model.py +0 -121
- catalystwan/api/templates/models/cisco_ospf.py +0 -241
- catalystwan/api/templates/models/cisco_ospfv3.py +0 -498
- catalystwan/api/templates/models/cisco_secure_internet_gateway.py +0 -385
- catalystwan/api/templates/models/cisco_snmp_model.py +0 -102
- catalystwan/api/templates/models/cisco_system.py +0 -318
- catalystwan/api/templates/models/cisco_vpn_interface_model.py +0 -822
- catalystwan/api/templates/models/cisco_vpn_model.py +0 -603
- catalystwan/api/templates/models/cli_template.py +0 -18
- catalystwan/api/templates/models/omp_vsmart_model.py +0 -73
- catalystwan/api/templates/models/security_vsmart_model.py +0 -28
- catalystwan/api/templates/models/supported.py +0 -42
- catalystwan/api/templates/models/system_vsmart_model.py +0 -182
- catalystwan/api/templates/models/vpn_vsmart_interface_model.py +0 -198
- catalystwan/api/templates/models/vpn_vsmart_model.py +0 -124
- catalystwan/api/templates/payloads/aaa/aaa_model.py +0 -91
- catalystwan/api/templates/payloads/aaa/feature/aaa.json.j2 +0 -373
- catalystwan/api/templates/payloads/aaa/feature/accounting.json.j2 +0 -40
- catalystwan/api/templates/payloads/aaa/feature/radius.json.j2 +0 -107
- catalystwan/api/templates/payloads/aaa/feature/tacacs.json.j2 +0 -95
- catalystwan/api/templates/payloads/aaa/feature/user.json.j2 +0 -60
- catalystwan/api/templates/payloads/cisco_vpn/cisco_vpn_model.py +0 -92
- catalystwan/api/templates/payloads/cisco_vpn/feature/cisco_vpn.json.j2 +0 -224
- catalystwan/api/templates/payloads/cisco_vpn/feature/dns.json.j2 +0 -86
- catalystwan/api/templates/payloads/cisco_vpn/feature/ipv4route.json.j2 +0 -59
- catalystwan/api/templates/payloads/cisco_vpn/feature/ipv6route.json.j2 +0 -58
- catalystwan/api/templates/payloads/cisco_vpn/feature/mapping.json.j2 +0 -24
- catalystwan/api/templates/payloads/tenant/tenant.json.j2 +0 -127
- catalystwan/api/templates/payloads/tenant/tenant_model.py +0 -43
- catalystwan/api/tenant_backup_restore_api.py +0 -154
- catalystwan/api/tenant_management_api.py +0 -127
- catalystwan/api/tenant_migration_api.py +0 -121
- catalystwan/api/versions_utils.py +0 -414
- catalystwan/api/virtual_image_action_api.py +0 -200
- catalystwan/dataclasses.py +0 -493
- catalystwan/endpoints/__init__.py +0 -606
- catalystwan/endpoints/administration_user_and_group.py +0 -341
- catalystwan/endpoints/api_gateway.py +0 -24
- catalystwan/endpoints/certificate_management_device.py +0 -141
- catalystwan/endpoints/certificate_management_vmanage.py +0 -48
- catalystwan/endpoints/client.py +0 -96
- catalystwan/endpoints/cluster_management.py +0 -130
- catalystwan/endpoints/configuration/device/software_update.py +0 -31
- catalystwan/endpoints/configuration/disaster_recovery.py +0 -305
- catalystwan/endpoints/configuration/feature_profile/sdwan/application_priority.py +0 -107
- catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py +0 -60
- catalystwan/endpoints/configuration/feature_profile/sdwan/dns_security.py +0 -83
- catalystwan/endpoints/configuration/feature_profile/sdwan/embedded_security.py +0 -88
- catalystwan/endpoints/configuration/feature_profile/sdwan/other.py +0 -62
- catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py +0 -105
- catalystwan/endpoints/configuration/feature_profile/sdwan/service.py +0 -137
- catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py +0 -88
- catalystwan/endpoints/configuration/feature_profile/sdwan/system.py +0 -205
- catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py +0 -93
- catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py +0 -214
- catalystwan/endpoints/configuration/feature_profile/sdwan/uc_voice.py +0 -77
- catalystwan/endpoints/configuration/network_hierarchy.py +0 -32
- catalystwan/endpoints/configuration/policy/abstractions.py +0 -49
- catalystwan/endpoints/configuration/policy/definition/access_control_list.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/access_control_list_ipv6.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/aip.py +0 -52
- catalystwan/endpoints/configuration/policy/definition/amp.py +0 -52
- catalystwan/endpoints/configuration/policy/definition/app_route.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/cflowd.py +0 -46
- catalystwan/endpoints/configuration/policy/definition/control.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/device_access.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/device_access_ipv6.py +0 -59
- catalystwan/endpoints/configuration/policy/definition/dial_peer.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/dns_security.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/fxo_port.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/fxs_did_port.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/fxs_port.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/hub_and_spoke.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/intrusion_prevention.py +0 -52
- catalystwan/endpoints/configuration/policy/definition/mesh.py +0 -53
- catalystwan/endpoints/configuration/policy/definition/pri_isdn_port.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/qos_map.py +0 -53
- catalystwan/endpoints/configuration/policy/definition/rewrite.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/route_policy.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/rule_set.py +0 -53
- catalystwan/endpoints/configuration/policy/definition/security_group.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/srst_phone_profile.py +0 -59
- catalystwan/endpoints/configuration/policy/definition/ssl_decryption.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/ssl_decryption_utd_profile.py +0 -52
- catalystwan/endpoints/configuration/policy/definition/traffic_data.py +0 -58
- catalystwan/endpoints/configuration/policy/definition/url_filtering.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/vpn_membership.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/vpn_qos_map.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/zone_based_firewall.py +0 -57
- catalystwan/endpoints/configuration/policy/list/app.py +0 -48
- catalystwan/endpoints/configuration/policy/list/app_probe.py +0 -52
- catalystwan/endpoints/configuration/policy/list/as_path.py +0 -48
- catalystwan/endpoints/configuration/policy/list/class_map.py +0 -48
- catalystwan/endpoints/configuration/policy/list/color.py +0 -48
- catalystwan/endpoints/configuration/policy/list/community.py +0 -48
- catalystwan/endpoints/configuration/policy/list/data_ipv6_prefix.py +0 -52
- catalystwan/endpoints/configuration/policy/list/data_prefix.py +0 -48
- catalystwan/endpoints/configuration/policy/list/expanded_community.py +0 -52
- catalystwan/endpoints/configuration/policy/list/extended_community.py +0 -52
- catalystwan/endpoints/configuration/policy/list/fax_protocol.py +0 -48
- catalystwan/endpoints/configuration/policy/list/fqdn.py +0 -48
- catalystwan/endpoints/configuration/policy/list/geo_location.py +0 -48
- catalystwan/endpoints/configuration/policy/list/identity.py +0 -48
- catalystwan/endpoints/configuration/policy/list/ips_signature.py +0 -52
- catalystwan/endpoints/configuration/policy/list/ipv6_prefix.py +0 -48
- catalystwan/endpoints/configuration/policy/list/local_app.py +0 -48
- catalystwan/endpoints/configuration/policy/list/local_domain.py +0 -48
- catalystwan/endpoints/configuration/policy/list/media_profile.py +0 -52
- catalystwan/endpoints/configuration/policy/list/mirror.py +0 -48
- catalystwan/endpoints/configuration/policy/list/modem_pass_through.py +0 -52
- catalystwan/endpoints/configuration/policy/list/policer.py +0 -48
- catalystwan/endpoints/configuration/policy/list/port.py +0 -48
- catalystwan/endpoints/configuration/policy/list/preferred_color_group.py +0 -52
- catalystwan/endpoints/configuration/policy/list/prefix.py +0 -49
- catalystwan/endpoints/configuration/policy/list/protocol_name.py +0 -52
- catalystwan/endpoints/configuration/policy/list/region.py +0 -47
- catalystwan/endpoints/configuration/policy/list/scalable_group_tag.py +0 -52
- catalystwan/endpoints/configuration/policy/list/site.py +0 -52
- catalystwan/endpoints/configuration/policy/list/sla.py +0 -48
- catalystwan/endpoints/configuration/policy/list/supervisory_disconnect.py +0 -52
- catalystwan/endpoints/configuration/policy/list/threat_grid_api_key.py +0 -52
- catalystwan/endpoints/configuration/policy/list/tloc.py +0 -48
- catalystwan/endpoints/configuration/policy/list/translation_profile.py +0 -52
- catalystwan/endpoints/configuration/policy/list/translation_rules.py +0 -52
- catalystwan/endpoints/configuration/policy/list/trunkgroup.py +0 -48
- catalystwan/endpoints/configuration/policy/list/umbrella_data.py +0 -52
- catalystwan/endpoints/configuration/policy/list/url_allow_list.py +0 -48
- catalystwan/endpoints/configuration/policy/list/url_block_list.py +0 -48
- catalystwan/endpoints/configuration/policy/list/vpn.py +0 -50
- catalystwan/endpoints/configuration/policy/list/zone.py +0 -48
- catalystwan/endpoints/configuration/policy/security_template.py +0 -55
- catalystwan/endpoints/configuration/policy/vedge_template.py +0 -52
- catalystwan/endpoints/configuration/policy/voice_template.py +0 -39
- catalystwan/endpoints/configuration/policy/vsmart_template.py +0 -79
- catalystwan/endpoints/configuration/policy_group.py +0 -30
- catalystwan/endpoints/configuration/software_actions.py +0 -201
- catalystwan/endpoints/configuration/topology_group.py +0 -51
- catalystwan/endpoints/configuration_dashboard_status.py +0 -127
- catalystwan/endpoints/configuration_device_actions.py +0 -385
- catalystwan/endpoints/configuration_device_inventory.py +0 -309
- catalystwan/endpoints/configuration_device_template.py +0 -39
- catalystwan/endpoints/configuration_feature_profile.py +0 -135
- catalystwan/endpoints/configuration_general_template.py +0 -31
- catalystwan/endpoints/configuration_group.py +0 -197
- catalystwan/endpoints/configuration_settings.py +0 -753
- catalystwan/endpoints/configuration_template_master.py +0 -48
- catalystwan/endpoints/endpoints_container.py +0 -279
- catalystwan/endpoints/misc.py +0 -21
- catalystwan/endpoints/monitoring/device_details.py +0 -246
- catalystwan/endpoints/monitoring/security_policy.py +0 -12
- catalystwan/endpoints/monitoring/server_info.py +0 -12
- catalystwan/endpoints/monitoring/status.py +0 -76
- catalystwan/endpoints/real_time_monitoring/reboot_history.py +0 -35
- catalystwan/endpoints/sdavc_cloud_connector.py +0 -43
- catalystwan/endpoints/tenant_backup_restore.py +0 -40
- catalystwan/endpoints/tenant_management.py +0 -215
- catalystwan/endpoints/tenant_migration.py +0 -102
- catalystwan/endpoints/troubleshooting_tools/device_connectivity.py +0 -128
- catalystwan/endpoints/url_monitoring.py +0 -26
- catalystwan/integration_tests/__init__.py +0 -0
- catalystwan/integration_tests/base.py +0 -81
- catalystwan/integration_tests/feature_profile/sdwan/__init__.py +0 -0
- catalystwan/integration_tests/feature_profile/sdwan/policy/__init__.py +0 -0
- catalystwan/integration_tests/feature_profile/sdwan/policy/base.py +0 -33
- catalystwan/integration_tests/feature_profile/sdwan/policy/test_extended_community.py +0 -33
- catalystwan/integration_tests/feature_profile/sdwan/policy/test_security_app_list.py +0 -32
- catalystwan/integration_tests/feature_profile/sdwan/test_application_priority.py +0 -433
- catalystwan/integration_tests/feature_profile/sdwan/test_cli.py +0 -54
- catalystwan/integration_tests/feature_profile/sdwan/test_dns_security.py +0 -106
- catalystwan/integration_tests/feature_profile/sdwan/test_other.py +0 -49
- catalystwan/integration_tests/feature_profile/sdwan/test_service.py +0 -1078
- catalystwan/integration_tests/feature_profile/sdwan/test_sig_security.py +0 -322
- catalystwan/integration_tests/feature_profile/sdwan/test_ssl_decryption.py +0 -85
- catalystwan/integration_tests/feature_profile/sdwan/test_system.py +0 -368
- catalystwan/integration_tests/feature_profile/sdwan/test_transport.py +0 -1700
- catalystwan/integration_tests/feature_profile/sdwan/topology/test_topology.py +0 -93
- catalystwan/integration_tests/profile_builder/__init__.py +0 -0
- catalystwan/integration_tests/profile_builder/test_pb_service.py +0 -78
- catalystwan/integration_tests/profile_builder/test_pb_transport.py +0 -56
- catalystwan/integration_tests/profile_builder/test_pb_uc_voice.py +0 -277
- catalystwan/integration_tests/test_data/__init__.py +0 -117
- catalystwan/integration_tests/test_find_template_values.py +0 -38
- catalystwan/integration_tests/test_network_hierarchy.py +0 -82
- catalystwan/integration_tests/test_settings.py +0 -30
- catalystwan/logging.conf +0 -37
- catalystwan/models/common.py +0 -1508
- catalystwan/models/configuration/common.py +0 -11
- catalystwan/models/configuration/feature_profile/README.md +0 -344
- catalystwan/models/configuration/feature_profile/builder.py +0 -22
- catalystwan/models/configuration/feature_profile/common.py +0 -790
- catalystwan/models/configuration/feature_profile/parcel.py +0 -232
- catalystwan/models/configuration/feature_profile/sdwan/acl/__init__.py +0 -13
- catalystwan/models/configuration/feature_profile/sdwan/acl/ipv4acl.py +0 -298
- catalystwan/models/configuration/feature_profile/sdwan/acl/ipv6acl.py +0 -344
- catalystwan/models/configuration/feature_profile/sdwan/application_priority/__init__.py +0 -218
- catalystwan/models/configuration/feature_profile/sdwan/application_priority/cloud_probe.py +0 -61
- catalystwan/models/configuration/feature_profile/sdwan/application_priority/policy_settings.py +0 -31
- catalystwan/models/configuration/feature_profile/sdwan/application_priority/qos_policy.py +0 -102
- catalystwan/models/configuration/feature_profile/sdwan/application_priority/traffic_policy.py +0 -1054
- catalystwan/models/configuration/feature_profile/sdwan/cli/__init__.py +0 -23
- catalystwan/models/configuration/feature_profile/sdwan/cli/config.py +0 -18
- catalystwan/models/configuration/feature_profile/sdwan/cli/full_config.py +0 -15
- catalystwan/models/configuration/feature_profile/sdwan/dns_security/__init__.py +0 -13
- catalystwan/models/configuration/feature_profile/sdwan/dns_security/dns.py +0 -110
- catalystwan/models/configuration/feature_profile/sdwan/embedded_security/__init__.py +0 -23
- catalystwan/models/configuration/feature_profile/sdwan/embedded_security/ngfirewall.py +0 -915
- catalystwan/models/configuration/feature_profile/sdwan/embedded_security/policy.py +0 -171
- catalystwan/models/configuration/feature_profile/sdwan/other/__init__.py +0 -25
- catalystwan/models/configuration/feature_profile/sdwan/other/cybervision.py +0 -44
- catalystwan/models/configuration/feature_profile/sdwan/other/thousandeyes.py +0 -147
- catalystwan/models/configuration/feature_profile/sdwan/other/ucse.py +0 -110
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/__init__.py +0 -178
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/app_probe.py +0 -56
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/application_list.py +0 -31
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/as_path.py +0 -22
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/color_list.py +0 -21
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/data_prefix.py +0 -35
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/expanded_community_list.py +0 -25
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/extended_community.py +0 -34
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/fowarding_class.py +0 -26
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv4_network_object.py +0 -15
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv4_service_object.py +0 -254
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_data_prefix.py +0 -28
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_prefix_list.py +0 -38
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/mirror.py +0 -27
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/network_object_group.py +0 -15
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/object_group.py +0 -15
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/policer.py +0 -42
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefered_group_color.py +0 -83
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefix_list.py +0 -28
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/service_object_group.py +0 -21
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/sla_class.py +0 -130
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/standard_community.py +0 -30
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/tloc_list.py +0 -44
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/aip.py +0 -64
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/amp.py +0 -79
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/application_list.py +0 -31
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/data_prefix.py +0 -22
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/fqdn.py +0 -24
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/geolocation_list.py +0 -32
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/identity.py +0 -30
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/intrusion_prevention.py +0 -58
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ips_signature.py +0 -44
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/local_domain.py +0 -24
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/protocol_list.py +0 -21
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/scalable_group_tag.py +0 -26
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/security_port.py +0 -45
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption.py +0 -126
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption_profile.py +0 -165
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url.py +0 -32
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url_filtering.py +0 -148
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/zone.py +0 -44
- catalystwan/models/configuration/feature_profile/sdwan/routing/__init__.py +0 -26
- catalystwan/models/configuration/feature_profile/sdwan/routing/bgp.py +0 -609
- catalystwan/models/configuration/feature_profile/sdwan/routing/ospf.py +0 -173
- catalystwan/models/configuration/feature_profile/sdwan/routing/ospfv3.py +0 -301
- catalystwan/models/configuration/feature_profile/sdwan/service/__init__.py +0 -91
- catalystwan/models/configuration/feature_profile/sdwan/service/appqoe.py +0 -270
- catalystwan/models/configuration/feature_profile/sdwan/service/dhcp_server.py +0 -127
- catalystwan/models/configuration/feature_profile/sdwan/service/dual_router_ha.py +0 -26
- catalystwan/models/configuration/feature_profile/sdwan/service/eigrp.py +0 -103
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/common.py +0 -33
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/ethernet.py +0 -404
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/gre.py +0 -136
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/ipsec.py +0 -119
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/multilink.py +0 -101
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/svi.py +0 -182
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py +0 -627
- catalystwan/models/configuration/feature_profile/sdwan/service/multicast.py +0 -242
- catalystwan/models/configuration/feature_profile/sdwan/service/object_tracker.py +0 -84
- catalystwan/models/configuration/feature_profile/sdwan/service/route_policy.py +0 -419
- catalystwan/models/configuration/feature_profile/sdwan/service/service_chain.py +0 -38
- catalystwan/models/configuration/feature_profile/sdwan/service/service_insertion_attachment.py +0 -184
- catalystwan/models/configuration/feature_profile/sdwan/service/switchport.py +0 -110
- catalystwan/models/configuration/feature_profile/sdwan/service/tracker.py +0 -92
- catalystwan/models/configuration/feature_profile/sdwan/service/wireless_lan.py +0 -216
- catalystwan/models/configuration/feature_profile/sdwan/sig_security/__init__.py +0 -19
- catalystwan/models/configuration/feature_profile/sdwan/sig_security/sig_security.py +0 -379
- catalystwan/models/configuration/feature_profile/sdwan/system/__init__.py +0 -59
- catalystwan/models/configuration/feature_profile/sdwan/system/aaa.py +0 -406
- catalystwan/models/configuration/feature_profile/sdwan/system/banner.py +0 -30
- catalystwan/models/configuration/feature_profile/sdwan/system/basic.py +0 -290
- catalystwan/models/configuration/feature_profile/sdwan/system/bfd.py +0 -69
- catalystwan/models/configuration/feature_profile/sdwan/system/device_access.py +0 -157
- catalystwan/models/configuration/feature_profile/sdwan/system/device_access_ipv6.py +0 -157
- catalystwan/models/configuration/feature_profile/sdwan/system/global_parcel.py +0 -163
- catalystwan/models/configuration/feature_profile/sdwan/system/logging_parcel.py +0 -162
- catalystwan/models/configuration/feature_profile/sdwan/system/mrf.py +0 -75
- catalystwan/models/configuration/feature_profile/sdwan/system/ntp.py +0 -103
- catalystwan/models/configuration/feature_profile/sdwan/system/omp.py +0 -120
- catalystwan/models/configuration/feature_profile/sdwan/system/security.py +0 -179
- catalystwan/models/configuration/feature_profile/sdwan/system/snmp.py +0 -173
- catalystwan/models/configuration/feature_profile/sdwan/topology/__init__.py +0 -29
- catalystwan/models/configuration/feature_profile/sdwan/topology/custom_control.py +0 -425
- catalystwan/models/configuration/feature_profile/sdwan/topology/hubspoke.py +0 -60
- catalystwan/models/configuration/feature_profile/sdwan/topology/mesh.py +0 -23
- catalystwan/models/configuration/feature_profile/sdwan/transport/__init__.py +0 -93
- catalystwan/models/configuration/feature_profile/sdwan/transport/cellular_controller.py +0 -58
- catalystwan/models/configuration/feature_profile/sdwan/transport/cellular_profile.py +0 -71
- catalystwan/models/configuration/feature_profile/sdwan/transport/gps.py +0 -37
- catalystwan/models/configuration/feature_profile/sdwan/transport/management/ethernet.py +0 -121
- catalystwan/models/configuration/feature_profile/sdwan/transport/t1e1controller.py +0 -124
- catalystwan/models/configuration/feature_profile/sdwan/transport/vpn.py +0 -285
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/cellular.py +0 -173
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/ethernet.py +0 -389
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/gre.py +0 -46
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/ipsec.py +0 -98
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/multilink.py +0 -219
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/protocol_over.py +0 -405
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/t1e1serial.py +0 -195
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/__init__.py +0 -62
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/analog_interface.py +0 -436
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/call_routing.py +0 -179
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/digital_interface.py +0 -375
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/dsp_farm.py +0 -193
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/media_profile.py +0 -25
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/server_group.py +0 -51
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/srst.py +0 -86
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/supervisory_disconnect.py +0 -68
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/translation_profile.py +0 -42
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/translation_rule.py +0 -31
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/trunk_group.py +0 -26
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/voice_global.py +0 -55
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/voice_tenant.py +0 -40
- catalystwan/models/configuration/network_hierarchy/__init__.py +0 -22
- catalystwan/models/configuration/network_hierarchy/cflowd.py +0 -120
- catalystwan/models/configuration/network_hierarchy/node.py +0 -88
- catalystwan/models/configuration/policy_group.py +0 -74
- catalystwan/models/configuration/profile_type.py +0 -5
- catalystwan/models/configuration/topology_group.py +0 -52
- catalystwan/models/device_inventory.py +0 -30
- catalystwan/models/feature_profile_parcel.py +0 -15
- catalystwan/models/misc/application_protocols.py +0 -29
- catalystwan/models/monitoring/security_policy.py +0 -16
- catalystwan/models/monitoring/server_info.py +0 -12
- catalystwan/models/policy/__init__.py +0 -392
- catalystwan/models/policy/centralized.py +0 -265
- catalystwan/models/policy/definition/access_control_list.py +0 -193
- catalystwan/models/policy/definition/access_control_list_ipv6.py +0 -187
- catalystwan/models/policy/definition/aip.py +0 -60
- catalystwan/models/policy/definition/amp.py +0 -65
- catalystwan/models/policy/definition/app_route.py +0 -246
- catalystwan/models/policy/definition/cflowd.py +0 -95
- catalystwan/models/policy/definition/control.py +0 -366
- catalystwan/models/policy/definition/device_access.py +0 -117
- catalystwan/models/policy/definition/device_access_ipv6.py +0 -115
- catalystwan/models/policy/definition/dial_peer.py +0 -60
- catalystwan/models/policy/definition/dns_security.py +0 -130
- catalystwan/models/policy/definition/fxo_port.py +0 -63
- catalystwan/models/policy/definition/fxs_did_port.py +0 -58
- catalystwan/models/policy/definition/fxs_port.py +0 -56
- catalystwan/models/policy/definition/hub_and_spoke.py +0 -87
- catalystwan/models/policy/definition/intrusion_prevention.py +0 -55
- catalystwan/models/policy/definition/mesh.py +0 -47
- catalystwan/models/policy/definition/pri_isdn_port.py +0 -48
- catalystwan/models/policy/definition/qos_map.py +0 -111
- catalystwan/models/policy/definition/rewrite.py +0 -47
- catalystwan/models/policy/definition/route_policy.py +0 -187
- catalystwan/models/policy/definition/rule_set.py +0 -270
- catalystwan/models/policy/definition/security_group.py +0 -93
- catalystwan/models/policy/definition/srst_phone_profile.py +0 -37
- catalystwan/models/policy/definition/ssl_decryption.py +0 -209
- catalystwan/models/policy/definition/ssl_decryption_utd_profile.py +0 -87
- catalystwan/models/policy/definition/traffic_data.py +0 -496
- catalystwan/models/policy/definition/url_filtering.py +0 -70
- catalystwan/models/policy/definition/vpn_membership.py +0 -42
- catalystwan/models/policy/definition/vpn_qos_map.py +0 -46
- catalystwan/models/policy/definition/zone_based_firewall.py +0 -301
- catalystwan/models/policy/list/app.py +0 -44
- catalystwan/models/policy/list/app_probe.py +0 -42
- catalystwan/models/policy/list/as_path.py +0 -30
- catalystwan/models/policy/list/class_map.py +0 -30
- catalystwan/models/policy/list/color.py +0 -28
- catalystwan/models/policy/list/communities.py +0 -83
- catalystwan/models/policy/list/data_ipv6_prefix.py +0 -30
- catalystwan/models/policy/list/data_prefix.py +0 -30
- catalystwan/models/policy/list/fax_protocol.py +0 -45
- catalystwan/models/policy/list/fqdn.py +0 -24
- catalystwan/models/policy/list/geo_location.py +0 -33
- catalystwan/models/policy/list/identity.py +0 -29
- catalystwan/models/policy/list/ips_signature.py +0 -27
- catalystwan/models/policy/list/ipv6_prefix.py +0 -33
- catalystwan/models/policy/list/local_app.py +0 -45
- catalystwan/models/policy/list/local_domain.py +0 -36
- catalystwan/models/policy/list/media_profile.py +0 -44
- catalystwan/models/policy/list/mirror.py +0 -27
- catalystwan/models/policy/list/modem_pass_through.py +0 -27
- catalystwan/models/policy/list/policer.py +0 -39
- catalystwan/models/policy/list/port.py +0 -33
- catalystwan/models/policy/list/preferred_color_group.py +0 -82
- catalystwan/models/policy/list/prefix.py +0 -33
- catalystwan/models/policy/list/protocol_name.py +0 -26
- catalystwan/models/policy/list/region.py +0 -45
- catalystwan/models/policy/list/scalable_group_tag.py +0 -30
- catalystwan/models/policy/list/site.py +0 -34
- catalystwan/models/policy/list/sla.py +0 -77
- catalystwan/models/policy/list/supervisory_disconnect.py +0 -62
- catalystwan/models/policy/list/threat_grid_api_key.py +0 -32
- catalystwan/models/policy/list/tloc.py +0 -32
- catalystwan/models/policy/list/translation_profile.py +0 -32
- catalystwan/models/policy/list/translation_rules.py +0 -29
- catalystwan/models/policy/list/trunkgroup.py +0 -56
- catalystwan/models/policy/list/umbrella_data.py +0 -30
- catalystwan/models/policy/list/url.py +0 -39
- catalystwan/models/policy/list/vpn.py +0 -40
- catalystwan/models/policy/list/zone.py +0 -45
- catalystwan/models/policy/localized.py +0 -154
- catalystwan/models/policy/policy.py +0 -100
- catalystwan/models/policy/policy_definition.py +0 -1624
- catalystwan/models/policy/policy_list.py +0 -47
- catalystwan/models/policy/security.py +0 -279
- catalystwan/models/policy/voice.py +0 -77
- catalystwan/models/settings.py +0 -41
- catalystwan/models/templates.py +0 -79
- catalystwan/models/tenant.py +0 -105
- catalystwan/models/url_monitoring.py +0 -28
- catalystwan/tests/__init__.py +0 -0
- catalystwan/tests/builders/uc_voice.py +0 -85
- catalystwan/tests/models/__init__.py +0 -0
- catalystwan/tests/models/test_digital_interface.py +0 -56
- catalystwan/tests/templates/__init__.py +0 -0
- catalystwan/tests/templates/definitions/__init__.py +0 -0
- catalystwan/tests/templates/definitions/aaa_basic.json +0 -96
- catalystwan/tests/templates/definitions/aaa_complex.json +0 -464
- catalystwan/tests/templates/definitions/basic/__init__.py +0 -0
- catalystwan/tests/templates/definitions/basic/alias.json +0 -7
- catalystwan/tests/templates/definitions/basic/basic.json +0 -7
- catalystwan/tests/templates/definitions/basic/basic_no_value.json +0 -7
- catalystwan/tests/templates/definitions/basic/children.json +0 -39
- catalystwan/tests/templates/definitions/basic/children_nested.json +0 -72
- catalystwan/tests/templates/definitions/basic/children_nested_datapath.json +0 -72
- catalystwan/tests/templates/definitions/basic/data_path.json +0 -13
- catalystwan/tests/templates/definitions/cisco_aaa.json +0 -178
- catalystwan/tests/templates/definitions/cisco_aaa_complex.json +0 -361
- catalystwan/tests/templates/definitions/cisco_banner.json +0 -20
- catalystwan/tests/templates/definitions/cisco_bfd.json +0 -90
- catalystwan/tests/templates/definitions/cisco_logging_complex.json +0 -268
- catalystwan/tests/templates/definitions/cisco_ntp_complex.json +0 -143
- catalystwan/tests/templates/definitions/cisco_omp_complex.json +0 -175
- catalystwan/tests/templates/definitions/cisco_ospf_complex.json +0 -302
- catalystwan/tests/templates/definitions/cisco_sig.json +0 -405
- catalystwan/tests/templates/definitions/cisco_snmp_complex.json +0 -258
- catalystwan/tests/templates/definitions/cisco_system_complex.json +0 -502
- catalystwan/tests/templates/definitions/cisco_vpn_basic.json +0 -17
- catalystwan/tests/templates/definitions/cisco_vpn_complex.json +0 -1081
- catalystwan/tests/templates/definitions/cisco_vpn_interface_complex.json +0 -821
- catalystwan/tests/templates/definitions/default_cisco_system.json +0 -184
- catalystwan/tests/templates/definitions/omp_vsmart_1.json +0 -26
- catalystwan/tests/templates/definitions/omp_vsmart_2.json +0 -48
- catalystwan/tests/templates/definitions/omp_vsmart_3.json +0 -71
- catalystwan/tests/templates/definitions/omp_vsmart_complex.json +0 -73
- catalystwan/tests/templates/definitions/security_vsmart_complex.json +0 -24
- catalystwan/tests/templates/definitions/system_vsmart_complex.json +0 -193
- catalystwan/tests/templates/definitions/vpn_vsmart_basic.json +0 -17
- catalystwan/tests/templates/definitions/vpn_vsmart_complex.json +0 -179
- catalystwan/tests/templates/definitions/vpn_vsmart_interface_basic.json +0 -42
- catalystwan/tests/templates/definitions/vpn_vsmart_interface_complex.json +0 -208
- catalystwan/tests/templates/models/__init__.py +0 -53
- catalystwan/tests/templates/models/aaa.py +0 -106
- catalystwan/tests/templates/models/cisco_aaa.py +0 -124
- catalystwan/tests/templates/models/cisco_banner.py +0 -7
- catalystwan/tests/templates/models/cisco_bfd.py +0 -15
- catalystwan/tests/templates/models/cisco_logging.py +0 -65
- catalystwan/tests/templates/models/cisco_ntp.py +0 -17
- catalystwan/tests/templates/models/cisco_omp.py +0 -37
- catalystwan/tests/templates/models/cisco_ospf.py +0 -60
- catalystwan/tests/templates/models/cisco_secure_internet_gateway.py +0 -95
- catalystwan/tests/templates/models/cisco_snmp.py +0 -40
- catalystwan/tests/templates/models/cisco_system.py +0 -113
- catalystwan/tests/templates/models/cisco_vpn.py +0 -240
- catalystwan/tests/templates/models/cisco_vpn_interface.py +0 -200
- catalystwan/tests/templates/models/omp_vsmart.py +0 -53
- catalystwan/tests/templates/models/security_vsmart.py +0 -11
- catalystwan/tests/templates/models/system_vsmart.py +0 -37
- catalystwan/tests/templates/models/vpn_vsmart.py +0 -32
- catalystwan/tests/templates/models/vpn_vsmart_interface.py +0 -54
- catalystwan/tests/templates/schemas/aaa.json +0 -1096
- catalystwan/tests/templates/schemas/basic/alias.json +0 -24
- catalystwan/tests/templates/schemas/basic/basic.json +0 -23
- catalystwan/tests/templates/schemas/basic/children.json +0 -59
- catalystwan/tests/templates/schemas/basic/children_nested.json +0 -112
- catalystwan/tests/templates/schemas/basic/children_nested_datapath.json +0 -112
- catalystwan/tests/templates/schemas/basic/data_path.json +0 -29
- catalystwan/tests/templates/schemas/cedge_aaa.json +0 -1185
- catalystwan/tests/templates/schemas/cisco_banner.json +0 -44
- catalystwan/tests/templates/schemas/cisco_bfd.json +0 -266
- catalystwan/tests/templates/schemas/cisco_logging.json +0 -577
- catalystwan/tests/templates/schemas/cisco_ntp.json +0 -265
- catalystwan/tests/templates/schemas/cisco_omp.json +0 -479
- catalystwan/tests/templates/schemas/cisco_ospf.json +0 -908
- catalystwan/tests/templates/schemas/cisco_secure_internet_gateway.json +0 -1520
- catalystwan/tests/templates/schemas/cisco_snmp.json +0 -561
- catalystwan/tests/templates/schemas/cisco_system.json +0 -3099
- catalystwan/tests/templates/schemas/cisco_vpn.json +0 -2504
- catalystwan/tests/templates/schemas/cisco_vpn_interface.json +0 -3348
- catalystwan/tests/templates/schemas/omp-vsmart.json +0 -222
- catalystwan/tests/templates/schemas/security-vsmart.json +0 -58
- catalystwan/tests/templates/schemas/system-vsmart.json +0 -2585
- catalystwan/tests/templates/schemas/vpn-vsmart-interface.json +0 -859
- catalystwan/tests/templates/schemas/vpn-vsmart.json +0 -445
- catalystwan/tests/templates/test_chose_model.py +0 -32
- catalystwan/tests/templates/test_deserialize_model.py +0 -69
- catalystwan/tests/templates/test_find_template_values.py +0 -193
- catalystwan/tests/templates/test_find_template_values_2.py +0 -193
- catalystwan/tests/templates/test_generate_payload.py +0 -137
- catalystwan/tests/templates/test_serialize_model.py +0 -52
- catalystwan/tests/test_admin_tech_api.py +0 -198
- catalystwan/tests/test_administration.py +0 -470
- catalystwan/tests/test_alarms_api.py +0 -251
- catalystwan/tests/test_cli_template.py +0 -218
- catalystwan/tests/test_creation_tools.py +0 -155
- catalystwan/tests/test_device_action_api.py +0 -117
- catalystwan/tests/test_devices_api.py +0 -674
- catalystwan/tests/test_endpoints.py +0 -907
- catalystwan/tests/test_feature_profile_api.py +0 -282
- catalystwan/tests/test_feature_template_field.py +0 -33
- catalystwan/tests/test_logs_api.py +0 -40
- catalystwan/tests/test_models_common.py +0 -53
- catalystwan/tests/test_monitoring_security_policy.py +0 -65
- catalystwan/tests/test_monitoring_server_info.py +0 -49
- catalystwan/tests/test_monitoring_status_api.py +0 -118
- catalystwan/tests/test_mtt_aaa_api.py +0 -293
- catalystwan/tests/test_omp_api.py +0 -438
- catalystwan/tests/test_packet_capture.py +0 -125
- catalystwan/tests/test_partition_manager_api.py +0 -121
- catalystwan/tests/test_response.py +0 -183
- catalystwan/tests/test_session.py +0 -102
- catalystwan/tests/test_software_action_api.py +0 -154
- catalystwan/tests/test_speed_test_api.py +0 -143
- catalystwan/tests/test_task_status_api.py +0 -381
- catalystwan/tests/test_templates.py +0 -405
- catalystwan/tests/test_tenant_backup_restore_api.py +0 -88
- catalystwan/tests/test_tenant_management_api.py +0 -153
- catalystwan/tests/test_tenant_migration_api.py +0 -102
- catalystwan/tests/test_typed_list.py +0 -426
- catalystwan/tests/test_url_monitoring.py +0 -80
- catalystwan/tests/test_version.py +0 -99
- catalystwan/tests/test_version_utils.py +0 -240
- catalystwan/tests/test_vmanage_auth.py +0 -149
- catalystwan/typed_list.py +0 -288
- catalystwan/utils/__init__.py +0 -0
- catalystwan/utils/alarm_status.py +0 -16
- catalystwan/utils/certificate_status.py +0 -13
- catalystwan/utils/colors.py +0 -12
- catalystwan/utils/config_status.py +0 -8
- catalystwan/utils/creation_tools.py +0 -136
- catalystwan/utils/dashboard.py +0 -255
- catalystwan/utils/device_model.py +0 -322
- catalystwan/utils/dict.py +0 -61
- catalystwan/utils/feature_template/choose_model.py +0 -30
- catalystwan/utils/feature_template/find_template_values.py +0 -111
- catalystwan/utils/model.py +0 -45
- catalystwan/utils/operation_status.py +0 -22
- catalystwan/utils/persona.py +0 -5
- catalystwan/utils/personality.py +0 -10
- catalystwan/utils/pydantic_field.py +0 -12
- catalystwan/utils/reachability.py +0 -14
- catalystwan/utils/session_type.py +0 -17
- catalystwan/utils/template_type.py +0 -8
- catalystwan/utils/type_check.py +0 -22
- catalystwan/utils/upgrades_helper.py +0 -95
- catalystwan/utils/validate_status.py +0 -8
- catalystwan/workflows/backup_restore_device_templates.py +0 -467
- catalystwan/workflows/tenant_migration.py +0 -203
- catalystwan-0.40.2.dev1.dist-info/METADATA +0 -539
- catalystwan-0.40.2.dev1.dist-info/RECORD +0 -628
- /catalystwan/{api → core/models}/__init__.py +0 -0
- /catalystwan/{api/builders/feature_profiles/__init__.py → core/py.typed} +0 -0
- {catalystwan-0.40.2.dev1.dist-info → catalystwan-2.0.0a1.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from dataclasses import Field, fields, is_dataclass
|
|
2
|
+
from typing import Any, Dict, List, Optional, Protocol, Union, cast
|
|
3
|
+
|
|
4
|
+
from catalystwan.core.encoder import serialize_model_value
|
|
5
|
+
from catalystwan.core.types import MODEL_TYPES, AliasPath, DataclassInstance, is_variable
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ValueWrapperCallable(Protocol):
|
|
9
|
+
def __call__(self, field: Field, field_value: Any, to_json: bool): ...
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ModelSerializer:
|
|
13
|
+
def __init__(self, model: DataclassInstance):
|
|
14
|
+
self.model = model
|
|
15
|
+
try:
|
|
16
|
+
self.model_type: MODEL_TYPES = model._catalystwan_model_type # type: ignore[attr-defined]
|
|
17
|
+
except AttributeError:
|
|
18
|
+
self.model_type = "base"
|
|
19
|
+
# Values need to be wrapped in a specific form, depending on the model type
|
|
20
|
+
self.VALUE_WRAPPERS: Dict[MODEL_TYPES, ValueWrapperCallable] = {
|
|
21
|
+
"base": self.__value_wrapper_base,
|
|
22
|
+
"feature_template": self.__value_wrapper_ft,
|
|
23
|
+
"parcel": self.__value_wrapper_parcel,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def serialize(
|
|
27
|
+
self, by_alias: bool = True, to_json: bool = False, exclude_none: bool = True
|
|
28
|
+
) -> Dict[str, Any]:
|
|
29
|
+
return_dict: Dict[str, Any] = {}
|
|
30
|
+
for field in fields(self.model):
|
|
31
|
+
return_value = getattr(self.model, field.name)
|
|
32
|
+
# skip None values, if needed
|
|
33
|
+
if exclude_none and return_value is None:
|
|
34
|
+
continue
|
|
35
|
+
|
|
36
|
+
return_value = self.__value_serializer(
|
|
37
|
+
field, return_value, by_alias, to_json, exclude_none
|
|
38
|
+
)
|
|
39
|
+
if by_alias:
|
|
40
|
+
alias: Optional[Union[str, AliasPath]] = field.metadata.get("alias")
|
|
41
|
+
field_name = alias or field.name
|
|
42
|
+
key_path = field_name if isinstance(field_name, AliasPath) else [field_name]
|
|
43
|
+
self.__insert_key(return_dict, key_path, return_value)
|
|
44
|
+
else:
|
|
45
|
+
return_dict[field.name] = return_value
|
|
46
|
+
return return_dict
|
|
47
|
+
|
|
48
|
+
def __value_serializer(
|
|
49
|
+
self,
|
|
50
|
+
field: Field,
|
|
51
|
+
field_value: Any,
|
|
52
|
+
by_alias: bool,
|
|
53
|
+
to_json: bool,
|
|
54
|
+
exclude_none: bool,
|
|
55
|
+
) -> Any:
|
|
56
|
+
return_value: Any
|
|
57
|
+
if is_dataclass(field_value):
|
|
58
|
+
return_value = serialize(
|
|
59
|
+
model=cast(DataclassInstance, field_value),
|
|
60
|
+
by_alias=by_alias,
|
|
61
|
+
to_json=to_json,
|
|
62
|
+
exclude_none=exclude_none,
|
|
63
|
+
)
|
|
64
|
+
elif isinstance(field_value, list):
|
|
65
|
+
if len(field_value) == 0 or not is_dataclass(field_value[0]):
|
|
66
|
+
return_value = serialize_model_value(field_value, to_json)
|
|
67
|
+
else:
|
|
68
|
+
return_value = [
|
|
69
|
+
serialize(
|
|
70
|
+
model=v,
|
|
71
|
+
by_alias=by_alias,
|
|
72
|
+
to_json=to_json,
|
|
73
|
+
exclude_none=exclude_none,
|
|
74
|
+
)
|
|
75
|
+
for v in field_value
|
|
76
|
+
]
|
|
77
|
+
else:
|
|
78
|
+
return_value = serialize_model_value(field_value, to_json)
|
|
79
|
+
|
|
80
|
+
return self.__value_wrapper(field=field, field_value=return_value, to_json=to_json)
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def __value_wrapper(self) -> ValueWrapperCallable:
|
|
84
|
+
return self.VALUE_WRAPPERS[self.model_type]
|
|
85
|
+
|
|
86
|
+
def __value_wrapper_base(self, field: Field, field_value: Any, to_json: bool):
|
|
87
|
+
return field_value
|
|
88
|
+
|
|
89
|
+
def __value_wrapper_ft(self, field: Field, field_value: Any, to_json: bool) -> Any:
|
|
90
|
+
if not field.metadata.get("wrap", True) or not to_json:
|
|
91
|
+
return field_value
|
|
92
|
+
if is_variable(field_value):
|
|
93
|
+
return {
|
|
94
|
+
"vipType": "variable",
|
|
95
|
+
"vipValue": field_value,
|
|
96
|
+
"vipObjectType": field.metadata.get("object_type"),
|
|
97
|
+
}
|
|
98
|
+
else:
|
|
99
|
+
return {
|
|
100
|
+
"vipType": "constant",
|
|
101
|
+
"vipValue": field_value,
|
|
102
|
+
"vipObjectType": field.metadata.get("object_type"),
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
def __value_wrapper_parcel(self, field: Field, field_value: Any, to_json: bool) -> Any:
|
|
106
|
+
if (
|
|
107
|
+
not field.metadata.get("wrap", True)
|
|
108
|
+
or (isinstance(field_value, (list, dict)) or is_dataclass(field_value))
|
|
109
|
+
or not to_json
|
|
110
|
+
):
|
|
111
|
+
return field_value
|
|
112
|
+
if is_variable(field_value):
|
|
113
|
+
return {"option_type": "variable", "value": field_value}
|
|
114
|
+
elif field_value == field.default:
|
|
115
|
+
return {"option_type": "default", "value": field_value}
|
|
116
|
+
else:
|
|
117
|
+
return {"option_type": "global", "value": field_value}
|
|
118
|
+
|
|
119
|
+
def __insert_key(self, d: Dict[str, Any], key_path: List[str], value: Any):
|
|
120
|
+
nested = d
|
|
121
|
+
for key in key_path[:-1]:
|
|
122
|
+
nested = nested.setdefault(key, {})
|
|
123
|
+
nested[key_path[-1]] = value
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def serialize(
|
|
127
|
+
model: DataclassInstance,
|
|
128
|
+
by_alias: bool = True,
|
|
129
|
+
to_json: bool = False,
|
|
130
|
+
exclude_none: bool = True,
|
|
131
|
+
) -> Dict[str, Any]:
|
|
132
|
+
if not is_dataclass(model):
|
|
133
|
+
raise Exception
|
|
134
|
+
|
|
135
|
+
return ModelSerializer(model=model).serialize(
|
|
136
|
+
by_alias=by_alias, to_json=to_json, exclude_none=exclude_none
|
|
137
|
+
)
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from copy import copy
|
|
5
|
+
from dataclasses import dataclass, field, fields, is_dataclass
|
|
6
|
+
from string import Formatter
|
|
7
|
+
from typing import Any, Dict, List, Optional, Type, TypeVar, Union, cast
|
|
8
|
+
|
|
9
|
+
from catalystwan.abc import RequestAdapterInterface, ResponseInterface, SessionInterface
|
|
10
|
+
from catalystwan.abc.types import HTTP_METHOD, JSON
|
|
11
|
+
from catalystwan.core.exceptions import (
|
|
12
|
+
CatalystwanModelValidationError,
|
|
13
|
+
CatalystwanResponseTypeError,
|
|
14
|
+
)
|
|
15
|
+
from catalystwan.core.models.deserialize import deserialize
|
|
16
|
+
from catalystwan.core.models.serialize import serialize
|
|
17
|
+
from catalystwan.core.types import DataclassInstance
|
|
18
|
+
from typing_extensions import get_args, get_origin
|
|
19
|
+
|
|
20
|
+
DataclassType = TypeVar("DataclassType", bound=DataclassInstance)
|
|
21
|
+
ReturnType = TypeVar("ReturnType")
|
|
22
|
+
Payload = TypeVar("Payload")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class JsonContent:
|
|
27
|
+
# data extracted from a specific key
|
|
28
|
+
extracted_data: JSON
|
|
29
|
+
# raw version of the data
|
|
30
|
+
raw_data: JSON
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Used for data extraction from a response, when it takes a specific form.
|
|
34
|
+
# data_key is the key to pull data from, if required_keys are present
|
|
35
|
+
@dataclass
|
|
36
|
+
class ResponseDataPath:
|
|
37
|
+
data_key: str
|
|
38
|
+
required_keys: List[str] = field(default_factory=list)
|
|
39
|
+
|
|
40
|
+
def is_data_available(self, data: Dict[str, Any]) -> bool:
|
|
41
|
+
keys = self.required_keys + [self.data_key]
|
|
42
|
+
return all(key in data for key in keys)
|
|
43
|
+
|
|
44
|
+
def get_data(self, data: Dict[str, Any]) -> JSON:
|
|
45
|
+
return data[self.data_key]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class RequestAdapter(RequestAdapterInterface):
|
|
49
|
+
known_data_paths: List[ResponseDataPath] = [
|
|
50
|
+
ResponseDataPath(data_key="data", required_keys=["header"]),
|
|
51
|
+
ResponseDataPath(data_key="devices", required_keys=["header"]),
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
def __init__(self, session: SessionInterface, logger: Optional[logging.Logger] = None):
|
|
55
|
+
self.session = session
|
|
56
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
57
|
+
|
|
58
|
+
def request(
|
|
59
|
+
self,
|
|
60
|
+
method: HTTP_METHOD,
|
|
61
|
+
url: str,
|
|
62
|
+
payload: Union[Payload, JSON] = None,
|
|
63
|
+
params: Optional[dict] = None,
|
|
64
|
+
return_type: Optional[Type[ReturnType]] = None,
|
|
65
|
+
headers: Optional[dict] = None,
|
|
66
|
+
**kwargs,
|
|
67
|
+
) -> Union[ReturnType, JSON, bytes, None]:
|
|
68
|
+
if params:
|
|
69
|
+
path_keys = [
|
|
70
|
+
field_name
|
|
71
|
+
for _, field_name, _, _ in Formatter().parse(url)
|
|
72
|
+
if field_name is not None
|
|
73
|
+
]
|
|
74
|
+
url = url.format_map({path_key: params.pop(path_key) for path_key in path_keys})
|
|
75
|
+
if is_dataclass(payload):
|
|
76
|
+
payload = serialize(cast(DataclassInstance, payload), to_json=True)
|
|
77
|
+
response = self.session.request(
|
|
78
|
+
method=method,
|
|
79
|
+
url=url,
|
|
80
|
+
json=payload,
|
|
81
|
+
params=params,
|
|
82
|
+
headers=headers,
|
|
83
|
+
**kwargs,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
content = self.__get_content(response)
|
|
87
|
+
return self.__prepare_return_type(return_type, content)
|
|
88
|
+
|
|
89
|
+
def __prepare_return_type(
|
|
90
|
+
self, return_type: Optional[Type[ReturnType]], content: Union[JsonContent, str, bytes, None]
|
|
91
|
+
) -> Union[ReturnType, JSON, bytes, None]:
|
|
92
|
+
if is_dataclass(return_type):
|
|
93
|
+
return cast(
|
|
94
|
+
ReturnType, self.__get_dataclass(return_type=return_type, model_payload=content)
|
|
95
|
+
)
|
|
96
|
+
# If we are expecting a list, it should be found within the extracted_data - the response was either a list from
|
|
97
|
+
# the beginning or we extracted it from an appropriate key
|
|
98
|
+
elif (
|
|
99
|
+
get_origin(return_type) is list
|
|
100
|
+
and type(content) is JsonContent
|
|
101
|
+
and type(content.extracted_data) is list
|
|
102
|
+
):
|
|
103
|
+
return [
|
|
104
|
+
self.__parse_list(get_args(return_type)[0], value)
|
|
105
|
+
for value in content.extracted_data
|
|
106
|
+
]
|
|
107
|
+
else:
|
|
108
|
+
extracted_data: Union[JSON, bytes, None]
|
|
109
|
+
if isinstance(content, JsonContent):
|
|
110
|
+
extracted_data = content.extracted_data
|
|
111
|
+
else:
|
|
112
|
+
extracted_data = content
|
|
113
|
+
if type(extracted_data) is not return_type and return_type is not None:
|
|
114
|
+
self.logger.warning(
|
|
115
|
+
f"Server returned unexpected data. Expected: {return_type}, received {type(extracted_data)}"
|
|
116
|
+
)
|
|
117
|
+
return extracted_data
|
|
118
|
+
|
|
119
|
+
def __get_content(self, response: ResponseInterface) -> Union[JsonContent, str, bytes, None]:
|
|
120
|
+
content_type: str = response.headers.get("content-type", "")
|
|
121
|
+
if not content_type:
|
|
122
|
+
return None
|
|
123
|
+
if content_type.startswith("application/json"):
|
|
124
|
+
return self.__extract_json_data(response.json())
|
|
125
|
+
if content_type.startswith("text"):
|
|
126
|
+
return response.text
|
|
127
|
+
else:
|
|
128
|
+
return response.content
|
|
129
|
+
|
|
130
|
+
def __parse_list(
|
|
131
|
+
self, arg_type: Type[ReturnType], values: Union[JSON]
|
|
132
|
+
) -> Union[ReturnType, JSON]:
|
|
133
|
+
if is_dataclass(arg_type):
|
|
134
|
+
model_payload = self.__extract_json_data(values)
|
|
135
|
+
return cast(
|
|
136
|
+
ReturnType, self.__get_dataclass(return_type=arg_type, model_payload=model_payload)
|
|
137
|
+
)
|
|
138
|
+
elif get_origin(arg_type) is list:
|
|
139
|
+
if not isinstance(values, list):
|
|
140
|
+
raise CatalystwanResponseTypeError(
|
|
141
|
+
f"Expected type: list. Type received: {type(values)}"
|
|
142
|
+
)
|
|
143
|
+
return [self.__parse_list(get_args(arg_type)[0], value) for value in values]
|
|
144
|
+
else:
|
|
145
|
+
return values
|
|
146
|
+
|
|
147
|
+
def __extract_json_data(self, data: JSON) -> JsonContent:
|
|
148
|
+
if not isinstance(data, dict):
|
|
149
|
+
return JsonContent(extracted_data=data, raw_data=data)
|
|
150
|
+
for known_data_path in self.known_data_paths:
|
|
151
|
+
if known_data_path.is_data_available(data):
|
|
152
|
+
return JsonContent(extracted_data=known_data_path.get_data(data), raw_data=data)
|
|
153
|
+
return JsonContent(extracted_data=data, raw_data=data)
|
|
154
|
+
|
|
155
|
+
def __get_dataclass(
|
|
156
|
+
self, return_type: Type[DataclassType], model_payload: Union[JsonContent, str, bytes, None]
|
|
157
|
+
) -> DataclassType:
|
|
158
|
+
# Get a dataclass using payload from a response.
|
|
159
|
+
# This method includes a bit of brute-force trickery, to fight inconsistent schemas.
|
|
160
|
+
# Sometimes the schema requires are to pull data from a specific key, while at other times it doesn't.
|
|
161
|
+
# This method tries to check which version - extracted or raw - matches better.
|
|
162
|
+
@dataclass
|
|
163
|
+
class ModelPayload:
|
|
164
|
+
name: str
|
|
165
|
+
data: JSON
|
|
166
|
+
priority: int
|
|
167
|
+
|
|
168
|
+
@dataclass
|
|
169
|
+
class ModelReturn:
|
|
170
|
+
model: DataclassType
|
|
171
|
+
payload: ModelPayload
|
|
172
|
+
|
|
173
|
+
if not isinstance(model_payload, JsonContent):
|
|
174
|
+
raise CatalystwanResponseTypeError(
|
|
175
|
+
f"Expected data for {return_type} model. Received data of type {type(model_payload)} instead."
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
data_sources = [
|
|
179
|
+
ModelPayload(data=model_payload.extracted_data, name="extracted_data", priority=1),
|
|
180
|
+
ModelPayload(data=model_payload.raw_data, name="raw_data", priority=0),
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
field_names = [f.metadata.get("alias") or f.name for f in fields(return_type)]
|
|
184
|
+
# Empty dataclass, return as is
|
|
185
|
+
if not field_names:
|
|
186
|
+
return return_type()
|
|
187
|
+
|
|
188
|
+
valid_models: List[ModelReturn] = []
|
|
189
|
+
for data_source in data_sources:
|
|
190
|
+
try:
|
|
191
|
+
if isinstance(data_source.data, dict):
|
|
192
|
+
valid_models.append(
|
|
193
|
+
ModelReturn(
|
|
194
|
+
model=deserialize(return_type, **data_source.data), payload=data_source
|
|
195
|
+
)
|
|
196
|
+
)
|
|
197
|
+
else:
|
|
198
|
+
self.logger.debug(
|
|
199
|
+
f"Failed to create model {return_type} using {data_source.name} source. Reason: data of type {type(data_source.data)} is invalid"
|
|
200
|
+
)
|
|
201
|
+
except CatalystwanModelValidationError:
|
|
202
|
+
self.logger.debug(
|
|
203
|
+
f"Failed to create model {return_type} using {data_source.name} source."
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
if not valid_models:
|
|
207
|
+
raise CatalystwanResponseTypeError(
|
|
208
|
+
f"Failed to create model {return_type} from given data."
|
|
209
|
+
)
|
|
210
|
+
if len(valid_models) == 1:
|
|
211
|
+
return valid_models[0].model
|
|
212
|
+
|
|
213
|
+
# return model that matches best with the input
|
|
214
|
+
valid_models.sort(
|
|
215
|
+
key=lambda x: (
|
|
216
|
+
self.__count_matching_keys(x.model, cast(dict, x.payload.data)),
|
|
217
|
+
x.payload.priority,
|
|
218
|
+
),
|
|
219
|
+
reverse=True,
|
|
220
|
+
)
|
|
221
|
+
return valid_models[0].model
|
|
222
|
+
|
|
223
|
+
def __count_matching_keys(self, model: DataclassType, model_payload: dict):
|
|
224
|
+
matched_keys = 0
|
|
225
|
+
for key, value in model_payload.items():
|
|
226
|
+
try:
|
|
227
|
+
model_value = getattr(model, key)
|
|
228
|
+
matched_keys += 1
|
|
229
|
+
if is_dataclass(model_value) and isinstance(value, dict):
|
|
230
|
+
matched_keys += self.__count_matching_keys(
|
|
231
|
+
cast(DataclassType, model_value), value
|
|
232
|
+
)
|
|
233
|
+
elif (
|
|
234
|
+
isinstance(model_value, list)
|
|
235
|
+
and all([is_dataclass(element) for element in model_value])
|
|
236
|
+
and isinstance(value, list)
|
|
237
|
+
):
|
|
238
|
+
for model_v, input_v in zip(model_value, value):
|
|
239
|
+
matched_keys += self.__count_matching_keys(model_v, input_v)
|
|
240
|
+
except AttributeError:
|
|
241
|
+
continue
|
|
242
|
+
|
|
243
|
+
return matched_keys
|
|
244
|
+
|
|
245
|
+
def __copy__(self) -> RequestAdapter:
|
|
246
|
+
return RequestAdapter(session=copy(self.session), logger=self.logger)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# Copyright 2024 Cisco Systems, Inc. and its affiliates
|
|
2
1
|
from __future__ import annotations
|
|
3
2
|
|
|
4
3
|
from contextlib import AbstractContextManager
|
|
@@ -6,7 +5,7 @@ from threading import Semaphore
|
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
class RequestLimiter(AbstractContextManager):
|
|
9
|
-
def __init__(self, max_requests: int =
|
|
8
|
+
def __init__(self, max_requests: int = 10):
|
|
10
9
|
self._max_requests: int = max_requests
|
|
11
10
|
self._semaphore: Semaphore = Semaphore(value=self._max_requests)
|
|
12
11
|
|
|
@@ -1,32 +1,28 @@
|
|
|
1
|
-
# Copyright 2023 Cisco Systems, Inc. and its affiliates
|
|
2
|
-
|
|
3
1
|
import re
|
|
4
2
|
from datetime import datetime
|
|
5
3
|
from email.utils import parsedate_to_datetime
|
|
6
|
-
from functools import wraps
|
|
7
4
|
from os import environ
|
|
8
5
|
from pprint import pformat
|
|
9
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, Dict, Optional, TypeVar, Union
|
|
10
7
|
from urllib.parse import urlparse
|
|
11
8
|
|
|
12
|
-
from
|
|
9
|
+
from catalystwan.core.exceptions import ManagerErrorInfo
|
|
10
|
+
from catalystwan.core.metadata import with_proc_info_header
|
|
13
11
|
from requests import PreparedRequest, Request, Response
|
|
14
12
|
from requests.cookies import RequestsCookieJar
|
|
15
13
|
from requests.exceptions import JSONDecodeError
|
|
16
14
|
|
|
17
|
-
from catalystwan import with_proc_info_header
|
|
18
|
-
from catalystwan.abstractions import APIEndpointClientResponse
|
|
19
|
-
from catalystwan.exceptions import ManagerErrorInfo
|
|
20
|
-
from catalystwan.typed_list import DataSequence
|
|
21
|
-
from catalystwan.utils.creation_tools import create_dataclass
|
|
22
|
-
|
|
23
15
|
T = TypeVar("T")
|
|
24
|
-
PRINTABLE_CONTENT = re.compile(
|
|
16
|
+
PRINTABLE_CONTENT = re.compile(
|
|
17
|
+
r"(text\/.+)|(application\/(json|html|xhtml|xml|x-www-form-urlencoded))",
|
|
18
|
+
re.IGNORECASE,
|
|
19
|
+
)
|
|
25
20
|
SENSITIVE_URL_PATHS = ["/dataservice/settings/configuration/smartaccountcredentials"]
|
|
26
|
-
APIGW_EXPIRED_TOKEN_MESSAGE = "token has invalid claims: token is expired"
|
|
27
21
|
|
|
28
22
|
|
|
29
|
-
def response_debug(
|
|
23
|
+
def response_debug(
|
|
24
|
+
response: Optional[Response], request: Union[Request, PreparedRequest, None]
|
|
25
|
+
) -> str:
|
|
30
26
|
"""Returns human readable string containing Request-Response contents (helpful for debugging).
|
|
31
27
|
|
|
32
28
|
Args:
|
|
@@ -87,7 +83,9 @@ def response_debug(response: Optional[Response], request: Union[Request, Prepare
|
|
|
87
83
|
|
|
88
84
|
|
|
89
85
|
@with_proc_info_header
|
|
90
|
-
def response_history_debug(
|
|
86
|
+
def response_history_debug(
|
|
87
|
+
response: Optional[Response], request: Union[Request, PreparedRequest, None]
|
|
88
|
+
) -> str:
|
|
91
89
|
"""Returns human readable string containing Request-Response history contents for given response.
|
|
92
90
|
|
|
93
91
|
Args:
|
|
@@ -110,7 +108,11 @@ def auth_response_debug(response: Response, title: str = "Auth") -> str:
|
|
|
110
108
|
if environ.get("catalystwan_auth_trace") is not None:
|
|
111
109
|
return response_history_debug(response, None)
|
|
112
110
|
return ", ".join(
|
|
113
|
-
[title]
|
|
111
|
+
[title]
|
|
112
|
+
+ [
|
|
113
|
+
f"{r.request.method} {r.request.url} <{r.status_code}>"
|
|
114
|
+
for r in response.history + [response]
|
|
115
|
+
]
|
|
114
116
|
)
|
|
115
117
|
|
|
116
118
|
|
|
@@ -142,14 +144,18 @@ class JsonPayload:
|
|
|
142
144
|
self.headers = json.get("headers", None)
|
|
143
145
|
|
|
144
146
|
|
|
145
|
-
class ManagerResponse(
|
|
147
|
+
class ManagerResponse(
|
|
148
|
+
Response
|
|
149
|
+
# ResponseInterface
|
|
150
|
+
):
|
|
146
151
|
"""Extends Response object with methods specific to vManage.
|
|
147
152
|
Object is meant to be created from aready received requests.Response"""
|
|
148
153
|
|
|
149
154
|
def __init__(self, response: Response):
|
|
155
|
+
# @todo find better way to copy response
|
|
150
156
|
self.__dict__.update(response.__dict__)
|
|
151
157
|
self.jsessionid_expired = self._detect_expired_jsessionid()
|
|
152
|
-
self.api_gw_unauthorized = self.
|
|
158
|
+
self.api_gw_unauthorized = self._detect_apigw_unauthorized()
|
|
153
159
|
try:
|
|
154
160
|
self.payload = JsonPayload(response.json())
|
|
155
161
|
except JSONDecodeError:
|
|
@@ -162,7 +168,11 @@ class ManagerResponse(Response, APIEndpointClientResponse):
|
|
|
162
168
|
# get current server time, when not present use local time
|
|
163
169
|
# local time might be innacurate but "Expires" is usually set to year 1970
|
|
164
170
|
response_date = self.headers.get("date")
|
|
165
|
-
compare_date =
|
|
171
|
+
compare_date = (
|
|
172
|
+
parsedate_to_datetime(response_date)
|
|
173
|
+
if response_date is not None
|
|
174
|
+
else datetime.now()
|
|
175
|
+
)
|
|
166
176
|
if parsedate_to_datetime(expires) <= compare_date:
|
|
167
177
|
return True
|
|
168
178
|
return False
|
|
@@ -174,8 +184,11 @@ class ManagerResponse(Response, APIEndpointClientResponse):
|
|
|
174
184
|
jar.update(parse_cookies_to_dict(cookies_string))
|
|
175
185
|
return jar
|
|
176
186
|
|
|
177
|
-
def
|
|
178
|
-
|
|
187
|
+
def _detect_apigw_unauthorized(self) -> bool:
|
|
188
|
+
"""Determines if server sent unauthorized response"""
|
|
189
|
+
return (
|
|
190
|
+
self.status_code == 401 and self.json().get("message", "") == "failed to validate user"
|
|
191
|
+
)
|
|
179
192
|
|
|
180
193
|
def info(self, history: bool = False) -> str:
|
|
181
194
|
"""Returns human readable string containing Request-Response contents
|
|
@@ -189,72 +202,12 @@ class ManagerResponse(Response, APIEndpointClientResponse):
|
|
|
189
202
|
return response_history_debug(self, None)
|
|
190
203
|
return response_debug(self, None)
|
|
191
204
|
|
|
192
|
-
def dataseq(self, cls: Type[T], sourcekey: Optional[str] = "data", validate: bool = True) -> DataSequence[T]:
|
|
193
|
-
"""Returns data contents from JSON payload parsed as DataSequence of Dataclass/BaseModel instances
|
|
194
|
-
Args:
|
|
195
|
-
cls: Dataclass/BaseModel subtype (eg. Devices)
|
|
196
|
-
sourcekey: name of the JSON key from response payload to be parsed. If None whole JSON payload will be used
|
|
197
|
-
|
|
198
|
-
Returns:
|
|
199
|
-
DataSequence[T] of given type T which is subclassing from Dataclass/BaseModel,
|
|
200
|
-
in case JSON payload was containing a single Object - sequence with one element is returned
|
|
201
|
-
"""
|
|
202
|
-
if self.payload.empty:
|
|
203
|
-
return DataSequence(cls, [])
|
|
204
|
-
|
|
205
|
-
if sourcekey is None:
|
|
206
|
-
data = self.payload.json
|
|
207
|
-
else:
|
|
208
|
-
data = self.payload.json.get(sourcekey)
|
|
209
|
-
|
|
210
|
-
if isinstance(data, Sequence):
|
|
211
|
-
sequence = data
|
|
212
|
-
else:
|
|
213
|
-
sequence = [cast(dict, data)]
|
|
214
|
-
|
|
215
|
-
if issubclass(cls, BaseModel):
|
|
216
|
-
if validate:
|
|
217
|
-
return DataSequence(cls, [cls.model_validate(item) for item in sequence]) # type: ignore
|
|
218
|
-
return DataSequence(cls, [cls.model_construct(**item) for item in sequence]) # type: ignore
|
|
219
|
-
return DataSequence(cls, [create_dataclass(cls, item) for item in sequence])
|
|
220
|
-
|
|
221
|
-
def dataobj(self, cls: Type[T], sourcekey: Optional[str] = "data", validate: bool = True) -> T:
|
|
222
|
-
"""Returns data contents from JSON payload parsed as Dataclass/BaseModel instance
|
|
223
|
-
Args:
|
|
224
|
-
cls: Dataclass/BaseModel subtype (eg. Devices)
|
|
225
|
-
sourcekey: name of the JSON key from response payload to be parsed. If None whole JSON payload will be used
|
|
226
|
-
|
|
227
|
-
Returns:
|
|
228
|
-
Object of given type T which is subclassing from Dataclass/BaseModel,
|
|
229
|
-
|
|
230
|
-
"""
|
|
231
|
-
if sourcekey is None:
|
|
232
|
-
data = self.payload.json
|
|
233
|
-
else:
|
|
234
|
-
data = self.payload.json.get(sourcekey)
|
|
235
|
-
|
|
236
|
-
if issubclass(cls, BaseModel):
|
|
237
|
-
if validate:
|
|
238
|
-
return cls.model_validate(data) # type: ignore[return-value]
|
|
239
|
-
return cls.model_construct(**data) # type: ignore[return-value]
|
|
240
|
-
return create_dataclass(cls, data)
|
|
241
|
-
|
|
242
205
|
def get_error_info(self) -> ManagerErrorInfo:
|
|
243
206
|
"""Returns error information from JSON payload"""
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return ManagerErrorInfo(**self.payload.error)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
def with_vmanage_response(method: Callable[[Any], Response]) -> Callable[[Any], ManagerResponse]:
|
|
256
|
-
@wraps(method)
|
|
257
|
-
def wrapper(*args, **kwargs) -> ManagerResponse:
|
|
258
|
-
return ManagerResponse(method(*args, **kwargs))
|
|
259
|
-
|
|
260
|
-
return wrapper
|
|
207
|
+
error = {} if self.payload.error is None else self.payload.error
|
|
208
|
+
return ManagerErrorInfo(
|
|
209
|
+
message=error.get("message"),
|
|
210
|
+
details=error.get("details"),
|
|
211
|
+
code=error.get("code"),
|
|
212
|
+
type=error.get("type"),
|
|
213
|
+
)
|