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.

Files changed (487) hide show
  1. rucio/__init__.py +17 -0
  2. rucio/alembicrevision.py +15 -0
  3. rucio/cli/__init__.py +14 -0
  4. rucio/cli/account.py +216 -0
  5. rucio/cli/bin_legacy/__init__.py +13 -0
  6. rucio/cli/bin_legacy/rucio.py +2825 -0
  7. rucio/cli/bin_legacy/rucio_admin.py +2500 -0
  8. rucio/cli/command.py +272 -0
  9. rucio/cli/config.py +72 -0
  10. rucio/cli/did.py +191 -0
  11. rucio/cli/download.py +128 -0
  12. rucio/cli/lifetime_exception.py +33 -0
  13. rucio/cli/replica.py +162 -0
  14. rucio/cli/rse.py +293 -0
  15. rucio/cli/rule.py +158 -0
  16. rucio/cli/scope.py +40 -0
  17. rucio/cli/subscription.py +73 -0
  18. rucio/cli/upload.py +60 -0
  19. rucio/cli/utils.py +226 -0
  20. rucio/client/__init__.py +15 -0
  21. rucio/client/accountclient.py +432 -0
  22. rucio/client/accountlimitclient.py +183 -0
  23. rucio/client/baseclient.py +983 -0
  24. rucio/client/client.py +120 -0
  25. rucio/client/configclient.py +126 -0
  26. rucio/client/credentialclient.py +59 -0
  27. rucio/client/didclient.py +868 -0
  28. rucio/client/diracclient.py +56 -0
  29. rucio/client/downloadclient.py +1783 -0
  30. rucio/client/exportclient.py +44 -0
  31. rucio/client/fileclient.py +50 -0
  32. rucio/client/importclient.py +42 -0
  33. rucio/client/lifetimeclient.py +90 -0
  34. rucio/client/lockclient.py +109 -0
  35. rucio/client/metaconventionsclient.py +140 -0
  36. rucio/client/pingclient.py +44 -0
  37. rucio/client/replicaclient.py +452 -0
  38. rucio/client/requestclient.py +125 -0
  39. rucio/client/richclient.py +317 -0
  40. rucio/client/rseclient.py +746 -0
  41. rucio/client/ruleclient.py +294 -0
  42. rucio/client/scopeclient.py +90 -0
  43. rucio/client/subscriptionclient.py +173 -0
  44. rucio/client/touchclient.py +82 -0
  45. rucio/client/uploadclient.py +969 -0
  46. rucio/common/__init__.py +13 -0
  47. rucio/common/bittorrent.py +234 -0
  48. rucio/common/cache.py +111 -0
  49. rucio/common/checksum.py +168 -0
  50. rucio/common/client.py +122 -0
  51. rucio/common/config.py +788 -0
  52. rucio/common/constants.py +217 -0
  53. rucio/common/constraints.py +17 -0
  54. rucio/common/didtype.py +237 -0
  55. rucio/common/dumper/__init__.py +342 -0
  56. rucio/common/dumper/consistency.py +497 -0
  57. rucio/common/dumper/data_models.py +362 -0
  58. rucio/common/dumper/path_parsing.py +75 -0
  59. rucio/common/exception.py +1208 -0
  60. rucio/common/extra.py +31 -0
  61. rucio/common/logging.py +420 -0
  62. rucio/common/pcache.py +1409 -0
  63. rucio/common/plugins.py +185 -0
  64. rucio/common/policy.py +93 -0
  65. rucio/common/schema/__init__.py +200 -0
  66. rucio/common/schema/generic.py +416 -0
  67. rucio/common/schema/generic_multi_vo.py +395 -0
  68. rucio/common/stomp_utils.py +423 -0
  69. rucio/common/stopwatch.py +55 -0
  70. rucio/common/test_rucio_server.py +154 -0
  71. rucio/common/types.py +483 -0
  72. rucio/common/utils.py +1688 -0
  73. rucio/core/__init__.py +13 -0
  74. rucio/core/account.py +496 -0
  75. rucio/core/account_counter.py +236 -0
  76. rucio/core/account_limit.py +425 -0
  77. rucio/core/authentication.py +620 -0
  78. rucio/core/config.py +437 -0
  79. rucio/core/credential.py +224 -0
  80. rucio/core/did.py +3004 -0
  81. rucio/core/did_meta_plugins/__init__.py +252 -0
  82. rucio/core/did_meta_plugins/did_column_meta.py +331 -0
  83. rucio/core/did_meta_plugins/did_meta_plugin_interface.py +165 -0
  84. rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
  85. rucio/core/did_meta_plugins/filter_engine.py +672 -0
  86. rucio/core/did_meta_plugins/json_meta.py +240 -0
  87. rucio/core/did_meta_plugins/mongo_meta.py +229 -0
  88. rucio/core/did_meta_plugins/postgres_meta.py +352 -0
  89. rucio/core/dirac.py +237 -0
  90. rucio/core/distance.py +187 -0
  91. rucio/core/exporter.py +59 -0
  92. rucio/core/heartbeat.py +363 -0
  93. rucio/core/identity.py +301 -0
  94. rucio/core/importer.py +260 -0
  95. rucio/core/lifetime_exception.py +377 -0
  96. rucio/core/lock.py +577 -0
  97. rucio/core/message.py +288 -0
  98. rucio/core/meta_conventions.py +203 -0
  99. rucio/core/monitor.py +448 -0
  100. rucio/core/naming_convention.py +195 -0
  101. rucio/core/nongrid_trace.py +136 -0
  102. rucio/core/oidc.py +1463 -0
  103. rucio/core/permission/__init__.py +161 -0
  104. rucio/core/permission/generic.py +1124 -0
  105. rucio/core/permission/generic_multi_vo.py +1144 -0
  106. rucio/core/quarantined_replica.py +224 -0
  107. rucio/core/replica.py +4483 -0
  108. rucio/core/replica_sorter.py +362 -0
  109. rucio/core/request.py +3091 -0
  110. rucio/core/rse.py +2079 -0
  111. rucio/core/rse_counter.py +185 -0
  112. rucio/core/rse_expression_parser.py +459 -0
  113. rucio/core/rse_selector.py +304 -0
  114. rucio/core/rule.py +4484 -0
  115. rucio/core/rule_grouping.py +1620 -0
  116. rucio/core/scope.py +181 -0
  117. rucio/core/subscription.py +362 -0
  118. rucio/core/topology.py +490 -0
  119. rucio/core/trace.py +375 -0
  120. rucio/core/transfer.py +1531 -0
  121. rucio/core/vo.py +169 -0
  122. rucio/core/volatile_replica.py +151 -0
  123. rucio/daemons/__init__.py +13 -0
  124. rucio/daemons/abacus/__init__.py +13 -0
  125. rucio/daemons/abacus/account.py +116 -0
  126. rucio/daemons/abacus/collection_replica.py +124 -0
  127. rucio/daemons/abacus/rse.py +117 -0
  128. rucio/daemons/atropos/__init__.py +13 -0
  129. rucio/daemons/atropos/atropos.py +242 -0
  130. rucio/daemons/auditor/__init__.py +289 -0
  131. rucio/daemons/auditor/hdfs.py +97 -0
  132. rucio/daemons/auditor/srmdumps.py +355 -0
  133. rucio/daemons/automatix/__init__.py +13 -0
  134. rucio/daemons/automatix/automatix.py +304 -0
  135. rucio/daemons/badreplicas/__init__.py +13 -0
  136. rucio/daemons/badreplicas/minos.py +322 -0
  137. rucio/daemons/badreplicas/minos_temporary_expiration.py +171 -0
  138. rucio/daemons/badreplicas/necromancer.py +196 -0
  139. rucio/daemons/bb8/__init__.py +13 -0
  140. rucio/daemons/bb8/bb8.py +353 -0
  141. rucio/daemons/bb8/common.py +759 -0
  142. rucio/daemons/bb8/nuclei_background_rebalance.py +153 -0
  143. rucio/daemons/bb8/t2_background_rebalance.py +153 -0
  144. rucio/daemons/cache/__init__.py +13 -0
  145. rucio/daemons/cache/consumer.py +133 -0
  146. rucio/daemons/common.py +405 -0
  147. rucio/daemons/conveyor/__init__.py +13 -0
  148. rucio/daemons/conveyor/common.py +562 -0
  149. rucio/daemons/conveyor/finisher.py +529 -0
  150. rucio/daemons/conveyor/poller.py +394 -0
  151. rucio/daemons/conveyor/preparer.py +205 -0
  152. rucio/daemons/conveyor/receiver.py +179 -0
  153. rucio/daemons/conveyor/stager.py +133 -0
  154. rucio/daemons/conveyor/submitter.py +403 -0
  155. rucio/daemons/conveyor/throttler.py +532 -0
  156. rucio/daemons/follower/__init__.py +13 -0
  157. rucio/daemons/follower/follower.py +101 -0
  158. rucio/daemons/hermes/__init__.py +13 -0
  159. rucio/daemons/hermes/hermes.py +534 -0
  160. rucio/daemons/judge/__init__.py +13 -0
  161. rucio/daemons/judge/cleaner.py +159 -0
  162. rucio/daemons/judge/evaluator.py +185 -0
  163. rucio/daemons/judge/injector.py +162 -0
  164. rucio/daemons/judge/repairer.py +154 -0
  165. rucio/daemons/oauthmanager/__init__.py +13 -0
  166. rucio/daemons/oauthmanager/oauthmanager.py +198 -0
  167. rucio/daemons/reaper/__init__.py +13 -0
  168. rucio/daemons/reaper/dark_reaper.py +282 -0
  169. rucio/daemons/reaper/reaper.py +739 -0
  170. rucio/daemons/replicarecoverer/__init__.py +13 -0
  171. rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +626 -0
  172. rucio/daemons/rsedecommissioner/__init__.py +13 -0
  173. rucio/daemons/rsedecommissioner/config.py +81 -0
  174. rucio/daemons/rsedecommissioner/profiles/__init__.py +24 -0
  175. rucio/daemons/rsedecommissioner/profiles/atlas.py +60 -0
  176. rucio/daemons/rsedecommissioner/profiles/generic.py +452 -0
  177. rucio/daemons/rsedecommissioner/profiles/types.py +93 -0
  178. rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
  179. rucio/daemons/storage/__init__.py +13 -0
  180. rucio/daemons/storage/consistency/__init__.py +13 -0
  181. rucio/daemons/storage/consistency/actions.py +848 -0
  182. rucio/daemons/tracer/__init__.py +13 -0
  183. rucio/daemons/tracer/kronos.py +511 -0
  184. rucio/daemons/transmogrifier/__init__.py +13 -0
  185. rucio/daemons/transmogrifier/transmogrifier.py +762 -0
  186. rucio/daemons/undertaker/__init__.py +13 -0
  187. rucio/daemons/undertaker/undertaker.py +137 -0
  188. rucio/db/__init__.py +13 -0
  189. rucio/db/sqla/__init__.py +52 -0
  190. rucio/db/sqla/constants.py +206 -0
  191. rucio/db/sqla/migrate_repo/__init__.py +13 -0
  192. rucio/db/sqla/migrate_repo/env.py +110 -0
  193. rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +70 -0
  194. rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +47 -0
  195. rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +59 -0
  196. rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +43 -0
  197. rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +91 -0
  198. rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +76 -0
  199. rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +43 -0
  200. rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +50 -0
  201. rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +68 -0
  202. rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +40 -0
  203. rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +45 -0
  204. rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +60 -0
  205. rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +40 -0
  206. rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +140 -0
  207. rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +73 -0
  208. rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +74 -0
  209. rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +43 -0
  210. rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +50 -0
  211. rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +134 -0
  212. rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +64 -0
  213. rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +39 -0
  214. rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +64 -0
  215. rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +51 -0
  216. rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +41 -0
  217. rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +43 -0
  218. rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +44 -0
  219. rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +53 -0
  220. rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +38 -0
  221. rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +47 -0
  222. rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +45 -0
  223. rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +45 -0
  224. rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +57 -0
  225. rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +45 -0
  226. rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +69 -0
  227. rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +43 -0
  228. rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +42 -0
  229. rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +47 -0
  230. rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +46 -0
  231. rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +40 -0
  232. rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +67 -0
  233. rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
  234. rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +44 -0
  235. rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +77 -0
  236. rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +60 -0
  237. rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +72 -0
  238. rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +42 -0
  239. rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +65 -0
  240. rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +133 -0
  241. rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +55 -0
  242. rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +76 -0
  243. rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +60 -0
  244. rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +44 -0
  245. rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +43 -0
  246. rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +64 -0
  247. rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +40 -0
  248. rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +43 -0
  249. rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +44 -0
  250. rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +78 -0
  251. rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +41 -0
  252. rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +59 -0
  253. rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +44 -0
  254. rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +43 -0
  255. rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +49 -0
  256. rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +40 -0
  257. rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +63 -0
  258. rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +43 -0
  259. rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +55 -0
  260. rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +45 -0
  261. rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +43 -0
  262. rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +43 -0
  263. rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +45 -0
  264. rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +47 -0
  265. rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +58 -0
  266. rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +45 -0
  267. rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +106 -0
  268. rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +55 -0
  269. rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +50 -0
  270. rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +47 -0
  271. rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +43 -0
  272. rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +41 -0
  273. rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +91 -0
  274. rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +72 -0
  275. rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +49 -0
  276. rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +43 -0
  277. rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +43 -0
  278. rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +53 -0
  279. rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +45 -0
  280. rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +68 -0
  281. rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +45 -0
  282. rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +94 -0
  283. rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +54 -0
  284. rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +72 -0
  285. rucio/db/sqla/migrate_repo/versions/a08fa8de1545_transfer_stats_table.py +55 -0
  286. rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +76 -0
  287. rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +47 -0
  288. rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +121 -0
  289. rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +59 -0
  290. rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +52 -0
  291. rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +54 -0
  292. rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +64 -0
  293. rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +49 -0
  294. rucio/db/sqla/migrate_repo/versions/b0070f3695c8_add_deletedidmeta_table.py +57 -0
  295. rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +43 -0
  296. rucio/db/sqla/migrate_repo/versions/b5493606bbf5_fix_primary_key_for_subscription_history.py +41 -0
  297. rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +91 -0
  298. rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +40 -0
  299. rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +43 -0
  300. rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +143 -0
  301. rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +76 -0
  302. rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +50 -0
  303. rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +72 -0
  304. rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +55 -0
  305. rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +43 -0
  306. rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +65 -0
  307. rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +47 -0
  308. rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +146 -0
  309. rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +104 -0
  310. rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +44 -0
  311. rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +43 -0
  312. rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +103 -0
  313. rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +49 -0
  314. rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +104 -0
  315. rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +29 -0
  316. rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +74 -0
  317. rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +47 -0
  318. rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +43 -0
  319. rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +37 -0
  320. rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +43 -0
  321. rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +43 -0
  322. rucio/db/sqla/models.py +1743 -0
  323. rucio/db/sqla/sautils.py +55 -0
  324. rucio/db/sqla/session.py +529 -0
  325. rucio/db/sqla/types.py +206 -0
  326. rucio/db/sqla/util.py +543 -0
  327. rucio/gateway/__init__.py +13 -0
  328. rucio/gateway/account.py +345 -0
  329. rucio/gateway/account_limit.py +363 -0
  330. rucio/gateway/authentication.py +381 -0
  331. rucio/gateway/config.py +227 -0
  332. rucio/gateway/credential.py +70 -0
  333. rucio/gateway/did.py +987 -0
  334. rucio/gateway/dirac.py +83 -0
  335. rucio/gateway/exporter.py +60 -0
  336. rucio/gateway/heartbeat.py +76 -0
  337. rucio/gateway/identity.py +189 -0
  338. rucio/gateway/importer.py +46 -0
  339. rucio/gateway/lifetime_exception.py +121 -0
  340. rucio/gateway/lock.py +153 -0
  341. rucio/gateway/meta_conventions.py +98 -0
  342. rucio/gateway/permission.py +74 -0
  343. rucio/gateway/quarantined_replica.py +79 -0
  344. rucio/gateway/replica.py +538 -0
  345. rucio/gateway/request.py +330 -0
  346. rucio/gateway/rse.py +632 -0
  347. rucio/gateway/rule.py +437 -0
  348. rucio/gateway/scope.py +100 -0
  349. rucio/gateway/subscription.py +280 -0
  350. rucio/gateway/vo.py +126 -0
  351. rucio/rse/__init__.py +96 -0
  352. rucio/rse/protocols/__init__.py +13 -0
  353. rucio/rse/protocols/bittorrent.py +194 -0
  354. rucio/rse/protocols/cache.py +111 -0
  355. rucio/rse/protocols/dummy.py +100 -0
  356. rucio/rse/protocols/gfal.py +708 -0
  357. rucio/rse/protocols/globus.py +243 -0
  358. rucio/rse/protocols/http_cache.py +82 -0
  359. rucio/rse/protocols/mock.py +123 -0
  360. rucio/rse/protocols/ngarc.py +209 -0
  361. rucio/rse/protocols/posix.py +250 -0
  362. rucio/rse/protocols/protocol.py +361 -0
  363. rucio/rse/protocols/rclone.py +365 -0
  364. rucio/rse/protocols/rfio.py +145 -0
  365. rucio/rse/protocols/srm.py +338 -0
  366. rucio/rse/protocols/ssh.py +414 -0
  367. rucio/rse/protocols/storm.py +195 -0
  368. rucio/rse/protocols/webdav.py +594 -0
  369. rucio/rse/protocols/xrootd.py +302 -0
  370. rucio/rse/rsemanager.py +881 -0
  371. rucio/rse/translation.py +260 -0
  372. rucio/tests/__init__.py +13 -0
  373. rucio/tests/common.py +280 -0
  374. rucio/tests/common_server.py +149 -0
  375. rucio/transfertool/__init__.py +13 -0
  376. rucio/transfertool/bittorrent.py +200 -0
  377. rucio/transfertool/bittorrent_driver.py +50 -0
  378. rucio/transfertool/bittorrent_driver_qbittorrent.py +134 -0
  379. rucio/transfertool/fts3.py +1600 -0
  380. rucio/transfertool/fts3_plugins.py +152 -0
  381. rucio/transfertool/globus.py +201 -0
  382. rucio/transfertool/globus_library.py +181 -0
  383. rucio/transfertool/mock.py +89 -0
  384. rucio/transfertool/transfertool.py +221 -0
  385. rucio/vcsversion.py +11 -0
  386. rucio/version.py +45 -0
  387. rucio/web/__init__.py +13 -0
  388. rucio/web/rest/__init__.py +13 -0
  389. rucio/web/rest/flaskapi/__init__.py +13 -0
  390. rucio/web/rest/flaskapi/authenticated_bp.py +27 -0
  391. rucio/web/rest/flaskapi/v1/__init__.py +13 -0
  392. rucio/web/rest/flaskapi/v1/accountlimits.py +236 -0
  393. rucio/web/rest/flaskapi/v1/accounts.py +1103 -0
  394. rucio/web/rest/flaskapi/v1/archives.py +102 -0
  395. rucio/web/rest/flaskapi/v1/auth.py +1644 -0
  396. rucio/web/rest/flaskapi/v1/common.py +426 -0
  397. rucio/web/rest/flaskapi/v1/config.py +304 -0
  398. rucio/web/rest/flaskapi/v1/credentials.py +213 -0
  399. rucio/web/rest/flaskapi/v1/dids.py +2340 -0
  400. rucio/web/rest/flaskapi/v1/dirac.py +116 -0
  401. rucio/web/rest/flaskapi/v1/export.py +75 -0
  402. rucio/web/rest/flaskapi/v1/heartbeats.py +127 -0
  403. rucio/web/rest/flaskapi/v1/identities.py +285 -0
  404. rucio/web/rest/flaskapi/v1/import.py +132 -0
  405. rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +312 -0
  406. rucio/web/rest/flaskapi/v1/locks.py +358 -0
  407. rucio/web/rest/flaskapi/v1/main.py +91 -0
  408. rucio/web/rest/flaskapi/v1/meta_conventions.py +241 -0
  409. rucio/web/rest/flaskapi/v1/metrics.py +36 -0
  410. rucio/web/rest/flaskapi/v1/nongrid_traces.py +97 -0
  411. rucio/web/rest/flaskapi/v1/ping.py +88 -0
  412. rucio/web/rest/flaskapi/v1/redirect.py +366 -0
  413. rucio/web/rest/flaskapi/v1/replicas.py +1894 -0
  414. rucio/web/rest/flaskapi/v1/requests.py +998 -0
  415. rucio/web/rest/flaskapi/v1/rses.py +2250 -0
  416. rucio/web/rest/flaskapi/v1/rules.py +854 -0
  417. rucio/web/rest/flaskapi/v1/scopes.py +159 -0
  418. rucio/web/rest/flaskapi/v1/subscriptions.py +650 -0
  419. rucio/web/rest/flaskapi/v1/templates/auth_crash.html +80 -0
  420. rucio/web/rest/flaskapi/v1/templates/auth_granted.html +82 -0
  421. rucio/web/rest/flaskapi/v1/traces.py +137 -0
  422. rucio/web/rest/flaskapi/v1/types.py +20 -0
  423. rucio/web/rest/flaskapi/v1/vos.py +278 -0
  424. rucio/web/rest/main.py +18 -0
  425. rucio/web/rest/metrics.py +27 -0
  426. rucio/web/rest/ping.py +27 -0
  427. rucio-37.0.0rc1.data/data/rucio/etc/alembic.ini.template +71 -0
  428. rucio-37.0.0rc1.data/data/rucio/etc/alembic_offline.ini.template +74 -0
  429. rucio-37.0.0rc1.data/data/rucio/etc/globus-config.yml.template +5 -0
  430. rucio-37.0.0rc1.data/data/rucio/etc/ldap.cfg.template +30 -0
  431. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approval_request.tmpl +38 -0
  432. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +4 -0
  433. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_user.tmpl +17 -0
  434. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +6 -0
  435. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_user.tmpl +17 -0
  436. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +19 -0
  437. rucio-37.0.0rc1.data/data/rucio/etc/rse-accounts.cfg.template +25 -0
  438. rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.atlas.client.template +43 -0
  439. rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.template +241 -0
  440. rucio-37.0.0rc1.data/data/rucio/etc/rucio_multi_vo.cfg.template +217 -0
  441. rucio-37.0.0rc1.data/data/rucio/requirements.server.txt +297 -0
  442. rucio-37.0.0rc1.data/data/rucio/tools/bootstrap.py +34 -0
  443. rucio-37.0.0rc1.data/data/rucio/tools/merge_rucio_configs.py +144 -0
  444. rucio-37.0.0rc1.data/data/rucio/tools/reset_database.py +40 -0
  445. rucio-37.0.0rc1.data/scripts/rucio +133 -0
  446. rucio-37.0.0rc1.data/scripts/rucio-abacus-account +74 -0
  447. rucio-37.0.0rc1.data/scripts/rucio-abacus-collection-replica +46 -0
  448. rucio-37.0.0rc1.data/scripts/rucio-abacus-rse +78 -0
  449. rucio-37.0.0rc1.data/scripts/rucio-admin +97 -0
  450. rucio-37.0.0rc1.data/scripts/rucio-atropos +60 -0
  451. rucio-37.0.0rc1.data/scripts/rucio-auditor +206 -0
  452. rucio-37.0.0rc1.data/scripts/rucio-automatix +50 -0
  453. rucio-37.0.0rc1.data/scripts/rucio-bb8 +57 -0
  454. rucio-37.0.0rc1.data/scripts/rucio-cache-client +141 -0
  455. rucio-37.0.0rc1.data/scripts/rucio-cache-consumer +42 -0
  456. rucio-37.0.0rc1.data/scripts/rucio-conveyor-finisher +58 -0
  457. rucio-37.0.0rc1.data/scripts/rucio-conveyor-poller +66 -0
  458. rucio-37.0.0rc1.data/scripts/rucio-conveyor-preparer +37 -0
  459. rucio-37.0.0rc1.data/scripts/rucio-conveyor-receiver +44 -0
  460. rucio-37.0.0rc1.data/scripts/rucio-conveyor-stager +76 -0
  461. rucio-37.0.0rc1.data/scripts/rucio-conveyor-submitter +139 -0
  462. rucio-37.0.0rc1.data/scripts/rucio-conveyor-throttler +104 -0
  463. rucio-37.0.0rc1.data/scripts/rucio-dark-reaper +53 -0
  464. rucio-37.0.0rc1.data/scripts/rucio-dumper +160 -0
  465. rucio-37.0.0rc1.data/scripts/rucio-follower +44 -0
  466. rucio-37.0.0rc1.data/scripts/rucio-hermes +54 -0
  467. rucio-37.0.0rc1.data/scripts/rucio-judge-cleaner +89 -0
  468. rucio-37.0.0rc1.data/scripts/rucio-judge-evaluator +137 -0
  469. rucio-37.0.0rc1.data/scripts/rucio-judge-injector +44 -0
  470. rucio-37.0.0rc1.data/scripts/rucio-judge-repairer +44 -0
  471. rucio-37.0.0rc1.data/scripts/rucio-kronos +44 -0
  472. rucio-37.0.0rc1.data/scripts/rucio-minos +53 -0
  473. rucio-37.0.0rc1.data/scripts/rucio-minos-temporary-expiration +50 -0
  474. rucio-37.0.0rc1.data/scripts/rucio-necromancer +120 -0
  475. rucio-37.0.0rc1.data/scripts/rucio-oauth-manager +63 -0
  476. rucio-37.0.0rc1.data/scripts/rucio-reaper +83 -0
  477. rucio-37.0.0rc1.data/scripts/rucio-replica-recoverer +248 -0
  478. rucio-37.0.0rc1.data/scripts/rucio-rse-decommissioner +66 -0
  479. rucio-37.0.0rc1.data/scripts/rucio-storage-consistency-actions +74 -0
  480. rucio-37.0.0rc1.data/scripts/rucio-transmogrifier +77 -0
  481. rucio-37.0.0rc1.data/scripts/rucio-undertaker +76 -0
  482. rucio-37.0.0rc1.dist-info/METADATA +92 -0
  483. rucio-37.0.0rc1.dist-info/RECORD +487 -0
  484. rucio-37.0.0rc1.dist-info/WHEEL +5 -0
  485. rucio-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
  486. rucio-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
  487. 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