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