rucio 37.0.0rc1__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 rucio might be problematic. Click here for more details.
- rucio/__init__.py +17 -0
- rucio/alembicrevision.py +15 -0
- rucio/cli/__init__.py +14 -0
- rucio/cli/account.py +216 -0
- rucio/cli/bin_legacy/__init__.py +13 -0
- rucio/cli/bin_legacy/rucio.py +2825 -0
- rucio/cli/bin_legacy/rucio_admin.py +2500 -0
- rucio/cli/command.py +272 -0
- rucio/cli/config.py +72 -0
- rucio/cli/did.py +191 -0
- rucio/cli/download.py +128 -0
- rucio/cli/lifetime_exception.py +33 -0
- rucio/cli/replica.py +162 -0
- rucio/cli/rse.py +293 -0
- rucio/cli/rule.py +158 -0
- rucio/cli/scope.py +40 -0
- rucio/cli/subscription.py +73 -0
- rucio/cli/upload.py +60 -0
- rucio/cli/utils.py +226 -0
- rucio/client/__init__.py +15 -0
- rucio/client/accountclient.py +432 -0
- rucio/client/accountlimitclient.py +183 -0
- rucio/client/baseclient.py +983 -0
- rucio/client/client.py +120 -0
- rucio/client/configclient.py +126 -0
- rucio/client/credentialclient.py +59 -0
- rucio/client/didclient.py +868 -0
- rucio/client/diracclient.py +56 -0
- rucio/client/downloadclient.py +1783 -0
- rucio/client/exportclient.py +44 -0
- rucio/client/fileclient.py +50 -0
- rucio/client/importclient.py +42 -0
- rucio/client/lifetimeclient.py +90 -0
- rucio/client/lockclient.py +109 -0
- rucio/client/metaconventionsclient.py +140 -0
- rucio/client/pingclient.py +44 -0
- rucio/client/replicaclient.py +452 -0
- rucio/client/requestclient.py +125 -0
- rucio/client/richclient.py +317 -0
- rucio/client/rseclient.py +746 -0
- rucio/client/ruleclient.py +294 -0
- rucio/client/scopeclient.py +90 -0
- rucio/client/subscriptionclient.py +173 -0
- rucio/client/touchclient.py +82 -0
- rucio/client/uploadclient.py +969 -0
- rucio/common/__init__.py +13 -0
- rucio/common/bittorrent.py +234 -0
- rucio/common/cache.py +111 -0
- rucio/common/checksum.py +168 -0
- rucio/common/client.py +122 -0
- rucio/common/config.py +788 -0
- rucio/common/constants.py +217 -0
- rucio/common/constraints.py +17 -0
- rucio/common/didtype.py +237 -0
- rucio/common/dumper/__init__.py +342 -0
- rucio/common/dumper/consistency.py +497 -0
- rucio/common/dumper/data_models.py +362 -0
- rucio/common/dumper/path_parsing.py +75 -0
- rucio/common/exception.py +1208 -0
- rucio/common/extra.py +31 -0
- rucio/common/logging.py +420 -0
- rucio/common/pcache.py +1409 -0
- rucio/common/plugins.py +185 -0
- rucio/common/policy.py +93 -0
- rucio/common/schema/__init__.py +200 -0
- rucio/common/schema/generic.py +416 -0
- rucio/common/schema/generic_multi_vo.py +395 -0
- rucio/common/stomp_utils.py +423 -0
- rucio/common/stopwatch.py +55 -0
- rucio/common/test_rucio_server.py +154 -0
- rucio/common/types.py +483 -0
- rucio/common/utils.py +1688 -0
- rucio/core/__init__.py +13 -0
- rucio/core/account.py +496 -0
- rucio/core/account_counter.py +236 -0
- rucio/core/account_limit.py +425 -0
- rucio/core/authentication.py +620 -0
- rucio/core/config.py +437 -0
- rucio/core/credential.py +224 -0
- rucio/core/did.py +3004 -0
- rucio/core/did_meta_plugins/__init__.py +252 -0
- rucio/core/did_meta_plugins/did_column_meta.py +331 -0
- rucio/core/did_meta_plugins/did_meta_plugin_interface.py +165 -0
- rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
- rucio/core/did_meta_plugins/filter_engine.py +672 -0
- rucio/core/did_meta_plugins/json_meta.py +240 -0
- rucio/core/did_meta_plugins/mongo_meta.py +229 -0
- rucio/core/did_meta_plugins/postgres_meta.py +352 -0
- rucio/core/dirac.py +237 -0
- rucio/core/distance.py +187 -0
- rucio/core/exporter.py +59 -0
- rucio/core/heartbeat.py +363 -0
- rucio/core/identity.py +301 -0
- rucio/core/importer.py +260 -0
- rucio/core/lifetime_exception.py +377 -0
- rucio/core/lock.py +577 -0
- rucio/core/message.py +288 -0
- rucio/core/meta_conventions.py +203 -0
- rucio/core/monitor.py +448 -0
- rucio/core/naming_convention.py +195 -0
- rucio/core/nongrid_trace.py +136 -0
- rucio/core/oidc.py +1463 -0
- rucio/core/permission/__init__.py +161 -0
- rucio/core/permission/generic.py +1124 -0
- rucio/core/permission/generic_multi_vo.py +1144 -0
- rucio/core/quarantined_replica.py +224 -0
- rucio/core/replica.py +4483 -0
- rucio/core/replica_sorter.py +362 -0
- rucio/core/request.py +3091 -0
- rucio/core/rse.py +2079 -0
- rucio/core/rse_counter.py +185 -0
- rucio/core/rse_expression_parser.py +459 -0
- rucio/core/rse_selector.py +304 -0
- rucio/core/rule.py +4484 -0
- rucio/core/rule_grouping.py +1620 -0
- rucio/core/scope.py +181 -0
- rucio/core/subscription.py +362 -0
- rucio/core/topology.py +490 -0
- rucio/core/trace.py +375 -0
- rucio/core/transfer.py +1531 -0
- rucio/core/vo.py +169 -0
- rucio/core/volatile_replica.py +151 -0
- rucio/daemons/__init__.py +13 -0
- rucio/daemons/abacus/__init__.py +13 -0
- rucio/daemons/abacus/account.py +116 -0
- rucio/daemons/abacus/collection_replica.py +124 -0
- rucio/daemons/abacus/rse.py +117 -0
- rucio/daemons/atropos/__init__.py +13 -0
- rucio/daemons/atropos/atropos.py +242 -0
- rucio/daemons/auditor/__init__.py +289 -0
- rucio/daemons/auditor/hdfs.py +97 -0
- rucio/daemons/auditor/srmdumps.py +355 -0
- rucio/daemons/automatix/__init__.py +13 -0
- rucio/daemons/automatix/automatix.py +304 -0
- rucio/daemons/badreplicas/__init__.py +13 -0
- rucio/daemons/badreplicas/minos.py +322 -0
- rucio/daemons/badreplicas/minos_temporary_expiration.py +171 -0
- rucio/daemons/badreplicas/necromancer.py +196 -0
- rucio/daemons/bb8/__init__.py +13 -0
- rucio/daemons/bb8/bb8.py +353 -0
- rucio/daemons/bb8/common.py +759 -0
- rucio/daemons/bb8/nuclei_background_rebalance.py +153 -0
- rucio/daemons/bb8/t2_background_rebalance.py +153 -0
- rucio/daemons/cache/__init__.py +13 -0
- rucio/daemons/cache/consumer.py +133 -0
- rucio/daemons/common.py +405 -0
- rucio/daemons/conveyor/__init__.py +13 -0
- rucio/daemons/conveyor/common.py +562 -0
- rucio/daemons/conveyor/finisher.py +529 -0
- rucio/daemons/conveyor/poller.py +394 -0
- rucio/daemons/conveyor/preparer.py +205 -0
- rucio/daemons/conveyor/receiver.py +179 -0
- rucio/daemons/conveyor/stager.py +133 -0
- rucio/daemons/conveyor/submitter.py +403 -0
- rucio/daemons/conveyor/throttler.py +532 -0
- rucio/daemons/follower/__init__.py +13 -0
- rucio/daemons/follower/follower.py +101 -0
- rucio/daemons/hermes/__init__.py +13 -0
- rucio/daemons/hermes/hermes.py +534 -0
- rucio/daemons/judge/__init__.py +13 -0
- rucio/daemons/judge/cleaner.py +159 -0
- rucio/daemons/judge/evaluator.py +185 -0
- rucio/daemons/judge/injector.py +162 -0
- rucio/daemons/judge/repairer.py +154 -0
- rucio/daemons/oauthmanager/__init__.py +13 -0
- rucio/daemons/oauthmanager/oauthmanager.py +198 -0
- rucio/daemons/reaper/__init__.py +13 -0
- rucio/daemons/reaper/dark_reaper.py +282 -0
- rucio/daemons/reaper/reaper.py +739 -0
- rucio/daemons/replicarecoverer/__init__.py +13 -0
- rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +626 -0
- rucio/daemons/rsedecommissioner/__init__.py +13 -0
- rucio/daemons/rsedecommissioner/config.py +81 -0
- rucio/daemons/rsedecommissioner/profiles/__init__.py +24 -0
- rucio/daemons/rsedecommissioner/profiles/atlas.py +60 -0
- rucio/daemons/rsedecommissioner/profiles/generic.py +452 -0
- rucio/daemons/rsedecommissioner/profiles/types.py +93 -0
- rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
- rucio/daemons/storage/__init__.py +13 -0
- rucio/daemons/storage/consistency/__init__.py +13 -0
- rucio/daemons/storage/consistency/actions.py +848 -0
- rucio/daemons/tracer/__init__.py +13 -0
- rucio/daemons/tracer/kronos.py +511 -0
- rucio/daemons/transmogrifier/__init__.py +13 -0
- rucio/daemons/transmogrifier/transmogrifier.py +762 -0
- rucio/daemons/undertaker/__init__.py +13 -0
- rucio/daemons/undertaker/undertaker.py +137 -0
- rucio/db/__init__.py +13 -0
- rucio/db/sqla/__init__.py +52 -0
- rucio/db/sqla/constants.py +206 -0
- rucio/db/sqla/migrate_repo/__init__.py +13 -0
- rucio/db/sqla/migrate_repo/env.py +110 -0
- rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +70 -0
- rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +47 -0
- rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +59 -0
- rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +43 -0
- rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +91 -0
- rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +76 -0
- rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +43 -0
- rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +50 -0
- rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +68 -0
- rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +40 -0
- rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +45 -0
- rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +60 -0
- rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +40 -0
- rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +140 -0
- rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +73 -0
- rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +74 -0
- rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +43 -0
- rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +50 -0
- rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +134 -0
- rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +64 -0
- rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +39 -0
- rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +64 -0
- rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +51 -0
- rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +41 -0
- rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +43 -0
- rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +44 -0
- rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +53 -0
- rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +38 -0
- rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +47 -0
- rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +57 -0
- rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +69 -0
- rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +42 -0
- rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +47 -0
- rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +46 -0
- rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +40 -0
- rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +67 -0
- rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
- rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +44 -0
- rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +77 -0
- rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +60 -0
- rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +72 -0
- rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +42 -0
- rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +65 -0
- rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +133 -0
- rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +76 -0
- rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +60 -0
- rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +44 -0
- rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +64 -0
- rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +40 -0
- rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +43 -0
- rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +44 -0
- rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +78 -0
- rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +41 -0
- rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +59 -0
- rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +44 -0
- rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +49 -0
- rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +40 -0
- rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +63 -0
- rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +55 -0
- rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +45 -0
- rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +43 -0
- rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +45 -0
- rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +47 -0
- rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +58 -0
- rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +45 -0
- rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +106 -0
- rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +55 -0
- rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +50 -0
- rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +47 -0
- rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +43 -0
- rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +41 -0
- rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +91 -0
- rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +72 -0
- rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +49 -0
- rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +43 -0
- rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +53 -0
- rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +45 -0
- rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +68 -0
- rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +45 -0
- rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +94 -0
- rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +54 -0
- rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +72 -0
- rucio/db/sqla/migrate_repo/versions/a08fa8de1545_transfer_stats_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +76 -0
- rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +47 -0
- rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +121 -0
- rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +59 -0
- rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +52 -0
- rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +54 -0
- rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +64 -0
- rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +49 -0
- rucio/db/sqla/migrate_repo/versions/b0070f3695c8_add_deletedidmeta_table.py +57 -0
- rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +43 -0
- rucio/db/sqla/migrate_repo/versions/b5493606bbf5_fix_primary_key_for_subscription_history.py +41 -0
- rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +91 -0
- rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +40 -0
- rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +143 -0
- rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +76 -0
- rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +50 -0
- rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +72 -0
- rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +43 -0
- rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +65 -0
- rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +47 -0
- rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +146 -0
- rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +104 -0
- rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +44 -0
- rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +43 -0
- rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +103 -0
- rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +49 -0
- rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +104 -0
- rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +29 -0
- rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +74 -0
- rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +47 -0
- rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +43 -0
- rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +37 -0
- rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +43 -0
- rucio/db/sqla/models.py +1743 -0
- rucio/db/sqla/sautils.py +55 -0
- rucio/db/sqla/session.py +529 -0
- rucio/db/sqla/types.py +206 -0
- rucio/db/sqla/util.py +543 -0
- rucio/gateway/__init__.py +13 -0
- rucio/gateway/account.py +345 -0
- rucio/gateway/account_limit.py +363 -0
- rucio/gateway/authentication.py +381 -0
- rucio/gateway/config.py +227 -0
- rucio/gateway/credential.py +70 -0
- rucio/gateway/did.py +987 -0
- rucio/gateway/dirac.py +83 -0
- rucio/gateway/exporter.py +60 -0
- rucio/gateway/heartbeat.py +76 -0
- rucio/gateway/identity.py +189 -0
- rucio/gateway/importer.py +46 -0
- rucio/gateway/lifetime_exception.py +121 -0
- rucio/gateway/lock.py +153 -0
- rucio/gateway/meta_conventions.py +98 -0
- rucio/gateway/permission.py +74 -0
- rucio/gateway/quarantined_replica.py +79 -0
- rucio/gateway/replica.py +538 -0
- rucio/gateway/request.py +330 -0
- rucio/gateway/rse.py +632 -0
- rucio/gateway/rule.py +437 -0
- rucio/gateway/scope.py +100 -0
- rucio/gateway/subscription.py +280 -0
- rucio/gateway/vo.py +126 -0
- rucio/rse/__init__.py +96 -0
- rucio/rse/protocols/__init__.py +13 -0
- rucio/rse/protocols/bittorrent.py +194 -0
- rucio/rse/protocols/cache.py +111 -0
- rucio/rse/protocols/dummy.py +100 -0
- rucio/rse/protocols/gfal.py +708 -0
- rucio/rse/protocols/globus.py +243 -0
- rucio/rse/protocols/http_cache.py +82 -0
- rucio/rse/protocols/mock.py +123 -0
- rucio/rse/protocols/ngarc.py +209 -0
- rucio/rse/protocols/posix.py +250 -0
- rucio/rse/protocols/protocol.py +361 -0
- rucio/rse/protocols/rclone.py +365 -0
- rucio/rse/protocols/rfio.py +145 -0
- rucio/rse/protocols/srm.py +338 -0
- rucio/rse/protocols/ssh.py +414 -0
- rucio/rse/protocols/storm.py +195 -0
- rucio/rse/protocols/webdav.py +594 -0
- rucio/rse/protocols/xrootd.py +302 -0
- rucio/rse/rsemanager.py +881 -0
- rucio/rse/translation.py +260 -0
- rucio/tests/__init__.py +13 -0
- rucio/tests/common.py +280 -0
- rucio/tests/common_server.py +149 -0
- rucio/transfertool/__init__.py +13 -0
- rucio/transfertool/bittorrent.py +200 -0
- rucio/transfertool/bittorrent_driver.py +50 -0
- rucio/transfertool/bittorrent_driver_qbittorrent.py +134 -0
- rucio/transfertool/fts3.py +1600 -0
- rucio/transfertool/fts3_plugins.py +152 -0
- rucio/transfertool/globus.py +201 -0
- rucio/transfertool/globus_library.py +181 -0
- rucio/transfertool/mock.py +89 -0
- rucio/transfertool/transfertool.py +221 -0
- rucio/vcsversion.py +11 -0
- rucio/version.py +45 -0
- rucio/web/__init__.py +13 -0
- rucio/web/rest/__init__.py +13 -0
- rucio/web/rest/flaskapi/__init__.py +13 -0
- rucio/web/rest/flaskapi/authenticated_bp.py +27 -0
- rucio/web/rest/flaskapi/v1/__init__.py +13 -0
- rucio/web/rest/flaskapi/v1/accountlimits.py +236 -0
- rucio/web/rest/flaskapi/v1/accounts.py +1103 -0
- rucio/web/rest/flaskapi/v1/archives.py +102 -0
- rucio/web/rest/flaskapi/v1/auth.py +1644 -0
- rucio/web/rest/flaskapi/v1/common.py +426 -0
- rucio/web/rest/flaskapi/v1/config.py +304 -0
- rucio/web/rest/flaskapi/v1/credentials.py +213 -0
- rucio/web/rest/flaskapi/v1/dids.py +2340 -0
- rucio/web/rest/flaskapi/v1/dirac.py +116 -0
- rucio/web/rest/flaskapi/v1/export.py +75 -0
- rucio/web/rest/flaskapi/v1/heartbeats.py +127 -0
- rucio/web/rest/flaskapi/v1/identities.py +285 -0
- rucio/web/rest/flaskapi/v1/import.py +132 -0
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +312 -0
- rucio/web/rest/flaskapi/v1/locks.py +358 -0
- rucio/web/rest/flaskapi/v1/main.py +91 -0
- rucio/web/rest/flaskapi/v1/meta_conventions.py +241 -0
- rucio/web/rest/flaskapi/v1/metrics.py +36 -0
- rucio/web/rest/flaskapi/v1/nongrid_traces.py +97 -0
- rucio/web/rest/flaskapi/v1/ping.py +88 -0
- rucio/web/rest/flaskapi/v1/redirect.py +366 -0
- rucio/web/rest/flaskapi/v1/replicas.py +1894 -0
- rucio/web/rest/flaskapi/v1/requests.py +998 -0
- rucio/web/rest/flaskapi/v1/rses.py +2250 -0
- rucio/web/rest/flaskapi/v1/rules.py +854 -0
- rucio/web/rest/flaskapi/v1/scopes.py +159 -0
- rucio/web/rest/flaskapi/v1/subscriptions.py +650 -0
- rucio/web/rest/flaskapi/v1/templates/auth_crash.html +80 -0
- rucio/web/rest/flaskapi/v1/templates/auth_granted.html +82 -0
- rucio/web/rest/flaskapi/v1/traces.py +137 -0
- rucio/web/rest/flaskapi/v1/types.py +20 -0
- rucio/web/rest/flaskapi/v1/vos.py +278 -0
- rucio/web/rest/main.py +18 -0
- rucio/web/rest/metrics.py +27 -0
- rucio/web/rest/ping.py +27 -0
- rucio-37.0.0rc1.data/data/rucio/etc/alembic.ini.template +71 -0
- rucio-37.0.0rc1.data/data/rucio/etc/alembic_offline.ini.template +74 -0
- rucio-37.0.0rc1.data/data/rucio/etc/globus-config.yml.template +5 -0
- rucio-37.0.0rc1.data/data/rucio/etc/ldap.cfg.template +30 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approval_request.tmpl +38 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +4 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_user.tmpl +17 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +6 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_user.tmpl +17 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +19 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rse-accounts.cfg.template +25 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.atlas.client.template +43 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.template +241 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio_multi_vo.cfg.template +217 -0
- rucio-37.0.0rc1.data/data/rucio/requirements.server.txt +297 -0
- rucio-37.0.0rc1.data/data/rucio/tools/bootstrap.py +34 -0
- rucio-37.0.0rc1.data/data/rucio/tools/merge_rucio_configs.py +144 -0
- rucio-37.0.0rc1.data/data/rucio/tools/reset_database.py +40 -0
- rucio-37.0.0rc1.data/scripts/rucio +133 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-account +74 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-collection-replica +46 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-rse +78 -0
- rucio-37.0.0rc1.data/scripts/rucio-admin +97 -0
- rucio-37.0.0rc1.data/scripts/rucio-atropos +60 -0
- rucio-37.0.0rc1.data/scripts/rucio-auditor +206 -0
- rucio-37.0.0rc1.data/scripts/rucio-automatix +50 -0
- rucio-37.0.0rc1.data/scripts/rucio-bb8 +57 -0
- rucio-37.0.0rc1.data/scripts/rucio-cache-client +141 -0
- rucio-37.0.0rc1.data/scripts/rucio-cache-consumer +42 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-finisher +58 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-poller +66 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-preparer +37 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-receiver +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-stager +76 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-submitter +139 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-throttler +104 -0
- rucio-37.0.0rc1.data/scripts/rucio-dark-reaper +53 -0
- rucio-37.0.0rc1.data/scripts/rucio-dumper +160 -0
- rucio-37.0.0rc1.data/scripts/rucio-follower +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-hermes +54 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-cleaner +89 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-evaluator +137 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-injector +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-repairer +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-kronos +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-minos +53 -0
- rucio-37.0.0rc1.data/scripts/rucio-minos-temporary-expiration +50 -0
- rucio-37.0.0rc1.data/scripts/rucio-necromancer +120 -0
- rucio-37.0.0rc1.data/scripts/rucio-oauth-manager +63 -0
- rucio-37.0.0rc1.data/scripts/rucio-reaper +83 -0
- rucio-37.0.0rc1.data/scripts/rucio-replica-recoverer +248 -0
- rucio-37.0.0rc1.data/scripts/rucio-rse-decommissioner +66 -0
- rucio-37.0.0rc1.data/scripts/rucio-storage-consistency-actions +74 -0
- rucio-37.0.0rc1.data/scripts/rucio-transmogrifier +77 -0
- rucio-37.0.0rc1.data/scripts/rucio-undertaker +76 -0
- rucio-37.0.0rc1.dist-info/METADATA +92 -0
- rucio-37.0.0rc1.dist-info/RECORD +487 -0
- rucio-37.0.0rc1.dist-info/WHEEL +5 -0
- rucio-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
- rucio-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
- rucio-37.0.0rc1.dist-info/top_level.txt +1 -0
rucio/gateway/did.py
ADDED
|
@@ -0,0 +1,987 @@
|
|
|
1
|
+
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from copy import deepcopy
|
|
16
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
17
|
+
|
|
18
|
+
import rucio.gateway.permission
|
|
19
|
+
from rucio.common.constants import RESERVED_KEYS
|
|
20
|
+
from rucio.common.exception import AccessDenied, InvalidObject, RucioException
|
|
21
|
+
from rucio.common.schema import validate_schema
|
|
22
|
+
from rucio.common.types import InternalAccount, InternalScope
|
|
23
|
+
from rucio.common.utils import gateway_update_return_dict
|
|
24
|
+
from rucio.core import did, naming_convention
|
|
25
|
+
from rucio.core import meta_conventions as meta_convention_core
|
|
26
|
+
from rucio.core.rse import get_rse_id
|
|
27
|
+
from rucio.db.sqla.constants import DIDType
|
|
28
|
+
from rucio.db.sqla.session import read_session, stream_session, transactional_session
|
|
29
|
+
|
|
30
|
+
if TYPE_CHECKING:
|
|
31
|
+
from collections.abc import Iterable, Iterator, Mapping, Sequence
|
|
32
|
+
|
|
33
|
+
from sqlalchemy.orm import Session
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@stream_session
|
|
37
|
+
def list_dids(
|
|
38
|
+
scope: str,
|
|
39
|
+
filters: 'Mapping[Any, Any]',
|
|
40
|
+
did_type: str = 'collection',
|
|
41
|
+
ignore_case: bool = False,
|
|
42
|
+
limit: Optional[int] = None,
|
|
43
|
+
offset: Optional[int] = None,
|
|
44
|
+
long: bool = False,
|
|
45
|
+
recursive: bool = False,
|
|
46
|
+
vo: str = 'def',
|
|
47
|
+
*,
|
|
48
|
+
session: "Session"
|
|
49
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
50
|
+
"""
|
|
51
|
+
List dids in a scope.
|
|
52
|
+
|
|
53
|
+
:param scope: The scope name.
|
|
54
|
+
:param filters: Filter arguments in form supported by the filter engine.
|
|
55
|
+
:param did_type: The type of the did: all(container, dataset, file), collection(dataset or container), dataset, container
|
|
56
|
+
:param ignore_case: Ignore case distinctions.
|
|
57
|
+
:param limit: The maximum number of DIDs returned.
|
|
58
|
+
:param offset: Offset number.
|
|
59
|
+
:param long: Long format option to display more information for each DID.
|
|
60
|
+
:param recursive: Recursively list DIDs content.
|
|
61
|
+
:param vo: The VO to act on.
|
|
62
|
+
:param session: The database session in use.
|
|
63
|
+
"""
|
|
64
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
65
|
+
|
|
66
|
+
# replace account and scope in filters with internal representation
|
|
67
|
+
for or_group in filters:
|
|
68
|
+
if 'account' in or_group:
|
|
69
|
+
or_group['account'] = InternalAccount(or_group['account'], vo=vo)
|
|
70
|
+
if 'scope' in or_group:
|
|
71
|
+
or_group['account'] = InternalScope(or_group['scope'], vo=vo)
|
|
72
|
+
|
|
73
|
+
result = did.list_dids(scope=internal_scope, filters=filters, did_type=did_type, ignore_case=ignore_case,
|
|
74
|
+
limit=limit, offset=offset, long=long, recursive=recursive, session=session)
|
|
75
|
+
|
|
76
|
+
for d in result:
|
|
77
|
+
yield gateway_update_return_dict(d, session=session)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@transactional_session
|
|
81
|
+
def add_did(
|
|
82
|
+
scope: str,
|
|
83
|
+
name: str,
|
|
84
|
+
did_type: str,
|
|
85
|
+
issuer: str,
|
|
86
|
+
account: Optional[str] = None,
|
|
87
|
+
statuses: Optional[dict[str, str]] = None,
|
|
88
|
+
meta: Optional[dict[str, str]] = None,
|
|
89
|
+
rules: Optional['Sequence[dict[str, Any]]'] = None,
|
|
90
|
+
lifetime: Optional[str] = None,
|
|
91
|
+
dids: Optional['Sequence[dict[str, Any]]'] = None,
|
|
92
|
+
rse: Optional[str] = None,
|
|
93
|
+
vo: str = 'def',
|
|
94
|
+
*,
|
|
95
|
+
session: "Session"
|
|
96
|
+
) -> None:
|
|
97
|
+
"""
|
|
98
|
+
Add data did.
|
|
99
|
+
|
|
100
|
+
:param scope: The scope name.
|
|
101
|
+
:param name: The data identifier name.
|
|
102
|
+
:param did_type: The data identifier type.
|
|
103
|
+
:param issuer: The issuer account.
|
|
104
|
+
:param account: The account owner. If None, then issuer is selected as owner.
|
|
105
|
+
:param statuses: Dictionary with statuses, e.g.g {'monotonic':True}.
|
|
106
|
+
:meta: Meta-data associated with the data identifier is represented using key/value pairs in a dictionary.
|
|
107
|
+
:rules: Replication rules associated with the data did. A list of dictionaries, e.g., [{'copies': 2, 'rse_expression': 'TIERS1'}, ].
|
|
108
|
+
:param lifetime: DID's lifetime (in seconds).
|
|
109
|
+
:param dids: The content.
|
|
110
|
+
:param rse: The RSE name when registering replicas.
|
|
111
|
+
:param vo: The VO to act on.
|
|
112
|
+
:param session: The database session in use.
|
|
113
|
+
"""
|
|
114
|
+
statuses = statuses or {}
|
|
115
|
+
meta = meta or {}
|
|
116
|
+
rules = rules or []
|
|
117
|
+
dids = dids or []
|
|
118
|
+
v_did = {'name': name, 'type': did_type.upper(), 'scope': scope}
|
|
119
|
+
validate_schema(name='did', obj=v_did, vo=vo)
|
|
120
|
+
validate_schema(name='dids', obj=dids, vo=vo)
|
|
121
|
+
validate_schema(name='rse', obj=rse, vo=vo)
|
|
122
|
+
kwargs = {'scope': scope, 'name': name, 'type': did_type, 'issuer': issuer, 'account': account, 'statuses': statuses, 'meta': meta, 'rules': rules, 'lifetime': lifetime}
|
|
123
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='add_did', kwargs=kwargs, session=session)
|
|
124
|
+
if not auth_result.allowed:
|
|
125
|
+
raise AccessDenied('Account %s can not add data identifier to scope %s. %s' % (issuer, scope, auth_result.message))
|
|
126
|
+
|
|
127
|
+
owner_account = None if account is None else InternalAccount(account, vo=vo)
|
|
128
|
+
issuer_account = InternalAccount(issuer, vo=vo)
|
|
129
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
130
|
+
for d in dids:
|
|
131
|
+
d['scope'] = InternalScope(d['scope'], vo=vo)
|
|
132
|
+
for r in rules:
|
|
133
|
+
r['account'] = InternalAccount(r['account'], vo=vo)
|
|
134
|
+
|
|
135
|
+
rse_id = None
|
|
136
|
+
if rse is not None:
|
|
137
|
+
rse_id = get_rse_id(rse=rse, vo=vo, session=session)
|
|
138
|
+
|
|
139
|
+
if did_type == 'DATASET':
|
|
140
|
+
# naming_convention validation
|
|
141
|
+
extra_meta = naming_convention.validate_name(scope=internal_scope, name=name, did_type='D', session=session)
|
|
142
|
+
|
|
143
|
+
# merge extra_meta with meta
|
|
144
|
+
for k in extra_meta or {}:
|
|
145
|
+
if k not in meta:
|
|
146
|
+
meta[k] = extra_meta[k]
|
|
147
|
+
elif meta[k] != extra_meta[k]:
|
|
148
|
+
print("Provided metadata %s doesn't match the naming convention: %s != %s" % (k, meta[k], extra_meta[k]))
|
|
149
|
+
raise InvalidObject("Provided metadata %s doesn't match the naming convention: %s != %s" % (k, meta[k], extra_meta[k]))
|
|
150
|
+
|
|
151
|
+
# Validate metadata
|
|
152
|
+
meta_convention_core.validate_meta(meta=meta, did_type=DIDType[did_type.upper()], session=session)
|
|
153
|
+
|
|
154
|
+
return did.add_did(scope=internal_scope, name=name, did_type=DIDType[did_type.upper()], account=owner_account or issuer_account,
|
|
155
|
+
statuses=statuses, meta=meta, rules=rules, lifetime=lifetime,
|
|
156
|
+
dids=dids, rse_id=rse_id, session=session)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@transactional_session
|
|
160
|
+
def add_dids(
|
|
161
|
+
dids: 'Sequence[dict[str, Any]]',
|
|
162
|
+
issuer: str,
|
|
163
|
+
vo: str = 'def',
|
|
164
|
+
*,
|
|
165
|
+
session: "Session"
|
|
166
|
+
) -> None:
|
|
167
|
+
"""
|
|
168
|
+
Bulk Add did.
|
|
169
|
+
|
|
170
|
+
:param dids: A list of dids.
|
|
171
|
+
:param issuer: The issuer account.
|
|
172
|
+
:param vo: The VO to act on.
|
|
173
|
+
:param session: The database session in use.
|
|
174
|
+
"""
|
|
175
|
+
for d in dids:
|
|
176
|
+
if 'rse' in d:
|
|
177
|
+
rse_id = None
|
|
178
|
+
if d['rse'] is not None:
|
|
179
|
+
rse_id = get_rse_id(rse=d['rse'], vo=vo, session=session)
|
|
180
|
+
d['rse_id'] = rse_id
|
|
181
|
+
|
|
182
|
+
kwargs = {'issuer': issuer, 'dids': dids}
|
|
183
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='add_dids', kwargs=kwargs, session=session)
|
|
184
|
+
if not auth_result.allowed:
|
|
185
|
+
raise AccessDenied('Account %s can not bulk add data identifier. %s' % (issuer, auth_result.message))
|
|
186
|
+
|
|
187
|
+
issuer_account = InternalAccount(issuer, vo=vo)
|
|
188
|
+
for d in dids:
|
|
189
|
+
d['scope'] = InternalScope(d['scope'], vo=vo)
|
|
190
|
+
if 'account' in d.keys():
|
|
191
|
+
d['account'] = InternalAccount(d['account'], vo=vo)
|
|
192
|
+
if 'dids' in d.keys():
|
|
193
|
+
for child in d['dids']:
|
|
194
|
+
child['scope'] = InternalScope(child['scope'], vo=vo)
|
|
195
|
+
return did.add_dids(dids, account=issuer_account, session=session)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@transactional_session
|
|
199
|
+
def attach_dids(
|
|
200
|
+
scope: str,
|
|
201
|
+
name: str,
|
|
202
|
+
attachment: dict[str, Any],
|
|
203
|
+
issuer: str,
|
|
204
|
+
vo='def',
|
|
205
|
+
*,
|
|
206
|
+
session: "Session"
|
|
207
|
+
) -> None:
|
|
208
|
+
"""
|
|
209
|
+
Append content to data did.
|
|
210
|
+
|
|
211
|
+
:param attachment: The attachment.
|
|
212
|
+
:param issuer: The issuer account.
|
|
213
|
+
:param vo: The VO to act on.
|
|
214
|
+
:param session: The database session in use.
|
|
215
|
+
"""
|
|
216
|
+
validate_schema(name='attachment', obj=attachment, vo=vo)
|
|
217
|
+
|
|
218
|
+
rse_id = None
|
|
219
|
+
if 'rse' in attachment:
|
|
220
|
+
if attachment['rse'] is not None:
|
|
221
|
+
rse_id = get_rse_id(rse=attachment['rse'], vo=vo, session=session)
|
|
222
|
+
attachment['rse_id'] = rse_id
|
|
223
|
+
|
|
224
|
+
kwargs = {'scope': scope, 'name': name, 'attachment': attachment}
|
|
225
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='attach_dids', kwargs=kwargs, session=session)
|
|
226
|
+
if not auth_result.allowed:
|
|
227
|
+
raise AccessDenied('Account %s can not add data identifiers to %s:%s. %s' % (issuer, scope, name, auth_result.message))
|
|
228
|
+
|
|
229
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
230
|
+
issuer_account = InternalAccount(issuer, vo=vo)
|
|
231
|
+
if 'account' in attachment.keys():
|
|
232
|
+
attachment['account'] = InternalAccount(attachment['account'], vo=vo)
|
|
233
|
+
for d in attachment['dids']:
|
|
234
|
+
d['scope'] = InternalScope(d['scope'], vo=vo)
|
|
235
|
+
if 'account' in d.keys():
|
|
236
|
+
d['account'] = InternalAccount(d['account'], vo=vo)
|
|
237
|
+
|
|
238
|
+
if rse_id is not None:
|
|
239
|
+
dids = did.attach_dids(scope=internal_scope, name=name, dids=attachment['dids'],
|
|
240
|
+
account=attachment.get('account', issuer_account), rse_id=rse_id, session=session)
|
|
241
|
+
else:
|
|
242
|
+
dids = did.attach_dids(scope=internal_scope, name=name, dids=attachment['dids'],
|
|
243
|
+
account=attachment.get('account', issuer_account), session=session)
|
|
244
|
+
|
|
245
|
+
return dids
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
@transactional_session
|
|
249
|
+
def attach_dids_to_dids(
|
|
250
|
+
attachments: 'Sequence[dict[str, Any]]',
|
|
251
|
+
issuer: str,
|
|
252
|
+
ignore_duplicate: bool = False,
|
|
253
|
+
vo: str = 'def',
|
|
254
|
+
*,
|
|
255
|
+
session: "Session"
|
|
256
|
+
) -> None:
|
|
257
|
+
"""
|
|
258
|
+
Append content to dids.
|
|
259
|
+
|
|
260
|
+
:param attachments: The contents.
|
|
261
|
+
:param issuer: The issuer account.
|
|
262
|
+
:param ignore_duplicate: If True, ignore duplicate entries.
|
|
263
|
+
:param vo: The VO to act on.
|
|
264
|
+
:param session: The database session in use.
|
|
265
|
+
"""
|
|
266
|
+
validate_schema(name='attachments', obj=attachments, vo=vo)
|
|
267
|
+
|
|
268
|
+
for a in attachments:
|
|
269
|
+
if 'rse' in a:
|
|
270
|
+
rse_id = None
|
|
271
|
+
if a['rse'] is not None:
|
|
272
|
+
rse_id = get_rse_id(rse=a['rse'], vo=vo, session=session)
|
|
273
|
+
a['rse_id'] = rse_id
|
|
274
|
+
|
|
275
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='attach_dids_to_dids', kwargs={'attachments': attachments}, session=session)
|
|
276
|
+
if not auth_result.allowed:
|
|
277
|
+
raise AccessDenied('Account %s can not add data identifiers. %s' % (issuer, auth_result.message))
|
|
278
|
+
|
|
279
|
+
issuer_account = InternalAccount(issuer, vo=vo)
|
|
280
|
+
for attachment in attachments:
|
|
281
|
+
attachment['scope'] = InternalScope(attachment['scope'], vo=vo)
|
|
282
|
+
for d in attachment['dids']:
|
|
283
|
+
d['scope'] = InternalScope(d['scope'], vo=vo)
|
|
284
|
+
if 'account' in d.keys():
|
|
285
|
+
d['account'] = InternalAccount(d['account'], vo=vo)
|
|
286
|
+
|
|
287
|
+
return did.attach_dids_to_dids(attachments=attachments, account=issuer_account,
|
|
288
|
+
ignore_duplicate=ignore_duplicate, session=session)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
@transactional_session
|
|
292
|
+
def detach_dids(
|
|
293
|
+
scope: str,
|
|
294
|
+
name: str,
|
|
295
|
+
dids: 'Sequence[dict[str, Any]]',
|
|
296
|
+
issuer: str,
|
|
297
|
+
vo: str = 'def',
|
|
298
|
+
*,
|
|
299
|
+
session: "Session"
|
|
300
|
+
) -> None:
|
|
301
|
+
"""
|
|
302
|
+
Detach data identifier
|
|
303
|
+
|
|
304
|
+
:param scope: The scope name.
|
|
305
|
+
:param name: The data identifier name.
|
|
306
|
+
:param dids: The content.
|
|
307
|
+
:param issuer: The issuer account.
|
|
308
|
+
:param vo: The VO to act on.
|
|
309
|
+
:param session: The database session in use.
|
|
310
|
+
"""
|
|
311
|
+
kwargs = {'scope': scope, 'name': name, 'dids': dids, 'issuer': issuer}
|
|
312
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='detach_dids', kwargs=kwargs, session=session)
|
|
313
|
+
if not auth_result.allowed:
|
|
314
|
+
raise AccessDenied('Account %s can not detach data identifiers from %s:%s. %s' % (issuer, scope, name, auth_result.message))
|
|
315
|
+
|
|
316
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
317
|
+
for d in dids:
|
|
318
|
+
d['scope'] = InternalScope(d['scope'], vo=vo)
|
|
319
|
+
|
|
320
|
+
return did.detach_dids(scope=internal_scope, name=name, dids=dids, session=session)
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
@stream_session
|
|
324
|
+
def list_new_dids(
|
|
325
|
+
did_type: Optional[str] = None,
|
|
326
|
+
thread: Optional[int] = None,
|
|
327
|
+
total_threads: Optional[int] = None,
|
|
328
|
+
chunk_size: int = 1000,
|
|
329
|
+
vo: str = 'def',
|
|
330
|
+
*,
|
|
331
|
+
session: "Session"
|
|
332
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
333
|
+
"""
|
|
334
|
+
List recent identifiers.
|
|
335
|
+
|
|
336
|
+
:param did_type : The DID type.
|
|
337
|
+
:param thread: The assigned thread for this necromancer.
|
|
338
|
+
:param total_threads: The total number of threads of all necromancers.
|
|
339
|
+
:param chunk_size: Number of requests to return per yield.
|
|
340
|
+
:param vo: The VO to act on.
|
|
341
|
+
:param session: The database session in use.
|
|
342
|
+
"""
|
|
343
|
+
dids = did.list_new_dids(did_type=did_type and DIDType[did_type.upper()], thread=thread, total_threads=total_threads, chunk_size=chunk_size, session=session)
|
|
344
|
+
for d in dids:
|
|
345
|
+
if d['scope'].vo == vo:
|
|
346
|
+
yield gateway_update_return_dict(d, session=session)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
@transactional_session
|
|
350
|
+
def set_new_dids(
|
|
351
|
+
dids: 'Sequence[dict[str, Any]]',
|
|
352
|
+
new_flag: bool = True,
|
|
353
|
+
vo: str = 'def',
|
|
354
|
+
*,
|
|
355
|
+
session: "Session"
|
|
356
|
+
) -> bool:
|
|
357
|
+
"""
|
|
358
|
+
Set/reset the flag new
|
|
359
|
+
|
|
360
|
+
:param scope: The scope name.
|
|
361
|
+
:param name: The data identifier name.
|
|
362
|
+
:param new_flag: A boolean to flag new DIDs.
|
|
363
|
+
:param vo: The VO to act on.
|
|
364
|
+
:param session: The database session in use.
|
|
365
|
+
"""
|
|
366
|
+
for d in dids:
|
|
367
|
+
d['scope'] = InternalScope(d['scope'], vo=vo)
|
|
368
|
+
|
|
369
|
+
return did.set_new_dids(dids, new_flag, session=session)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
@stream_session
|
|
373
|
+
def list_content(
|
|
374
|
+
scope: str,
|
|
375
|
+
name: str,
|
|
376
|
+
vo: str = 'def',
|
|
377
|
+
*,
|
|
378
|
+
session: "Session"
|
|
379
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
380
|
+
"""
|
|
381
|
+
List data identifier contents.
|
|
382
|
+
|
|
383
|
+
:param scope: The scope name.
|
|
384
|
+
:param name: The data identifier name.
|
|
385
|
+
:param vo: The VO to act on.
|
|
386
|
+
:param session: The database session in use.
|
|
387
|
+
"""
|
|
388
|
+
|
|
389
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
390
|
+
|
|
391
|
+
dids = did.list_content(scope=internal_scope, name=name, session=session)
|
|
392
|
+
for d in dids:
|
|
393
|
+
yield gateway_update_return_dict(d, session=session)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
@stream_session
|
|
397
|
+
def list_content_history(
|
|
398
|
+
scope: str,
|
|
399
|
+
name: str,
|
|
400
|
+
vo='def',
|
|
401
|
+
*,
|
|
402
|
+
session: "Session"
|
|
403
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
404
|
+
"""
|
|
405
|
+
List data identifier contents history.
|
|
406
|
+
|
|
407
|
+
:param scope: The scope name.
|
|
408
|
+
:param name: The data identifier name.
|
|
409
|
+
:param vo: The VO to act on.
|
|
410
|
+
:param session: The database session in use.
|
|
411
|
+
"""
|
|
412
|
+
|
|
413
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
414
|
+
|
|
415
|
+
dids = did.list_content_history(scope=internal_scope, name=name, session=session)
|
|
416
|
+
|
|
417
|
+
for d in dids:
|
|
418
|
+
yield gateway_update_return_dict(d, session=session)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
@stream_session
|
|
422
|
+
def bulk_list_files(
|
|
423
|
+
dids: 'Iterable[dict[str, Any]]',
|
|
424
|
+
long: bool = False,
|
|
425
|
+
vo: str = 'def',
|
|
426
|
+
*,
|
|
427
|
+
session: "Session"
|
|
428
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
429
|
+
"""
|
|
430
|
+
List file contents of a list of data identifiers.
|
|
431
|
+
|
|
432
|
+
:param dids: A list of DIDs.
|
|
433
|
+
:param long: A boolean to choose if more metadata are returned or not.
|
|
434
|
+
:param vo: The VO to act on.
|
|
435
|
+
:param session: The database session in use.
|
|
436
|
+
"""
|
|
437
|
+
|
|
438
|
+
for did_ in dids:
|
|
439
|
+
did_['scope'] = InternalScope(did_['scope'], vo=vo)
|
|
440
|
+
|
|
441
|
+
for file_ in did.bulk_list_files(dids=dids, long=long, session=session):
|
|
442
|
+
yield gateway_update_return_dict(file_, session=session)
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
@stream_session
|
|
446
|
+
def list_files(
|
|
447
|
+
scope: str,
|
|
448
|
+
name: str,
|
|
449
|
+
long: bool,
|
|
450
|
+
vo: str = 'def',
|
|
451
|
+
*,
|
|
452
|
+
session: "Session"
|
|
453
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
454
|
+
"""
|
|
455
|
+
List data identifier file contents.
|
|
456
|
+
|
|
457
|
+
:param scope: The scope name.
|
|
458
|
+
:param name: The data identifier name.
|
|
459
|
+
:param long: A boolean to choose if GUID is returned or not.
|
|
460
|
+
:param vo: The VO to act on.
|
|
461
|
+
:param session: The database session in use.
|
|
462
|
+
"""
|
|
463
|
+
|
|
464
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
465
|
+
|
|
466
|
+
dids = did.list_files(scope=internal_scope, name=name, long=long, session=session)
|
|
467
|
+
|
|
468
|
+
for d in dids:
|
|
469
|
+
yield gateway_update_return_dict(d, session=session)
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
@stream_session
|
|
473
|
+
def scope_list(
|
|
474
|
+
scope: str,
|
|
475
|
+
name: Optional[str] = None,
|
|
476
|
+
recursive: bool = False,
|
|
477
|
+
vo: str = 'def',
|
|
478
|
+
*,
|
|
479
|
+
session: "Session"
|
|
480
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
481
|
+
"""
|
|
482
|
+
List data identifiers in a scope.
|
|
483
|
+
|
|
484
|
+
:param scope: The scope name.
|
|
485
|
+
:param name: The data identifier name.
|
|
486
|
+
:param recursive: boolean, True or False.
|
|
487
|
+
:param vo: The VO to act on.
|
|
488
|
+
:param session: The database session in use.
|
|
489
|
+
"""
|
|
490
|
+
|
|
491
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
492
|
+
|
|
493
|
+
dids = did.scope_list(internal_scope, name=name, recursive=recursive, session=session)
|
|
494
|
+
|
|
495
|
+
for d in dids:
|
|
496
|
+
ret_did = deepcopy(d)
|
|
497
|
+
ret_did['scope'] = ret_did['scope'].external
|
|
498
|
+
if ret_did['parent'] is not None:
|
|
499
|
+
ret_did['parent']['scope'] = ret_did['parent']['scope'].external
|
|
500
|
+
yield ret_did
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
@read_session
|
|
504
|
+
def get_did(scope: str, name: str, dynamic_depth: Optional[DIDType] = None, vo: str = 'def', *, session: "Session") -> "dict[str, Any]":
|
|
505
|
+
"""
|
|
506
|
+
Retrieve a single data did.
|
|
507
|
+
|
|
508
|
+
:param scope: The scope name.
|
|
509
|
+
:param name: The data identifier name.
|
|
510
|
+
:param dynamic_depth: the DID type to use as source for estimation of this DIDs length/bytes.
|
|
511
|
+
If set to None, or to a value which doesn't make sense (ex: requesting depth = CONTAINER for a did of type DATASET)
|
|
512
|
+
will not compute the size dynamically.
|
|
513
|
+
:param vo: The VO to act on.
|
|
514
|
+
:return did: Dictionary containing {'name', 'scope', 'type'}, Exception otherwise
|
|
515
|
+
:param session: The database session in use.
|
|
516
|
+
"""
|
|
517
|
+
|
|
518
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
519
|
+
|
|
520
|
+
d = did.get_did(scope=internal_scope, name=name, dynamic_depth=dynamic_depth, session=session)
|
|
521
|
+
return gateway_update_return_dict(d, session=session)
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
@transactional_session
|
|
525
|
+
def set_metadata(
|
|
526
|
+
scope: str,
|
|
527
|
+
name: str,
|
|
528
|
+
key: str,
|
|
529
|
+
value: Any,
|
|
530
|
+
issuer: str,
|
|
531
|
+
recursive: bool = False,
|
|
532
|
+
vo: str = 'def',
|
|
533
|
+
*,
|
|
534
|
+
session: "Session"
|
|
535
|
+
) -> None:
|
|
536
|
+
"""
|
|
537
|
+
Add metadata to data did.
|
|
538
|
+
|
|
539
|
+
:param scope: The scope name.
|
|
540
|
+
:param name: The data identifier name.
|
|
541
|
+
:param key: the key.
|
|
542
|
+
:param value: the value.
|
|
543
|
+
:param issuer: The issuer account.
|
|
544
|
+
:param recursive: Option to propagate the metadata update to content.
|
|
545
|
+
:param vo: The VO to act on.
|
|
546
|
+
:param session: The database session in use.
|
|
547
|
+
"""
|
|
548
|
+
kwargs = {'scope': scope, 'name': name, 'key': key, 'value': value, 'issuer': issuer}
|
|
549
|
+
|
|
550
|
+
if key in RESERVED_KEYS:
|
|
551
|
+
raise AccessDenied('Account %s can not change this metadata value to data identifier %s:%s' % (issuer, scope, name))
|
|
552
|
+
|
|
553
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='set_metadata', kwargs=kwargs, session=session)
|
|
554
|
+
if not auth_result.allowed:
|
|
555
|
+
raise AccessDenied('Account %s can not add metadata to data identifier %s:%s. %s' % (issuer, scope, name, auth_result.message))
|
|
556
|
+
|
|
557
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
558
|
+
return did.set_metadata(scope=internal_scope, name=name, key=key, value=value, recursive=recursive, session=session)
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
@transactional_session
|
|
562
|
+
def set_metadata_bulk(
|
|
563
|
+
scope: str,
|
|
564
|
+
name: str,
|
|
565
|
+
meta: dict[str, Any],
|
|
566
|
+
issuer: str,
|
|
567
|
+
recursive: bool = False,
|
|
568
|
+
vo: str = 'def',
|
|
569
|
+
*,
|
|
570
|
+
session: "Session"
|
|
571
|
+
) -> None:
|
|
572
|
+
"""
|
|
573
|
+
Add metadata to data did.
|
|
574
|
+
|
|
575
|
+
:param scope: The scope name.
|
|
576
|
+
:param name: The data identifier name.
|
|
577
|
+
:param meta: the key-values.
|
|
578
|
+
:param issuer: The issuer account.
|
|
579
|
+
:param recursive: Option to propagate the metadata update to content.
|
|
580
|
+
:param vo: The VO to act on.
|
|
581
|
+
:param session: The database session in use.
|
|
582
|
+
"""
|
|
583
|
+
kwargs = {'scope': scope, 'name': name, 'meta': meta, 'issuer': issuer}
|
|
584
|
+
|
|
585
|
+
for key in meta:
|
|
586
|
+
if key in RESERVED_KEYS:
|
|
587
|
+
raise AccessDenied('Account %s can not change the value of the metadata key %s to data identifier %s:%s' % (issuer, key, scope, name))
|
|
588
|
+
|
|
589
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='set_metadata_bulk', kwargs=kwargs, session=session)
|
|
590
|
+
if not auth_result.allowed:
|
|
591
|
+
raise AccessDenied('Account %s can not add metadata to data identifier %s:%s. %s' % (issuer, scope, name, auth_result.message))
|
|
592
|
+
|
|
593
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
594
|
+
return did.set_metadata_bulk(scope=internal_scope, name=name, meta=meta, recursive=recursive, session=session)
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
@transactional_session
|
|
598
|
+
def set_dids_metadata_bulk(
|
|
599
|
+
dids: 'Iterable[dict[str, Any]]',
|
|
600
|
+
issuer: str,
|
|
601
|
+
recursive: bool = False,
|
|
602
|
+
vo: str = 'def',
|
|
603
|
+
*,
|
|
604
|
+
session: "Session"
|
|
605
|
+
) -> None:
|
|
606
|
+
"""
|
|
607
|
+
Add metadata to a list of data identifiers.
|
|
608
|
+
|
|
609
|
+
:param issuer: The issuer account.
|
|
610
|
+
:param dids: A list of dids including metadata.
|
|
611
|
+
:param recursive: Option to propagate the metadata update to content.
|
|
612
|
+
:param vo: The VO to act on.
|
|
613
|
+
:param session: The database session in use.
|
|
614
|
+
"""
|
|
615
|
+
|
|
616
|
+
for entry in dids:
|
|
617
|
+
kwargs = {'scope': entry['scope'], 'name': entry['name'], 'meta': entry['meta'], 'issuer': issuer}
|
|
618
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='set_metadata_bulk', kwargs=kwargs, session=session)
|
|
619
|
+
if not auth_result.allowed:
|
|
620
|
+
raise AccessDenied('Account %s can not add metadata to data identifier %s:%s. %s' % (issuer, entry['scope'], entry['name'], auth_result.message))
|
|
621
|
+
entry['scope'] = InternalScope(entry['scope'], vo=vo)
|
|
622
|
+
meta = entry['meta']
|
|
623
|
+
for key in meta:
|
|
624
|
+
if key in RESERVED_KEYS:
|
|
625
|
+
raise AccessDenied('Account %s can not change the value of the metadata key %s to data identifier %s:%s' % (issuer, key, entry['scope'], entry['name']))
|
|
626
|
+
|
|
627
|
+
return did.set_dids_metadata_bulk(dids=dids, recursive=recursive, session=session)
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
@read_session
|
|
631
|
+
def get_metadata(
|
|
632
|
+
scope: str,
|
|
633
|
+
name: str,
|
|
634
|
+
plugin: str = 'DID_COLUMN',
|
|
635
|
+
vo: str = 'def',
|
|
636
|
+
*,
|
|
637
|
+
session: "Session"
|
|
638
|
+
) -> dict[str, Any]:
|
|
639
|
+
"""
|
|
640
|
+
Get data identifier metadata
|
|
641
|
+
|
|
642
|
+
:param scope: The scope name.
|
|
643
|
+
:param name: The data identifier name.
|
|
644
|
+
:param vo: The VO to act on.
|
|
645
|
+
:param plugin: The metadata plugin to query, 'ALL' for all available plugins
|
|
646
|
+
:param session: The database session in use.
|
|
647
|
+
"""
|
|
648
|
+
|
|
649
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
650
|
+
|
|
651
|
+
d = did.get_metadata(scope=internal_scope, name=name, plugin=plugin, session=session)
|
|
652
|
+
return gateway_update_return_dict(d, session=session)
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
@stream_session
|
|
656
|
+
def get_metadata_bulk(
|
|
657
|
+
dids: 'Iterable[dict[str, Any]]',
|
|
658
|
+
inherit: bool = False,
|
|
659
|
+
plugin: str = 'DID_COLUMN',
|
|
660
|
+
vo: str = 'def',
|
|
661
|
+
*,
|
|
662
|
+
session: "Session"
|
|
663
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
664
|
+
"""
|
|
665
|
+
Get metadata for a list of dids
|
|
666
|
+
:param dids: A list of dids.
|
|
667
|
+
:param inherit: A boolean. If set to true, the metadata of the parent are concatenated.
|
|
668
|
+
:param plugin: The metadata plugin to query, 'ALL' for all available plugins
|
|
669
|
+
:param vo: The VO to act on.
|
|
670
|
+
:param session: The database session in use.
|
|
671
|
+
"""
|
|
672
|
+
|
|
673
|
+
validate_schema(name='dids', obj=dids, vo=vo)
|
|
674
|
+
for entry in dids:
|
|
675
|
+
entry['scope'] = InternalScope(entry['scope'], vo=vo)
|
|
676
|
+
meta = did.get_metadata_bulk(dids, inherit=inherit, plugin=plugin, session=session)
|
|
677
|
+
for met in meta:
|
|
678
|
+
yield gateway_update_return_dict(met, session=session)
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
@transactional_session
|
|
682
|
+
def delete_metadata(
|
|
683
|
+
scope: str,
|
|
684
|
+
name: str,
|
|
685
|
+
key: str,
|
|
686
|
+
vo: str = 'def',
|
|
687
|
+
*,
|
|
688
|
+
session: "Session"
|
|
689
|
+
) -> None:
|
|
690
|
+
"""
|
|
691
|
+
Delete a key from the metadata column
|
|
692
|
+
|
|
693
|
+
:param scope: the scope of did
|
|
694
|
+
:param name: the name of the did
|
|
695
|
+
:param key: the key to be deleted
|
|
696
|
+
:param vo: The VO to act on.
|
|
697
|
+
:param session: The database session in use.
|
|
698
|
+
"""
|
|
699
|
+
|
|
700
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
701
|
+
return did.delete_metadata(scope=internal_scope, name=name, key=key, session=session)
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
@transactional_session
|
|
705
|
+
def set_status(
|
|
706
|
+
scope: str,
|
|
707
|
+
name: str,
|
|
708
|
+
issuer: str,
|
|
709
|
+
vo: str = 'def',
|
|
710
|
+
*,
|
|
711
|
+
session: "Session",
|
|
712
|
+
**kwargs
|
|
713
|
+
) -> None:
|
|
714
|
+
"""
|
|
715
|
+
Set data identifier status
|
|
716
|
+
|
|
717
|
+
:param scope: The scope name.
|
|
718
|
+
:param name: The data identifier name.
|
|
719
|
+
:param issuer: The issuer account.
|
|
720
|
+
:param kwargs: Keyword arguments of the form status_name=value.
|
|
721
|
+
:param vo: The VO to act on.
|
|
722
|
+
:param session: The database session in use.
|
|
723
|
+
"""
|
|
724
|
+
|
|
725
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='set_status', kwargs={'scope': scope, 'name': name, 'issuer': issuer}, session=session)
|
|
726
|
+
if not auth_result.allowed:
|
|
727
|
+
raise AccessDenied('Account %s can not set status on data identifier %s:%s. %s' % (issuer, scope, name, auth_result.message))
|
|
728
|
+
|
|
729
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
730
|
+
|
|
731
|
+
return did.set_status(scope=internal_scope, name=name, session=session, **kwargs)
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
@stream_session
|
|
735
|
+
def get_dataset_by_guid(
|
|
736
|
+
guid: str,
|
|
737
|
+
vo: str = 'def',
|
|
738
|
+
*,
|
|
739
|
+
session: "Session"
|
|
740
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
741
|
+
"""
|
|
742
|
+
Get the parent datasets for a given GUID.
|
|
743
|
+
:param guid: The GUID.
|
|
744
|
+
:param vo: The VO to act on.
|
|
745
|
+
:param session: The database session in use.
|
|
746
|
+
|
|
747
|
+
:returns: A did
|
|
748
|
+
"""
|
|
749
|
+
dids = did.get_dataset_by_guid(guid=guid, session=session)
|
|
750
|
+
|
|
751
|
+
for d in dids:
|
|
752
|
+
if d['scope'].vo != vo:
|
|
753
|
+
raise RucioException('GUID unavailable on VO {}'.format(vo))
|
|
754
|
+
yield gateway_update_return_dict(d, session=session)
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
@stream_session
|
|
758
|
+
def list_parent_dids(
|
|
759
|
+
scope: str,
|
|
760
|
+
name: str,
|
|
761
|
+
vo: str = 'def',
|
|
762
|
+
*,
|
|
763
|
+
session: "Session"
|
|
764
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
765
|
+
"""
|
|
766
|
+
List parent datasets and containers of a did.
|
|
767
|
+
|
|
768
|
+
:param scope: The scope.
|
|
769
|
+
:param name: The name.
|
|
770
|
+
:param vo: The VO to act on.
|
|
771
|
+
:param session: The database session in use.
|
|
772
|
+
"""
|
|
773
|
+
|
|
774
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
775
|
+
|
|
776
|
+
dids = did.list_parent_dids(scope=internal_scope, name=name, session=session)
|
|
777
|
+
|
|
778
|
+
for d in dids:
|
|
779
|
+
yield gateway_update_return_dict(d, session=session)
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
@transactional_session
|
|
783
|
+
def create_did_sample(
|
|
784
|
+
input_scope: str,
|
|
785
|
+
input_name: str,
|
|
786
|
+
output_scope: str,
|
|
787
|
+
output_name: str,
|
|
788
|
+
issuer: str,
|
|
789
|
+
nbfiles: str,
|
|
790
|
+
vo: str = 'def',
|
|
791
|
+
*,
|
|
792
|
+
session: "Session"
|
|
793
|
+
):
|
|
794
|
+
"""
|
|
795
|
+
Create a sample from an input collection.
|
|
796
|
+
|
|
797
|
+
:param input_scope: The scope of the input DID.
|
|
798
|
+
:param input_name: The name of the input DID.
|
|
799
|
+
:param output_scope: The scope of the output dataset.
|
|
800
|
+
:param output_name: The name of the output dataset.
|
|
801
|
+
:param account: The account.
|
|
802
|
+
:param nbfiles: The number of files to register in the output dataset.
|
|
803
|
+
:param issuer: The issuer account.
|
|
804
|
+
:param vo: The VO to act on.
|
|
805
|
+
:param session: The database session in use.
|
|
806
|
+
"""
|
|
807
|
+
kwargs = {'issuer': issuer, 'scope': output_scope}
|
|
808
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='create_did_sample', kwargs=kwargs, session=session)
|
|
809
|
+
if not auth_result.allowed:
|
|
810
|
+
raise AccessDenied('Account %s can not bulk add data identifier. %s' % (issuer, auth_result.message))
|
|
811
|
+
|
|
812
|
+
input_internal_scope = InternalScope(input_scope, vo=vo)
|
|
813
|
+
output_internal_scope = InternalScope(output_scope, vo=vo)
|
|
814
|
+
|
|
815
|
+
issuer_account = InternalAccount(issuer, vo=vo)
|
|
816
|
+
|
|
817
|
+
return did.create_did_sample(input_scope=input_internal_scope, input_name=input_name, output_scope=output_internal_scope, output_name=output_name,
|
|
818
|
+
account=issuer_account, nbfiles=nbfiles, session=session)
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
@transactional_session
|
|
822
|
+
def resurrect(
|
|
823
|
+
dids: 'Iterable[dict[str, Any]]',
|
|
824
|
+
issuer: str,
|
|
825
|
+
vo: str = 'def',
|
|
826
|
+
*,
|
|
827
|
+
session: "Session"
|
|
828
|
+
) -> None:
|
|
829
|
+
"""
|
|
830
|
+
Resurrect DIDs.
|
|
831
|
+
|
|
832
|
+
:param dids: A list of dids.
|
|
833
|
+
:param issuer: The issuer account.
|
|
834
|
+
:param vo: The VO to act on.
|
|
835
|
+
:param session: The database session in use.
|
|
836
|
+
"""
|
|
837
|
+
kwargs = {'issuer': issuer}
|
|
838
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='resurrect', kwargs=kwargs, session=session)
|
|
839
|
+
if not auth_result.allowed:
|
|
840
|
+
raise AccessDenied('Account %s can not resurrect data identifiers. %s' % (issuer, auth_result.message))
|
|
841
|
+
validate_schema(name='dids', obj=dids, vo=vo)
|
|
842
|
+
|
|
843
|
+
for d in dids:
|
|
844
|
+
d['scope'] = InternalScope(d['scope'], vo=vo)
|
|
845
|
+
|
|
846
|
+
return did.resurrect(dids=dids, session=session)
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
@stream_session
|
|
850
|
+
def list_archive_content(
|
|
851
|
+
scope: str,
|
|
852
|
+
name: str,
|
|
853
|
+
vo: str = 'def',
|
|
854
|
+
*,
|
|
855
|
+
session: "Session"
|
|
856
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
857
|
+
"""
|
|
858
|
+
List archive contents.
|
|
859
|
+
|
|
860
|
+
:param scope: The archive scope name.
|
|
861
|
+
:param name: The archive data identifier name.
|
|
862
|
+
:param vo: The VO to act on.
|
|
863
|
+
:param session: The database session in use.
|
|
864
|
+
"""
|
|
865
|
+
|
|
866
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
867
|
+
|
|
868
|
+
dids = did.list_archive_content(scope=internal_scope, name=name, session=session)
|
|
869
|
+
for d in dids:
|
|
870
|
+
yield gateway_update_return_dict(d, session=session)
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
@transactional_session
|
|
874
|
+
def add_did_to_followed(
|
|
875
|
+
scope: str,
|
|
876
|
+
name: str,
|
|
877
|
+
account: str,
|
|
878
|
+
*,
|
|
879
|
+
session: "Session",
|
|
880
|
+
vo: str = 'def'
|
|
881
|
+
) -> None:
|
|
882
|
+
"""
|
|
883
|
+
Mark a did as followed by the given account
|
|
884
|
+
|
|
885
|
+
:param scope: The scope name.
|
|
886
|
+
:param name: The data identifier name.
|
|
887
|
+
:param account: The account owner.
|
|
888
|
+
:param session: The database session in use.
|
|
889
|
+
"""
|
|
890
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
891
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
892
|
+
return did.add_did_to_followed(scope=internal_scope, name=name, account=internal_account, session=session)
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
@transactional_session
|
|
896
|
+
def add_dids_to_followed(
|
|
897
|
+
dids: 'Iterable[Mapping[str, Any]]',
|
|
898
|
+
account: str,
|
|
899
|
+
*,
|
|
900
|
+
session: "Session",
|
|
901
|
+
vo: str = 'def'
|
|
902
|
+
) -> None:
|
|
903
|
+
"""
|
|
904
|
+
Bulk mark datasets as followed
|
|
905
|
+
|
|
906
|
+
:param dids: A list of dids.
|
|
907
|
+
:param account: The account owner.
|
|
908
|
+
:param session: The database session in use.
|
|
909
|
+
"""
|
|
910
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
911
|
+
return did.add_dids_to_followed(dids=dids, account=internal_account, session=session)
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
@stream_session
|
|
915
|
+
def get_users_following_did(
|
|
916
|
+
name: str,
|
|
917
|
+
scope: str,
|
|
918
|
+
*,
|
|
919
|
+
session: "Session",
|
|
920
|
+
vo: str = 'def'
|
|
921
|
+
) -> 'Iterator[dict[str, str]]':
|
|
922
|
+
"""
|
|
923
|
+
Return list of users following a did
|
|
924
|
+
|
|
925
|
+
:param scope: The scope name.
|
|
926
|
+
:param name: The data identifier name.
|
|
927
|
+
:param session: The database session in use.
|
|
928
|
+
"""
|
|
929
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
930
|
+
users = did.get_users_following_did(name=name, scope=internal_scope, session=session)
|
|
931
|
+
for user in users:
|
|
932
|
+
user['user'] = user['user'].external
|
|
933
|
+
yield user
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
@transactional_session
|
|
937
|
+
def remove_did_from_followed(
|
|
938
|
+
scope: str,
|
|
939
|
+
name: str,
|
|
940
|
+
account: str,
|
|
941
|
+
issuer: str,
|
|
942
|
+
*,
|
|
943
|
+
session: "Session",
|
|
944
|
+
vo: str = 'def'
|
|
945
|
+
) -> None:
|
|
946
|
+
"""
|
|
947
|
+
Mark a did as not followed
|
|
948
|
+
|
|
949
|
+
:param scope: The scope name.
|
|
950
|
+
:param name: The data identifier name.
|
|
951
|
+
:param account: The account owner.
|
|
952
|
+
:param session: The database session in use.
|
|
953
|
+
:param issuer: The issuer account
|
|
954
|
+
"""
|
|
955
|
+
kwargs = {'scope': scope, 'issuer': issuer}
|
|
956
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='remove_did_from_followed', kwargs=kwargs, session=session)
|
|
957
|
+
if not auth_result.allowed:
|
|
958
|
+
raise AccessDenied('Account %s can not remove data identifiers from followed table. %s' % (issuer, auth_result.message))
|
|
959
|
+
|
|
960
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
961
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
962
|
+
return did.remove_did_from_followed(scope=internal_scope, name=name, account=internal_account, session=session)
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
@transactional_session
|
|
966
|
+
def remove_dids_from_followed(
|
|
967
|
+
dids: 'Iterable[Mapping[str, Any]]',
|
|
968
|
+
account: str,
|
|
969
|
+
issuer: str,
|
|
970
|
+
*,
|
|
971
|
+
session: "Session",
|
|
972
|
+
vo: str = 'def'
|
|
973
|
+
) -> None:
|
|
974
|
+
"""
|
|
975
|
+
Bulk mark datasets as not followed
|
|
976
|
+
|
|
977
|
+
:param dids: A list of dids.
|
|
978
|
+
:param account: The account owner.
|
|
979
|
+
:param session: The database session in use.
|
|
980
|
+
"""
|
|
981
|
+
kwargs = {'dids': dids, 'issuer': issuer}
|
|
982
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='remove_dids_from_followed', kwargs=kwargs, session=session)
|
|
983
|
+
if not auth_result.allowed:
|
|
984
|
+
raise AccessDenied('Account %s can not bulk remove data identifiers from followed table. %s' % (issuer, auth_result.message))
|
|
985
|
+
|
|
986
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
987
|
+
return did.remove_dids_from_followed(dids=dids, account=internal_account, session=session)
|