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