ethyca-fides 2.66.2rc0__py2.py3-none-any.whl → 2.67.0__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.
Potentially problematic release.
This version of ethyca-fides might be problematic. Click here for more details.
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0.dist-info}/METADATA +1 -1
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0.dist-info}/RECORD +297 -282
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/7e9a2b52f498_adding_masking_secrets.py +60 -0
- fides/api/alembic/migrations/versions/a7065df4dcf1_add_finalized_fields_to_privacy_request.py +65 -0
- fides/api/alembic/migrations/versions/d0031087eacb_create_manualtaskconditionaldependency_.py +106 -0
- fides/api/api/v1/endpoints/dataset_config_endpoints.py +13 -5
- fides/api/api/v1/endpoints/drp_endpoints.py +7 -1
- fides/api/api/v1/endpoints/privacy_request_endpoints.py +44 -1
- fides/api/api/v1/endpoints/user_endpoints.py +83 -7
- fides/api/app_setup.py +3 -2
- fides/api/common_exceptions.py +8 -0
- fides/api/db/base.py +1 -0
- fides/api/db/database.py +1 -1
- fides/api/graph/execution.py +46 -0
- fides/api/graph/graph.py +13 -2
- fides/api/graph/traversal.py +126 -39
- fides/api/models/manual_task/__init__.py +2 -0
- fides/api/models/manual_task/conditional_dependency.py +144 -0
- fides/api/models/{manual_task.py → manual_task/manual_task.py} +10 -0
- fides/api/models/masking_secret.py +72 -0
- fides/api/models/policy.py +23 -0
- fides/api/models/privacy_request/execution_log.py +1 -0
- fides/api/models/privacy_request/privacy_request.py +64 -26
- fides/api/oauth/roles.py +2 -0
- fides/api/schemas/application_config.py +12 -1
- fides/api/schemas/connection_configuration/connection_secrets_datahub.py +10 -1
- fides/api/schemas/masking/masking_secrets.py +1 -1
- fides/api/schemas/policy.py +1 -0
- fides/api/schemas/privacy_request.py +5 -0
- fides/api/service/connectors/base_connector.py +15 -0
- fides/api/service/connectors/bigquery_connector.py +72 -19
- fides/api/service/connectors/dynamodb_connector.py +2 -1
- fides/api/service/connectors/fides_connector.py +1 -0
- fides/api/service/connectors/http_connector.py +1 -0
- fides/api/service/connectors/manual_task_connector.py +1 -0
- fides/api/service/connectors/manual_webhook_connector.py +2 -1
- fides/api/service/connectors/mongodb_connector.py +1 -0
- fides/api/service/connectors/okta_connector.py +1 -0
- fides/api/service/connectors/query_configs/bigquery_query_config.py +95 -36
- fides/api/service/connectors/query_configs/snowflake_query_config.py +3 -3
- fides/api/service/connectors/rds_mysql_connector.py +1 -0
- fides/api/service/connectors/rds_postgres_connector.py +1 -0
- fides/api/service/connectors/s3_connector.py +1 -0
- fides/api/service/connectors/saas_connector.py +1 -0
- fides/api/service/connectors/scylla_connector.py +1 -0
- fides/api/service/connectors/snowflake_connector.py +55 -2
- fides/api/service/connectors/sql_connector.py +159 -13
- fides/api/service/connectors/website_connector.py +1 -0
- fides/api/service/privacy_request/dsr_package/templates/welcome.html +2 -2
- fides/api/service/privacy_request/request_runner_service.py +145 -55
- fides/api/service/privacy_request/request_service.py +172 -52
- fides/api/task/conditional_dependencies/__init__.py +0 -0
- fides/api/task/conditional_dependencies/evaluator.py +109 -0
- fides/api/task/conditional_dependencies/schemas.py +54 -0
- fides/api/task/create_request_tasks.py +1 -1
- fides/api/task/deprecated_graph_task.py +24 -6
- fides/api/task/execute_request_tasks.py +93 -12
- fides/api/task/filter_results.py +1 -1
- fides/api/task/graph_task.py +86 -5
- fides/api/task/manual/manual_task_address.py +46 -0
- fides/api/task/manual/manual_task_graph_task.py +118 -126
- fides/api/task/manual/manual_task_utils.py +52 -105
- fides/api/util/aws_util.py +5 -1
- fides/api/util/cache.py +61 -0
- fides/api/util/encryption/secrets_util.py +48 -18
- fides/api/util/memory_watchdog.py +286 -0
- fides/common/api/scope_registry.py +3 -0
- fides/common/api/v1/urn_registry.py +1 -1
- fides/config/execution_settings.py +12 -0
- fides/config/utils.py +2 -0
- fides/service/privacy_request/privacy_request_service.py +6 -1
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/MNlh9olWjgbqAHKyQY3LF/_buildManifest.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1817-b78b58ae3b75d75a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1975.7d4634a0e823a02b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{203-5a663f465ba26bb4.js → 203-cd78ea279cecba60.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/2150-930ffaf2c4718edc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/255-1bc0cbef7a59cdc6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{3450-0ba194991d0cca88.js → 3450-69f4e16978971bb8.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3550-d04125c828d591a1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{3855-e172870d3e21b0dd.js → 3855-509ca7ac99b5eada.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{3872-46cebf7ec1b31a2b.js → 3872-0a0f0032ca39a93f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/409-ea70638a59296659.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{4121-2bc09fc4ddbfe5cb.js → 4121-877e19d3fa078c7b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{4230-60100f7ef3ddcde1.js → 4230-114e31621c19ea69.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/4259.d1507e0db19cbed7.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/431-1db919f6569a4021.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{4608-bbb7bf511a05c3c2.js → 4608-f16f281f2d05d963.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5309-d9a488457898263b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{905-ffdbd0b14167e8bd.js → 5596-4378b2927dae65b2.js} +3 -3
- fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6084-7178ff6ea6822475.js → 6084-ddbad3149364725d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/6148-59a59d5c5925344f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6419-d0c00d661b01f8fa.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6662-507be5d46e5b719b.js → 6662-a9e54ead3dc53644.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/6780-b42a27e72707936d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6853-2ad3e08fe6f9f5f2.js → 6853-d0190d2cca9dbde2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{6882-6af16fef26c21e06.js → 6882-59ea739e3616ce83.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-ba98e778a5b45ebf.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{7476-281ee9a8286556f3.js → 7476-cc0d9a94ed7aad53.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/7725-539d3a906f627531.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{787-fb41002f797eb2df.js → 787-c57185ad89c4e288.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{79-7e87aff851423d4a.js → 79-2aab56be75e16187.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{796-329a5f823ec258a5.js → 796-3bdda2a7868464af.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/8735-40caf91800a3610c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9046-7085a401297c5520.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{9226-746771d47dff6266.js → 9226-2dcac54ab3fb94be.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{9951-9b753ad7c3f51bdf.js → 9951-7c6639e5d062779e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-39ccb07327c2c5d5.js → _app-750d6bd16c971bb9.js} +56 -56
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-98777246bec9dc2a.js → manual-2a655ff3a97f2492.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-a71c0aff4e0e6535.js → add-systems-0902f0bb4080643e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-1edf582ba3cd3bbb.js → [id]-f22ddd9b48a5c418.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-06bb3b0bf097fcdb.js → new-e74cb5ea87f15b40.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-685771e5f7196d87.js → privacy-experience-21f997c69fc3b4c2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-6ccedc70dc447089.js → [id]-da4124b7600a2a1d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-944bca1cc57985b5.js → new-a57d251c88ce68ae.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-84f4bd14ce8673bc.js → privacy-notices-ad105181bc91209b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-b0c4235fe6d0b0c8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-11d52f1570759c4d.js → [resourceUrn]-aad6047a4604b945.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-32eac8bbd217615a.js → projects-29784a11fe0fbd0a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-b83afa5565d0c84e.js → [resourceUrn]-b6b98cea25dd94fa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-6f630d42ac9fb6b4.js → data-catalog-7770a8dc34bd0fc0.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-3e5725cd06d7fe6c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-92b0bd97d8e79340.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-ee3c0a103346fc06.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-9aa744d56cdacb0d.js → activity-ad6a84a6276f914c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-14bd7500362ff224.js → [resourceUrn]-f98dd251babb7e28.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-9e7dfd5a6acc2e8f.js → discovery-56eb4c014f0d96a3.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-d23b3ae139f0428b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-c0d2bfd465df20e0.js → [...subfieldNames]-15301bd6bf7cf718.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-28280a8a39a6e37c.js → [collectionName]-0fa72873e464f581.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-82fb246d87e58ebd.js → new-0d50084fbdf9b84c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-20165c31ab1bc7cf.js → dataset-f3348d0a92543bab.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-b4a6bcc87d126840.js → [id]-7d6027570d05c57f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-f95d7b0bbfc58f5a.js → new-c6614583b14dc9f2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-5d8fd1af75f19e2f.js → fides-js-docs-1f4335dca5c09860.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{index-1919aab9e5834b51.js → index-fbf9b845bb901238.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-8e346fb36e8034d2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-e2d5d7e2a5265e68.js → integrations-7f15cd8538cdc24d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging-1bae386d8c190348.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-69ad86b7a8a9a115.js → table-migration-05616e2ae20ff4f8.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-79f1576b1126975c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-f1d818242d8550f8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-d40a26bddb126c5c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-96a08c4431b5462c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-9d1840f8309b706e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/{[purpose_id]-fc201657f4a782c7.js → [purpose_id]-e891d01ece59669e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{consent-c2d39cba8396ef3a.js → consent-f61b87e79367865b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-d992103cc55901ae.js → custom-fields-f8eea5d508c60c64.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-023e1895552817de.js → locations-ed6a140b362c5baa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-ac403c0886b20e20.js → organization-ff9a34264d48c35f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-7a3396ac819c7904.js → test-datasets-a4b6d41ca679298b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-8314a819837f5b2a.js → [id]-c8f5fbaa83dd9945.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{systems-21f423a7c417aa9d.js → systems-c05b49ddec1a1b4f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-df0d88716578e295.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-da68efc31998dc66.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-173ac3a1ed2b05a6.js → user-management-e98dfc7d4f2a4e16.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/webpack-90e8ec1fc5c6455b.js +1 -0
- fides/ui-build/static/admin/_next/static/css/{5bfb2473e5701527.css → 23cf870196941c9a.css} +1 -1
- fides/ui-build/static/admin/_next/static/css/{94965f224bc991e9.css → 8bc1833f1fa53ff0.css} +1 -1
- fides/ui-build/static/admin/_next/static/css/d9924caa849931b3.css +1 -0
- fides/ui-build/static/admin/_next/static/css/dbcf63488933a4d5.css +29 -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/[monitorId]/[systemId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
- 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 +4 -4
- fides/ui-build/static/admin/lib/fides.js +4 -4
- fides/ui-build/static/admin/login/[provider].html +1 -1
- fides/ui-build/static/admin/login.html +1 -1
- fides/ui-build/static/admin/messaging/[id].html +1 -1
- fides/ui-build/static/admin/messaging/add-template.html +1 -1
- fides/ui-build/static/admin/messaging.html +1 -1
- 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/poc/table-migration.html +1 -1
- fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/messaging.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/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.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/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/ui-build/static/admin/_next/static/8108ANFxs99VY7KZ_Xev2/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1316-6cc72a45ebf7ff81.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1807-3beab149351d5ded.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-e601e737e3cc7a0e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/255-7db55b0e3a0f9dea.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2599-6c4d22e75028d8b6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2858-0b44609b6be7850b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2866-a73888c17a195cbe.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/409-a257e14acebcd73b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/431-34f0b91c26f8d9ab.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5309-b2c4803370634ff8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/570-c99f07161bd339cd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6780-e3d40aa17a4bf2e9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-bb875d9ac89f6030.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7062.fda15dcb7df85675.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7c79804f.7a7112aece470725.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9046-5c4c22c375de25b1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9278-9b1b5970f0702668.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9392.f4520f66206d347d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/ea076c0a.84423f606aef37cd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-afdbd4665657cfa1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-2265ecb899d45fbc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-5d522637871ac6c8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-9ddb52ebb7ac4c71.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-7674b97d655c193b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-0a58aee2d1e7fa01.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging-5094ffea13f32ed9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-32600543eb7b584f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-10ce53ea356f8bad.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-5501bbb129fee9c4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-cbe4c8f9096b6543.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-e130c0197362e8f3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-6387fcc8cce872eb.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-ff5738706da07801.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/webpack-ff0cd6bff75588da.js +0 -1
- fides/ui-build/static/admin/_next/static/css/2cadb5f62dcd7c2b.css +0 -1
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/{8108ANFxs99VY7KZ_Xev2 → MNlh9olWjgbqAHKyQY3LF}/_ssgManifest.js +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{2921-455e6357b74d2f76.js → 2921-86f1547ac40a5cdf.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3923-6cc911dafccc5f63.js → 3923-13a6b4da2d51bf8f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{401-1b529d5800aa1f3a.js → 401-3cc1fee61494e3bd.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5574-b13021775a15bfd2.js → 5574-9312f97b637d9ee2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7630-9aac73191ed5ed13.js → 7630-b1c93688013ef013.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9826-111aaee8bd8dbd09.js → 9826-3c578665c6d3b21d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{404-aece2c920ea14514.js → 404-2d803dab6a00f353.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-dc75dc6e37e52f05.js → multiple-8ff7f37913ad736a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-24d226b5a8de5c74.js → add-vendors-d00c9034cdeb0236.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-6a8ef51138ac926a.js → configure-0e1ca0f4c8e7f4da.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-6f86ab63a08a6528.js → properties-057cad65e7414a44.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-73d3cbf68f7c3a31.js → consent-e17c56eec8d91371.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-6ba9e160dae64695.js → [projectUrn]-80a6cc8e8573514a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-7648bbd4f6711e4d.js → resources-6c3714ee97a718c1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-393e20924c83373e.js → [resourceUrn]-31e6c54794a9883e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-8733807dad4bc96e.js → detection-2822a423a7ad0550.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-006b695e5af5ef24.js → [datasetId]-a8e8b5f4ee7af86c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{datastore-connection-c391c6fad56eec48.js → datastore-connection-3bd77864da523d41.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-53fecfb9dd6a1e0c.js → [id]-5627d0d0668077f9.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-76b01cec5fde10a9.js → add-template-feca66ad5c5fe54a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-5c08e8447c45ce44.js → ant-components-64a322d01aae5ca7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-06ad5f34585480aa.js → AntForm-8bca16a7726e7eb2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-6f071c2bc9446cb0.js → FormikAntFormItem-b0f246fc3b67ebf7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-efcc38c58991ac9e.js → FormikControlled-1a0852b090bfc392.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-430ba5c979abfb7c.js → FormikField-11f3de1b45e36583.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-5c561880bf131afb.js → forms-1b73a1c2b6c6285f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-d888a69a3bbe040e.js → configure-e551a860ec727802.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-d3d8e3d7583ec635.js → [id]-dd99183f93763ae4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-1af10ed303815d46.js → add-property-0bdbc1fcbf553b8f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{properties-cebc0dc186be499a.js → properties-e959378bb32b6b73.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-5e1322de868d615e.js → alpha-1066f0c202ef744c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-241f95e372b65d0f.js → about-37ba24a72a06862e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-41242f805599feda.js → domain-records-51333dbd21cb37c8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-2e885f74c92f669c.js → domains-bde86e5f6c09da5a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-ff112655ad5f41e5.js → email-templates-4f9a5cc8bea7725b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-86062a18e081a52a.js → regulations-102efd9199e87124.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-a2524414e968f862.js → new-de8cb3739ab99c09.js} +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import List, Optional, Union
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field, model_validator
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Operator(str, Enum):
|
|
8
|
+
eq = "eq"
|
|
9
|
+
neq = "neq"
|
|
10
|
+
lt = "lt"
|
|
11
|
+
lte = "lte"
|
|
12
|
+
gt = "gt"
|
|
13
|
+
gte = "gte"
|
|
14
|
+
exists = "exists"
|
|
15
|
+
not_exists = "not_exists"
|
|
16
|
+
list_contains = "list_contains"
|
|
17
|
+
not_in_list = "not_in_list"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class GroupOperator(str, Enum):
|
|
21
|
+
and_ = "and"
|
|
22
|
+
or_ = "or"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Leaf condition (e.g., "user.name exists", "user.created_at >= 2024-01-01")
|
|
26
|
+
class ConditionLeaf(BaseModel):
|
|
27
|
+
field_address: str = Field(
|
|
28
|
+
description="Field path to check (e.g., 'user.name', 'billing.subscription.status')"
|
|
29
|
+
)
|
|
30
|
+
operator: Operator = Field(description="Operator to apply")
|
|
31
|
+
value: Optional[
|
|
32
|
+
Union[str, int, float, bool, List[Union[str, int, float, bool]]]
|
|
33
|
+
] = Field(default=None, description="Expected value for comparison")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Nested logical condition (AND, OR)
|
|
37
|
+
class ConditionGroup(BaseModel):
|
|
38
|
+
logical_operator: GroupOperator = Field(
|
|
39
|
+
description="Logical operator: 'and' or 'or'"
|
|
40
|
+
)
|
|
41
|
+
conditions: list["Condition"] = Field(
|
|
42
|
+
description="List of conditions or nested groups"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
@model_validator(mode="after")
|
|
46
|
+
def validate_conditions(self) -> "ConditionGroup":
|
|
47
|
+
if not self.conditions:
|
|
48
|
+
raise ValueError("conditions list cannot be empty")
|
|
49
|
+
return self
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# Use model_rebuild to allow recursive nesting
|
|
53
|
+
Condition = Union[ConditionLeaf, ConditionGroup]
|
|
54
|
+
ConditionGroup.model_rebuild()
|
|
@@ -33,8 +33,8 @@ from fides.api.models.worker_task import ExecutionLogStatus
|
|
|
33
33
|
from fides.api.schemas.policy import ActionType
|
|
34
34
|
from fides.api.task.deprecated_graph_task import format_data_use_map_for_caching
|
|
35
35
|
from fides.api.task.execute_request_tasks import log_task_queued, queue_request_task
|
|
36
|
+
from fides.api.task.manual.manual_task_address import ManualTaskAddress
|
|
36
37
|
from fides.api.task.manual.manual_task_utils import (
|
|
37
|
-
ManualTaskAddress,
|
|
38
38
|
create_manual_task_instances_for_privacy_request,
|
|
39
39
|
)
|
|
40
40
|
from fides.api.util.logger_context_utils import log_context
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# pylint: disable=too-many-lines
|
|
2
|
+
from functools import partial
|
|
2
3
|
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
|
|
3
4
|
|
|
4
5
|
import dask
|
|
@@ -252,16 +253,33 @@ def run_erasure_request_deprecated( # pylint: disable = too-many-arguments
|
|
|
252
253
|
|
|
253
254
|
access_request_data[ROOT_COLLECTION_ADDRESS.value] = [identity]
|
|
254
255
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
# Build the dask task graph for erasure, ensuring we also pass along the
|
|
257
|
+
# upstream access data that may be required by the connector (e.g. BigQuery
|
|
258
|
+
# delete statements). We accomplish this by partially applying the
|
|
259
|
+
# `inputs` kwarg on each task's `erasure_request` method. The resulting
|
|
260
|
+
# callable accepts the original positional arguments expected by Dask.
|
|
261
|
+
|
|
262
|
+
dsk: Dict[CollectionAddress, Any] = {}
|
|
263
|
+
for k, t in env.items():
|
|
264
|
+
# Collect upstream access data in the same order as the input keys
|
|
265
|
+
upstream_access_data: List[List[Row]] = [
|
|
266
|
+
access_request_data.get(str(input_key), [])
|
|
267
|
+
for input_key in t.execution_node.input_keys
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
# Bind the `inputs` keyword argument so it is supplied when the task executes
|
|
271
|
+
erasure_fn_with_inputs = partial(
|
|
272
|
+
t.erasure_request, inputs=upstream_access_data
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
# Build the task tuple: (callable, retrieved_data, *prereqs)
|
|
276
|
+
dsk[k] = (
|
|
277
|
+
erasure_fn_with_inputs,
|
|
258
278
|
access_request_data.get(
|
|
259
279
|
str(k), []
|
|
260
|
-
), #
|
|
280
|
+
), # Data retrieved for this collection
|
|
261
281
|
*_evaluate_erasure_dependencies(t, erasure_end_nodes),
|
|
262
282
|
)
|
|
263
|
-
for k, t in env.items()
|
|
264
|
-
}
|
|
265
283
|
|
|
266
284
|
# root node returns 0 to be consistent with the output of the other erasure tasks
|
|
267
285
|
dsk[ROOT_COLLECTION_ADDRESS] = 0
|
|
@@ -29,13 +29,14 @@ from fides.api.task.graph_task import (
|
|
|
29
29
|
GraphTask,
|
|
30
30
|
mark_current_and_downstream_nodes_as_failed,
|
|
31
31
|
)
|
|
32
|
+
from fides.api.task.manual.manual_task_address import ManualTaskAddress
|
|
32
33
|
from fides.api.task.manual.manual_task_graph_task import ManualTaskGraphTask
|
|
33
|
-
from fides.api.task.manual.manual_task_utils import ManualTaskAddress
|
|
34
34
|
from fides.api.task.task_resources import TaskResources
|
|
35
35
|
from fides.api.tasks import DSR_QUEUE_NAME, DatabaseTask, celery_app
|
|
36
36
|
from fides.api.util.cache import cache_task_tracking_key
|
|
37
37
|
from fides.api.util.collection_util import Row
|
|
38
38
|
from fides.api.util.logger_context_utils import LoggerContextKeys, log_context
|
|
39
|
+
from fides.api.util.memory_watchdog import memory_limiter
|
|
39
40
|
|
|
40
41
|
# DSR 3.0 task functions
|
|
41
42
|
|
|
@@ -255,6 +256,7 @@ def queue_downstream_tasks(
|
|
|
255
256
|
|
|
256
257
|
|
|
257
258
|
@celery_app.task(base=DatabaseTask, bind=True)
|
|
259
|
+
@memory_limiter
|
|
258
260
|
@log_context(
|
|
259
261
|
capture_args={
|
|
260
262
|
"privacy_request_id": LoggerContextKeys.privacy_request_id,
|
|
@@ -298,17 +300,11 @@ def run_access_node(
|
|
|
298
300
|
)
|
|
299
301
|
# Currently, upstream tasks and "input keys" (which are built by data dependencies)
|
|
300
302
|
# are the same, but they may not be the same in the future.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
+
upstream_access_data: List[List[Row]] = (
|
|
304
|
+
_build_upstream_access_data(
|
|
303
305
|
graph_task.execution_node.input_keys, upstream_results
|
|
304
306
|
)
|
|
305
307
|
)
|
|
306
|
-
# Pass in access data dependencies in the same order as the input keys.
|
|
307
|
-
# If we don't have access data for an upstream node, pass in an empty list
|
|
308
|
-
upstream_access_data: List[List[Row]] = [
|
|
309
|
-
upstream.get_access_data() if upstream else []
|
|
310
|
-
for upstream in ordered_upstream_tasks
|
|
311
|
-
]
|
|
312
308
|
# Run the main access function
|
|
313
309
|
graph_task.access_request(*upstream_access_data)
|
|
314
310
|
|
|
@@ -325,6 +321,7 @@ def run_access_node(
|
|
|
325
321
|
|
|
326
322
|
|
|
327
323
|
@celery_app.task(base=DatabaseTask, bind=True)
|
|
324
|
+
@memory_limiter
|
|
328
325
|
@log_context(
|
|
329
326
|
capture_args={
|
|
330
327
|
"privacy_request_id": LoggerContextKeys.privacy_request_id,
|
|
@@ -359,7 +356,7 @@ def run_erasure_node(
|
|
|
359
356
|
session,
|
|
360
357
|
) as resources:
|
|
361
358
|
# Build GraphTask resource to facilitate execution
|
|
362
|
-
|
|
359
|
+
erasure_graph_task: GraphTask = create_graph_task(
|
|
363
360
|
session, request_task, resources
|
|
364
361
|
)
|
|
365
362
|
# Get access data that was saved in the erasure format that was collected from the
|
|
@@ -368,8 +365,24 @@ def run_erasure_node(
|
|
|
368
365
|
request_task.get_data_for_erasures() or []
|
|
369
366
|
)
|
|
370
367
|
|
|
371
|
-
|
|
372
|
-
|
|
368
|
+
upstream_access_data: List[List[Row]] = []
|
|
369
|
+
|
|
370
|
+
try:
|
|
371
|
+
upstream_access_data = (
|
|
372
|
+
get_upstream_access_data_for_erasure_task(
|
|
373
|
+
request_task, session, resources
|
|
374
|
+
)
|
|
375
|
+
)
|
|
376
|
+
except Exception as e:
|
|
377
|
+
logger.error(
|
|
378
|
+
f"Unable to get upstream access data for erasure task {request_task.collection_address}: {e}"
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
# Run the main erasure function, passing along the upstream access data.
|
|
382
|
+
# The extra data is currently only needed for generating BigQuery delete statements.
|
|
383
|
+
erasure_graph_task.erasure_request(
|
|
384
|
+
retrieved_data, inputs=upstream_access_data
|
|
385
|
+
)
|
|
373
386
|
|
|
374
387
|
queue_downstream_tasks_with_retries(
|
|
375
388
|
self,
|
|
@@ -381,6 +394,7 @@ def run_erasure_node(
|
|
|
381
394
|
|
|
382
395
|
|
|
383
396
|
@celery_app.task(base=DatabaseTask, bind=True)
|
|
397
|
+
@memory_limiter
|
|
384
398
|
@log_context(
|
|
385
399
|
capture_args={
|
|
386
400
|
"privacy_request_id": LoggerContextKeys.privacy_request_id,
|
|
@@ -487,6 +501,73 @@ def _order_tasks_by_input_key(
|
|
|
487
501
|
return tasks
|
|
488
502
|
|
|
489
503
|
|
|
504
|
+
def get_upstream_access_data_for_erasure_task(
|
|
505
|
+
erasure_request_task: RequestTask,
|
|
506
|
+
session: Session,
|
|
507
|
+
resources: TaskResources,
|
|
508
|
+
) -> List[List[Row]]:
|
|
509
|
+
"""
|
|
510
|
+
Retrieves upstream access data for a given erasure request task.
|
|
511
|
+
|
|
512
|
+
This function finds the corresponding access task for the erasure task,
|
|
513
|
+
creates a GraphTask to extract input keys, and builds the upstream access data
|
|
514
|
+
needed for erasure operations (particularly for BigQuery delete statements).
|
|
515
|
+
|
|
516
|
+
Args:
|
|
517
|
+
erasure_request_task: The erasure task that needs upstream access data
|
|
518
|
+
session: Database session for querying
|
|
519
|
+
resources: Task resources for creating GraphTask
|
|
520
|
+
|
|
521
|
+
Returns:
|
|
522
|
+
List[List[Row]]: Upstream access data ordered by input keys
|
|
523
|
+
|
|
524
|
+
Raises:
|
|
525
|
+
Exception: If the corresponding access task cannot be found
|
|
526
|
+
"""
|
|
527
|
+
# Get the corresponding access task for the current erasure task
|
|
528
|
+
access_request_task = (
|
|
529
|
+
session.query(RequestTask)
|
|
530
|
+
.filter(
|
|
531
|
+
RequestTask.privacy_request_id == erasure_request_task.privacy_request_id,
|
|
532
|
+
RequestTask.collection_address == erasure_request_task.collection_address,
|
|
533
|
+
RequestTask.action_type == ActionType.access,
|
|
534
|
+
)
|
|
535
|
+
.first()
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
if not access_request_task:
|
|
539
|
+
raise Exception(
|
|
540
|
+
f"Unable to find access request task for erasure task {erasure_request_task.collection_address}"
|
|
541
|
+
)
|
|
542
|
+
|
|
543
|
+
# Convert the request task to a GraphTask to get the input_keys
|
|
544
|
+
access_graph_task: GraphTask = create_graph_task(
|
|
545
|
+
session, access_request_task, resources
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
# Build and return the upstream access data
|
|
549
|
+
return _build_upstream_access_data(
|
|
550
|
+
access_graph_task.execution_node.input_keys,
|
|
551
|
+
access_request_task.upstream_tasks_objects(session),
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
def _build_upstream_access_data(
|
|
556
|
+
input_keys: List[CollectionAddress],
|
|
557
|
+
upstream_tasks: Query,
|
|
558
|
+
) -> List[List[Row]]:
|
|
559
|
+
"""
|
|
560
|
+
Helper function to build the access data for the current node.
|
|
561
|
+
The access data is passed in the same order as the input keys.
|
|
562
|
+
If we don't have access data for an upstream node, return an empty list.
|
|
563
|
+
"""
|
|
564
|
+
|
|
565
|
+
ordered_upstream: List[Optional[RequestTask]] = _order_tasks_by_input_key(
|
|
566
|
+
input_keys, upstream_tasks
|
|
567
|
+
)
|
|
568
|
+
return [task.get_access_data() if task else [] for task in ordered_upstream]
|
|
569
|
+
|
|
570
|
+
|
|
490
571
|
mapping = {
|
|
491
572
|
ActionType.access.value: run_access_node,
|
|
492
573
|
ActionType.erasure.value: run_erasure_node,
|
fides/api/task/filter_results.py
CHANGED
|
@@ -6,7 +6,7 @@ from loguru import logger
|
|
|
6
6
|
|
|
7
7
|
from fides.api.graph.config import CollectionAddress, FieldPath
|
|
8
8
|
from fides.api.graph.graph import DatasetGraph
|
|
9
|
-
from fides.api.task.manual.
|
|
9
|
+
from fides.api.task.manual.manual_task_address import ManualTaskAddress
|
|
10
10
|
from fides.api.util.collection_util import Row
|
|
11
11
|
|
|
12
12
|
|
fides/api/task/graph_task.py
CHANGED
|
@@ -18,6 +18,7 @@ from fides.api.common_exceptions import (
|
|
|
18
18
|
NotSupportedForCollection,
|
|
19
19
|
PrivacyRequestErasureEmailSendRequired,
|
|
20
20
|
SkippingConsentPropagation,
|
|
21
|
+
TableNotFound,
|
|
21
22
|
)
|
|
22
23
|
from fides.api.graph.config import (
|
|
23
24
|
ROOT_COLLECTION_ADDRESS,
|
|
@@ -61,6 +62,7 @@ from fides.api.util.consent_util import (
|
|
|
61
62
|
)
|
|
62
63
|
from fides.api.util.logger import Pii
|
|
63
64
|
from fides.api.util.logger_context_utils import LoggerContextKeys
|
|
65
|
+
from fides.api.util.memory_watchdog import MemoryLimitExceeded
|
|
64
66
|
from fides.api.util.saas_util import FIDESOPS_GROUPED_INPUTS
|
|
65
67
|
from fides.config import CONFIG
|
|
66
68
|
|
|
@@ -70,6 +72,16 @@ EMPTY_REQUEST = PrivacyRequest()
|
|
|
70
72
|
EMPTY_REQUEST_TASK = RequestTask()
|
|
71
73
|
|
|
72
74
|
|
|
75
|
+
def _is_memory_limit_exceeded(exception: BaseException) -> bool:
|
|
76
|
+
"""Check if the exception or any exception in its chain is a MemoryLimitExceeded."""
|
|
77
|
+
current_exception: Optional[BaseException] = exception
|
|
78
|
+
while current_exception:
|
|
79
|
+
if isinstance(current_exception, MemoryLimitExceeded):
|
|
80
|
+
return True
|
|
81
|
+
current_exception = current_exception.__cause__ or current_exception.__context__
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
|
|
73
85
|
def retry(
|
|
74
86
|
action_type: ActionType,
|
|
75
87
|
default_return: Any,
|
|
@@ -126,6 +138,7 @@ def retry(
|
|
|
126
138
|
CollectionDisabled,
|
|
127
139
|
ActionDisabled,
|
|
128
140
|
NotSupportedForCollection,
|
|
141
|
+
TableNotFound,
|
|
129
142
|
) as exc:
|
|
130
143
|
logger.warning(
|
|
131
144
|
"{} - Skipping collection {} for privacy_request: {}",
|
|
@@ -144,7 +157,31 @@ def retry(
|
|
|
144
157
|
self.log_skipped(action_type, exc)
|
|
145
158
|
self.cache_system_status_for_preferences()
|
|
146
159
|
return default_return
|
|
160
|
+
except MemoryLimitExceeded as ex:
|
|
161
|
+
# Hard failure – mark task & downstream as errored and abort.
|
|
162
|
+
logger.error(
|
|
163
|
+
"Memory watchdog exceeded ({}%). Aborting {} {} without retry.",
|
|
164
|
+
ex.memory_percent,
|
|
165
|
+
method_name,
|
|
166
|
+
self.execution_node.address,
|
|
167
|
+
)
|
|
168
|
+
# Persist error status and create execution logs before raising
|
|
169
|
+
self.log_end(action_type, ex)
|
|
170
|
+
self.add_error_status_for_consent_reporting()
|
|
171
|
+
raise
|
|
147
172
|
except BaseException as ex: # pylint: disable=W0703
|
|
173
|
+
# Check if this exception was caused by memory limit exceeded
|
|
174
|
+
if _is_memory_limit_exceeded(ex):
|
|
175
|
+
logger.error(
|
|
176
|
+
"Memory watchdog exceeded (wrapped exception). Aborting {} {} without retry.",
|
|
177
|
+
method_name,
|
|
178
|
+
self.execution_node.address,
|
|
179
|
+
)
|
|
180
|
+
# Persist error status and create execution logs before raising
|
|
181
|
+
self.log_end(action_type, ex)
|
|
182
|
+
self.add_error_status_for_consent_reporting()
|
|
183
|
+
raise
|
|
184
|
+
|
|
148
185
|
traceback.print_exc()
|
|
149
186
|
func_delay *= CONFIG.execution.task_retry_backoff
|
|
150
187
|
logger.warning(
|
|
@@ -421,6 +458,7 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
|
|
|
421
458
|
action_type: ActionType,
|
|
422
459
|
ex: Optional[BaseException] = None,
|
|
423
460
|
success_override_msg: Optional[str] = None,
|
|
461
|
+
record_count: Optional[int] = None,
|
|
424
462
|
) -> None:
|
|
425
463
|
"""On completion activities"""
|
|
426
464
|
if ex:
|
|
@@ -440,8 +478,23 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
|
|
|
440
478
|
mark_current_and_downstream_nodes_as_failed(request_task, db)
|
|
441
479
|
else:
|
|
442
480
|
logger.info("Ending {}, {}", self.resources.request.id, self.key)
|
|
481
|
+
|
|
482
|
+
# Build standardized success message with record count
|
|
483
|
+
base_message = (
|
|
484
|
+
str(success_override_msg) if success_override_msg else "success"
|
|
485
|
+
)
|
|
486
|
+
if record_count is not None:
|
|
487
|
+
if action_type == ActionType.access:
|
|
488
|
+
message = f"{base_message} - retrieved {record_count} records"
|
|
489
|
+
elif action_type == ActionType.erasure:
|
|
490
|
+
message = f"{base_message} - masked {record_count} records"
|
|
491
|
+
else:
|
|
492
|
+
message = f"{base_message} - processed {record_count} records"
|
|
493
|
+
else:
|
|
494
|
+
message = base_message
|
|
495
|
+
|
|
443
496
|
self.update_status(
|
|
444
|
-
|
|
497
|
+
message,
|
|
445
498
|
build_affected_field_logs(
|
|
446
499
|
self.execution_node, self.resources.policy, action_type
|
|
447
500
|
),
|
|
@@ -537,12 +590,21 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
|
|
|
537
590
|
# For access request results, mutate rows in-place to remove non-matching
|
|
538
591
|
# array elements. We already iterated over `output` above, so reuse the same
|
|
539
592
|
# loop structure to keep cache locality.
|
|
593
|
+
logger.info(
|
|
594
|
+
"Filtering {} rows in {} for matching array elements.",
|
|
595
|
+
len(output),
|
|
596
|
+
self.execution_node.address,
|
|
597
|
+
)
|
|
540
598
|
for row in output:
|
|
599
|
+
filter_element_match(row, post_processed_node_input_data)
|
|
600
|
+
|
|
601
|
+
if len(output) > 0:
|
|
541
602
|
logger.info(
|
|
542
|
-
"Filtering
|
|
603
|
+
"Filtering completed for {} rows in {}. Post-processed node size: {}",
|
|
604
|
+
len(output),
|
|
543
605
|
self.execution_node.address,
|
|
606
|
+
len(post_processed_node_input_data),
|
|
544
607
|
)
|
|
545
|
-
filter_element_match(row, post_processed_node_input_data)
|
|
546
608
|
|
|
547
609
|
if self.request_task.id:
|
|
548
610
|
# Saves intermediate access results for DSR 3.0 directly on the Request Task
|
|
@@ -637,7 +699,11 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
|
|
|
637
699
|
if messages:
|
|
638
700
|
success_message = "\n".join(messages)
|
|
639
701
|
|
|
640
|
-
self.log_end(
|
|
702
|
+
self.log_end(
|
|
703
|
+
ActionType.access,
|
|
704
|
+
success_override_msg=success_message,
|
|
705
|
+
record_count=len(filtered_output),
|
|
706
|
+
)
|
|
641
707
|
return filtered_output
|
|
642
708
|
|
|
643
709
|
@retry(action_type=ActionType.erasure, default_return=0)
|
|
@@ -645,9 +711,15 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
|
|
|
645
711
|
self,
|
|
646
712
|
retrieved_data: List[Row],
|
|
647
713
|
*erasure_prereqs: int, # TODO Remove when we stop support for DSR 2.0. DSR 3.0 enforces with downstream_tasks.
|
|
714
|
+
inputs: Optional[
|
|
715
|
+
List[List[Row]]
|
|
716
|
+
] = None, # Upstream data from corresponding access task
|
|
648
717
|
) -> int:
|
|
649
718
|
"""Run erasure request"""
|
|
650
719
|
|
|
720
|
+
if inputs is None:
|
|
721
|
+
inputs = []
|
|
722
|
+
|
|
651
723
|
# if there is no primary key specified in the graph node configuration
|
|
652
724
|
# note this in the execution log and perform no erasures on this node
|
|
653
725
|
if (
|
|
@@ -694,6 +766,10 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
|
|
|
694
766
|
)
|
|
695
767
|
return 0
|
|
696
768
|
|
|
769
|
+
formatted_input_data: NodeInput = self.pre_process_input_data(
|
|
770
|
+
*inputs, group_dependent_fields=True
|
|
771
|
+
)
|
|
772
|
+
|
|
697
773
|
# Use execution context to capture postprocessor messages
|
|
698
774
|
with collect_execution_log_messages() as messages:
|
|
699
775
|
output = self.connector.mask_data(
|
|
@@ -702,6 +778,7 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
|
|
|
702
778
|
self.resources.request,
|
|
703
779
|
self.resources.privacy_request_task,
|
|
704
780
|
retrieved_data,
|
|
781
|
+
formatted_input_data,
|
|
705
782
|
)
|
|
706
783
|
|
|
707
784
|
if self.request_task.id:
|
|
@@ -720,7 +797,11 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
|
|
|
720
797
|
if messages:
|
|
721
798
|
success_message = "\n".join(messages)
|
|
722
799
|
|
|
723
|
-
self.log_end(
|
|
800
|
+
self.log_end(
|
|
801
|
+
ActionType.erasure,
|
|
802
|
+
success_override_msg=success_message,
|
|
803
|
+
record_count=output,
|
|
804
|
+
)
|
|
724
805
|
return output
|
|
725
806
|
|
|
726
807
|
@retry(action_type=ActionType.consent, default_return=False)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from fides.api.graph.config import CollectionAddress
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ManualTaskAddress:
|
|
5
|
+
"""Utility class for creating and parsing manual task addresses"""
|
|
6
|
+
|
|
7
|
+
MANUAL_DATA_COLLECTION = "manual_data"
|
|
8
|
+
|
|
9
|
+
@staticmethod
|
|
10
|
+
def create(connection_config_key: str) -> CollectionAddress:
|
|
11
|
+
"""Create a CollectionAddress for manual data: {connection_key}:manual_data"""
|
|
12
|
+
return CollectionAddress(
|
|
13
|
+
dataset=connection_config_key,
|
|
14
|
+
collection=ManualTaskAddress.MANUAL_DATA_COLLECTION,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def _is_manual_data_collection(collection_name: str) -> bool:
|
|
19
|
+
"""Check if collection name represents manual task data"""
|
|
20
|
+
return collection_name == ManualTaskAddress.MANUAL_DATA_COLLECTION
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def is_manual_task_address(address: CollectionAddress) -> bool:
|
|
24
|
+
"""Check if address represents manual task data"""
|
|
25
|
+
if isinstance(address, str):
|
|
26
|
+
# Handle string format "connection_key:collection_name"
|
|
27
|
+
_, _, collection_part = address.partition(":")
|
|
28
|
+
if not collection_part:
|
|
29
|
+
return False
|
|
30
|
+
return ManualTaskAddress._is_manual_data_collection(collection_part)
|
|
31
|
+
|
|
32
|
+
# Handle CollectionAddress object
|
|
33
|
+
return ManualTaskAddress._is_manual_data_collection(address.collection)
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def get_connection_key(address: CollectionAddress) -> str:
|
|
37
|
+
"""Extract connection config key from manual task address"""
|
|
38
|
+
if not ManualTaskAddress.is_manual_task_address(address):
|
|
39
|
+
raise ValueError(f"Not a manual task address: {address}")
|
|
40
|
+
|
|
41
|
+
if isinstance(address, str):
|
|
42
|
+
# Handle string format "connection_key:collection_name"
|
|
43
|
+
return address.split(":")[0]
|
|
44
|
+
|
|
45
|
+
# Handle CollectionAddress object
|
|
46
|
+
return address.dataset
|