ethyca-fides 2.69.1rc0__py2.py3-none-any.whl → 2.76.0rc2__py2.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.
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/METADATA +9 -6
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/RECORD +488 -361
- fides/_version.py +3 -3
- fides/api/alembic/alembic.ini +5 -1
- fides/api/alembic/migrations/env.py +7 -1
- fides/api/alembic/migrations/versions/0eef0016cf06_adding_oauth2_config_for_.py +69 -0
- fides/api/alembic/migrations/versions/303287c70600_migrate_resource_type_from_enum_to_.py +99 -0
- fides/api/alembic/migrations/versions/30369bb8ae01_add_webmonitorgroupjob_model.py +67 -0
- fides/api/alembic/migrations/versions/3efe14d4469a_adds_new_experience_configs_for_vendor_.py +79 -0
- fides/api/alembic/migrations/versions/4bfbeff34611_add_polling_status.py +68 -0
- fides/api/alembic/migrations/versions/4d8c0fcc5771_adding_default_system_groups.py +78 -0
- fides/api/alembic/migrations/versions/5fa78b1f324d_add_event_audit_table.py +82 -0
- fides/api/alembic/migrations/versions/65a1bc82ae09_adds_experience_config_for_delete_.py +53 -0
- fides/api/alembic/migrations/versions/67d0e389b003_update_consentstatus_enum.py +47 -0
- fides/api/alembic/migrations/versions/795f46f656c0_migrate_field_type_from_enum_to_string.py +61 -0
- fides/api/alembic/migrations/versions/7db29f9cd77b_create_new_sub_request_table.py +95 -0
- fides/api/alembic/migrations/versions/918aefc950c9_create_digest_conditional_dependencies.py +125 -0
- fides/api/alembic/migrations/versions/9caf76161e55_make_user_assigned_data_uses_nullable_.py +64 -0
- fides/api/alembic/migrations/versions/9e0dcbf67b9f_add_digest_config.py +84 -0
- fides/api/alembic/migrations/versions/a55e12c2c2df_add_tagging_instructions_to_data_.py +29 -0
- fides/api/alembic/migrations/versions/a8e0c016afd_add_classification_benchmark_table.py +126 -0
- fides/api/alembic/migrations/versions/b97e92b038d2_add_digest_execution_model.py +117 -0
- fides/api/alembic/migrations/versions/b9bfa12c167b_add_not_applicable_to_asset_consentstatus.py +46 -0
- fides/api/alembic/migrations/versions/c09e76282dd1_add_privacy_request_duplication_cols.py +64 -0
- fides/api/alembic/migrations/versions/cd8649be3a2b_add_classifications_and_user_assigned_.py +74 -0
- fides/api/alembic/migrations/versions/e2cda8d6abc3_add_dismissed_in_activity_view_to_.py +29 -0
- fides/api/alembic/migrations/versions/f108fa05c579_adds_optional_duration_field_to_assets.py +28 -0
- fides/api/alembic/migrations/versions/f36ce1bde293_add_system_groups.py +132 -0
- fides/api/alembic/migrations/versions/fd7571bef683_adds_new_fields_to_messagingconfig_for_.py +31 -0
- fides/api/alembic/migrations/versions/xx_2025_10_17_1603_5093e92e2a5a_add_consent_data_v3_to_the_database.py +72 -0
- fides/api/alembic/migrations/versions/xx_2025_10_27_1834_67f0f2f4748e_adding_identity_definition_model.py +45 -0
- fides/api/alembic/migrations/versions/xx_2025_10_29_1659_80d28dea3b6b_added_duplicate_group_table.py +79 -0
- fides/api/alembic/migrations/versions/xx_2025_11_05_0200_f1a2b3c4d5e6_create_staged_resource_error_table.py +82 -0
- fides/api/alembic/migrations/versions/xx_2025_11_07_1709_56fe6fad2d89_add_notice_display_order.py +47 -0
- fides/api/alembic/migrations/versions/xx_2025_11_10_1200_a1b2c3d4e5f6_add_test_datastore_to_connectiontype.py +53 -0
- fides/api/alembic/migrations/versions/xx_2025_11_11_1317_7d82c8fc4c34_store_saas_template_datasets.py +68 -0
- fides/api/alembic/migrations/versions/xx_2025_11_12_1430_b2c3d4e5f6a7_add_default_identity_definitions.py +81 -0
- fides/api/alembic/migrations/versions/xx_2025_11_25_1854_3ff6449c099e_add_index_on_providedidentity_privacy_.py +50 -0
- fides/api/api/v1/api.py +2 -0
- fides/api/api/v1/endpoints/admin.py +39 -0
- fides/api/api/v1/endpoints/connection_endpoints.py +191 -47
- fides/api/api/v1/endpoints/connector_template_endpoints.py +167 -0
- fides/api/api/v1/endpoints/generic_overrides.py +90 -15
- fides/api/api/v1/endpoints/messaging_endpoints.py +164 -34
- fides/api/api/v1/endpoints/pre_approval_webhook_endpoints.py +5 -5
- fides/api/api/v1/endpoints/privacy_request_endpoints.py +231 -46
- fides/api/api/v1/endpoints/saas_config_endpoints.py +63 -92
- fides/api/api/v1/endpoints/storage_endpoints.py +5 -1
- fides/api/api/v1/endpoints/system.py +157 -100
- fides/api/api/v1/endpoints/user_endpoints.py +17 -4
- fides/api/app_setup.py +1 -3
- fides/api/common_exceptions.py +8 -0
- fides/api/db/base.py +8 -0
- fides/api/db/crud.py +30 -2
- fides/api/db/database.py +261 -4
- fides/api/db/safe_crud.py +377 -0
- fides/api/db/seed.py +35 -1
- fides/api/email_templates/get_email_template.py +3 -0
- fides/api/email_templates/template_names.py +1 -0
- fides/api/email_templates/templates/external_user_welcome.html +9 -5
- fides/api/email_templates/templates/manual_task_digest.html +316 -0
- fides/api/main.py +2 -0
- fides/api/migrations/post_upgrade_index_creation.py +20 -0
- fides/api/models/asset.py +17 -1
- fides/api/models/attachment.py +1 -0
- fides/api/models/conditional_dependency/__init__.py +0 -0
- fides/api/models/conditional_dependency/conditional_dependency_base.py +311 -0
- fides/api/models/connection_oauth_credentials.py +57 -0
- fides/api/models/connectionconfig.py +11 -1
- fides/api/models/detection_discovery/__init__.py +4 -0
- fides/api/models/detection_discovery/classification_benchmark.py +140 -0
- fides/api/models/detection_discovery/core.py +78 -3
- fides/api/models/detection_discovery/monitor_task.py +3 -1
- fides/api/models/detection_discovery/staged_resource_error.py +25 -0
- fides/api/models/detection_discovery/web_monitor.py +61 -0
- fides/api/models/digest/__init__.py +16 -0
- fides/api/models/digest/conditional_dependencies.py +275 -0
- fides/api/models/digest/digest_config.py +110 -0
- fides/api/models/digest/digest_execution.py +142 -0
- fides/api/models/event_audit.py +85 -0
- fides/api/models/experience_notices.py +6 -1
- fides/api/models/fides_user.py +9 -0
- fides/api/models/identity_definition.py +66 -0
- fides/api/models/location_regulation_selections.py +22 -0
- fides/api/models/manual_task/conditional_dependency.py +29 -87
- fides/api/models/manual_webhook.py +17 -6
- fides/api/models/messaging.py +30 -10
- fides/api/models/messaging_template.py +14 -0
- fides/api/models/policy.py +27 -0
- fides/api/models/privacy_experience.py +41 -0
- fides/api/models/privacy_notice.py +196 -13
- fides/api/models/privacy_preference.py +2 -0
- fides/api/models/privacy_request/duplicate_group.py +84 -0
- fides/api/models/privacy_request/privacy_request.py +154 -8
- fides/api/models/privacy_request/provided_identity.py +22 -1
- fides/api/models/privacy_request/request_task.py +98 -1
- fides/api/models/privacy_request/webhook.py +3 -1
- fides/api/models/saas_template_dataset.py +63 -0
- fides/api/models/sql_models.py +161 -7
- fides/api/models/system_group.py +85 -0
- fides/api/models/taxonomy.py +91 -9
- fides/api/models/v3/__init__.py +0 -0
- fides/api/models/v3/privacy_preferences.py +85 -0
- fides/api/models/worker_task.py +8 -0
- fides/api/oauth/roles.py +4 -0
- fides/api/schemas/application_config.py +32 -1
- fides/api/schemas/connection_configuration/connection_config.py +1 -30
- fides/api/schemas/connection_configuration/connection_oauth_config.py +42 -0
- fides/api/schemas/connection_configuration/connection_secrets_mongodb.py +15 -3
- fides/api/schemas/connection_configuration/connection_secrets_mssql.py +5 -0
- fides/api/schemas/messaging/messaging.py +49 -66
- fides/api/schemas/messaging/messaging_secrets_docs_only.py +1 -1
- fides/api/schemas/messaging/shared_schemas.py +102 -0
- fides/api/schemas/oauth.py +2 -1
- fides/api/schemas/privacy_center_config.py +29 -5
- fides/api/schemas/privacy_request.py +44 -7
- fides/api/schemas/saas/async_polling_configuration.py +81 -0
- fides/api/schemas/saas/connector_template.py +14 -0
- fides/api/schemas/saas/saas_config.py +12 -20
- fides/api/schemas/system.py +8 -0
- fides/api/schemas/taxonomy_extensions.py +8 -0
- fides/api/schemas/user.py +2 -2
- fides/api/service/async_dsr/handlers/__init__.py +0 -0
- fides/api/service/async_dsr/handlers/polling_attachment_handler.py +155 -0
- fides/api/service/async_dsr/handlers/polling_request_handler.py +88 -0
- fides/api/service/async_dsr/handlers/polling_response_handler.py +261 -0
- fides/api/service/async_dsr/handlers/polling_sub_request_handler.py +123 -0
- fides/api/service/async_dsr/strategies/__init__.py +0 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy.py +52 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_callback.py +199 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_factory.py +72 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +691 -0
- fides/api/service/async_dsr/utils.py +130 -0
- fides/api/service/connectors/base_erasure_email_connector.py +7 -0
- fides/api/service/connectors/bigquery_connector.py +34 -16
- fides/api/service/connectors/fides/fides_client.py +63 -1
- fides/api/service/connectors/http_connector.py +48 -12
- fides/api/service/connectors/microsoft_sql_server_connector.py +6 -1
- fides/api/service/connectors/mongodb_connector.py +74 -9
- fides/api/service/connectors/query_configs/saas_query_config.py +160 -79
- fides/api/service/connectors/saas/connector_registry_service.py +42 -135
- fides/api/service/connectors/saas_connector.py +116 -76
- fides/api/service/connectors/sql_connector.py +14 -4
- fides/api/service/deps.py +25 -2
- fides/api/service/messaging/message_dispatch_service.py +98 -20
- fides/api/service/messaging/messaging_crud_service.py +5 -9
- fides/api/service/privacy_request/attachment_handling.py +9 -2
- fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +17 -9
- fides/api/service/privacy_request/dsr_package/templates/attachments_index.html +41 -30
- fides/api/service/privacy_request/dsr_package/templates/clickme.html +68 -0
- fides/api/service/privacy_request/dsr_package/templates/dataset_index.html +30 -27
- fides/api/service/privacy_request/duplication_detection.py +439 -0
- fides/api/service/privacy_request/email_batch_service.py +2 -1
- fides/api/service/privacy_request/request_runner_service.py +92 -91
- fides/api/service/privacy_request/request_service.py +74 -90
- fides/api/service/saas_request/saas_request_override_factory.py +71 -1
- fides/api/service/storage/streaming/schemas.py +27 -19
- fides/api/service/storage/streaming/smart_open_client.py +2 -2
- fides/api/service/storage/streaming/smart_open_streaming_storage.py +238 -147
- fides/api/service/storage/util.py +20 -106
- fides/api/service/strategy.py +6 -3
- fides/api/task/conditional_dependencies/privacy_request/__init__.py +0 -0
- fides/api/task/conditional_dependencies/privacy_request/convenience_fields.py +155 -0
- fides/api/task/conditional_dependencies/privacy_request/privacy_request_data.py +140 -0
- fides/api/task/conditional_dependencies/privacy_request/schemas.py +212 -0
- fides/api/task/conditional_dependencies/sql_schemas.py +301 -0
- fides/api/task/conditional_dependencies/sql_translator.py +757 -0
- fides/api/task/conditional_dependencies/util.py +111 -0
- fides/api/task/execute_request_tasks.py +34 -13
- fides/api/task/filter_results.py +35 -2
- fides/api/task/graph_runners.py +2 -32
- fides/api/task/graph_task.py +42 -12
- fides/api/task/manual/manual_task_conditional_evaluation.py +33 -28
- fides/api/task/manual/manual_task_graph_task.py +4 -1
- fides/api/task/manual/manual_task_utils.py +68 -26
- fides/api/task/scheduler_utils.py +39 -0
- fides/api/tasks/__init__.py +15 -1
- fides/api/util/cache.py +5 -1
- fides/api/util/connection_util.py +101 -218
- fides/api/util/event_audit_util.py +230 -0
- fides/api/util/filter_utils.py +0 -3
- fides/api/util/fuzzy_search_utils.py +7 -1
- fides/api/util/lock.py +13 -3
- fides/api/util/logger.py +58 -4
- fides/api/util/logger_context_utils.py +3 -1
- fides/api/util/masking_util.py +31 -0
- fides/api/util/memory_watchdog.py +118 -0
- fides/api/util/rate_limit.py +25 -7
- fides/api/util/saas_config_updater.py +76 -0
- fides/api/util/saas_util.py +28 -1
- fides/api/worker/__init__.py +6 -0
- fides/common/api/scope_registry.py +6 -7
- fides/common/api/v1/urn_registry.py +15 -3
- fides/config/__init__.py +11 -2
- fides/config/celery_settings.py +42 -0
- fides/config/config_proxy.py +10 -0
- fides/config/duplicate_detection_settings.py +31 -0
- fides/config/execution_settings.py +6 -6
- fides/config/security_settings.py +4 -1
- fides/config/utils.py +5 -0
- fides/data/language/languages.yml +2 -0
- fides/service/connection/__init__.py +0 -0
- fides/service/connection/connection_service.py +651 -0
- fides/service/dataset/dataset_service.py +39 -0
- fides/service/event_audit_service.py +109 -0
- fides/service/messaging/aws_ses_service.py +2 -4
- fides/service/messaging/messaging_service.py +75 -74
- fides/service/privacy_request/privacy_request_service.py +345 -100
- fides/service/system/__init__.py +0 -0
- fides/service/system/system_service.py +153 -0
- fides/service/taxonomy/handlers/legacy_handler.py +3 -3
- fides/service/taxonomy/taxonomy_service.py +64 -18
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/chunks/1099-688fa865621531cc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1115-7fd171dac1eb0e51.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1276.deb10ae2643f8463.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1438-8a33b3834d6e43f3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6148-59a59d5c5925344f.js → 1533-84e250d1f26e6d7d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/1821-c1daa160f492aacf.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1840-359ee056e4cf6629.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{1975.78e719130cfe3fd6.js → 1975.bef017bc80e2012c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/2040-70972e15960d9afe.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/2121.321b0fd3932164d4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/2397-3434603a97f3f5d6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/2921-49ed0ed897832958.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3150-da5406b80d25fe6d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3214-90ce0a366b0f461a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3377-02bf9780fd383d94.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3655-5e1ba5dd68b5ec48.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3729-31ff8ba51491bf21.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3872-cff30ca0844fe2b1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3931-8bedde156fe83564.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/401-582d9970d89deefe.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4093-7e47408c28de5375.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{4259.d1507e0db19cbed7.js → 4259.05038c9b78467244.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/431-e01ee730c8ad9ece.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4322-f6aeff6880726c83.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4339-04a715ab07122744.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4496-ccbce2459174e0d6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/454-d5c2c84f1a14e4f1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4589-c1d83c6a8dab4d30.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4809-a8f4a108a42f53ed.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4903-19c0bc07a956dfa8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4910-d990773601f794c1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5185-96423702fba70ced.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5258-4e308cca01d59367.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5487-5c3501754bf027ba.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/549-1bdc3e6f3264c020.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5505-43b9c39491b88e08.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5698.2135391a128cc373.js +164 -0
- fides/ui-build/static/admin/_next/static/chunks/5783-016dfcee8e49bf61.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5826-4db99ea4e5077911.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/590-be447cacf12419dd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6084-91badbc6569a0efb.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6344-026cb323c1d49926.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6362-ba0e12f2fc4cad94.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6853-882889659769d7b4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6882-bb1b469d7d7f5335.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6954-0dcf22a9aabe39c5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7170-46db82bb5b55e856.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7218-2ace8c82e3e7eb74.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7245-1cdafb35f289861b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7630-7f75ab7b8df42eb3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7654-2e9a8be02e41769a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/8212-348ddd2b6933db70.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{5596-bb601cbf40e47a0f.js → 9195-da717d324917b049.js} +3 -3
- fides/ui-build/static/admin/_next/static/chunks/9450-b7b7bb1d755ecf57.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{9676.9fd9552ef744c717.js → 9676.1f395eeb9cc34968.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/9826-1078e46f3ac0b688.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9911-ece086f2230e34f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{404-471a6b18e712f050.js → 404-800be6996aaa999c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-fcdad91f6f66292b.js → _app-de4b578c904df772.js} +57 -220
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-f12020b82dd4bd1a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-a911b7990371704d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-ad585b79953c2753.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-406170eaae4329c6.js → add-vendors-bb263d394ca1c8fa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-6907c368d8611c44.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-f80cf2d3966816fd.js → [id]-c32f381af358149b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-e74cb5ea87f15b40.js → new-6efb3c069d8b47dd.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-1975c529905eea9b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-b378576cba255609.js → [id]-b05331178928ab52.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-2ca1de7b88094ab0.js → new-516834e930bb0d0d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-985717f2565f9d9d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-226efa1dcd41437f.js → properties-2be773e08498e40c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-850afb74f4192e87.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent-b63d1e395d879b86.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-5b28f0f674ea87bd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-04cfe2cfba7b7cd8.js → [projectUrn]-676177e2f3c9c2a2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-794906929efb8e1d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-3ccbf7c0d06507b9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-1ea0b24d306b1e67.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-d4861a4a218bb65a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore-4498881c26f1458d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure/[monitorId]-66bd265044daf97d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure-c9c79fa8576a4f77.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-60cacc3232c2eead.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]-437bd64a3016de36.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website-5b3e0009d442bc3f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-8349248c2da970a6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-6919a1d6cadaa46b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-8f736b078e9842da.js → [resourceUrn]-1a50d421897d3da1.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-eb814e3c22807871.js → detection-49509414a15e8393.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-6875b7783fcfda2f.js → [resourceUrn]-1a1bb80b586d0c0f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-172dbd7740e212ca.js → discovery-49de61df1e8e7fba.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-c2719f5cff20c0f8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-dfd71c1e9c458b89.js → [...subfieldNames]-415015aebab60436.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-7cdc42ec5493b83d.js → [collectionName]-5accb09715b5122d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-aebecca1d8ec5f98.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-9551a82ddec9f909.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-72f8fe47beef0f09.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-3a8aa3f633528e88.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-87512616f35ec6da.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-2f1bf4eac7aa55fd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-1f4335dca5c09860.js → fides-js-docs-5235760b3e508d7d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/index-8d67cd2872cb682a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-7a631df29cd0e31a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-ea3bc43cdaf273de.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-5d8632bba1b81cd4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/[id]-92e01822ecde8fb8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/new-1256cf6d3f6794e0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests-0daac00911d27617.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/[key]-2d976fe5e8ba0a3a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/new-7766ba497b863740.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers-f2880d2ed4734270.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/[id]-669f585c3458faff.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/add-template-c79e7724e4bc3899.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-891654e8dc13965c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications-40c8148244c5d347.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-1e86f3e28bd23ed6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-9b7bd8c38f02c091.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-b18a53a940cf9e19.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-6d028d7450e77578.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-8399083ee2cd8cc2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-0a910125cdb2b3b8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-acc90b6f7fe915cb.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-bbc42026f2685438.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-c08ca6ad21c99799.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-77c2db582f8823bc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-e784c05d056b2371.js → [id]-74ccea4868408e3d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-0a7a2db148a7561a.js → add-property-7d9f09bfe9d44dfc.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{properties-da734840e4f9d04b.js → properties-cd77bc30672bb1fa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-cc3bd9540132d5ed.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/sandbox/privacy-notices-7ce7d720107ab4b5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-68eaac2d79133679.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-6c4904c157477285.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-ae789892343c24f5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-13ee1b331ced0846.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/[id]-ee4e43692336a330.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/new-ca51d794abfcbf25.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-ecd1dc5db8e81409.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-df06f7e2f668c540.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-da0c77bd510c6c51.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-950b0c115bf673d8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-2e635dcd11b78224.js → locations-7e36cb4756973a9d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-a0e5ed486d24ccf3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-3cdebafb6870d3ad.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-7c02e469d8c5bd74.js → regulations-159aad34f1021320.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-dbd1a64090ad0946.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-7d042497a57a3788.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-21f1172e73dfc9f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-e553161e6338ee48.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-92f52c43f522a350.js → new-efc4af017723e57a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-64452dfae2c5e614.js → [id]-b152319d67372ee4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management-dba8692491f7935e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/webpack-09ca52bc7beb0b43.js +1 -0
- fides/ui-build/static/admin/_next/static/css/012b10627a654d5c.css +1 -0
- fides/ui-build/static/admin/_next/static/css/05d05fc31d09638b.css +1 -0
- fides/ui-build/static/admin/_next/static/css/0fd6e0884cfcc5f3.css +1 -0
- fides/ui-build/static/admin/_next/static/css/14ba79c49597d37a.css +1 -0
- fides/ui-build/static/admin/_next/static/css/{34a7eb08b86ddb57.css → 3d6582469f7d56e0.css} +1 -1
- fides/ui-build/static/admin/_next/static/css/3d66bb57ddcb0978.css +1 -0
- fides/ui-build/static/admin/_next/static/css/4861ca3e088f2d05.css +1 -0
- fides/ui-build/static/admin/_next/static/css/a1800714b486e230.css +1 -0
- fides/ui-build/static/admin/_next/static/css/a1e4be9466578ef1.css +1 -0
- fides/ui-build/static/admin/_next/static/css/af32fcac7a177a0e.css +1 -0
- fides/ui-build/static/admin/_next/static/css/cb417f0587918f85.css +1 -0
- fides/ui-build/static/admin/_next/static/css/dd15c278b964de80.css +1 -0
- fides/ui-build/static/admin/_next/static/css/{5f393dea1c0d031c.css → f89607996ad54f4b.css} +1 -1
- fides/ui-build/static/admin/_next/static/css/f9a2a44d3d34c904.css +1 -0
- fides/ui-build/static/admin/_next/static/l2vgGUHB04Fi4oEVlVMrc/_buildManifest.js +1 -0
- fides/ui-build/static/admin/add-systems/manual.html +1 -1
- fides/ui-build/static/admin/add-systems/multiple.html +1 -1
- fides/ui-build/static/admin/add-systems.html +1 -1
- fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
- fides/ui-build/static/admin/consent/configure.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
- fides/ui-build/static/admin/consent/properties.html +1 -1
- fides/ui-build/static/admin/consent/reporting.html +1 -1
- fides/ui-build/static/admin/consent.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
- fides/ui-build/static/admin/data-catalog.html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/datastore/[monitorId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/datastore.html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/infrastructure/[monitorId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/infrastructure.html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId]/[systemId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/website.html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
- fides/ui-build/static/admin/data-discovery/activity.html +1 -1
- fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/detection.html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
- fides/ui-build/static/admin/datamap.html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
- fides/ui-build/static/admin/dataset/new.html +1 -1
- fides/ui-build/static/admin/dataset.html +1 -1
- fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
- fides/ui-build/static/admin/datastore-connection/new.html +1 -1
- fides/ui-build/static/admin/datastore-connection.html +1 -1
- fides/ui-build/static/admin/index.html +1 -1
- fides/ui-build/static/admin/integrations/[id].html +1 -1
- fides/ui-build/static/admin/integrations.html +1 -1
- fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
- fides/ui-build/static/admin/lib/fides-headless.js +1 -1
- fides/ui-build/static/admin/lib/fides-preview.js +1 -1
- fides/ui-build/static/admin/lib/fides-tcf.js +3 -3
- fides/ui-build/static/admin/lib/fides.js +3 -3
- fides/ui-build/static/admin/login/[provider].html +1 -1
- fides/ui-build/static/admin/login.html +1 -1
- fides/ui-build/static/admin/new-privacy-requests.html +1 -0
- fides/ui-build/static/admin/notifications/digests/[id].html +1 -0
- fides/ui-build/static/admin/notifications/digests/new.html +1 -0
- fides/ui-build/static/admin/notifications/digests.html +1 -0
- fides/ui-build/static/admin/notifications/providers/[key].html +1 -0
- fides/ui-build/static/admin/notifications/providers/new.html +1 -0
- fides/ui-build/static/admin/notifications/providers.html +1 -0
- fides/ui-build/static/admin/notifications/templates/[id].html +1 -0
- fides/ui-build/static/admin/notifications/templates/add-template.html +1 -0
- fides/ui-build/static/admin/notifications/templates.html +1 -0
- fides/ui-build/static/admin/notifications.html +1 -0
- fides/ui-build/static/admin/poc/ant-components.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
- fides/ui-build/static/admin/poc/forms.html +1 -1
- fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
- fides/ui-build/static/admin/privacy-requests.html +1 -1
- fides/ui-build/static/admin/properties/[id].html +1 -1
- fides/ui-build/static/admin/properties/add-property.html +1 -1
- fides/ui-build/static/admin/properties.html +1 -1
- fides/ui-build/static/admin/reporting/datamap.html +1 -1
- fides/ui-build/static/admin/sandbox/privacy-notices.html +1 -0
- fides/ui-build/static/admin/settings/about/alpha.html +1 -1
- fides/ui-build/static/admin/settings/about.html +1 -1
- fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
- fides/ui-build/static/admin/settings/consent.html +1 -1
- fides/ui-build/static/admin/settings/custom-fields/[id].html +1 -0
- fides/ui-build/static/admin/settings/custom-fields/new.html +1 -0
- fides/ui-build/static/admin/settings/custom-fields.html +1 -1
- fides/ui-build/static/admin/settings/domain-records.html +1 -1
- fides/ui-build/static/admin/settings/domains.html +1 -1
- fides/ui-build/static/admin/settings/email-templates.html +1 -1
- fides/ui-build/static/admin/settings/locations.html +1 -1
- fides/ui-build/static/admin/settings/organization.html +1 -1
- fides/ui-build/static/admin/settings/privacy-requests.html +1 -1
- fides/ui-build/static/admin/settings/regulations.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id].html +1 -1
- fides/ui-build/static/admin/systems.html +1 -1
- fides/ui-build/static/admin/taxonomy.html +1 -1
- fides/ui-build/static/admin/user-management/new.html +1 -1
- fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
- fides/ui-build/static/admin/user-management.html +1 -1
- fides/api/service/async_dsr/async_dsr_service.py +0 -75
- fides/api/service/privacy_request/dsr_package/templates/welcome.html +0 -66
- fides/ui-build/static/admin/_next/static/OmXHlY9MvjoZH9jDkAytl/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1099-79646e64f26d62fa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1345-5e1c5b66e25c566e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-0ca16d288fad916d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2150-930ffaf2c4718edc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/255-1bc0cbef7a59cdc6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2921-52328140bc420d0f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3550-d04125c828d591a1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3620-602eb74dc896d556.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3729-c17ac8031a4c4fd1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3847-230bf61b053bc706.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3855-ef5194cdb228beb6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3872-f78dec02f0d959ae.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3923-bb2417b8dcade7a4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/401-4af0a912e249d30f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4164-355644b916ae0094.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/431-86ad2beeb93c95c9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4608-be8cba73f5d7c326.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4786-61154adf88e448e1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4808-dd4157aa72648068.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4831-fd99c0b3784de128.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4844-46324c3d848b8b6a.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5258-b0de22a8521686ab.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5487-02d00bad7c6830e0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/549-38ea1d91ee2addaa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6084-c153669d5567e242.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6419-d0c00d661b01f8fa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6853-b17673391117c976.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-5296188c19d7d0ac.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7476-45c5088baa8b66af.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7630-7ed6c6117775dffe.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/787-a8c7eab617e2fceb.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/79-65674011d455af4d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/796-9e1ca1a4030707c5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8002-24af20d679efc04e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9046-712156d461165f56.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9729-fcf6ff4e3534e4a8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9826-dbae8dee941a7fac.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9951-a88367a129b724ba.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-ace203dfacacbdc4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-920fb469e0dda1d2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-bd0d82078e67cac3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-7207ab23bdb36ce8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-9dda4de5ec580279.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-0d4844d0b808e6e4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-28b192e2c074b0f3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent-3e8bdefe714254ec.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-2c29ff7a01198f30.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-5f2d7b24804f861f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-8eb581024bc0172f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-30108b00ac769fc3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-e1ba213fb666b3f4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-6d133580045abdda.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-9a81d42a474e1e48.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-b6ae7adb8ef0b525.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-c7390e046b2e2b7f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-e12b11ba15bc3fc1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-e32fccc4ca520d2b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-7c59a6abf6ba6207.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-927b7e476c4b47d0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-cbe100d50df34285.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-cce20440b177050b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/index-6cd8708106331b8d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-4c3c413a2668df53.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-95402b5001c07ef2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-3c6dc2f6e6bae960.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-4a6d4023a7791be8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging-76b204c9b98d656f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-bc0e2adf6e0d3ac7.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-86ffcc1ad3fa912e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-ec04f595465bdf69.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-41d309754ff0c1de.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-cab1f78cec7808f9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-eb6058221403b156.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-48500551fd6a7602.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-0f25a76dd18c5e20.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-ad6ad3e5bd72765d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-6032d82f0fc2893d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-d83e5bd52a638234.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-baf31c3e4b081046.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-6903f42a0412bfa6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-a82f3df840d5c1b5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-d06fb16487705b9d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-9495e2eb506606c7.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-93a978443bf299db.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-9ecb803099082bf4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-16fdd91a81074dd1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-4cdd6001e7cb9aee.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-1914de830ce5cfc4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-f547f1f33c12faf3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-2ecc073f41628f62.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-20b1193ed76c56b0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-6e15332935f6b538.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-fbc8761ef4d55516.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-4d7827fc9c46b6b8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management-9cec020f89544426.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/webpack-678e89d68dbcd94f.js +0 -1
- fides/ui-build/static/admin/_next/static/css/073713cd1eddda79.css +0 -1
- fides/ui-build/static/admin/_next/static/css/23cf870196941c9a.css +0 -1
- fides/ui-build/static/admin/_next/static/css/304c6f148886a8d4.css +0 -1
- fides/ui-build/static/admin/_next/static/css/650df9c348000a26.css +0 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +0 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +0 -1
- fides/ui-build/static/admin/messaging/[id].html +0 -1
- fides/ui-build/static/admin/messaging/add-template.html +0 -1
- fides/ui-build/static/admin/messaging.html +0 -1
- fides/ui-build/static/admin/poc/table-migration.html +0 -1
- fides/ui-build/static/admin/privacy-requests/configure/messaging.html +0 -1
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-de704de849960f01.js → resources-81d1b50585468fb0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/{OmXHlY9MvjoZH9jDkAytl → l2vgGUHB04Fi4oEVlVMrc}/_ssgManifest.js +0 -0
fides/api/db/database.py
CHANGED
|
@@ -2,14 +2,19 @@
|
|
|
2
2
|
Contains all of the logic related to the database including connections, setup, teardown, etc.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import os
|
|
6
|
+
import subprocess
|
|
5
7
|
from os import path
|
|
8
|
+
from pathlib import Path
|
|
6
9
|
from typing import Literal, Optional, Tuple
|
|
7
10
|
|
|
8
11
|
from alembic import command, script
|
|
9
12
|
from alembic.config import Config
|
|
10
13
|
from alembic.runtime import migration
|
|
11
14
|
from loguru import logger as log
|
|
15
|
+
from sqlalchemy import text
|
|
12
16
|
from sqlalchemy.orm import Session
|
|
17
|
+
from sqlalchemy.schema import SchemaItem
|
|
13
18
|
from sqlalchemy_utils.functions import create_database, database_exists
|
|
14
19
|
from sqlalchemy_utils.types.encrypted.encrypted_type import InvalidCiphertextError
|
|
15
20
|
|
|
@@ -20,6 +25,25 @@ from fides.api.util.errors import get_full_exception_name
|
|
|
20
25
|
|
|
21
26
|
DatabaseHealth = Literal["healthy", "unhealthy", "needs migration"]
|
|
22
27
|
|
|
28
|
+
# Tables to exclude from migration auto-generation (e.g., tables without SQLAlchemy models)
|
|
29
|
+
EXCLUDED_TABLES = {
|
|
30
|
+
"privacy_preferences_current",
|
|
31
|
+
"privacy_preferences_historic",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def include_object(
|
|
36
|
+
object: SchemaItem, # pylint: disable=redefined-builtin
|
|
37
|
+
name: str,
|
|
38
|
+
type_: str,
|
|
39
|
+
reflected: bool,
|
|
40
|
+
compare_to: SchemaItem,
|
|
41
|
+
) -> bool:
|
|
42
|
+
"""Filter out excluded tables from migration comparison and auto-generation."""
|
|
43
|
+
if type_ == "table" and name in EXCLUDED_TABLES:
|
|
44
|
+
return False
|
|
45
|
+
return True
|
|
46
|
+
|
|
23
47
|
|
|
24
48
|
def get_alembic_config(database_url: str) -> Config:
|
|
25
49
|
"""
|
|
@@ -91,6 +115,10 @@ def reset_db(database_url: str) -> None:
|
|
|
91
115
|
log.info("Dropping tables...")
|
|
92
116
|
Base.metadata.drop_all(connection)
|
|
93
117
|
|
|
118
|
+
log.info("Dropping excluded tables without models...")
|
|
119
|
+
for table_name in EXCLUDED_TABLES:
|
|
120
|
+
connection.execute(text(f"DROP TABLE IF EXISTS {table_name} CASCADE"))
|
|
121
|
+
|
|
94
122
|
log.info("Dropping Alembic table...")
|
|
95
123
|
migration_context = migration.MigrationContext.configure(connection)
|
|
96
124
|
version = migration_context._version # pylint: disable=protected-access
|
|
@@ -151,13 +179,242 @@ def check_missing_migrations(database_url: str) -> None:
|
|
|
151
179
|
Tries to autogenerate migrations, returns True if a migration
|
|
152
180
|
was generated.
|
|
153
181
|
"""
|
|
154
|
-
|
|
155
182
|
engine = get_db_engine(database_uri=database_url)
|
|
156
183
|
connection = engine.connect()
|
|
157
184
|
|
|
158
|
-
migration_context = migration.MigrationContext.configure(
|
|
185
|
+
migration_context = migration.MigrationContext.configure(
|
|
186
|
+
connection, opts={"include_object": include_object}
|
|
187
|
+
)
|
|
159
188
|
result = command.autogen.compare_metadata(migration_context, Base.metadata) # type: ignore[attr-defined]
|
|
160
189
|
|
|
161
190
|
if result:
|
|
162
|
-
|
|
163
|
-
|
|
191
|
+
log.error("Migration needs to be generated!")
|
|
192
|
+
log.error("Detected the following schema differences:")
|
|
193
|
+
for item in result:
|
|
194
|
+
log.error(f" - {item}")
|
|
195
|
+
raise SystemExit("Migration needs to be generated!")
|
|
196
|
+
log.info("No migrations need to be generated.")
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _get_base_branch_for_comparison() -> str:
|
|
200
|
+
"""
|
|
201
|
+
Determine the base branch to compare against for detecting new migrations.
|
|
202
|
+
|
|
203
|
+
In GitHub Actions PRs, uses GITHUB_BASE_REF (the PR target branch).
|
|
204
|
+
Otherwise, falls back to origin/main for local development.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
The base branch reference (e.g., 'origin/main', 'origin/develop')
|
|
208
|
+
"""
|
|
209
|
+
base_ref = os.environ.get("GITHUB_BASE_REF")
|
|
210
|
+
if base_ref:
|
|
211
|
+
base_branch = f"origin/{base_ref}"
|
|
212
|
+
log.info(f"Comparing against PR target branch: {base_branch}")
|
|
213
|
+
else:
|
|
214
|
+
base_branch = "origin/main"
|
|
215
|
+
log.info(f"No GITHUB_BASE_REF found, comparing against: {base_branch}")
|
|
216
|
+
return base_branch
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def _get_new_migration_files(repo_root: str, base_branch: str) -> list[str]:
|
|
220
|
+
"""
|
|
221
|
+
Get list of new migration files added in the current branch.
|
|
222
|
+
|
|
223
|
+
Files are sorted by the timestamp in their filename to ensure chronological order.
|
|
224
|
+
Migration files follow the pattern: xx_YYYY_MM_DD_HHMM_revision_description.py
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
repo_root: Absolute path to the git repository root
|
|
228
|
+
base_branch: The base branch to compare against
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
List of relative file paths to new migration files, sorted chronologically
|
|
232
|
+
|
|
233
|
+
Raises:
|
|
234
|
+
SystemExit: If the migrations directory does not exist
|
|
235
|
+
"""
|
|
236
|
+
# Validate that the migrations directory exists
|
|
237
|
+
migrations_dir = (
|
|
238
|
+
Path(repo_root)
|
|
239
|
+
/ "src"
|
|
240
|
+
/ "fides"
|
|
241
|
+
/ "api"
|
|
242
|
+
/ "alembic"
|
|
243
|
+
/ "migrations"
|
|
244
|
+
/ "versions"
|
|
245
|
+
)
|
|
246
|
+
if not migrations_dir.exists():
|
|
247
|
+
log.error(f"Migrations directory not found: {migrations_dir}")
|
|
248
|
+
raise SystemExit(
|
|
249
|
+
f"Migration directory not found at expected path: {migrations_dir}\n"
|
|
250
|
+
"If the migrations directory has been moved, update the path in "
|
|
251
|
+
"fides.api.db.database._get_new_migration_files()"
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
migration_pattern = "src/fides/api/alembic/migrations/versions/*.py"
|
|
255
|
+
diff_output = subprocess.check_output(
|
|
256
|
+
[
|
|
257
|
+
"git",
|
|
258
|
+
"diff",
|
|
259
|
+
"--name-only",
|
|
260
|
+
"--diff-filter=A", # Only added files
|
|
261
|
+
f"{base_branch}...HEAD",
|
|
262
|
+
"--",
|
|
263
|
+
migration_pattern,
|
|
264
|
+
],
|
|
265
|
+
stderr=subprocess.STDOUT,
|
|
266
|
+
text=True,
|
|
267
|
+
cwd=repo_root,
|
|
268
|
+
).strip()
|
|
269
|
+
|
|
270
|
+
if not diff_output:
|
|
271
|
+
return []
|
|
272
|
+
|
|
273
|
+
migration_files = [f for f in diff_output.split("\n") if f]
|
|
274
|
+
|
|
275
|
+
# Sort by filename to ensure chronological order
|
|
276
|
+
# Files are named: xx_YYYY_MM_DD_HHMM_revision_description.py
|
|
277
|
+
# Sorting alphabetically will sort them chronologically due to the date format
|
|
278
|
+
migration_files.sort()
|
|
279
|
+
|
|
280
|
+
return migration_files
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def _parse_migration_revisions(migration_path: Path) -> tuple[str, Optional[str]]:
|
|
284
|
+
"""
|
|
285
|
+
Extract revision and down_revision IDs from a migration file.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
migration_path: Path to the migration file
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
Tuple of (revision, down_revision). down_revision may be None.
|
|
292
|
+
|
|
293
|
+
Raises:
|
|
294
|
+
SystemExit: If revision ID cannot be found in the file
|
|
295
|
+
"""
|
|
296
|
+
revision = None
|
|
297
|
+
down_revision = None
|
|
298
|
+
|
|
299
|
+
with open(migration_path, "r", encoding="utf-8") as f:
|
|
300
|
+
for line in f:
|
|
301
|
+
if line.strip().startswith("revision ="):
|
|
302
|
+
revision = line.split("=")[1].strip().strip("\"'")
|
|
303
|
+
elif line.strip().startswith("down_revision ="):
|
|
304
|
+
down_rev_value = line.split("=")[1].strip().strip("\"'")
|
|
305
|
+
if down_rev_value.lower() != "none":
|
|
306
|
+
down_revision = down_rev_value
|
|
307
|
+
|
|
308
|
+
if not revision:
|
|
309
|
+
log.error(f"Could not find revision ID in {migration_path}")
|
|
310
|
+
raise SystemExit(f"Invalid migration file: {migration_path}")
|
|
311
|
+
|
|
312
|
+
return revision, down_revision
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def _test_migrations_upgrade_downgrade_sequence(
|
|
316
|
+
alembic_config: Config,
|
|
317
|
+
migrations: list[tuple[str, str, Optional[str]]],
|
|
318
|
+
) -> None:
|
|
319
|
+
"""
|
|
320
|
+
Test multiple migrations can be upgraded and downgraded successfully in sequence.
|
|
321
|
+
|
|
322
|
+
Tests all new migrations together by:
|
|
323
|
+
1. Downgrading incrementally through all migrations (newest to oldest)
|
|
324
|
+
2. Upgrading incrementally back through all migrations (oldest to newest)
|
|
325
|
+
|
|
326
|
+
After Phase 2, the database is at the newest migration revision, which should
|
|
327
|
+
match HEAD for the new migrations being tested.
|
|
328
|
+
|
|
329
|
+
This approach tests migrations in a realistic sequence and can catch
|
|
330
|
+
interaction issues between migrations.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
alembic_config: Alembic configuration
|
|
334
|
+
migrations: List of (migration_name, revision, down_revision) tuples
|
|
335
|
+
|
|
336
|
+
Raises:
|
|
337
|
+
SystemExit: If any migration upgrade/downgrade test fails
|
|
338
|
+
"""
|
|
339
|
+
if not migrations:
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
log.info(f"Testing {len(migrations)} migration(s) in sequence")
|
|
343
|
+
|
|
344
|
+
try:
|
|
345
|
+
# Phase 1: Downgrade through all migrations (newest to oldest)
|
|
346
|
+
log.info("Phase 1: Downgrading through all new migrations...")
|
|
347
|
+
for migration_name, revision, down_revision in reversed(migrations):
|
|
348
|
+
if down_revision:
|
|
349
|
+
log.info(f" Downgrading {migration_name} to {down_revision}...")
|
|
350
|
+
downgrade_db(alembic_config, down_revision)
|
|
351
|
+
else:
|
|
352
|
+
log.info(f" Skipping {migration_name} (no down_revision)")
|
|
353
|
+
|
|
354
|
+
# Phase 2: Upgrade back through all migrations (oldest to newest)
|
|
355
|
+
log.info("Phase 2: Upgrading back through all new migrations...")
|
|
356
|
+
for migration_name, revision, down_revision in migrations:
|
|
357
|
+
log.info(f" Upgrading {migration_name} to {revision}...")
|
|
358
|
+
upgrade_db(alembic_config, revision)
|
|
359
|
+
|
|
360
|
+
log.info(f"✓ All {len(migrations)} migration(s) passed upgrade/downgrade test")
|
|
361
|
+
|
|
362
|
+
except Exception as error:
|
|
363
|
+
log.error("Migration upgrade/downgrade sequence test failed!")
|
|
364
|
+
log.error(str(error))
|
|
365
|
+
raise SystemExit("Migration upgrade/downgrade test failed")
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def check_new_migrations_upgrade_downgrade(database_url: str) -> None:
|
|
369
|
+
"""
|
|
370
|
+
Detects new migrations added in the current branch and tests that they
|
|
371
|
+
can be successfully upgraded and downgraded.
|
|
372
|
+
|
|
373
|
+
Uses git to compare against the target/base branch to find new migration files.
|
|
374
|
+
In CI, uses GITHUB_BASE_REF if available, otherwise falls back to origin/main.
|
|
375
|
+
"""
|
|
376
|
+
try:
|
|
377
|
+
# Get the repo root directory
|
|
378
|
+
repo_root = subprocess.check_output(
|
|
379
|
+
["git", "rev-parse", "--show-toplevel"],
|
|
380
|
+
stderr=subprocess.STDOUT,
|
|
381
|
+
text=True,
|
|
382
|
+
).strip()
|
|
383
|
+
|
|
384
|
+
# Determine base branch and get new migration files
|
|
385
|
+
base_branch = _get_base_branch_for_comparison()
|
|
386
|
+
migration_files = _get_new_migration_files(repo_root, base_branch)
|
|
387
|
+
|
|
388
|
+
if not migration_files:
|
|
389
|
+
log.info("No new migration files detected in current branch")
|
|
390
|
+
log.info("No new migrations to test.")
|
|
391
|
+
return
|
|
392
|
+
|
|
393
|
+
log.info(f"Detected {len(migration_files)} new migration(s) to test")
|
|
394
|
+
|
|
395
|
+
# Log the migrations in order
|
|
396
|
+
for i, file_path in enumerate(migration_files, 1):
|
|
397
|
+
log.info(f" {i}. {Path(file_path).name}")
|
|
398
|
+
|
|
399
|
+
alembic_config = get_alembic_config(database_url)
|
|
400
|
+
|
|
401
|
+
# Parse all migrations first
|
|
402
|
+
migrations = []
|
|
403
|
+
for file_path in migration_files:
|
|
404
|
+
abs_path = Path(repo_root) / file_path
|
|
405
|
+
revision, down_revision = _parse_migration_revisions(abs_path)
|
|
406
|
+
migrations.append((abs_path.name, revision, down_revision))
|
|
407
|
+
|
|
408
|
+
# Test all migrations in sequence
|
|
409
|
+
_test_migrations_upgrade_downgrade_sequence(alembic_config, migrations)
|
|
410
|
+
|
|
411
|
+
log.info(
|
|
412
|
+
f"All {len(migration_files)} new migration(s) passed upgrade/downgrade tests."
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
except subprocess.CalledProcessError as error:
|
|
416
|
+
# Git command failed - might not be in a git repo or no origin/main
|
|
417
|
+
log.warning(f"Could not detect new migrations via git: {error}")
|
|
418
|
+
log.warning(
|
|
419
|
+
"Skipping migration upgrade/downgrade check (git detection failed)."
|
|
420
|
+
)
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains "safe" versions of CRUD operations that do NOT
|
|
3
|
+
manually manage database transactions. Transaction management is left
|
|
4
|
+
to the calling code (endpoints, services) to handle at the appropriate
|
|
5
|
+
boundary.
|
|
6
|
+
|
|
7
|
+
Use functions from this module instead of fides.api.db.crud
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from collections import defaultdict
|
|
11
|
+
from typing import Any, Dict, List, Tuple, Type, TypeVar
|
|
12
|
+
|
|
13
|
+
from fastapi import HTTPException
|
|
14
|
+
from loguru import logger as log
|
|
15
|
+
from sqlalchemy import and_, column
|
|
16
|
+
from sqlalchemy import delete as _delete
|
|
17
|
+
from sqlalchemy import or_
|
|
18
|
+
from sqlalchemy import update as _update
|
|
19
|
+
from sqlalchemy.dialects.postgresql import Insert as _insert
|
|
20
|
+
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
|
|
21
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
22
|
+
from sqlalchemy.future import select
|
|
23
|
+
from sqlalchemy.sql import Select
|
|
24
|
+
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
|
|
25
|
+
|
|
26
|
+
from fides.api.models.sql_models import ( # type: ignore[attr-defined]
|
|
27
|
+
CustomField,
|
|
28
|
+
CustomFieldDefinition,
|
|
29
|
+
FidesBase,
|
|
30
|
+
ResourceTypes,
|
|
31
|
+
)
|
|
32
|
+
from fides.api.util import errors
|
|
33
|
+
|
|
34
|
+
# Helps return type be linked to the type of the parameter
|
|
35
|
+
T = TypeVar("T", bound="FidesBase")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# CRUD Functions
|
|
39
|
+
async def create_resource(
|
|
40
|
+
sql_model: Type[T], resource_dict: Dict, async_session: AsyncSession
|
|
41
|
+
) -> T:
|
|
42
|
+
"""
|
|
43
|
+
Create a resource in the database.
|
|
44
|
+
|
|
45
|
+
This version does NOT manually manage transactions - transaction management
|
|
46
|
+
is left to the calling code.
|
|
47
|
+
"""
|
|
48
|
+
with log.contextualize(
|
|
49
|
+
sql_model=sql_model.__name__, fides_key=resource_dict["fides_key"]
|
|
50
|
+
):
|
|
51
|
+
|
|
52
|
+
existing_resource = await get_resource(
|
|
53
|
+
sql_model, resource_dict["fides_key"], async_session, raise_not_found=False
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if existing_resource is not None:
|
|
57
|
+
already_exists_error = errors.AlreadyExistsError(
|
|
58
|
+
sql_model.__name__, resource_dict["fides_key"]
|
|
59
|
+
)
|
|
60
|
+
log.bind(error=already_exists_error.detail["error"]).info( # type: ignore[index]
|
|
61
|
+
"Failed to insert resource"
|
|
62
|
+
)
|
|
63
|
+
raise already_exists_error
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
log.debug("Creating resource")
|
|
67
|
+
query = _insert(sql_model.__table__).values(resource_dict)
|
|
68
|
+
await async_session.execute(query)
|
|
69
|
+
except SQLAlchemyError as e:
|
|
70
|
+
log.exception(f"Failed to create resource with error: '{e}'")
|
|
71
|
+
sa_error = errors.QueryError()
|
|
72
|
+
raise sa_error
|
|
73
|
+
|
|
74
|
+
return await get_resource(sql_model, resource_dict["fides_key"], async_session)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async def get_custom_fields_filtered(
|
|
78
|
+
async_session: AsyncSession,
|
|
79
|
+
resource_types_to_ids: Dict[ResourceTypes, List[str]] = defaultdict(list),
|
|
80
|
+
) -> FidesBase:
|
|
81
|
+
"""
|
|
82
|
+
Utility function to construct a filtered query for custom field values based on provided mapping of
|
|
83
|
+
resource types to resource IDs.
|
|
84
|
+
|
|
85
|
+
Only custom fields with an "active" CustomFieldDefinition are returned.
|
|
86
|
+
|
|
87
|
+
This is for use in bulk querying of custom fields, to avoid multiple round trips to the db.
|
|
88
|
+
"""
|
|
89
|
+
with log.contextualize(model=CustomField):
|
|
90
|
+
try:
|
|
91
|
+
log.debug("Fetching resource")
|
|
92
|
+
query = select(
|
|
93
|
+
CustomField.resource_id,
|
|
94
|
+
CustomField.value,
|
|
95
|
+
CustomFieldDefinition.resource_type,
|
|
96
|
+
CustomFieldDefinition.name,
|
|
97
|
+
CustomFieldDefinition.field_type,
|
|
98
|
+
).join(
|
|
99
|
+
CustomFieldDefinition,
|
|
100
|
+
CustomFieldDefinition.id == CustomField.custom_field_definition_id,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
criteria = [
|
|
104
|
+
and_(
|
|
105
|
+
CustomFieldDefinition.resource_type == resource_type.value,
|
|
106
|
+
CustomField.resource_id.in_(resource_ids),
|
|
107
|
+
# pylint: disable=singleton-comparison
|
|
108
|
+
CustomFieldDefinition.active == True,
|
|
109
|
+
)
|
|
110
|
+
for resource_type, resource_ids in resource_types_to_ids.items()
|
|
111
|
+
]
|
|
112
|
+
query = query.where(or_(False, *criteria))
|
|
113
|
+
result = await async_session.execute(query)
|
|
114
|
+
return result.mappings().all()
|
|
115
|
+
except SQLAlchemyError as e:
|
|
116
|
+
sa_error = errors.QueryError()
|
|
117
|
+
log.exception(f"Failed to fetch custom fields with error: '{e}'")
|
|
118
|
+
raise sa_error
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
async def get_resource(
|
|
122
|
+
sql_model: Type[T],
|
|
123
|
+
fides_key: str,
|
|
124
|
+
async_session: AsyncSession,
|
|
125
|
+
raise_not_found: bool = True,
|
|
126
|
+
) -> T:
|
|
127
|
+
"""
|
|
128
|
+
Get a resource from the database by its FidesKey.
|
|
129
|
+
|
|
130
|
+
Returns a SQLAlchemy model of that resource.
|
|
131
|
+
|
|
132
|
+
This version does NOT manually manage transactions - transaction management
|
|
133
|
+
is left to the calling code.
|
|
134
|
+
"""
|
|
135
|
+
with log.contextualize(sql_model=sql_model.__name__, fides_key=fides_key):
|
|
136
|
+
try:
|
|
137
|
+
log.debug("Fetching resource")
|
|
138
|
+
query = select(sql_model).where(sql_model.fides_key == fides_key)
|
|
139
|
+
result = await async_session.execute(query)
|
|
140
|
+
except SQLAlchemyError as e:
|
|
141
|
+
sa_error = errors.QueryError()
|
|
142
|
+
log.exception(f"Failed to fetch resource with error: '{e}'")
|
|
143
|
+
raise sa_error
|
|
144
|
+
|
|
145
|
+
sql_resource = result.scalars().first()
|
|
146
|
+
if sql_resource is None and raise_not_found:
|
|
147
|
+
not_found_error = errors.NotFoundError(sql_model.__name__, fides_key)
|
|
148
|
+
log.bind(error=not_found_error.detail["error"]).info("Resource not found") # type: ignore[index]
|
|
149
|
+
raise not_found_error
|
|
150
|
+
|
|
151
|
+
return sql_resource
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
async def get_resource_with_custom_fields(
|
|
155
|
+
sql_model: Type[T], fides_key: str, async_session: AsyncSession
|
|
156
|
+
) -> Dict[str, Any]:
|
|
157
|
+
"""Get a resource from the database by its FidesKey including it's custom fields.
|
|
158
|
+
|
|
159
|
+
Returns a dictionary of that resource.
|
|
160
|
+
|
|
161
|
+
This version does NOT manually manage transactions - transaction management
|
|
162
|
+
is left to the calling code.
|
|
163
|
+
"""
|
|
164
|
+
resource: T = await get_resource(sql_model, fides_key, async_session)
|
|
165
|
+
resource_dict = resource.__dict__
|
|
166
|
+
resource_dict.pop("_sa_instance_state", None)
|
|
167
|
+
|
|
168
|
+
with log.contextualize(sql_model=sql_model.__name__, fides_key=fides_key):
|
|
169
|
+
try:
|
|
170
|
+
log.debug("Fetching custom fields for resource")
|
|
171
|
+
query = (
|
|
172
|
+
select(CustomFieldDefinition.name, CustomField.value)
|
|
173
|
+
.join(
|
|
174
|
+
CustomField,
|
|
175
|
+
CustomField.custom_field_definition_id == CustomFieldDefinition.id,
|
|
176
|
+
)
|
|
177
|
+
.where(
|
|
178
|
+
(CustomField.resource_id == resource.fides_key)
|
|
179
|
+
& ( # pylint: disable=singleton-comparison
|
|
180
|
+
CustomFieldDefinition.active == True
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
result = await async_session.execute(query)
|
|
185
|
+
except SQLAlchemyError as e:
|
|
186
|
+
sa_error = errors.QueryError()
|
|
187
|
+
log.exception(f"Failed to fetch custom fields with error: '{e}'")
|
|
188
|
+
raise sa_error
|
|
189
|
+
|
|
190
|
+
custom_fields = result.mappings().all()
|
|
191
|
+
|
|
192
|
+
if not custom_fields:
|
|
193
|
+
return resource_dict
|
|
194
|
+
|
|
195
|
+
for field in custom_fields:
|
|
196
|
+
if field["name"] in resource_dict:
|
|
197
|
+
resource_dict[field["name"]] = (
|
|
198
|
+
f"{resource_dict[field['name']]}, {', '.join(field['value'])}"
|
|
199
|
+
)
|
|
200
|
+
else:
|
|
201
|
+
resource_dict[field["name"]] = ", ".join(field["value"])
|
|
202
|
+
|
|
203
|
+
return resource_dict
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
async def list_resource(sql_model: Type[T], async_session: AsyncSession) -> List[T]:
|
|
207
|
+
"""
|
|
208
|
+
Get a list of all of the resources of this type from the database.
|
|
209
|
+
|
|
210
|
+
Returns a list of SQLAlchemy models of that resource type.
|
|
211
|
+
|
|
212
|
+
This version does NOT manually manage transactions - transaction management
|
|
213
|
+
is left to the calling code.
|
|
214
|
+
"""
|
|
215
|
+
query = select(sql_model)
|
|
216
|
+
return await list_resource_query(async_session, query, sql_model)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
async def list_resource_query(
|
|
220
|
+
async_session: AsyncSession, query: Select, sql_model: Type[T]
|
|
221
|
+
) -> List[T]:
|
|
222
|
+
"""
|
|
223
|
+
Utility function to wrap a select query in generic "list_resource" execution handling.
|
|
224
|
+
Wrapping includes execution against the DB session, logging and error handling.
|
|
225
|
+
|
|
226
|
+
This version does NOT manually manage transactions - transaction management
|
|
227
|
+
is left to the calling code.
|
|
228
|
+
"""
|
|
229
|
+
|
|
230
|
+
with log.contextualize(sql_model=sql_model.__name__):
|
|
231
|
+
try:
|
|
232
|
+
log.debug("Fetching resources")
|
|
233
|
+
result = await async_session.execute(query)
|
|
234
|
+
sql_resources = result.scalars().all()
|
|
235
|
+
except SQLAlchemyError as e:
|
|
236
|
+
log.exception(f"Failed to fetch resources with error: '{e}'")
|
|
237
|
+
sa_error = errors.QueryError()
|
|
238
|
+
raise sa_error
|
|
239
|
+
|
|
240
|
+
return sql_resources
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
async def update_resource(
|
|
244
|
+
sql_model: Type[T], resource_dict: Dict, async_session: AsyncSession
|
|
245
|
+
) -> Dict:
|
|
246
|
+
"""
|
|
247
|
+
Update a resource in the database by its fides_key.
|
|
248
|
+
|
|
249
|
+
This version does NOT manually manage transactions - transaction management
|
|
250
|
+
is left to the calling code.
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
with log.contextualize(
|
|
254
|
+
sql_model=sql_model.__name__, fides_key=resource_dict["fides_key"]
|
|
255
|
+
):
|
|
256
|
+
await get_resource(sql_model, resource_dict["fides_key"], async_session)
|
|
257
|
+
|
|
258
|
+
try:
|
|
259
|
+
log.debug("Updating resource")
|
|
260
|
+
await async_session.execute(
|
|
261
|
+
_update(sql_model.__table__)
|
|
262
|
+
.where(sql_model.fides_key == resource_dict["fides_key"])
|
|
263
|
+
.values(resource_dict)
|
|
264
|
+
)
|
|
265
|
+
except SQLAlchemyError as e:
|
|
266
|
+
log.exception(f"Failed to update resource with error: '{e}'")
|
|
267
|
+
sa_error = errors.QueryError()
|
|
268
|
+
raise sa_error
|
|
269
|
+
|
|
270
|
+
return await get_resource(sql_model, resource_dict["fides_key"], async_session)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
async def upsert_resources(
|
|
274
|
+
sql_model: Type[T], resource_dicts: List[Dict], async_session: AsyncSession
|
|
275
|
+
) -> Tuple[int, int]:
|
|
276
|
+
"""
|
|
277
|
+
Insert new resources into the database. If a resource already exists,
|
|
278
|
+
update it by it's fides_key.
|
|
279
|
+
|
|
280
|
+
Returns a Tuple containing the counts of inserted and updated rows.
|
|
281
|
+
|
|
282
|
+
This version does NOT manually manage transactions - transaction management
|
|
283
|
+
is left to the calling code.
|
|
284
|
+
"""
|
|
285
|
+
|
|
286
|
+
with log.contextualize(
|
|
287
|
+
sql_model=sql_model.__name__,
|
|
288
|
+
fides_keys=[resource["fides_key"] for resource in resource_dicts],
|
|
289
|
+
):
|
|
290
|
+
try:
|
|
291
|
+
log.debug("Upserting resources")
|
|
292
|
+
insert_stmt = (
|
|
293
|
+
_insert(sql_model.__table__)
|
|
294
|
+
.values(resource_dicts)
|
|
295
|
+
.returning(
|
|
296
|
+
(column("xmax") == 0), # Row was inserted
|
|
297
|
+
(column("xmax") != 0), # Row was updated
|
|
298
|
+
)
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
excluded = dict(insert_stmt.excluded.items()) # type: ignore[attr-defined]
|
|
302
|
+
excluded.pop("id", None) # If updating, don't update the "id"
|
|
303
|
+
|
|
304
|
+
result = await async_session.execute(
|
|
305
|
+
insert_stmt.on_conflict_do_update(
|
|
306
|
+
index_elements=["fides_key"],
|
|
307
|
+
set_=excluded,
|
|
308
|
+
)
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
inserts, updates = 0, 0
|
|
312
|
+
for xmax in result:
|
|
313
|
+
inserts += 1 if xmax[0] else 0
|
|
314
|
+
updates += 1 if xmax[1] else 0
|
|
315
|
+
|
|
316
|
+
return (inserts, updates)
|
|
317
|
+
|
|
318
|
+
except SQLAlchemyError as e:
|
|
319
|
+
log.exception(f"Failed to upsert resources with error: '{e}'")
|
|
320
|
+
sa_error = errors.QueryError()
|
|
321
|
+
raise sa_error
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
async def delete_resource(
|
|
325
|
+
sql_model: Type[T], fides_key: str, async_session: AsyncSession
|
|
326
|
+
) -> T:
|
|
327
|
+
"""
|
|
328
|
+
Delete a resource by its fides_key.
|
|
329
|
+
|
|
330
|
+
If the resource has child keys referring to it, also delete those.
|
|
331
|
+
|
|
332
|
+
This version does NOT manually manage transactions - transaction management
|
|
333
|
+
is left to the calling code.
|
|
334
|
+
"""
|
|
335
|
+
|
|
336
|
+
with log.contextualize(sql_model=sql_model.__name__, fides_key=fides_key):
|
|
337
|
+
sql_resource = await get_resource(sql_model, fides_key, async_session)
|
|
338
|
+
|
|
339
|
+
try:
|
|
340
|
+
# Automatically delete related resources if they are CTL objects
|
|
341
|
+
if hasattr(sql_model, "parent_key"):
|
|
342
|
+
log.debug("Deleting resource and its children")
|
|
343
|
+
query = (
|
|
344
|
+
_delete(sql_model.__table__)
|
|
345
|
+
.where(
|
|
346
|
+
or_(
|
|
347
|
+
sql_model.fides_key == fides_key,
|
|
348
|
+
sql_model.fides_key.like(f"{fides_key}.%"),
|
|
349
|
+
)
|
|
350
|
+
)
|
|
351
|
+
.execution_options(synchronize_session=False)
|
|
352
|
+
)
|
|
353
|
+
else:
|
|
354
|
+
log.debug("Deleting resource")
|
|
355
|
+
query = _delete(sql_model.__table__).where(
|
|
356
|
+
sql_model.fides_key == fides_key
|
|
357
|
+
)
|
|
358
|
+
await async_session.execute(query)
|
|
359
|
+
except IntegrityError as err:
|
|
360
|
+
raw_error_text: str = err.orig.args[0]
|
|
361
|
+
|
|
362
|
+
if "violates foreign key constraint" in raw_error_text:
|
|
363
|
+
error_message = "Failed to delete resource! Foreign key constraint found, try deleting related resources first."
|
|
364
|
+
else:
|
|
365
|
+
error_message = "Failed to delete resource!"
|
|
366
|
+
|
|
367
|
+
log.bind(error="SQL Query integrity error!").error(raw_error_text)
|
|
368
|
+
raise HTTPException(
|
|
369
|
+
status_code=HTTP_422_UNPROCESSABLE_ENTITY,
|
|
370
|
+
detail=error_message,
|
|
371
|
+
)
|
|
372
|
+
except SQLAlchemyError as e:
|
|
373
|
+
log.exception(f"Failed to delete resource with error: '{e}'")
|
|
374
|
+
sa_error = errors.QueryError()
|
|
375
|
+
raise sa_error
|
|
376
|
+
|
|
377
|
+
return sql_resource
|