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
|
@@ -0,0 +1,2250 @@
|
|
|
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 json import dumps
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
17
|
+
|
|
18
|
+
from flask import Flask, Response, jsonify, request
|
|
19
|
+
|
|
20
|
+
from rucio.common.exception import (
|
|
21
|
+
AccessDenied,
|
|
22
|
+
CounterNotFound,
|
|
23
|
+
Duplicate,
|
|
24
|
+
InputValidationError,
|
|
25
|
+
InvalidObject,
|
|
26
|
+
InvalidPath,
|
|
27
|
+
InvalidRSEExpression,
|
|
28
|
+
ReplicaNotFound,
|
|
29
|
+
RSEAttributeNotFound,
|
|
30
|
+
RSENotFound,
|
|
31
|
+
RSEOperationNotSupported,
|
|
32
|
+
RSEProtocolDomainNotSupported,
|
|
33
|
+
RSEProtocolNotSupported,
|
|
34
|
+
RSEProtocolPriorityError,
|
|
35
|
+
)
|
|
36
|
+
from rucio.common.utils import APIEncoder, Availability, render_json
|
|
37
|
+
from rucio.gateway.account_limit import get_rse_account_usage
|
|
38
|
+
from rucio.gateway.rse import (
|
|
39
|
+
add_distance,
|
|
40
|
+
add_protocol,
|
|
41
|
+
add_qos_policy,
|
|
42
|
+
add_rse,
|
|
43
|
+
add_rse_attribute,
|
|
44
|
+
del_protocols,
|
|
45
|
+
del_rse,
|
|
46
|
+
del_rse_attribute,
|
|
47
|
+
delete_distance,
|
|
48
|
+
delete_qos_policy,
|
|
49
|
+
delete_rse_limits,
|
|
50
|
+
get_distance,
|
|
51
|
+
get_rse,
|
|
52
|
+
get_rse_limits,
|
|
53
|
+
get_rse_protocols,
|
|
54
|
+
get_rse_usage,
|
|
55
|
+
list_qos_policies,
|
|
56
|
+
list_rse_attributes,
|
|
57
|
+
list_rse_usage_history,
|
|
58
|
+
list_rses,
|
|
59
|
+
parse_rse_expression,
|
|
60
|
+
set_rse_limits,
|
|
61
|
+
set_rse_usage,
|
|
62
|
+
update_distance,
|
|
63
|
+
update_protocols,
|
|
64
|
+
update_rse,
|
|
65
|
+
)
|
|
66
|
+
from rucio.rse import rsemanager
|
|
67
|
+
from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
|
|
68
|
+
from rucio.web.rest.flaskapi.v1.common import ErrorHandlingMethodView, check_accept_header_wrapper_flask, generate_http_error_flask, json_parameters, param_get, response_headers, try_stream
|
|
69
|
+
|
|
70
|
+
if TYPE_CHECKING:
|
|
71
|
+
from rucio.common.types import LFNDict
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class RSEs(ErrorHandlingMethodView):
|
|
75
|
+
""" List all RSEs in the database. """
|
|
76
|
+
|
|
77
|
+
@check_accept_header_wrapper_flask(['application/x-json-stream'])
|
|
78
|
+
def get(self):
|
|
79
|
+
"""
|
|
80
|
+
---
|
|
81
|
+
summary: List RSEs
|
|
82
|
+
description: Lists all RSEs.
|
|
83
|
+
tags:
|
|
84
|
+
- Rucio Storage Elements
|
|
85
|
+
parameters:
|
|
86
|
+
- name: expression
|
|
87
|
+
in: query
|
|
88
|
+
description: RSE expression to select RSEs.
|
|
89
|
+
schema:
|
|
90
|
+
type: string
|
|
91
|
+
responses:
|
|
92
|
+
200:
|
|
93
|
+
description: OK
|
|
94
|
+
content:
|
|
95
|
+
application/json:
|
|
96
|
+
schema:
|
|
97
|
+
description: A list with the corresponding rses.
|
|
98
|
+
type: array
|
|
99
|
+
items:
|
|
100
|
+
type: object
|
|
101
|
+
properties:
|
|
102
|
+
id:
|
|
103
|
+
description: The rse id.
|
|
104
|
+
type: string
|
|
105
|
+
rse:
|
|
106
|
+
description: The name of the rse.
|
|
107
|
+
type: string
|
|
108
|
+
rse_type:
|
|
109
|
+
description: The type of the rse.
|
|
110
|
+
type: string
|
|
111
|
+
deterministic:
|
|
112
|
+
description: If the rse is deterministic.
|
|
113
|
+
type: boolean
|
|
114
|
+
volatile:
|
|
115
|
+
description: If the rse is volatile.
|
|
116
|
+
type: boolean
|
|
117
|
+
staging_area:
|
|
118
|
+
description: Is this rse a staging area?
|
|
119
|
+
type: boolean
|
|
120
|
+
city:
|
|
121
|
+
description: The city of the rse.
|
|
122
|
+
type: string
|
|
123
|
+
region_code:
|
|
124
|
+
description: The region_code of the rse.
|
|
125
|
+
type: string
|
|
126
|
+
country_name:
|
|
127
|
+
description: The country name of the rse.
|
|
128
|
+
type: string
|
|
129
|
+
continent:
|
|
130
|
+
description: The continent of the rse.
|
|
131
|
+
type: string
|
|
132
|
+
time_zone:
|
|
133
|
+
description: The time zone of the rse.
|
|
134
|
+
type: string
|
|
135
|
+
ISP:
|
|
136
|
+
description: The isp of the rse.
|
|
137
|
+
type: string
|
|
138
|
+
ASN:
|
|
139
|
+
description: The asn of the rse.
|
|
140
|
+
type: string
|
|
141
|
+
longitude:
|
|
142
|
+
description: The longitude of the rse.
|
|
143
|
+
type: number
|
|
144
|
+
latitude:
|
|
145
|
+
description: The latitude of the rse.
|
|
146
|
+
type: number
|
|
147
|
+
availability:
|
|
148
|
+
description: The availability of the rse.
|
|
149
|
+
type: integer
|
|
150
|
+
deprecated: true
|
|
151
|
+
availability_read:
|
|
152
|
+
description: If the RSE is readable.
|
|
153
|
+
type: integer
|
|
154
|
+
availability_write:
|
|
155
|
+
description: If the RSE is writable.
|
|
156
|
+
type: integer
|
|
157
|
+
availability_delete:
|
|
158
|
+
description: If the RSE is deletable.
|
|
159
|
+
type: integer
|
|
160
|
+
usage:
|
|
161
|
+
description: The usage of the rse.
|
|
162
|
+
type: integer
|
|
163
|
+
qos_class:
|
|
164
|
+
description: The quality of service class.
|
|
165
|
+
type: string
|
|
166
|
+
400:
|
|
167
|
+
description: Invalid RSE expression
|
|
168
|
+
401:
|
|
169
|
+
description: Invalid Auth Token
|
|
170
|
+
406:
|
|
171
|
+
description: Not acceptable
|
|
172
|
+
"""
|
|
173
|
+
expression = request.args.get('expression', default=None)
|
|
174
|
+
|
|
175
|
+
if expression:
|
|
176
|
+
try:
|
|
177
|
+
def generate(vo):
|
|
178
|
+
for rse in parse_rse_expression(expression, vo=vo):
|
|
179
|
+
yield render_json(rse=rse) + '\n'
|
|
180
|
+
|
|
181
|
+
return try_stream(generate(vo=request.environ.get('vo')))
|
|
182
|
+
except (InvalidRSEExpression, InvalidObject) as error:
|
|
183
|
+
return generate_http_error_flask(400, error)
|
|
184
|
+
else:
|
|
185
|
+
def generate(vo):
|
|
186
|
+
for rse in list_rses(vo=vo):
|
|
187
|
+
rse['availability'] = Availability(rse['availability_read'], rse['availability_write'], rse['availability_delete']).integer
|
|
188
|
+
yield render_json(**rse) + '\n'
|
|
189
|
+
|
|
190
|
+
return try_stream(generate(vo=request.environ.get('vo')))
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class RSE(ErrorHandlingMethodView):
|
|
194
|
+
""" Create, update, get and disable RSE. """
|
|
195
|
+
|
|
196
|
+
def post(self, rse):
|
|
197
|
+
"""
|
|
198
|
+
---
|
|
199
|
+
summary: Create RSE
|
|
200
|
+
description: Creates a RSE with all the metadata.
|
|
201
|
+
tags:
|
|
202
|
+
- Rucio Storage Elements
|
|
203
|
+
parameters:
|
|
204
|
+
- name: rse
|
|
205
|
+
in: path
|
|
206
|
+
description: The name of the Rucio Storage Element name.
|
|
207
|
+
schema:
|
|
208
|
+
type: string
|
|
209
|
+
style: simple
|
|
210
|
+
requestBody:
|
|
211
|
+
content:
|
|
212
|
+
application/json:
|
|
213
|
+
schema:
|
|
214
|
+
type: object
|
|
215
|
+
properties:
|
|
216
|
+
deterministic:
|
|
217
|
+
description: If the pfn is generated deterministicly.
|
|
218
|
+
type: boolean
|
|
219
|
+
volatile:
|
|
220
|
+
description: RSE cache.
|
|
221
|
+
type: boolean
|
|
222
|
+
city:
|
|
223
|
+
description: The city of the RSE.
|
|
224
|
+
type: string
|
|
225
|
+
staging_area:
|
|
226
|
+
description: Staging area.
|
|
227
|
+
type: string
|
|
228
|
+
region_code:
|
|
229
|
+
description: The region code of the RSE.
|
|
230
|
+
type: string
|
|
231
|
+
country_name:
|
|
232
|
+
description: The country name of the RSE.
|
|
233
|
+
type: string
|
|
234
|
+
continent:
|
|
235
|
+
description: The continent of the RSE.
|
|
236
|
+
type: string
|
|
237
|
+
time_zone:
|
|
238
|
+
description: The time zone of the RSE.
|
|
239
|
+
type: string
|
|
240
|
+
ISP:
|
|
241
|
+
description: The internet service provider of the RSE.
|
|
242
|
+
type: string
|
|
243
|
+
rse_type:
|
|
244
|
+
description: The rse type.
|
|
245
|
+
type: string
|
|
246
|
+
enum: ["DISK", "TAPE"]
|
|
247
|
+
latitude:
|
|
248
|
+
description: The latitude of the RSE.
|
|
249
|
+
type: number
|
|
250
|
+
longitude:
|
|
251
|
+
description: The longitude of the RSE.
|
|
252
|
+
type: number
|
|
253
|
+
ASN:
|
|
254
|
+
description: The access service network of the RSE.
|
|
255
|
+
type: string
|
|
256
|
+
availability:
|
|
257
|
+
description: The availability of the RSE.
|
|
258
|
+
type: integer
|
|
259
|
+
deprecated: true
|
|
260
|
+
availability_read:
|
|
261
|
+
description: If the RSE is readable.
|
|
262
|
+
type: boolean
|
|
263
|
+
availability_write:
|
|
264
|
+
description: If the RSE is writable.
|
|
265
|
+
type: boolean
|
|
266
|
+
availability_delete:
|
|
267
|
+
description: If the RSE is deletable.
|
|
268
|
+
type: boolean
|
|
269
|
+
responses:
|
|
270
|
+
201:
|
|
271
|
+
description: OK
|
|
272
|
+
content:
|
|
273
|
+
application/json:
|
|
274
|
+
schema:
|
|
275
|
+
type: string
|
|
276
|
+
enum: ["Created"]
|
|
277
|
+
400:
|
|
278
|
+
description: Cannot decode json parameter dictionary
|
|
279
|
+
401:
|
|
280
|
+
description: Invalid Auth Token
|
|
281
|
+
404:
|
|
282
|
+
description: RSE not found
|
|
283
|
+
409:
|
|
284
|
+
description: RSE already exists.
|
|
285
|
+
"""
|
|
286
|
+
kwargs = {
|
|
287
|
+
'deterministic': True,
|
|
288
|
+
'volatile': False,
|
|
289
|
+
'city': None,
|
|
290
|
+
'staging_area': False,
|
|
291
|
+
'region_code': None,
|
|
292
|
+
'country_name': None,
|
|
293
|
+
'continent': None,
|
|
294
|
+
'time_zone': None,
|
|
295
|
+
'ISP': None,
|
|
296
|
+
'rse_type': None,
|
|
297
|
+
'latitude': None,
|
|
298
|
+
'longitude': None,
|
|
299
|
+
'ASN': None,
|
|
300
|
+
'availability_read': None,
|
|
301
|
+
'availability_write': None,
|
|
302
|
+
'availability_delete': None,
|
|
303
|
+
}
|
|
304
|
+
if request.get_data(as_text=True):
|
|
305
|
+
parameters = json_parameters()
|
|
306
|
+
|
|
307
|
+
if "availability" in parameters and ("availability_read" in parameters or "availability_write" in parameters or "availability_delete" in parameters):
|
|
308
|
+
return generate_http_error_flask(422, InputValidationError("'availability' can not be specified with 'availability_read', 'availability_write' or 'availability_delete'")) # noqa: E501
|
|
309
|
+
|
|
310
|
+
if "availability" in parameters:
|
|
311
|
+
availability = Availability.from_integer(parameters["availability"])
|
|
312
|
+
kwargs["availability_read"] = availability.read
|
|
313
|
+
kwargs["availability_write"] = availability.write
|
|
314
|
+
kwargs["availability_delete"] = availability.delete
|
|
315
|
+
|
|
316
|
+
for keyword in kwargs.keys():
|
|
317
|
+
kwargs[keyword] = param_get(parameters, keyword, default=kwargs[keyword])
|
|
318
|
+
|
|
319
|
+
kwargs['issuer'] = request.environ.get('issuer')
|
|
320
|
+
kwargs['vo'] = request.environ.get('vo')
|
|
321
|
+
try:
|
|
322
|
+
add_rse(rse, **kwargs)
|
|
323
|
+
except InvalidObject as error:
|
|
324
|
+
return generate_http_error_flask(400, error)
|
|
325
|
+
except AccessDenied as error:
|
|
326
|
+
return generate_http_error_flask(401, error)
|
|
327
|
+
except RSENotFound as error:
|
|
328
|
+
return generate_http_error_flask(404, error)
|
|
329
|
+
except Duplicate as error:
|
|
330
|
+
return generate_http_error_flask(409, error)
|
|
331
|
+
|
|
332
|
+
return 'Created', 201
|
|
333
|
+
|
|
334
|
+
def put(self, rse):
|
|
335
|
+
"""
|
|
336
|
+
---
|
|
337
|
+
summary: Update RSE
|
|
338
|
+
description: Update RSE properties.
|
|
339
|
+
tags:
|
|
340
|
+
- Rucio Storage Elements
|
|
341
|
+
parameters:
|
|
342
|
+
- name: rse
|
|
343
|
+
in: path
|
|
344
|
+
description: The name of the Rucio Storage Element name.
|
|
345
|
+
schema:
|
|
346
|
+
type: string
|
|
347
|
+
style: simple
|
|
348
|
+
requestBody:
|
|
349
|
+
content:
|
|
350
|
+
application/json:
|
|
351
|
+
schema:
|
|
352
|
+
type: object
|
|
353
|
+
properties:
|
|
354
|
+
availability_read:
|
|
355
|
+
description: The vailability of the RSE.
|
|
356
|
+
type: boolean
|
|
357
|
+
availability_write:
|
|
358
|
+
description: The vailability of the RSE.
|
|
359
|
+
type: boolean
|
|
360
|
+
availability_delete:
|
|
361
|
+
description: The vailability of the RSE.
|
|
362
|
+
type: boolean
|
|
363
|
+
deterministic:
|
|
364
|
+
description: If the pfn is generated deterministicly.
|
|
365
|
+
type: boolean
|
|
366
|
+
volatile:
|
|
367
|
+
description: RSE cache.
|
|
368
|
+
type: boolean
|
|
369
|
+
city:
|
|
370
|
+
description: The city of the RSE.
|
|
371
|
+
type: string
|
|
372
|
+
staging_area:
|
|
373
|
+
description: Staging area.
|
|
374
|
+
type: string
|
|
375
|
+
region_code:
|
|
376
|
+
description: The region code of the RSE.
|
|
377
|
+
type: string
|
|
378
|
+
country_name:
|
|
379
|
+
description: The country name of the RSE.
|
|
380
|
+
type: string
|
|
381
|
+
time_zone:
|
|
382
|
+
description: The time zone of the RSE.
|
|
383
|
+
type: string
|
|
384
|
+
rse_type:
|
|
385
|
+
description: The rse type.
|
|
386
|
+
type: string
|
|
387
|
+
enum: ["DISK", "TAPE"]
|
|
388
|
+
latitude:
|
|
389
|
+
description: The latitude of the RSE.
|
|
390
|
+
type: number
|
|
391
|
+
longitude:
|
|
392
|
+
description: The longitude of the RSE.
|
|
393
|
+
type: number
|
|
394
|
+
responses:
|
|
395
|
+
201:
|
|
396
|
+
description: OK
|
|
397
|
+
content:
|
|
398
|
+
application/json:
|
|
399
|
+
schema:
|
|
400
|
+
type: string
|
|
401
|
+
enum: ["Created"]
|
|
402
|
+
400:
|
|
403
|
+
description: Cannot decode json parameter dictionary or invalid option provided
|
|
404
|
+
401:
|
|
405
|
+
description: Invalid Auth Token
|
|
406
|
+
404:
|
|
407
|
+
description: RSE not found
|
|
408
|
+
"""
|
|
409
|
+
kwargs = {
|
|
410
|
+
'parameters': json_parameters(optional=True),
|
|
411
|
+
'issuer': request.environ.get('issuer'),
|
|
412
|
+
'vo': request.environ.get('vo'),
|
|
413
|
+
}
|
|
414
|
+
try:
|
|
415
|
+
update_rse(rse, **kwargs)
|
|
416
|
+
except (InvalidObject, InputValidationError) as error:
|
|
417
|
+
return generate_http_error_flask(400, error)
|
|
418
|
+
except AccessDenied as error:
|
|
419
|
+
return generate_http_error_flask(401, error)
|
|
420
|
+
except RSENotFound as error:
|
|
421
|
+
return generate_http_error_flask(404, error)
|
|
422
|
+
except Duplicate as error:
|
|
423
|
+
return generate_http_error_flask(409, error)
|
|
424
|
+
|
|
425
|
+
return 'Created', 201
|
|
426
|
+
|
|
427
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
428
|
+
def get(self, rse):
|
|
429
|
+
"""
|
|
430
|
+
---
|
|
431
|
+
summary: Get RSE
|
|
432
|
+
description: Get details about a specific RSE.
|
|
433
|
+
tags:
|
|
434
|
+
- Rucio Storage Elements
|
|
435
|
+
parameters:
|
|
436
|
+
- name: rse
|
|
437
|
+
in: path
|
|
438
|
+
description: The name of the Rucio Storage Element name.
|
|
439
|
+
schema:
|
|
440
|
+
type: string
|
|
441
|
+
style: simple
|
|
442
|
+
responses:
|
|
443
|
+
200:
|
|
444
|
+
description: OK
|
|
445
|
+
content:
|
|
446
|
+
application/json:
|
|
447
|
+
schema:
|
|
448
|
+
description: The RSE properties.
|
|
449
|
+
type: object
|
|
450
|
+
properties:
|
|
451
|
+
deterministic:
|
|
452
|
+
description: If the pfn is generated deterministicly.
|
|
453
|
+
type: boolean
|
|
454
|
+
volatile:
|
|
455
|
+
description: RSE cache.
|
|
456
|
+
type: boolean
|
|
457
|
+
city:
|
|
458
|
+
description: The city of the RSE.
|
|
459
|
+
type: string
|
|
460
|
+
staging_area:
|
|
461
|
+
description: Staging area.
|
|
462
|
+
type: string
|
|
463
|
+
region_code:
|
|
464
|
+
description: The region code of the RSE.
|
|
465
|
+
type: string
|
|
466
|
+
country_name:
|
|
467
|
+
description: The country name of the RSE.
|
|
468
|
+
type: string
|
|
469
|
+
continent:
|
|
470
|
+
description: The continent of the RSE.
|
|
471
|
+
type: string
|
|
472
|
+
time_zone:
|
|
473
|
+
description: The time zone of the RSE.
|
|
474
|
+
type: string
|
|
475
|
+
ISP:
|
|
476
|
+
description: The internet service provider of the RSE.
|
|
477
|
+
type: string
|
|
478
|
+
rse_type:
|
|
479
|
+
description: The rse type.
|
|
480
|
+
type: string
|
|
481
|
+
enum: ["DISK", "TAPE"]
|
|
482
|
+
latitude:
|
|
483
|
+
description: The latitude of the RSE.
|
|
484
|
+
type: number
|
|
485
|
+
longitude:
|
|
486
|
+
description: The longitude of the RSE.
|
|
487
|
+
type: number
|
|
488
|
+
ASN:
|
|
489
|
+
description: The access service network of the RSE.
|
|
490
|
+
type: string
|
|
491
|
+
availability:
|
|
492
|
+
description: The availability of the RSE.
|
|
493
|
+
type: integer
|
|
494
|
+
deprecated: true
|
|
495
|
+
availability_read:
|
|
496
|
+
description: If the RSE is readable.
|
|
497
|
+
type: integer
|
|
498
|
+
availability_write:
|
|
499
|
+
description: If the RSE is writable.
|
|
500
|
+
type: integer
|
|
501
|
+
availability_delete:
|
|
502
|
+
description: If the RSE is deletable.
|
|
503
|
+
401:
|
|
504
|
+
description: Invalid Auth Token
|
|
505
|
+
404:
|
|
506
|
+
description: RSE not found
|
|
507
|
+
406:
|
|
508
|
+
description: Not acceptable
|
|
509
|
+
"""
|
|
510
|
+
try:
|
|
511
|
+
rse = get_rse(rse=rse, vo=request.environ.get('vo'))
|
|
512
|
+
rse['availability'] = Availability(rse['availability_read'], rse['availability_write'], rse['availability_delete']).integer
|
|
513
|
+
return Response(render_json(**rse), content_type="application/json")
|
|
514
|
+
except RSENotFound as error:
|
|
515
|
+
return generate_http_error_flask(404, error)
|
|
516
|
+
|
|
517
|
+
def delete(self, rse):
|
|
518
|
+
"""
|
|
519
|
+
---
|
|
520
|
+
summary: Disable RSE
|
|
521
|
+
description: Disable a specific RSE.
|
|
522
|
+
tags:
|
|
523
|
+
- Rucio Storage Elements
|
|
524
|
+
parameters:
|
|
525
|
+
- name: rse
|
|
526
|
+
in: path
|
|
527
|
+
description: The name of the Rucio Storage Element name.
|
|
528
|
+
schema:
|
|
529
|
+
type: string
|
|
530
|
+
style: simple
|
|
531
|
+
responses:
|
|
532
|
+
200:
|
|
533
|
+
description: OK
|
|
534
|
+
401:
|
|
535
|
+
description: Invalid Auth Token
|
|
536
|
+
404:
|
|
537
|
+
description: RSE not found
|
|
538
|
+
"""
|
|
539
|
+
try:
|
|
540
|
+
del_rse(rse=rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
541
|
+
except (RSENotFound, RSEOperationNotSupported, CounterNotFound) as error:
|
|
542
|
+
return generate_http_error_flask(404, error)
|
|
543
|
+
except AccessDenied as error:
|
|
544
|
+
return generate_http_error_flask(401, error)
|
|
545
|
+
|
|
546
|
+
return '', 200
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
class Attributes(ErrorHandlingMethodView):
|
|
550
|
+
""" Create, update, get and disable RSE attribute."""
|
|
551
|
+
|
|
552
|
+
def post(self, rse, key):
|
|
553
|
+
"""
|
|
554
|
+
---
|
|
555
|
+
summary: Create RSE Attribute
|
|
556
|
+
description: Create a RSE attribute with given RSE name.
|
|
557
|
+
tags:
|
|
558
|
+
- Rucio Storage Elements
|
|
559
|
+
parameters:
|
|
560
|
+
- name: rse
|
|
561
|
+
in: path
|
|
562
|
+
description: The name of the Rucio Storage Element name.
|
|
563
|
+
schema:
|
|
564
|
+
type: string
|
|
565
|
+
style: simple
|
|
566
|
+
- name: key
|
|
567
|
+
in: path
|
|
568
|
+
description: The name of the attribute of the RSE.
|
|
569
|
+
schema:
|
|
570
|
+
type: string
|
|
571
|
+
style: simple
|
|
572
|
+
requestBody:
|
|
573
|
+
content:
|
|
574
|
+
application/json:
|
|
575
|
+
schema:
|
|
576
|
+
type: object
|
|
577
|
+
required:
|
|
578
|
+
- value
|
|
579
|
+
properties:
|
|
580
|
+
value:
|
|
581
|
+
description: The value of the RSE attribute.
|
|
582
|
+
type: string
|
|
583
|
+
responses:
|
|
584
|
+
201:
|
|
585
|
+
description: OK
|
|
586
|
+
content:
|
|
587
|
+
application/json:
|
|
588
|
+
schema:
|
|
589
|
+
type: string
|
|
590
|
+
enum: ["Created"]
|
|
591
|
+
400:
|
|
592
|
+
description: Cannot decode json parameter dictionary
|
|
593
|
+
401:
|
|
594
|
+
description: Invalid Auth Token
|
|
595
|
+
404:
|
|
596
|
+
description: RSE not found
|
|
597
|
+
409:
|
|
598
|
+
description: Attribute already exists
|
|
599
|
+
"""
|
|
600
|
+
parameters = json_parameters()
|
|
601
|
+
value = param_get(parameters, 'value')
|
|
602
|
+
try:
|
|
603
|
+
add_rse_attribute(rse=rse, key=key, value=value, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
604
|
+
except AccessDenied as error:
|
|
605
|
+
return generate_http_error_flask(401, error)
|
|
606
|
+
except Duplicate as error:
|
|
607
|
+
return generate_http_error_flask(409, error)
|
|
608
|
+
except RSENotFound as error:
|
|
609
|
+
return generate_http_error_flask(404, error)
|
|
610
|
+
|
|
611
|
+
return 'Created', 201
|
|
612
|
+
|
|
613
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
614
|
+
def get(self, rse):
|
|
615
|
+
"""
|
|
616
|
+
---
|
|
617
|
+
summary: Get RSE Attributes
|
|
618
|
+
description: Lists all RSE attributes for a RSE.
|
|
619
|
+
tags:
|
|
620
|
+
- Rucio Storage Elements
|
|
621
|
+
parameters:
|
|
622
|
+
- name: rse
|
|
623
|
+
in: path
|
|
624
|
+
description: The name of the Rucio Storage Element name.
|
|
625
|
+
schema:
|
|
626
|
+
type: string
|
|
627
|
+
style: simple
|
|
628
|
+
responses:
|
|
629
|
+
200:
|
|
630
|
+
description: OK
|
|
631
|
+
content:
|
|
632
|
+
application/json:
|
|
633
|
+
schema:
|
|
634
|
+
description: The RSE attribute list. Returns a dictionary with the attribute names as keys and the values as values.
|
|
635
|
+
type: object
|
|
636
|
+
additionalProperties:
|
|
637
|
+
type: string
|
|
638
|
+
401:
|
|
639
|
+
description: Invalid Auth Token
|
|
640
|
+
404:
|
|
641
|
+
description: RSE not found
|
|
642
|
+
406:
|
|
643
|
+
description: Not acceptable
|
|
644
|
+
"""
|
|
645
|
+
try:
|
|
646
|
+
rse_attr = list_rse_attributes(rse, vo=request.environ.get('vo'))
|
|
647
|
+
except AccessDenied as error:
|
|
648
|
+
return generate_http_error_flask(401, error)
|
|
649
|
+
except RSENotFound as error:
|
|
650
|
+
return generate_http_error_flask(404, error)
|
|
651
|
+
|
|
652
|
+
return jsonify(rse_attr)
|
|
653
|
+
|
|
654
|
+
def delete(self, rse, key):
|
|
655
|
+
"""
|
|
656
|
+
---
|
|
657
|
+
summary: Delete RSE Attribute
|
|
658
|
+
description: Delete an RSE attribute for given RSE name.
|
|
659
|
+
tags:
|
|
660
|
+
- Rucio Storage Elements
|
|
661
|
+
parameters:
|
|
662
|
+
- name: rse
|
|
663
|
+
in: path
|
|
664
|
+
description: The name of the Rucio Storage Element name.
|
|
665
|
+
schema:
|
|
666
|
+
type: string
|
|
667
|
+
style: simple
|
|
668
|
+
- name: key
|
|
669
|
+
in: path
|
|
670
|
+
description: The name of the attribute of the RSE.
|
|
671
|
+
schema:
|
|
672
|
+
type: string
|
|
673
|
+
style: simple
|
|
674
|
+
responses:
|
|
675
|
+
200:
|
|
676
|
+
description: OK
|
|
677
|
+
401:
|
|
678
|
+
description: Invalid Auth Token
|
|
679
|
+
404:
|
|
680
|
+
description: RSE or RSE attribute not found
|
|
681
|
+
"""
|
|
682
|
+
try:
|
|
683
|
+
del_rse_attribute(rse=rse, key=key, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
684
|
+
except AccessDenied as error:
|
|
685
|
+
return generate_http_error_flask(401, error)
|
|
686
|
+
except (RSENotFound, RSEAttributeNotFound) as error:
|
|
687
|
+
return generate_http_error_flask(404, error)
|
|
688
|
+
|
|
689
|
+
return '', 200
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
class ProtocolList(ErrorHandlingMethodView):
|
|
693
|
+
""" List supported protocols. """
|
|
694
|
+
|
|
695
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
696
|
+
def get(self, rse):
|
|
697
|
+
"""
|
|
698
|
+
---
|
|
699
|
+
summary: List RSE Protocols
|
|
700
|
+
description: List all supported protocols of the given RSE.
|
|
701
|
+
tags:
|
|
702
|
+
- Rucio Storage Elements
|
|
703
|
+
parameters:
|
|
704
|
+
- name: rse
|
|
705
|
+
in: path
|
|
706
|
+
description: The name of the Rucio Storage Element name.
|
|
707
|
+
schema:
|
|
708
|
+
type: string
|
|
709
|
+
style: simple
|
|
710
|
+
responses:
|
|
711
|
+
200:
|
|
712
|
+
description: OK
|
|
713
|
+
content:
|
|
714
|
+
application/json:
|
|
715
|
+
schema:
|
|
716
|
+
description: Supported RSE Protocols and other information.
|
|
717
|
+
type: object
|
|
718
|
+
properties:
|
|
719
|
+
deterministic:
|
|
720
|
+
description: If the pfn is generated deterministicly.
|
|
721
|
+
type: boolean
|
|
722
|
+
volatile:
|
|
723
|
+
description: RSE cache.
|
|
724
|
+
type: boolean
|
|
725
|
+
staging_area:
|
|
726
|
+
description: Staging area.
|
|
727
|
+
type: string
|
|
728
|
+
rse_type:
|
|
729
|
+
description: The rse type.
|
|
730
|
+
type: string
|
|
731
|
+
enum: ["DISK", "TAPE"]
|
|
732
|
+
availability_read:
|
|
733
|
+
description: The read availability of the RSE.
|
|
734
|
+
type: boolean
|
|
735
|
+
availability_write:
|
|
736
|
+
description: The write availability of the RSE.
|
|
737
|
+
type: boolean
|
|
738
|
+
availability_delete:
|
|
739
|
+
description: The delete availability of the RSE.
|
|
740
|
+
type: boolean
|
|
741
|
+
credentials:
|
|
742
|
+
description: The credentials, currently None.
|
|
743
|
+
type: string
|
|
744
|
+
domain:
|
|
745
|
+
description: The domains of the RSE protocols.
|
|
746
|
+
type: array
|
|
747
|
+
id:
|
|
748
|
+
description: The RSE id.
|
|
749
|
+
type: string
|
|
750
|
+
lfn2pfn_algorithm:
|
|
751
|
+
description: The algorithm used to translate the logical file names to the physical ones.
|
|
752
|
+
type: string
|
|
753
|
+
qos_class:
|
|
754
|
+
description: The qos class of the RSE.
|
|
755
|
+
type: string
|
|
756
|
+
rse:
|
|
757
|
+
description: The name of the RSE.
|
|
758
|
+
type: string
|
|
759
|
+
sign_url:
|
|
760
|
+
description: The sign url of the RSE.
|
|
761
|
+
type: string
|
|
762
|
+
verify_checksum:
|
|
763
|
+
description: If the checksum of the files should be verified.
|
|
764
|
+
type: boolean
|
|
765
|
+
protocols:
|
|
766
|
+
description: All supported protocols of the RSE.
|
|
767
|
+
type: array
|
|
768
|
+
items:
|
|
769
|
+
type: object
|
|
770
|
+
description: A supported RSE protocol.
|
|
771
|
+
properties:
|
|
772
|
+
hostname:
|
|
773
|
+
description: The hostname of the protocol.
|
|
774
|
+
type: string
|
|
775
|
+
scheme:
|
|
776
|
+
description: The scheme of the protocol.
|
|
777
|
+
type: string
|
|
778
|
+
port:
|
|
779
|
+
description: The port of the protocol.
|
|
780
|
+
type: integer
|
|
781
|
+
prefix:
|
|
782
|
+
description: The prefix of the protocol.
|
|
783
|
+
type: string
|
|
784
|
+
impl:
|
|
785
|
+
description: The implementation of the protocol.
|
|
786
|
+
type: string
|
|
787
|
+
domains:
|
|
788
|
+
description: The domains of the protocol.
|
|
789
|
+
type: object
|
|
790
|
+
properties:
|
|
791
|
+
lan:
|
|
792
|
+
description: The lan domain
|
|
793
|
+
type: object
|
|
794
|
+
properties:
|
|
795
|
+
read:
|
|
796
|
+
description: The read value of the lan protocol.
|
|
797
|
+
type: integer
|
|
798
|
+
write:
|
|
799
|
+
description: The write value of the lan protocol.
|
|
800
|
+
type: integer
|
|
801
|
+
delete:
|
|
802
|
+
description: The delete value of the lan protocol.
|
|
803
|
+
type: integer
|
|
804
|
+
wan:
|
|
805
|
+
description: The wan domain
|
|
806
|
+
type: object
|
|
807
|
+
properties:
|
|
808
|
+
read:
|
|
809
|
+
description: The read value of the wan protocol.
|
|
810
|
+
type: integer
|
|
811
|
+
write:
|
|
812
|
+
description: The read value of the wan protocol.
|
|
813
|
+
type: integer
|
|
814
|
+
delete:
|
|
815
|
+
description: The read value of the wan protocol.
|
|
816
|
+
type: integer
|
|
817
|
+
third_party_copy_read:
|
|
818
|
+
description: The third party copy read value of the wan protocol.
|
|
819
|
+
type: integer
|
|
820
|
+
third_party_copy_write:
|
|
821
|
+
description: The third party copy write value of the wan protocol.
|
|
822
|
+
type: integer
|
|
823
|
+
extended_attributes:
|
|
824
|
+
description: The extended attributes of the protocol.
|
|
825
|
+
type: string
|
|
826
|
+
401:
|
|
827
|
+
description: Invalid Auth Token
|
|
828
|
+
404:
|
|
829
|
+
description: RSE not found or RSE Operation, RSE Protocol Domain, RSE Protocol not supported
|
|
830
|
+
406:
|
|
831
|
+
description: Not acceptable
|
|
832
|
+
"""
|
|
833
|
+
try:
|
|
834
|
+
p_list = get_rse_protocols(rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
835
|
+
except (RSEOperationNotSupported, RSENotFound, RSEProtocolNotSupported, RSEProtocolDomainNotSupported) as error:
|
|
836
|
+
return generate_http_error_flask(404, error)
|
|
837
|
+
|
|
838
|
+
if len(p_list['protocols']):
|
|
839
|
+
return jsonify(p_list['protocols'])
|
|
840
|
+
else:
|
|
841
|
+
return generate_http_error_flask(404, RSEProtocolNotSupported.__name__, 'No protocols found for this RSE')
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
class LFNS2PFNS(ErrorHandlingMethodView):
|
|
845
|
+
""" Translate one-or-more LFNs to corresponding PFNs. """
|
|
846
|
+
|
|
847
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
848
|
+
def get(self, rse):
|
|
849
|
+
"""
|
|
850
|
+
---
|
|
851
|
+
summary: Translate LFNs to PFNs
|
|
852
|
+
description: Return PFNs for a set of LFNs. Formatted as a JSON object where the key is a LFN and the value is the corresponding PFN.
|
|
853
|
+
tags:
|
|
854
|
+
- Rucio Storage Elements
|
|
855
|
+
parameters:
|
|
856
|
+
- name: rse
|
|
857
|
+
in: path
|
|
858
|
+
description: The name of the Rucio Storage Element name.
|
|
859
|
+
schema:
|
|
860
|
+
type: string
|
|
861
|
+
style: simple
|
|
862
|
+
- name: lfn
|
|
863
|
+
in: query
|
|
864
|
+
description: The lfns of the request.
|
|
865
|
+
schema:
|
|
866
|
+
type: string
|
|
867
|
+
required: True
|
|
868
|
+
- name: scheme
|
|
869
|
+
in: query
|
|
870
|
+
description: Optional argument to help with the protocol selection (e.g., http / gsiftp / srm)
|
|
871
|
+
schema:
|
|
872
|
+
type: string
|
|
873
|
+
- name: domain
|
|
874
|
+
in: query
|
|
875
|
+
description: Optional argument used to select the protocol for wan or lan use cases.
|
|
876
|
+
schema:
|
|
877
|
+
type: string
|
|
878
|
+
- name: operation
|
|
879
|
+
in: query
|
|
880
|
+
description: Optional query argument to select the protocol for read-vs-writes.
|
|
881
|
+
schema:
|
|
882
|
+
type: string
|
|
883
|
+
responses:
|
|
884
|
+
200:
|
|
885
|
+
description: OK
|
|
886
|
+
content:
|
|
887
|
+
application/json:
|
|
888
|
+
schema:
|
|
889
|
+
description: The PFNs to the LFNs. Dictionary with lfns as keys and pfns as values.
|
|
890
|
+
type: object
|
|
891
|
+
additionalProperties:
|
|
892
|
+
type:
|
|
893
|
+
string
|
|
894
|
+
401:
|
|
895
|
+
description: Invalid Auth Token
|
|
896
|
+
404:
|
|
897
|
+
description: RSE not found or RSE Protocol or RSE Protocol Domain not supported
|
|
898
|
+
406:
|
|
899
|
+
description: Not acceptable
|
|
900
|
+
"""
|
|
901
|
+
lfns = request.args.getlist('lfn')
|
|
902
|
+
lfns = list(map(lambda lfn: lfn.split(":", 1), lfns))
|
|
903
|
+
if any(filter(lambda info: len(info) != 2, lfns)):
|
|
904
|
+
invalid_lfns = ', '.join(filter(lambda info: len(info) != 2, lfns))
|
|
905
|
+
return generate_http_error_flask(400, InvalidPath.__name__, 'LFN(s) in invalid format: ' + invalid_lfns)
|
|
906
|
+
lfns_list: list["LFNDict"] = list(map(lambda info: {'scope': info[0], 'name': info[1]}, lfns))
|
|
907
|
+
scheme = request.args.get('scheme', default=None)
|
|
908
|
+
domain = request.args.get('domain', default='wan')
|
|
909
|
+
operation = request.args.get('operation', default='write')
|
|
910
|
+
|
|
911
|
+
try:
|
|
912
|
+
rse_settings = get_rse_protocols(rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
913
|
+
except (RSENotFound, RSEProtocolNotSupported, RSEProtocolDomainNotSupported) as error:
|
|
914
|
+
return generate_http_error_flask(404, error)
|
|
915
|
+
|
|
916
|
+
pfns = rsemanager.lfns2pfns(rse_settings, lfns_list, operation=operation, scheme=scheme, domain=domain)
|
|
917
|
+
if not pfns:
|
|
918
|
+
return generate_http_error_flask(404, ReplicaNotFound.__name__, 'No replicas found')
|
|
919
|
+
|
|
920
|
+
return jsonify(pfns)
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
class Protocol(ErrorHandlingMethodView):
|
|
924
|
+
""" Create, Update, Read and delete a specific protocol. """
|
|
925
|
+
|
|
926
|
+
def post(self, rse, scheme):
|
|
927
|
+
"""
|
|
928
|
+
---
|
|
929
|
+
summary: Create RSE Protocol
|
|
930
|
+
description: Create a protocol for a given RSE.
|
|
931
|
+
tags:
|
|
932
|
+
- Rucio Storage Elements
|
|
933
|
+
parameters:
|
|
934
|
+
- name: rse
|
|
935
|
+
in: path
|
|
936
|
+
description: The name of the Rucio Storage Element name.
|
|
937
|
+
schema:
|
|
938
|
+
type: string
|
|
939
|
+
style: simple
|
|
940
|
+
- name: scheme
|
|
941
|
+
in: path
|
|
942
|
+
description: The protocol identifier.
|
|
943
|
+
schema:
|
|
944
|
+
type: string
|
|
945
|
+
style: simple
|
|
946
|
+
required: False
|
|
947
|
+
requestBody:
|
|
948
|
+
content:
|
|
949
|
+
application/json:
|
|
950
|
+
schema:
|
|
951
|
+
type: object
|
|
952
|
+
properties:
|
|
953
|
+
domains:
|
|
954
|
+
description: The domains for the protocol.
|
|
955
|
+
type: array
|
|
956
|
+
port:
|
|
957
|
+
description: The port the protocol uses.
|
|
958
|
+
type: integer
|
|
959
|
+
hostname:
|
|
960
|
+
description: The hostname of the protocol.
|
|
961
|
+
type: string
|
|
962
|
+
extended_attributes:
|
|
963
|
+
description: Extended attributes for the protocol.
|
|
964
|
+
type: string
|
|
965
|
+
prefix:
|
|
966
|
+
description: The prefix of the Protocol.
|
|
967
|
+
type: string
|
|
968
|
+
impl:
|
|
969
|
+
description: The impl used by the Protocol.
|
|
970
|
+
type: string
|
|
971
|
+
read_lan:
|
|
972
|
+
description: If the protocol is readable via lan.
|
|
973
|
+
type: integer
|
|
974
|
+
write_lan:
|
|
975
|
+
description: If the protocol is writable via lan.
|
|
976
|
+
type: integer
|
|
977
|
+
delete_lan:
|
|
978
|
+
description: If the protocol is deletable via lan.
|
|
979
|
+
type: integer
|
|
980
|
+
read_wan:
|
|
981
|
+
description: If the protocol is readable via wan.
|
|
982
|
+
type: integer
|
|
983
|
+
write_wan:
|
|
984
|
+
description: If the protocol is writable via wan.
|
|
985
|
+
type: integer
|
|
986
|
+
delete_wan:
|
|
987
|
+
description: If the protocol is deletable via wan.
|
|
988
|
+
type: integer
|
|
989
|
+
responses:
|
|
990
|
+
201:
|
|
991
|
+
description: OK
|
|
992
|
+
content:
|
|
993
|
+
application/json:
|
|
994
|
+
schema:
|
|
995
|
+
type: string
|
|
996
|
+
enum: ["Created"]
|
|
997
|
+
400:
|
|
998
|
+
description: Cannot decode json parameter dictionary
|
|
999
|
+
401:
|
|
1000
|
+
description: Invalid Auth Token
|
|
1001
|
+
404:
|
|
1002
|
+
description: RSE not found or RSE Protocol Domain not supported
|
|
1003
|
+
409:
|
|
1004
|
+
description: RSE protocol priority error
|
|
1005
|
+
"""
|
|
1006
|
+
parameters = json_parameters()
|
|
1007
|
+
|
|
1008
|
+
# Fill defaults and check mandatory parameters
|
|
1009
|
+
parameters['scheme'] = scheme
|
|
1010
|
+
|
|
1011
|
+
try:
|
|
1012
|
+
add_protocol(rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'), data=parameters)
|
|
1013
|
+
except (RSENotFound, RSEProtocolDomainNotSupported) as error:
|
|
1014
|
+
return generate_http_error_flask(404, error)
|
|
1015
|
+
except AccessDenied as error:
|
|
1016
|
+
return generate_http_error_flask(401, error)
|
|
1017
|
+
except (Duplicate, RSEProtocolPriorityError) as error:
|
|
1018
|
+
return generate_http_error_flask(409, error)
|
|
1019
|
+
except InvalidObject as error:
|
|
1020
|
+
return generate_http_error_flask(400, error)
|
|
1021
|
+
|
|
1022
|
+
return 'Created', 201
|
|
1023
|
+
|
|
1024
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
1025
|
+
def get(self, rse, scheme):
|
|
1026
|
+
"""
|
|
1027
|
+
---
|
|
1028
|
+
summary: Get Protocols
|
|
1029
|
+
description: List all references of the provided RSE for the given protocol.
|
|
1030
|
+
tags:
|
|
1031
|
+
- Rucio Storage Elements
|
|
1032
|
+
parameters:
|
|
1033
|
+
- name: rse
|
|
1034
|
+
in: path
|
|
1035
|
+
description: The name of the Rucio Storage Element name.
|
|
1036
|
+
schema:
|
|
1037
|
+
type: string
|
|
1038
|
+
style: simple
|
|
1039
|
+
- name: scheme
|
|
1040
|
+
in: path
|
|
1041
|
+
description: The protocol identifier.
|
|
1042
|
+
schema:
|
|
1043
|
+
type: string
|
|
1044
|
+
style: simple
|
|
1045
|
+
required: False
|
|
1046
|
+
responses:
|
|
1047
|
+
200:
|
|
1048
|
+
description: OK
|
|
1049
|
+
content:
|
|
1050
|
+
application/json:
|
|
1051
|
+
schema:
|
|
1052
|
+
description: A dict with RSE information and supported protocols.
|
|
1053
|
+
type: object
|
|
1054
|
+
properties:
|
|
1055
|
+
deterministic:
|
|
1056
|
+
description: If the pfn is generated deterministicly.
|
|
1057
|
+
type: boolean
|
|
1058
|
+
volatile:
|
|
1059
|
+
description: RSE cache.
|
|
1060
|
+
type: boolean
|
|
1061
|
+
staging_area:
|
|
1062
|
+
description: Staging area.
|
|
1063
|
+
type: string
|
|
1064
|
+
rse_type:
|
|
1065
|
+
description: The rse type.
|
|
1066
|
+
type: string
|
|
1067
|
+
enum: ["DISK", "TAPE"]
|
|
1068
|
+
availability_read:
|
|
1069
|
+
description: The read availability of the RSE.
|
|
1070
|
+
type: boolean
|
|
1071
|
+
availability_write:
|
|
1072
|
+
description: The write availability of the RSE.
|
|
1073
|
+
type: boolean
|
|
1074
|
+
availability_delete:
|
|
1075
|
+
description: The delete availability of the RSE.
|
|
1076
|
+
type: boolean
|
|
1077
|
+
credentials:
|
|
1078
|
+
description: The credentials, currently None.
|
|
1079
|
+
type: string
|
|
1080
|
+
domain:
|
|
1081
|
+
description: The domains of the RSE protocols.
|
|
1082
|
+
type: array
|
|
1083
|
+
id:
|
|
1084
|
+
description: The RSE id.
|
|
1085
|
+
type: string
|
|
1086
|
+
lfn2pfn_algorithm:
|
|
1087
|
+
description: The algorithm used to translate the logical file names to the physical ones.
|
|
1088
|
+
type: string
|
|
1089
|
+
qos_class:
|
|
1090
|
+
description: The qos class of the RSE.
|
|
1091
|
+
type: string
|
|
1092
|
+
rse:
|
|
1093
|
+
description: The name of the RSE.
|
|
1094
|
+
type: string
|
|
1095
|
+
sign_url:
|
|
1096
|
+
description: The sign url of the RSE.
|
|
1097
|
+
type: string
|
|
1098
|
+
verify_checksum:
|
|
1099
|
+
description: If the checksum of the files should be verified.
|
|
1100
|
+
type: boolean
|
|
1101
|
+
protocols:
|
|
1102
|
+
description: All supported protocols of the RSE.
|
|
1103
|
+
type: array
|
|
1104
|
+
items:
|
|
1105
|
+
type: object
|
|
1106
|
+
description: A supported RSE protocol.
|
|
1107
|
+
properties:
|
|
1108
|
+
hostname:
|
|
1109
|
+
description: The hostname of the protocol.
|
|
1110
|
+
type: string
|
|
1111
|
+
scheme:
|
|
1112
|
+
description: The scheme of the protocol.
|
|
1113
|
+
type: string
|
|
1114
|
+
port:
|
|
1115
|
+
description: The port of the protocol.
|
|
1116
|
+
type: integer
|
|
1117
|
+
prefix:
|
|
1118
|
+
description: The prefix of the protocol.
|
|
1119
|
+
type: string
|
|
1120
|
+
impl:
|
|
1121
|
+
description: The implementation of the protocol.
|
|
1122
|
+
type: string
|
|
1123
|
+
domains:
|
|
1124
|
+
description: The domains of the protocol.
|
|
1125
|
+
type: object
|
|
1126
|
+
properties:
|
|
1127
|
+
lan:
|
|
1128
|
+
description: The lan domain
|
|
1129
|
+
type: object
|
|
1130
|
+
properties:
|
|
1131
|
+
read:
|
|
1132
|
+
description: The read value of the lan protocol.
|
|
1133
|
+
type: integer
|
|
1134
|
+
write:
|
|
1135
|
+
description: The write value of the lan protocol.
|
|
1136
|
+
type: integer
|
|
1137
|
+
delete:
|
|
1138
|
+
description: The delete value of the lan protocol.
|
|
1139
|
+
type: integer
|
|
1140
|
+
wan:
|
|
1141
|
+
description: The wan domain
|
|
1142
|
+
type: object
|
|
1143
|
+
properties:
|
|
1144
|
+
read:
|
|
1145
|
+
description: The read value of the wan protocol.
|
|
1146
|
+
type: integer
|
|
1147
|
+
write:
|
|
1148
|
+
description: The read value of the wan protocol.
|
|
1149
|
+
type: integer
|
|
1150
|
+
delete:
|
|
1151
|
+
description: The read value of the wan protocol.
|
|
1152
|
+
type: integer
|
|
1153
|
+
third_party_copy_read:
|
|
1154
|
+
description: The third party copy read value of the wan protocol.
|
|
1155
|
+
type: integer
|
|
1156
|
+
third_party_copy_write:
|
|
1157
|
+
description: The third party copy write value of the wan protocol.
|
|
1158
|
+
type: integer
|
|
1159
|
+
extended_attributes:
|
|
1160
|
+
description: The extended attributes of the protocol.
|
|
1161
|
+
type: string
|
|
1162
|
+
401:
|
|
1163
|
+
description: Invalid Auth Token
|
|
1164
|
+
404:
|
|
1165
|
+
description: RSE not found or Protocol or Protocol domain not Supported.
|
|
1166
|
+
406:
|
|
1167
|
+
description: Not acceptable
|
|
1168
|
+
"""
|
|
1169
|
+
try:
|
|
1170
|
+
p_list = get_rse_protocols(rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
1171
|
+
except (RSENotFound, RSEProtocolNotSupported, RSEProtocolDomainNotSupported) as error:
|
|
1172
|
+
return generate_http_error_flask(404, error)
|
|
1173
|
+
|
|
1174
|
+
return jsonify(p_list)
|
|
1175
|
+
|
|
1176
|
+
def put(self, rse, scheme, hostname=None, port=None):
|
|
1177
|
+
"""
|
|
1178
|
+
---
|
|
1179
|
+
summary: Update Protocol Attributes
|
|
1180
|
+
description: Updates attributes of an existing protocol entry. Because protocol identifier, hostname, and port are used as unique identifier they are immutable.
|
|
1181
|
+
tags:
|
|
1182
|
+
- Rucio Storage Elements
|
|
1183
|
+
parameters:
|
|
1184
|
+
- name: rse
|
|
1185
|
+
in: path
|
|
1186
|
+
description: The name of the Rucio Storage Element name.
|
|
1187
|
+
schema:
|
|
1188
|
+
type: string
|
|
1189
|
+
style: simple
|
|
1190
|
+
- name: scheme
|
|
1191
|
+
in: path
|
|
1192
|
+
description: The protocol identifier.
|
|
1193
|
+
schema:
|
|
1194
|
+
type: string
|
|
1195
|
+
style: simple
|
|
1196
|
+
- name: hostname
|
|
1197
|
+
in: path
|
|
1198
|
+
description: The hostname of the protocol.
|
|
1199
|
+
schema:
|
|
1200
|
+
type: string
|
|
1201
|
+
style: simple
|
|
1202
|
+
required: False
|
|
1203
|
+
- name: port
|
|
1204
|
+
in: path
|
|
1205
|
+
description: The port of the protocol.
|
|
1206
|
+
schema:
|
|
1207
|
+
type: integer
|
|
1208
|
+
style: simple
|
|
1209
|
+
required: False
|
|
1210
|
+
responses:
|
|
1211
|
+
200:
|
|
1212
|
+
description: OK
|
|
1213
|
+
content:
|
|
1214
|
+
application/json:
|
|
1215
|
+
schema:
|
|
1216
|
+
description: A dict with RSE information and supported protocols.
|
|
1217
|
+
type: object
|
|
1218
|
+
properties:
|
|
1219
|
+
deterministic:
|
|
1220
|
+
description: If the pfn is generated deterministicly.
|
|
1221
|
+
type: boolean
|
|
1222
|
+
volatile:
|
|
1223
|
+
description: RSE cache.
|
|
1224
|
+
type: boolean
|
|
1225
|
+
staging_area:
|
|
1226
|
+
description: Staging area.
|
|
1227
|
+
type: string
|
|
1228
|
+
rse_type:
|
|
1229
|
+
description: The rse type.
|
|
1230
|
+
type: string
|
|
1231
|
+
enum: ["DISK", "TAPE"]
|
|
1232
|
+
availability_read:
|
|
1233
|
+
description: The read availability of the RSE.
|
|
1234
|
+
type: boolean
|
|
1235
|
+
availability_write:
|
|
1236
|
+
description: The write availability of the RSE.
|
|
1237
|
+
type: boolean
|
|
1238
|
+
availability_delete:
|
|
1239
|
+
description: The delete availability of the RSE.
|
|
1240
|
+
type: boolean
|
|
1241
|
+
credentials:
|
|
1242
|
+
description: The credentials, currently None.
|
|
1243
|
+
type: string
|
|
1244
|
+
domain:
|
|
1245
|
+
description: The domains of the RSE protocols.
|
|
1246
|
+
type: array
|
|
1247
|
+
id:
|
|
1248
|
+
description: The RSE id.
|
|
1249
|
+
type: string
|
|
1250
|
+
lfn2pfn_algorithm:
|
|
1251
|
+
description: The algorithm used to translate the logical file names to the physical ones.
|
|
1252
|
+
type: string
|
|
1253
|
+
qos_class:
|
|
1254
|
+
description: The qos class of the RSE.
|
|
1255
|
+
type: string
|
|
1256
|
+
rse:
|
|
1257
|
+
description: The name of the RSE.
|
|
1258
|
+
type: string
|
|
1259
|
+
sign_url:
|
|
1260
|
+
description: The sign url of the RSE.
|
|
1261
|
+
type: string
|
|
1262
|
+
verify_checksum:
|
|
1263
|
+
description: If the checksum of the files should be verified.
|
|
1264
|
+
type: boolean
|
|
1265
|
+
protocols:
|
|
1266
|
+
description: All supported protocols of the RSE.
|
|
1267
|
+
type: array
|
|
1268
|
+
items:
|
|
1269
|
+
type: object
|
|
1270
|
+
description: A supported RSE protocol.
|
|
1271
|
+
properties:
|
|
1272
|
+
hostname:
|
|
1273
|
+
description: The hostname of the protocol.
|
|
1274
|
+
type: string
|
|
1275
|
+
scheme:
|
|
1276
|
+
description: The scheme of the protocol.
|
|
1277
|
+
type: string
|
|
1278
|
+
port:
|
|
1279
|
+
description: The port of the protocol.
|
|
1280
|
+
type: integer
|
|
1281
|
+
prefix:
|
|
1282
|
+
description: The prefix of the protocol.
|
|
1283
|
+
type: string
|
|
1284
|
+
impl:
|
|
1285
|
+
description: The implementation of the protocol.
|
|
1286
|
+
type: string
|
|
1287
|
+
domains:
|
|
1288
|
+
description: The domains of the protocol.
|
|
1289
|
+
type: object
|
|
1290
|
+
properties:
|
|
1291
|
+
lan:
|
|
1292
|
+
description: The lan domain
|
|
1293
|
+
type: object
|
|
1294
|
+
properties:
|
|
1295
|
+
read:
|
|
1296
|
+
description: The read value of the lan protocol.
|
|
1297
|
+
type: integer
|
|
1298
|
+
write:
|
|
1299
|
+
description: The write value of the lan protocol.
|
|
1300
|
+
type: integer
|
|
1301
|
+
delete:
|
|
1302
|
+
description: The delete value of the lan protocol.
|
|
1303
|
+
type: integer
|
|
1304
|
+
wan:
|
|
1305
|
+
description: The wan domain
|
|
1306
|
+
type: object
|
|
1307
|
+
properties:
|
|
1308
|
+
read:
|
|
1309
|
+
description: The read value of the wan protocol.
|
|
1310
|
+
type: integer
|
|
1311
|
+
write:
|
|
1312
|
+
description: The read value of the wan protocol.
|
|
1313
|
+
type: integer
|
|
1314
|
+
delete:
|
|
1315
|
+
description: The read value of the wan protocol.
|
|
1316
|
+
type: integer
|
|
1317
|
+
third_party_copy_read:
|
|
1318
|
+
description: The third party copy read value of the wan protocol.
|
|
1319
|
+
type: integer
|
|
1320
|
+
third_party_copy_write:
|
|
1321
|
+
description: The third party copy write value of the wan protocol.
|
|
1322
|
+
type: integer
|
|
1323
|
+
extended_attributes:
|
|
1324
|
+
description: The extended attributes of the protocol.
|
|
1325
|
+
type: string
|
|
1326
|
+
401:
|
|
1327
|
+
description: Invalid Auth Token
|
|
1328
|
+
404:
|
|
1329
|
+
description: RSE not found or Protocol or Protocol domain not Supported.
|
|
1330
|
+
406:
|
|
1331
|
+
description: Not acceptable
|
|
1332
|
+
"""
|
|
1333
|
+
parameters = json_parameters()
|
|
1334
|
+
try:
|
|
1335
|
+
update_protocols(
|
|
1336
|
+
rse,
|
|
1337
|
+
issuer=request.environ.get('issuer'),
|
|
1338
|
+
vo=request.environ.get('vo'),
|
|
1339
|
+
scheme=scheme,
|
|
1340
|
+
hostname=hostname,
|
|
1341
|
+
port=int(port) if port else None,
|
|
1342
|
+
data=parameters,
|
|
1343
|
+
)
|
|
1344
|
+
except InvalidObject as error:
|
|
1345
|
+
return generate_http_error_flask(400, error)
|
|
1346
|
+
except (RSEProtocolNotSupported, RSENotFound, RSEProtocolDomainNotSupported) as error:
|
|
1347
|
+
return generate_http_error_flask(404, error)
|
|
1348
|
+
except (RSEProtocolPriorityError, Duplicate) as error:
|
|
1349
|
+
return generate_http_error_flask(409, error)
|
|
1350
|
+
|
|
1351
|
+
return '', 200
|
|
1352
|
+
|
|
1353
|
+
def delete(self, rse, scheme, hostname=None, port=None):
|
|
1354
|
+
"""
|
|
1355
|
+
---
|
|
1356
|
+
summary: Delete Protocol Attributes
|
|
1357
|
+
description: Delete all protocol attributes.
|
|
1358
|
+
tags:
|
|
1359
|
+
- Rucio Storage Elements
|
|
1360
|
+
parameters:
|
|
1361
|
+
- name: rse
|
|
1362
|
+
in: path
|
|
1363
|
+
description: The name of the Rucio Storage Element name.
|
|
1364
|
+
schema:
|
|
1365
|
+
type: string
|
|
1366
|
+
style: simple
|
|
1367
|
+
- name: scheme
|
|
1368
|
+
in: path
|
|
1369
|
+
description: The protocol identifier.
|
|
1370
|
+
schema:
|
|
1371
|
+
type: string
|
|
1372
|
+
style: simple
|
|
1373
|
+
- name: hostname
|
|
1374
|
+
in: path
|
|
1375
|
+
description: The hostname of the protocol.
|
|
1376
|
+
schema:
|
|
1377
|
+
type: string
|
|
1378
|
+
style: simple
|
|
1379
|
+
required: False
|
|
1380
|
+
- name: port
|
|
1381
|
+
in: path
|
|
1382
|
+
description: The port of the protocol.
|
|
1383
|
+
schema:
|
|
1384
|
+
type: integer
|
|
1385
|
+
style: simple
|
|
1386
|
+
required: False
|
|
1387
|
+
responses:
|
|
1388
|
+
200:
|
|
1389
|
+
description: OK
|
|
1390
|
+
401:
|
|
1391
|
+
description: Invalid Auth Token
|
|
1392
|
+
404:
|
|
1393
|
+
description: Rse not found or protocol not supported
|
|
1394
|
+
"""
|
|
1395
|
+
try:
|
|
1396
|
+
del_protocols(
|
|
1397
|
+
rse,
|
|
1398
|
+
issuer=request.environ.get('issuer'),
|
|
1399
|
+
vo=request.environ.get('vo'),
|
|
1400
|
+
scheme=scheme,
|
|
1401
|
+
hostname=hostname,
|
|
1402
|
+
port=int(port) if port else None
|
|
1403
|
+
)
|
|
1404
|
+
except (RSEProtocolNotSupported, RSENotFound) as error:
|
|
1405
|
+
return generate_http_error_flask(404, error)
|
|
1406
|
+
|
|
1407
|
+
return '', 200
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
class Usage(ErrorHandlingMethodView):
|
|
1411
|
+
""" Update and read RSE space usage information. """
|
|
1412
|
+
|
|
1413
|
+
@check_accept_header_wrapper_flask(['application/x-json-stream'])
|
|
1414
|
+
def get(self, rse):
|
|
1415
|
+
"""
|
|
1416
|
+
---
|
|
1417
|
+
summary: Get Rse Usage Information
|
|
1418
|
+
description: Get rse usage information.
|
|
1419
|
+
tags:
|
|
1420
|
+
- Rucio Storage Elements
|
|
1421
|
+
parameters:
|
|
1422
|
+
- name: rse
|
|
1423
|
+
in: path
|
|
1424
|
+
description: The name of the Rucio Storage Element name.
|
|
1425
|
+
schema:
|
|
1426
|
+
type: string
|
|
1427
|
+
style: simple
|
|
1428
|
+
- name: per_account
|
|
1429
|
+
in: query
|
|
1430
|
+
description: Boolean whether the usage should be also calculated per account or not.
|
|
1431
|
+
schema:
|
|
1432
|
+
type: boolean
|
|
1433
|
+
- name: source
|
|
1434
|
+
in: query
|
|
1435
|
+
description: The information source, e.g., srm.
|
|
1436
|
+
schema:
|
|
1437
|
+
type: string
|
|
1438
|
+
responses:
|
|
1439
|
+
200:
|
|
1440
|
+
description: OK
|
|
1441
|
+
content:
|
|
1442
|
+
application/x-json-stream:
|
|
1443
|
+
schema:
|
|
1444
|
+
description: A list with the rse usage.
|
|
1445
|
+
type: array
|
|
1446
|
+
items:
|
|
1447
|
+
type: object
|
|
1448
|
+
properties:
|
|
1449
|
+
rse_id:
|
|
1450
|
+
description: The id of the rse.
|
|
1451
|
+
type: string
|
|
1452
|
+
rse:
|
|
1453
|
+
description: The name of the rse.
|
|
1454
|
+
type: string
|
|
1455
|
+
source:
|
|
1456
|
+
description: The source of the rse.
|
|
1457
|
+
type: string
|
|
1458
|
+
used:
|
|
1459
|
+
description: The number of used bytes.
|
|
1460
|
+
type: integer
|
|
1461
|
+
free:
|
|
1462
|
+
description: The number of free bytes.
|
|
1463
|
+
type: integer
|
|
1464
|
+
total:
|
|
1465
|
+
description: The number of total bytes.
|
|
1466
|
+
type: integer
|
|
1467
|
+
files:
|
|
1468
|
+
description: The number of files.
|
|
1469
|
+
type: integer
|
|
1470
|
+
updated_at:
|
|
1471
|
+
description: The last time it got updated.
|
|
1472
|
+
type: string
|
|
1473
|
+
401:
|
|
1474
|
+
description: Invalid Auth Token
|
|
1475
|
+
404:
|
|
1476
|
+
description: Rse not found
|
|
1477
|
+
406:
|
|
1478
|
+
description: Not acceptable
|
|
1479
|
+
"""
|
|
1480
|
+
per_account = request.args.get('per_account') == 'True'
|
|
1481
|
+
try:
|
|
1482
|
+
def generate(issuer, source, per_account, vo):
|
|
1483
|
+
for usage in get_rse_usage(rse, issuer=issuer, source=source, per_account=per_account, vo=vo):
|
|
1484
|
+
yield render_json(**usage) + '\n'
|
|
1485
|
+
|
|
1486
|
+
return try_stream(
|
|
1487
|
+
generate(
|
|
1488
|
+
issuer=request.environ.get('issuer'),
|
|
1489
|
+
source=request.args.get('source'),
|
|
1490
|
+
per_account=per_account,
|
|
1491
|
+
vo=request.environ.get('vo'),
|
|
1492
|
+
)
|
|
1493
|
+
)
|
|
1494
|
+
except RSENotFound as error:
|
|
1495
|
+
return generate_http_error_flask(404, error)
|
|
1496
|
+
|
|
1497
|
+
def put(self, rse):
|
|
1498
|
+
"""
|
|
1499
|
+
---
|
|
1500
|
+
summary: Update Rse Usage
|
|
1501
|
+
description: Update the RSE Update information.
|
|
1502
|
+
tags:
|
|
1503
|
+
- Rucio Storage Elements
|
|
1504
|
+
parameters:
|
|
1505
|
+
- name: rse
|
|
1506
|
+
in: path
|
|
1507
|
+
description: The name of the Rucio Storage Element name.
|
|
1508
|
+
schema:
|
|
1509
|
+
type: string
|
|
1510
|
+
style: simple
|
|
1511
|
+
requestBody:
|
|
1512
|
+
content:
|
|
1513
|
+
application/json:
|
|
1514
|
+
schema:
|
|
1515
|
+
type: object
|
|
1516
|
+
properties:
|
|
1517
|
+
source:
|
|
1518
|
+
description: The information source, e.g. srm.
|
|
1519
|
+
type: string
|
|
1520
|
+
used:
|
|
1521
|
+
description: The number of used bytes.
|
|
1522
|
+
type: integer
|
|
1523
|
+
free:
|
|
1524
|
+
description: The number of free bytes.
|
|
1525
|
+
type: integer
|
|
1526
|
+
files:
|
|
1527
|
+
description: The number of files.
|
|
1528
|
+
type: integer
|
|
1529
|
+
responses:
|
|
1530
|
+
200:
|
|
1531
|
+
description: OK
|
|
1532
|
+
400:
|
|
1533
|
+
description: Can not decode json parameter list.
|
|
1534
|
+
401:
|
|
1535
|
+
description: Invalid Auth Token
|
|
1536
|
+
404:
|
|
1537
|
+
description: Rse not found
|
|
1538
|
+
406:
|
|
1539
|
+
description: Not acceptable
|
|
1540
|
+
"""
|
|
1541
|
+
parameters = json_parameters()
|
|
1542
|
+
kwargs = {'source': None, 'used': None, 'free': None, 'files': None}
|
|
1543
|
+
for keyword in kwargs.keys():
|
|
1544
|
+
kwargs[keyword] = param_get(parameters, keyword, default=kwargs[keyword])
|
|
1545
|
+
|
|
1546
|
+
try:
|
|
1547
|
+
set_rse_usage(rse=rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'), **kwargs)
|
|
1548
|
+
except AccessDenied as error:
|
|
1549
|
+
return generate_http_error_flask(401, error)
|
|
1550
|
+
except RSENotFound as error:
|
|
1551
|
+
return generate_http_error_flask(404, error)
|
|
1552
|
+
|
|
1553
|
+
return '', 200
|
|
1554
|
+
|
|
1555
|
+
|
|
1556
|
+
class UsageHistory(ErrorHandlingMethodView):
|
|
1557
|
+
""" Read RSE space usage history information. """
|
|
1558
|
+
|
|
1559
|
+
@check_accept_header_wrapper_flask(['application/x-json-stream'])
|
|
1560
|
+
def get(self, rse):
|
|
1561
|
+
"""
|
|
1562
|
+
---
|
|
1563
|
+
summary: Get Rse Usage History
|
|
1564
|
+
description: Get the rse usage history
|
|
1565
|
+
tags:
|
|
1566
|
+
- Rucio Storage Elements
|
|
1567
|
+
parameters:
|
|
1568
|
+
- name: rse
|
|
1569
|
+
in: path
|
|
1570
|
+
description: The name of the Rucio Storage Element name.
|
|
1571
|
+
schema:
|
|
1572
|
+
type: string
|
|
1573
|
+
style: simple
|
|
1574
|
+
responses:
|
|
1575
|
+
200:
|
|
1576
|
+
description: OK
|
|
1577
|
+
content:
|
|
1578
|
+
application/x-json-stream:
|
|
1579
|
+
schema:
|
|
1580
|
+
description: A list with the rse usage history items.
|
|
1581
|
+
type: array
|
|
1582
|
+
items:
|
|
1583
|
+
type: object
|
|
1584
|
+
properties:
|
|
1585
|
+
rse_id:
|
|
1586
|
+
description: The id of the rse.
|
|
1587
|
+
type: string
|
|
1588
|
+
rse:
|
|
1589
|
+
description: The name of the rse.
|
|
1590
|
+
type: string
|
|
1591
|
+
source:
|
|
1592
|
+
description: The source of the rse.
|
|
1593
|
+
type: string
|
|
1594
|
+
used:
|
|
1595
|
+
description: The number of used bytes.
|
|
1596
|
+
type: integer
|
|
1597
|
+
free:
|
|
1598
|
+
description: The number of free bytes.
|
|
1599
|
+
type: integer
|
|
1600
|
+
total:
|
|
1601
|
+
description: The number of total bytes.
|
|
1602
|
+
type: integer
|
|
1603
|
+
updated_at:
|
|
1604
|
+
description: The last time it got updated.
|
|
1605
|
+
type: string
|
|
1606
|
+
401:
|
|
1607
|
+
description: Invalid Auth Token
|
|
1608
|
+
404:
|
|
1609
|
+
description: Rse not found
|
|
1610
|
+
406:
|
|
1611
|
+
description: Not acceptable
|
|
1612
|
+
"""
|
|
1613
|
+
try:
|
|
1614
|
+
def generate(issuer, source, vo):
|
|
1615
|
+
for usage in list_rse_usage_history(rse=rse, issuer=issuer, source=source, vo=vo):
|
|
1616
|
+
yield render_json(**usage) + '\n'
|
|
1617
|
+
|
|
1618
|
+
return try_stream(generate(issuer=request.environ.get('issuer'), source=request.args.get('source'), vo=request.environ.get('vo')))
|
|
1619
|
+
except RSENotFound as error:
|
|
1620
|
+
return generate_http_error_flask(404, error)
|
|
1621
|
+
|
|
1622
|
+
|
|
1623
|
+
class Limits(ErrorHandlingMethodView):
|
|
1624
|
+
""" Create, Update, Read and delete RSE limits. """
|
|
1625
|
+
|
|
1626
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
1627
|
+
def get(self, rse):
|
|
1628
|
+
"""
|
|
1629
|
+
---
|
|
1630
|
+
summary: Get Rse Limits
|
|
1631
|
+
description: Get the rse limits.
|
|
1632
|
+
tags:
|
|
1633
|
+
- Rucio Storage Elements
|
|
1634
|
+
parameters:
|
|
1635
|
+
- name: rse
|
|
1636
|
+
in: path
|
|
1637
|
+
description: The name of the Rucio Storage Element name.
|
|
1638
|
+
schema:
|
|
1639
|
+
type: string
|
|
1640
|
+
style: simple
|
|
1641
|
+
responses:
|
|
1642
|
+
200:
|
|
1643
|
+
description: OK
|
|
1644
|
+
content:
|
|
1645
|
+
application/json:
|
|
1646
|
+
schema:
|
|
1647
|
+
description: The limits.
|
|
1648
|
+
type: object
|
|
1649
|
+
additionalProperties:
|
|
1650
|
+
x-additionalPropertiesName: limit name
|
|
1651
|
+
description: An item with the name as key and the value as value.
|
|
1652
|
+
type: integer
|
|
1653
|
+
401:
|
|
1654
|
+
description: Invalid Auth Token
|
|
1655
|
+
404:
|
|
1656
|
+
description: Rse not found
|
|
1657
|
+
406:
|
|
1658
|
+
description: Not acceptable
|
|
1659
|
+
"""
|
|
1660
|
+
try:
|
|
1661
|
+
limits = get_rse_limits(rse=rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
1662
|
+
return Response(render_json(**limits), content_type="application/json")
|
|
1663
|
+
except RSENotFound as error:
|
|
1664
|
+
return generate_http_error_flask(404, error)
|
|
1665
|
+
|
|
1666
|
+
def put(self, rse):
|
|
1667
|
+
"""
|
|
1668
|
+
---
|
|
1669
|
+
summary: Update Rse Limit
|
|
1670
|
+
description: Update an rse limit.
|
|
1671
|
+
tags:
|
|
1672
|
+
- Rucio Storage Elements
|
|
1673
|
+
parameters:
|
|
1674
|
+
- name: rse
|
|
1675
|
+
in: path
|
|
1676
|
+
description: The name of the Rucio Storage Element name.
|
|
1677
|
+
schema:
|
|
1678
|
+
type: string
|
|
1679
|
+
style: simple
|
|
1680
|
+
requestBody:
|
|
1681
|
+
content:
|
|
1682
|
+
application/json:
|
|
1683
|
+
schema:
|
|
1684
|
+
type: object
|
|
1685
|
+
properties:
|
|
1686
|
+
name:
|
|
1687
|
+
description: The name of the limit.
|
|
1688
|
+
type: string
|
|
1689
|
+
value:
|
|
1690
|
+
description: The value of the limit.
|
|
1691
|
+
type: integer
|
|
1692
|
+
responses:
|
|
1693
|
+
200:
|
|
1694
|
+
description: OK
|
|
1695
|
+
401:
|
|
1696
|
+
description: Invalid Auth Token
|
|
1697
|
+
404:
|
|
1698
|
+
description: Rse not found
|
|
1699
|
+
406:
|
|
1700
|
+
description: Not acceptable
|
|
1701
|
+
"""
|
|
1702
|
+
parameters = json_parameters()
|
|
1703
|
+
kwargs = {'name': None, 'value': None}
|
|
1704
|
+
for keyword in kwargs.keys():
|
|
1705
|
+
kwargs[keyword] = param_get(parameters, keyword, default=kwargs[keyword])
|
|
1706
|
+
|
|
1707
|
+
try:
|
|
1708
|
+
set_rse_limits(rse=rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'), **kwargs)
|
|
1709
|
+
except AccessDenied as error:
|
|
1710
|
+
return generate_http_error_flask(401, error)
|
|
1711
|
+
except RSENotFound as error:
|
|
1712
|
+
return generate_http_error_flask(404, error)
|
|
1713
|
+
|
|
1714
|
+
return '', 200
|
|
1715
|
+
|
|
1716
|
+
def delete(self, rse):
|
|
1717
|
+
"""
|
|
1718
|
+
---
|
|
1719
|
+
summary: Delete Rse Limit
|
|
1720
|
+
description: Delete an rse limit
|
|
1721
|
+
tags:
|
|
1722
|
+
- Rucio Storage Elements
|
|
1723
|
+
parameters:
|
|
1724
|
+
- name: rse
|
|
1725
|
+
in: path
|
|
1726
|
+
description: The name of the Rucio Storage Element name.
|
|
1727
|
+
schema:
|
|
1728
|
+
type: string
|
|
1729
|
+
style: simple
|
|
1730
|
+
requestBody:
|
|
1731
|
+
content:
|
|
1732
|
+
application/json:
|
|
1733
|
+
schema:
|
|
1734
|
+
type: object
|
|
1735
|
+
required:
|
|
1736
|
+
- name
|
|
1737
|
+
properties:
|
|
1738
|
+
name:
|
|
1739
|
+
description: The name of the limit.
|
|
1740
|
+
type: string
|
|
1741
|
+
responses:
|
|
1742
|
+
200:
|
|
1743
|
+
description: OK
|
|
1744
|
+
401:
|
|
1745
|
+
description: Invalid Auth Token
|
|
1746
|
+
404:
|
|
1747
|
+
description: Rse not found
|
|
1748
|
+
406:
|
|
1749
|
+
description: Not acceptable
|
|
1750
|
+
"""
|
|
1751
|
+
parameters = json_parameters()
|
|
1752
|
+
name = param_get(parameters, 'name')
|
|
1753
|
+
|
|
1754
|
+
try:
|
|
1755
|
+
delete_rse_limits(rse=rse, name=name, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
1756
|
+
except AccessDenied as error:
|
|
1757
|
+
return generate_http_error_flask(401, error)
|
|
1758
|
+
except RSENotFound as error:
|
|
1759
|
+
return generate_http_error_flask(404, error)
|
|
1760
|
+
|
|
1761
|
+
return '', 200
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
class RSEAccountUsageLimit(ErrorHandlingMethodView):
|
|
1765
|
+
""" Read and delete RSE limits for accounts. """
|
|
1766
|
+
|
|
1767
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
1768
|
+
def get(self, rse):
|
|
1769
|
+
"""
|
|
1770
|
+
---
|
|
1771
|
+
summary: Get Rse Account Usage and Limit
|
|
1772
|
+
description: Returns the usage and limit of an account for a rse.
|
|
1773
|
+
tags:
|
|
1774
|
+
- Rucio Storage Elements
|
|
1775
|
+
parameters:
|
|
1776
|
+
- name: rse
|
|
1777
|
+
in: path
|
|
1778
|
+
description: The name of the Rucio Storage Element name.
|
|
1779
|
+
schema:
|
|
1780
|
+
type: string
|
|
1781
|
+
style: simple
|
|
1782
|
+
responses:
|
|
1783
|
+
200:
|
|
1784
|
+
description: OK
|
|
1785
|
+
content:
|
|
1786
|
+
application/json:
|
|
1787
|
+
schema:
|
|
1788
|
+
description: A list with the rse account limits and usages.
|
|
1789
|
+
type: array
|
|
1790
|
+
items:
|
|
1791
|
+
type: object
|
|
1792
|
+
properties:
|
|
1793
|
+
rse_id:
|
|
1794
|
+
description: The id of the rse.
|
|
1795
|
+
type: string
|
|
1796
|
+
rse:
|
|
1797
|
+
description: The name of the rse.
|
|
1798
|
+
type: string
|
|
1799
|
+
account:
|
|
1800
|
+
description: The account.
|
|
1801
|
+
type: string
|
|
1802
|
+
used_files:
|
|
1803
|
+
description: The number of used files.
|
|
1804
|
+
type: integer
|
|
1805
|
+
used_bytes:
|
|
1806
|
+
description: The number of used bytes.
|
|
1807
|
+
type: integer
|
|
1808
|
+
quota_bytes:
|
|
1809
|
+
description: The number of quota bytes.
|
|
1810
|
+
type: integer
|
|
1811
|
+
401:
|
|
1812
|
+
description: Invalid Auth Token
|
|
1813
|
+
404:
|
|
1814
|
+
description: Rse not found
|
|
1815
|
+
406:
|
|
1816
|
+
description: Not acceptable
|
|
1817
|
+
"""
|
|
1818
|
+
try:
|
|
1819
|
+
def generate(vo):
|
|
1820
|
+
for usage in get_rse_account_usage(rse=rse, vo=vo):
|
|
1821
|
+
yield render_json(**usage) + '\n'
|
|
1822
|
+
|
|
1823
|
+
return try_stream(generate(vo=request.environ.get('vo')), content_type='application/json')
|
|
1824
|
+
except RSENotFound as error:
|
|
1825
|
+
return generate_http_error_flask(404, error)
|
|
1826
|
+
|
|
1827
|
+
|
|
1828
|
+
class Distance(ErrorHandlingMethodView):
|
|
1829
|
+
""" Create/Update and read distances between RSEs. """
|
|
1830
|
+
|
|
1831
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
1832
|
+
def get(self, source, destination):
|
|
1833
|
+
"""
|
|
1834
|
+
---
|
|
1835
|
+
summary: Get Rse Distances
|
|
1836
|
+
description: Returns the distances between a source and destination rse.
|
|
1837
|
+
tags:
|
|
1838
|
+
- Rucio Storage Elements
|
|
1839
|
+
parameters:
|
|
1840
|
+
- name: source
|
|
1841
|
+
in: path
|
|
1842
|
+
description: The name of the source Rucio Storage Element.
|
|
1843
|
+
schema:
|
|
1844
|
+
type: string
|
|
1845
|
+
style: simple
|
|
1846
|
+
- name: destination
|
|
1847
|
+
in: path
|
|
1848
|
+
description: The name of the destination Rucio Storage Element.
|
|
1849
|
+
schema:
|
|
1850
|
+
type: string
|
|
1851
|
+
style: simple
|
|
1852
|
+
responses:
|
|
1853
|
+
200:
|
|
1854
|
+
description: OK
|
|
1855
|
+
content:
|
|
1856
|
+
application/json:
|
|
1857
|
+
schema:
|
|
1858
|
+
description: The distances between the Rses.
|
|
1859
|
+
type: array
|
|
1860
|
+
items:
|
|
1861
|
+
type: object
|
|
1862
|
+
description: One distance between source and destination.
|
|
1863
|
+
properties:
|
|
1864
|
+
src_rse_id:
|
|
1865
|
+
description: The source rse id.
|
|
1866
|
+
type: string
|
|
1867
|
+
dest_rse_id:
|
|
1868
|
+
description: The destination rse id.
|
|
1869
|
+
type: string
|
|
1870
|
+
distance:
|
|
1871
|
+
description: The distance between RSEs.
|
|
1872
|
+
type: integer
|
|
1873
|
+
ranking:
|
|
1874
|
+
deprecated: true
|
|
1875
|
+
description: Same as distance.
|
|
1876
|
+
type: integer
|
|
1877
|
+
401:
|
|
1878
|
+
description: Invalid Auth Token
|
|
1879
|
+
404:
|
|
1880
|
+
description: Rse not found
|
|
1881
|
+
406:
|
|
1882
|
+
description: Not acceptable
|
|
1883
|
+
"""
|
|
1884
|
+
try:
|
|
1885
|
+
distance = get_distance(source=source, destination=destination, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
1886
|
+
return Response(dumps(distance, cls=APIEncoder), content_type="application/json")
|
|
1887
|
+
except RSENotFound as error:
|
|
1888
|
+
return generate_http_error_flask(404, error)
|
|
1889
|
+
|
|
1890
|
+
def post(self, source, destination):
|
|
1891
|
+
"""
|
|
1892
|
+
---
|
|
1893
|
+
summary: Create Rse Distance
|
|
1894
|
+
description: Post a rse distance.
|
|
1895
|
+
tags:
|
|
1896
|
+
- Rucio Storage Elements
|
|
1897
|
+
parameters:
|
|
1898
|
+
- name: source
|
|
1899
|
+
in: path
|
|
1900
|
+
description: The name of the source Rucio Storage Element.
|
|
1901
|
+
schema:
|
|
1902
|
+
type: string
|
|
1903
|
+
style: simple
|
|
1904
|
+
- name: destination
|
|
1905
|
+
in: path
|
|
1906
|
+
description: The name of the destination Rucio Storage Element.
|
|
1907
|
+
schema:
|
|
1908
|
+
type: string
|
|
1909
|
+
style: simple
|
|
1910
|
+
requestBody:
|
|
1911
|
+
content:
|
|
1912
|
+
application/json:
|
|
1913
|
+
schema:
|
|
1914
|
+
type: object
|
|
1915
|
+
properties:
|
|
1916
|
+
distance:
|
|
1917
|
+
description: The distance between RSEs.
|
|
1918
|
+
type: integer
|
|
1919
|
+
ranking:
|
|
1920
|
+
deprecated: true
|
|
1921
|
+
description: Same as distance.
|
|
1922
|
+
type: integer
|
|
1923
|
+
responses:
|
|
1924
|
+
201:
|
|
1925
|
+
description: OK
|
|
1926
|
+
content:
|
|
1927
|
+
application/json:
|
|
1928
|
+
schema:
|
|
1929
|
+
type: string
|
|
1930
|
+
enum: ["Created"]
|
|
1931
|
+
401:
|
|
1932
|
+
description: Invalid Auth Token
|
|
1933
|
+
404:
|
|
1934
|
+
description: Rse not found
|
|
1935
|
+
406:
|
|
1936
|
+
description: Not acceptable
|
|
1937
|
+
"""
|
|
1938
|
+
parameters = json_parameters()
|
|
1939
|
+
|
|
1940
|
+
distance = param_get(parameters, 'distance', default=None)
|
|
1941
|
+
if distance is None:
|
|
1942
|
+
distance = param_get(parameters, 'ranking', default=None)
|
|
1943
|
+
|
|
1944
|
+
try:
|
|
1945
|
+
add_distance(
|
|
1946
|
+
source=source,
|
|
1947
|
+
destination=destination,
|
|
1948
|
+
distance=distance,
|
|
1949
|
+
issuer=request.environ.get('issuer'),
|
|
1950
|
+
vo=request.environ.get('vo'),
|
|
1951
|
+
)
|
|
1952
|
+
except AccessDenied as error:
|
|
1953
|
+
return generate_http_error_flask(401, error)
|
|
1954
|
+
except RSENotFound as error:
|
|
1955
|
+
return generate_http_error_flask(404, error)
|
|
1956
|
+
except Duplicate as error:
|
|
1957
|
+
return generate_http_error_flask(409, error)
|
|
1958
|
+
|
|
1959
|
+
return 'Created', 201
|
|
1960
|
+
|
|
1961
|
+
def put(self, source, destination):
|
|
1962
|
+
"""
|
|
1963
|
+
---
|
|
1964
|
+
summary: Update Rse Distance
|
|
1965
|
+
description: Update rse distance information.
|
|
1966
|
+
tags:
|
|
1967
|
+
- Rucio Storage Elements
|
|
1968
|
+
parameters:
|
|
1969
|
+
- name: source
|
|
1970
|
+
in: path
|
|
1971
|
+
description: The name of the source Rucio Storage Element.
|
|
1972
|
+
schema:
|
|
1973
|
+
type: string
|
|
1974
|
+
style: simple
|
|
1975
|
+
- name: destination
|
|
1976
|
+
in: path
|
|
1977
|
+
description: The name of the destination Rucio Storage Element.
|
|
1978
|
+
schema:
|
|
1979
|
+
type: string
|
|
1980
|
+
style: simple
|
|
1981
|
+
requestBody:
|
|
1982
|
+
content:
|
|
1983
|
+
application/json:
|
|
1984
|
+
schema:
|
|
1985
|
+
type: object
|
|
1986
|
+
properties:
|
|
1987
|
+
distance:
|
|
1988
|
+
description: The distance between the RSEs.
|
|
1989
|
+
type: integer
|
|
1990
|
+
ranking:
|
|
1991
|
+
deprecated: true
|
|
1992
|
+
description: Same as distance.
|
|
1993
|
+
type: integer
|
|
1994
|
+
responses:
|
|
1995
|
+
201:
|
|
1996
|
+
description: OK
|
|
1997
|
+
content:
|
|
1998
|
+
application/json:
|
|
1999
|
+
schema:
|
|
2000
|
+
type: string
|
|
2001
|
+
enum: ["Created"]
|
|
2002
|
+
401:
|
|
2003
|
+
description: Invalid Auth Token
|
|
2004
|
+
404:
|
|
2005
|
+
description: Rse not found
|
|
2006
|
+
406:
|
|
2007
|
+
description: Not acceptable
|
|
2008
|
+
"""
|
|
2009
|
+
parameters = json_parameters()
|
|
2010
|
+
|
|
2011
|
+
distance = param_get(parameters, 'distance', default=None)
|
|
2012
|
+
if distance is None:
|
|
2013
|
+
distance = param_get(parameters, 'ranking', default=None)
|
|
2014
|
+
|
|
2015
|
+
try:
|
|
2016
|
+
update_distance(
|
|
2017
|
+
source=source,
|
|
2018
|
+
destination=destination,
|
|
2019
|
+
distance=distance,
|
|
2020
|
+
issuer=request.environ.get('issuer'),
|
|
2021
|
+
vo=request.environ.get('vo'),
|
|
2022
|
+
)
|
|
2023
|
+
except AccessDenied as error:
|
|
2024
|
+
return generate_http_error_flask(401, error)
|
|
2025
|
+
except RSENotFound as error:
|
|
2026
|
+
return generate_http_error_flask(404, error)
|
|
2027
|
+
|
|
2028
|
+
return '', 200
|
|
2029
|
+
|
|
2030
|
+
def delete(self, source, destination):
|
|
2031
|
+
"""
|
|
2032
|
+
---
|
|
2033
|
+
summary: Delete Rse Distance
|
|
2034
|
+
description: Delete distance information between source RSE and destination RSE.
|
|
2035
|
+
tags:
|
|
2036
|
+
- Rucio Storage Elements
|
|
2037
|
+
parameters:
|
|
2038
|
+
- name: source
|
|
2039
|
+
in: path
|
|
2040
|
+
description: The name of the source Rucio Storage Element.
|
|
2041
|
+
schema:
|
|
2042
|
+
type: string
|
|
2043
|
+
style: simple
|
|
2044
|
+
- name: destination
|
|
2045
|
+
in: path
|
|
2046
|
+
description: The name of the destination Rucio Storage Element.
|
|
2047
|
+
schema:
|
|
2048
|
+
type: string
|
|
2049
|
+
style: simple
|
|
2050
|
+
responses:
|
|
2051
|
+
200:
|
|
2052
|
+
description: OK
|
|
2053
|
+
content:
|
|
2054
|
+
application/json:
|
|
2055
|
+
schema:
|
|
2056
|
+
type: string
|
|
2057
|
+
enum: ["Deleted"]
|
|
2058
|
+
401:
|
|
2059
|
+
description: Invalid Auth Token
|
|
2060
|
+
404:
|
|
2061
|
+
description: Rse not found
|
|
2062
|
+
406:
|
|
2063
|
+
description: Not acceptable
|
|
2064
|
+
"""
|
|
2065
|
+
try:
|
|
2066
|
+
delete_distance(
|
|
2067
|
+
source=source,
|
|
2068
|
+
destination=destination,
|
|
2069
|
+
issuer=request.environ.get('issuer'),
|
|
2070
|
+
vo=request.environ.get('vo')
|
|
2071
|
+
)
|
|
2072
|
+
except AccessDenied as error:
|
|
2073
|
+
return generate_http_error_flask(401, error)
|
|
2074
|
+
except RSENotFound as error:
|
|
2075
|
+
return generate_http_error_flask(404, error)
|
|
2076
|
+
|
|
2077
|
+
return 'Deleted', 200
|
|
2078
|
+
|
|
2079
|
+
|
|
2080
|
+
class QoSPolicy(ErrorHandlingMethodView):
|
|
2081
|
+
""" Add/Delete/List QoS policies on an RSE. """
|
|
2082
|
+
|
|
2083
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
2084
|
+
def post(self, rse, policy):
|
|
2085
|
+
"""
|
|
2086
|
+
---
|
|
2087
|
+
summary: Add QoS policy
|
|
2088
|
+
description: Add a QoS Policy to a RSE.
|
|
2089
|
+
tags:
|
|
2090
|
+
- Rucio Storage Elements
|
|
2091
|
+
parameters:
|
|
2092
|
+
- name: rse
|
|
2093
|
+
in: path
|
|
2094
|
+
description: The name of the Rucio Storage Element name.
|
|
2095
|
+
schema:
|
|
2096
|
+
type: string
|
|
2097
|
+
style: simple
|
|
2098
|
+
- name: policy
|
|
2099
|
+
in: path
|
|
2100
|
+
description: The QoS policy to add to and rse.
|
|
2101
|
+
schema:
|
|
2102
|
+
type: string
|
|
2103
|
+
style: simple
|
|
2104
|
+
responses:
|
|
2105
|
+
201:
|
|
2106
|
+
description: OK
|
|
2107
|
+
content:
|
|
2108
|
+
application/json:
|
|
2109
|
+
schema:
|
|
2110
|
+
type: string
|
|
2111
|
+
enum: ["Created"]
|
|
2112
|
+
401:
|
|
2113
|
+
description: Invalid Auth Token
|
|
2114
|
+
404:
|
|
2115
|
+
description: Rse not found
|
|
2116
|
+
406:
|
|
2117
|
+
description: Not acceptable
|
|
2118
|
+
"""
|
|
2119
|
+
try:
|
|
2120
|
+
add_qos_policy(rse=rse, qos_policy=policy, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
2121
|
+
except RSENotFound as error:
|
|
2122
|
+
return generate_http_error_flask(404, error)
|
|
2123
|
+
|
|
2124
|
+
return 'Created', 201
|
|
2125
|
+
|
|
2126
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
2127
|
+
def delete(self, rse, policy):
|
|
2128
|
+
"""
|
|
2129
|
+
---
|
|
2130
|
+
summary: Delete QoS Policy
|
|
2131
|
+
description: Delete QoS policy from RSE.
|
|
2132
|
+
tags:
|
|
2133
|
+
- Rucio Storage Elements
|
|
2134
|
+
parameters:
|
|
2135
|
+
- name: rse
|
|
2136
|
+
in: path
|
|
2137
|
+
description: The name of the Rucio Storage Element name.
|
|
2138
|
+
schema:
|
|
2139
|
+
type: string
|
|
2140
|
+
style: simple
|
|
2141
|
+
- name: policy
|
|
2142
|
+
in: path
|
|
2143
|
+
description: The QoS policy to add to and rse.
|
|
2144
|
+
schema:
|
|
2145
|
+
type: string
|
|
2146
|
+
style: simple
|
|
2147
|
+
responses:
|
|
2148
|
+
200:
|
|
2149
|
+
description: OK
|
|
2150
|
+
401:
|
|
2151
|
+
description: Invalid Auth Token
|
|
2152
|
+
404:
|
|
2153
|
+
description: Rse not found
|
|
2154
|
+
406:
|
|
2155
|
+
description: Not acceptable
|
|
2156
|
+
"""
|
|
2157
|
+
try:
|
|
2158
|
+
delete_qos_policy(rse=rse, qos_policy=policy, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
2159
|
+
except RSENotFound as error:
|
|
2160
|
+
return generate_http_error_flask(404, error)
|
|
2161
|
+
|
|
2162
|
+
return '', 200
|
|
2163
|
+
|
|
2164
|
+
@check_accept_header_wrapper_flask(['application/json'])
|
|
2165
|
+
def get(self, rse):
|
|
2166
|
+
"""
|
|
2167
|
+
---
|
|
2168
|
+
summary: Gett QoS Policies
|
|
2169
|
+
description: List all QoS policies for an Rse.
|
|
2170
|
+
tags:
|
|
2171
|
+
- Rucio Storage Elements
|
|
2172
|
+
parameters:
|
|
2173
|
+
- name: rse
|
|
2174
|
+
in: path
|
|
2175
|
+
description: The name of the Rucio Storage Element name.
|
|
2176
|
+
schema:
|
|
2177
|
+
type: string
|
|
2178
|
+
style: simple
|
|
2179
|
+
responses:
|
|
2180
|
+
200:
|
|
2181
|
+
description: OK
|
|
2182
|
+
content:
|
|
2183
|
+
application/json:
|
|
2184
|
+
schema:
|
|
2185
|
+
description: A list with all the QoS policies for an Rse.
|
|
2186
|
+
type: array
|
|
2187
|
+
items:
|
|
2188
|
+
type: object
|
|
2189
|
+
properties:
|
|
2190
|
+
rse_id:
|
|
2191
|
+
description: The rse id.
|
|
2192
|
+
type: string
|
|
2193
|
+
qos_policy:
|
|
2194
|
+
description: The qos policy.
|
|
2195
|
+
type: string
|
|
2196
|
+
401:
|
|
2197
|
+
description: Invalid Auth Token
|
|
2198
|
+
404:
|
|
2199
|
+
description: Rse not found
|
|
2200
|
+
406:
|
|
2201
|
+
description: Not acceptable
|
|
2202
|
+
"""
|
|
2203
|
+
try:
|
|
2204
|
+
qos_policies = list_qos_policies(rse=rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
2205
|
+
return Response(dumps(qos_policies, cls=APIEncoder), content_type='application/json')
|
|
2206
|
+
except RSENotFound as error:
|
|
2207
|
+
return generate_http_error_flask(404, error)
|
|
2208
|
+
|
|
2209
|
+
|
|
2210
|
+
def blueprint():
|
|
2211
|
+
bp = AuthenticatedBlueprint('rses', __name__, url_prefix='/rses')
|
|
2212
|
+
|
|
2213
|
+
attributes_view = Attributes.as_view('attributes')
|
|
2214
|
+
bp.add_url_rule('/<rse>/attr/<key>', view_func=attributes_view, methods=['post', 'delete'])
|
|
2215
|
+
bp.add_url_rule('/<rse>/attr/', view_func=attributes_view, methods=['get', ])
|
|
2216
|
+
distance_view = Distance.as_view('distance')
|
|
2217
|
+
bp.add_url_rule('/<source>/distances/<destination>', view_func=distance_view, methods=['get', 'post', 'put', 'delete'])
|
|
2218
|
+
protocol_view = Protocol.as_view('protocol')
|
|
2219
|
+
bp.add_url_rule('/<rse>/protocols/<scheme>/<hostname>/<port>', view_func=protocol_view, methods=['delete', 'put'])
|
|
2220
|
+
bp.add_url_rule('/<rse>/protocols/<scheme>/<hostname>', view_func=protocol_view, methods=['delete', 'put'])
|
|
2221
|
+
bp.add_url_rule('/<rse>/protocols/<scheme>', view_func=protocol_view, methods=['get', 'post', 'delete', 'put'])
|
|
2222
|
+
protocol_list_view = ProtocolList.as_view('protocol_list')
|
|
2223
|
+
bp.add_url_rule('/<rse>/protocols', view_func=protocol_list_view, methods=['get', ])
|
|
2224
|
+
lfns2pfns_view = LFNS2PFNS.as_view('lfns2pfns')
|
|
2225
|
+
bp.add_url_rule('/<rse>/lfns2pfns', view_func=lfns2pfns_view, methods=['get', ])
|
|
2226
|
+
rse_account_usage_limit_view = RSEAccountUsageLimit.as_view('rse_account_usage_limit')
|
|
2227
|
+
bp.add_url_rule('/<rse>/accounts/usage', view_func=rse_account_usage_limit_view, methods=['get', ])
|
|
2228
|
+
usage_view = Usage.as_view('usage')
|
|
2229
|
+
bp.add_url_rule('/<rse>/usage', view_func=usage_view, methods=['get', 'put'])
|
|
2230
|
+
usage_history_view = UsageHistory.as_view('usage_history')
|
|
2231
|
+
bp.add_url_rule('/<rse>/usage/history', view_func=usage_history_view, methods=['get', ])
|
|
2232
|
+
limits_view = Limits.as_view('limits')
|
|
2233
|
+
bp.add_url_rule('/<rse>/limits', view_func=limits_view, methods=['get', 'put', 'delete'])
|
|
2234
|
+
qos_policy_view = QoSPolicy.as_view('qos_policy')
|
|
2235
|
+
bp.add_url_rule('/<rse>/qos_policy', view_func=qos_policy_view, methods=['get', ])
|
|
2236
|
+
bp.add_url_rule('/<rse>/qos_policy/<policy>', view_func=qos_policy_view, methods=['post', 'delete'])
|
|
2237
|
+
rse_view = RSE.as_view('rse')
|
|
2238
|
+
bp.add_url_rule('/<rse>', view_func=rse_view, methods=['get', 'delete', 'put', 'post'])
|
|
2239
|
+
rses_view = RSEs.as_view('rses')
|
|
2240
|
+
bp.add_url_rule('/', view_func=rses_view, methods=['get', ])
|
|
2241
|
+
|
|
2242
|
+
bp.after_request(response_headers)
|
|
2243
|
+
return bp
|
|
2244
|
+
|
|
2245
|
+
|
|
2246
|
+
def make_doc():
|
|
2247
|
+
""" Only used for sphinx documentation """
|
|
2248
|
+
doc_app = Flask(__name__)
|
|
2249
|
+
doc_app.register_blueprint(blueprint())
|
|
2250
|
+
return doc_app
|