rucio 37.0.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rucio might be problematic. Click here for more details.

Files changed (487) hide show
  1. rucio/__init__.py +17 -0
  2. rucio/alembicrevision.py +15 -0
  3. rucio/cli/__init__.py +14 -0
  4. rucio/cli/account.py +216 -0
  5. rucio/cli/bin_legacy/__init__.py +13 -0
  6. rucio/cli/bin_legacy/rucio.py +2825 -0
  7. rucio/cli/bin_legacy/rucio_admin.py +2500 -0
  8. rucio/cli/command.py +272 -0
  9. rucio/cli/config.py +72 -0
  10. rucio/cli/did.py +191 -0
  11. rucio/cli/download.py +128 -0
  12. rucio/cli/lifetime_exception.py +33 -0
  13. rucio/cli/replica.py +162 -0
  14. rucio/cli/rse.py +293 -0
  15. rucio/cli/rule.py +158 -0
  16. rucio/cli/scope.py +40 -0
  17. rucio/cli/subscription.py +73 -0
  18. rucio/cli/upload.py +60 -0
  19. rucio/cli/utils.py +226 -0
  20. rucio/client/__init__.py +15 -0
  21. rucio/client/accountclient.py +432 -0
  22. rucio/client/accountlimitclient.py +183 -0
  23. rucio/client/baseclient.py +983 -0
  24. rucio/client/client.py +120 -0
  25. rucio/client/configclient.py +126 -0
  26. rucio/client/credentialclient.py +59 -0
  27. rucio/client/didclient.py +868 -0
  28. rucio/client/diracclient.py +56 -0
  29. rucio/client/downloadclient.py +1783 -0
  30. rucio/client/exportclient.py +44 -0
  31. rucio/client/fileclient.py +50 -0
  32. rucio/client/importclient.py +42 -0
  33. rucio/client/lifetimeclient.py +90 -0
  34. rucio/client/lockclient.py +109 -0
  35. rucio/client/metaconventionsclient.py +140 -0
  36. rucio/client/pingclient.py +44 -0
  37. rucio/client/replicaclient.py +452 -0
  38. rucio/client/requestclient.py +125 -0
  39. rucio/client/richclient.py +317 -0
  40. rucio/client/rseclient.py +746 -0
  41. rucio/client/ruleclient.py +294 -0
  42. rucio/client/scopeclient.py +90 -0
  43. rucio/client/subscriptionclient.py +173 -0
  44. rucio/client/touchclient.py +82 -0
  45. rucio/client/uploadclient.py +969 -0
  46. rucio/common/__init__.py +13 -0
  47. rucio/common/bittorrent.py +234 -0
  48. rucio/common/cache.py +111 -0
  49. rucio/common/checksum.py +168 -0
  50. rucio/common/client.py +122 -0
  51. rucio/common/config.py +788 -0
  52. rucio/common/constants.py +217 -0
  53. rucio/common/constraints.py +17 -0
  54. rucio/common/didtype.py +237 -0
  55. rucio/common/dumper/__init__.py +342 -0
  56. rucio/common/dumper/consistency.py +497 -0
  57. rucio/common/dumper/data_models.py +362 -0
  58. rucio/common/dumper/path_parsing.py +75 -0
  59. rucio/common/exception.py +1208 -0
  60. rucio/common/extra.py +31 -0
  61. rucio/common/logging.py +420 -0
  62. rucio/common/pcache.py +1409 -0
  63. rucio/common/plugins.py +185 -0
  64. rucio/common/policy.py +93 -0
  65. rucio/common/schema/__init__.py +200 -0
  66. rucio/common/schema/generic.py +416 -0
  67. rucio/common/schema/generic_multi_vo.py +395 -0
  68. rucio/common/stomp_utils.py +423 -0
  69. rucio/common/stopwatch.py +55 -0
  70. rucio/common/test_rucio_server.py +154 -0
  71. rucio/common/types.py +483 -0
  72. rucio/common/utils.py +1688 -0
  73. rucio/core/__init__.py +13 -0
  74. rucio/core/account.py +496 -0
  75. rucio/core/account_counter.py +236 -0
  76. rucio/core/account_limit.py +425 -0
  77. rucio/core/authentication.py +620 -0
  78. rucio/core/config.py +437 -0
  79. rucio/core/credential.py +224 -0
  80. rucio/core/did.py +3004 -0
  81. rucio/core/did_meta_plugins/__init__.py +252 -0
  82. rucio/core/did_meta_plugins/did_column_meta.py +331 -0
  83. rucio/core/did_meta_plugins/did_meta_plugin_interface.py +165 -0
  84. rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
  85. rucio/core/did_meta_plugins/filter_engine.py +672 -0
  86. rucio/core/did_meta_plugins/json_meta.py +240 -0
  87. rucio/core/did_meta_plugins/mongo_meta.py +229 -0
  88. rucio/core/did_meta_plugins/postgres_meta.py +352 -0
  89. rucio/core/dirac.py +237 -0
  90. rucio/core/distance.py +187 -0
  91. rucio/core/exporter.py +59 -0
  92. rucio/core/heartbeat.py +363 -0
  93. rucio/core/identity.py +301 -0
  94. rucio/core/importer.py +260 -0
  95. rucio/core/lifetime_exception.py +377 -0
  96. rucio/core/lock.py +577 -0
  97. rucio/core/message.py +288 -0
  98. rucio/core/meta_conventions.py +203 -0
  99. rucio/core/monitor.py +448 -0
  100. rucio/core/naming_convention.py +195 -0
  101. rucio/core/nongrid_trace.py +136 -0
  102. rucio/core/oidc.py +1463 -0
  103. rucio/core/permission/__init__.py +161 -0
  104. rucio/core/permission/generic.py +1124 -0
  105. rucio/core/permission/generic_multi_vo.py +1144 -0
  106. rucio/core/quarantined_replica.py +224 -0
  107. rucio/core/replica.py +4483 -0
  108. rucio/core/replica_sorter.py +362 -0
  109. rucio/core/request.py +3091 -0
  110. rucio/core/rse.py +2079 -0
  111. rucio/core/rse_counter.py +185 -0
  112. rucio/core/rse_expression_parser.py +459 -0
  113. rucio/core/rse_selector.py +304 -0
  114. rucio/core/rule.py +4484 -0
  115. rucio/core/rule_grouping.py +1620 -0
  116. rucio/core/scope.py +181 -0
  117. rucio/core/subscription.py +362 -0
  118. rucio/core/topology.py +490 -0
  119. rucio/core/trace.py +375 -0
  120. rucio/core/transfer.py +1531 -0
  121. rucio/core/vo.py +169 -0
  122. rucio/core/volatile_replica.py +151 -0
  123. rucio/daemons/__init__.py +13 -0
  124. rucio/daemons/abacus/__init__.py +13 -0
  125. rucio/daemons/abacus/account.py +116 -0
  126. rucio/daemons/abacus/collection_replica.py +124 -0
  127. rucio/daemons/abacus/rse.py +117 -0
  128. rucio/daemons/atropos/__init__.py +13 -0
  129. rucio/daemons/atropos/atropos.py +242 -0
  130. rucio/daemons/auditor/__init__.py +289 -0
  131. rucio/daemons/auditor/hdfs.py +97 -0
  132. rucio/daemons/auditor/srmdumps.py +355 -0
  133. rucio/daemons/automatix/__init__.py +13 -0
  134. rucio/daemons/automatix/automatix.py +304 -0
  135. rucio/daemons/badreplicas/__init__.py +13 -0
  136. rucio/daemons/badreplicas/minos.py +322 -0
  137. rucio/daemons/badreplicas/minos_temporary_expiration.py +171 -0
  138. rucio/daemons/badreplicas/necromancer.py +196 -0
  139. rucio/daemons/bb8/__init__.py +13 -0
  140. rucio/daemons/bb8/bb8.py +353 -0
  141. rucio/daemons/bb8/common.py +759 -0
  142. rucio/daemons/bb8/nuclei_background_rebalance.py +153 -0
  143. rucio/daemons/bb8/t2_background_rebalance.py +153 -0
  144. rucio/daemons/cache/__init__.py +13 -0
  145. rucio/daemons/cache/consumer.py +133 -0
  146. rucio/daemons/common.py +405 -0
  147. rucio/daemons/conveyor/__init__.py +13 -0
  148. rucio/daemons/conveyor/common.py +562 -0
  149. rucio/daemons/conveyor/finisher.py +529 -0
  150. rucio/daemons/conveyor/poller.py +394 -0
  151. rucio/daemons/conveyor/preparer.py +205 -0
  152. rucio/daemons/conveyor/receiver.py +179 -0
  153. rucio/daemons/conveyor/stager.py +133 -0
  154. rucio/daemons/conveyor/submitter.py +403 -0
  155. rucio/daemons/conveyor/throttler.py +532 -0
  156. rucio/daemons/follower/__init__.py +13 -0
  157. rucio/daemons/follower/follower.py +101 -0
  158. rucio/daemons/hermes/__init__.py +13 -0
  159. rucio/daemons/hermes/hermes.py +534 -0
  160. rucio/daemons/judge/__init__.py +13 -0
  161. rucio/daemons/judge/cleaner.py +159 -0
  162. rucio/daemons/judge/evaluator.py +185 -0
  163. rucio/daemons/judge/injector.py +162 -0
  164. rucio/daemons/judge/repairer.py +154 -0
  165. rucio/daemons/oauthmanager/__init__.py +13 -0
  166. rucio/daemons/oauthmanager/oauthmanager.py +198 -0
  167. rucio/daemons/reaper/__init__.py +13 -0
  168. rucio/daemons/reaper/dark_reaper.py +282 -0
  169. rucio/daemons/reaper/reaper.py +739 -0
  170. rucio/daemons/replicarecoverer/__init__.py +13 -0
  171. rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +626 -0
  172. rucio/daemons/rsedecommissioner/__init__.py +13 -0
  173. rucio/daemons/rsedecommissioner/config.py +81 -0
  174. rucio/daemons/rsedecommissioner/profiles/__init__.py +24 -0
  175. rucio/daemons/rsedecommissioner/profiles/atlas.py +60 -0
  176. rucio/daemons/rsedecommissioner/profiles/generic.py +452 -0
  177. rucio/daemons/rsedecommissioner/profiles/types.py +93 -0
  178. rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
  179. rucio/daemons/storage/__init__.py +13 -0
  180. rucio/daemons/storage/consistency/__init__.py +13 -0
  181. rucio/daemons/storage/consistency/actions.py +848 -0
  182. rucio/daemons/tracer/__init__.py +13 -0
  183. rucio/daemons/tracer/kronos.py +511 -0
  184. rucio/daemons/transmogrifier/__init__.py +13 -0
  185. rucio/daemons/transmogrifier/transmogrifier.py +762 -0
  186. rucio/daemons/undertaker/__init__.py +13 -0
  187. rucio/daemons/undertaker/undertaker.py +137 -0
  188. rucio/db/__init__.py +13 -0
  189. rucio/db/sqla/__init__.py +52 -0
  190. rucio/db/sqla/constants.py +206 -0
  191. rucio/db/sqla/migrate_repo/__init__.py +13 -0
  192. rucio/db/sqla/migrate_repo/env.py +110 -0
  193. rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +70 -0
  194. rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +47 -0
  195. rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +59 -0
  196. rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +43 -0
  197. rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +91 -0
  198. rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +76 -0
  199. rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +43 -0
  200. rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +50 -0
  201. rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +68 -0
  202. rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +40 -0
  203. rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +45 -0
  204. rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +60 -0
  205. rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +40 -0
  206. rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +140 -0
  207. rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +73 -0
  208. rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +74 -0
  209. rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +43 -0
  210. rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +50 -0
  211. rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +134 -0
  212. rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +64 -0
  213. rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +39 -0
  214. rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +64 -0
  215. rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +51 -0
  216. rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +41 -0
  217. rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +43 -0
  218. rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +44 -0
  219. rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +53 -0
  220. rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +38 -0
  221. rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +47 -0
  222. rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +45 -0
  223. rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +45 -0
  224. rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +57 -0
  225. rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +45 -0
  226. rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +69 -0
  227. rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +43 -0
  228. rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +42 -0
  229. rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +47 -0
  230. rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +46 -0
  231. rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +40 -0
  232. rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +67 -0
  233. rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
  234. rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +44 -0
  235. rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +77 -0
  236. rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +60 -0
  237. rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +72 -0
  238. rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +42 -0
  239. rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +65 -0
  240. rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +133 -0
  241. rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +55 -0
  242. rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +76 -0
  243. rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +60 -0
  244. rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +44 -0
  245. rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +43 -0
  246. rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +64 -0
  247. rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +40 -0
  248. rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +43 -0
  249. rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +44 -0
  250. rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +78 -0
  251. rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +41 -0
  252. rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +59 -0
  253. rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +44 -0
  254. rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +43 -0
  255. rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +49 -0
  256. rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +40 -0
  257. rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +63 -0
  258. rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +43 -0
  259. rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +55 -0
  260. rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +45 -0
  261. rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +43 -0
  262. rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +43 -0
  263. rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +45 -0
  264. rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +47 -0
  265. rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +58 -0
  266. rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +45 -0
  267. rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +106 -0
  268. rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +55 -0
  269. rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +50 -0
  270. rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +47 -0
  271. rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +43 -0
  272. rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +41 -0
  273. rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +91 -0
  274. rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +72 -0
  275. rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +49 -0
  276. rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +43 -0
  277. rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +43 -0
  278. rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +53 -0
  279. rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +45 -0
  280. rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +68 -0
  281. rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +45 -0
  282. rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +94 -0
  283. rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +54 -0
  284. rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +72 -0
  285. rucio/db/sqla/migrate_repo/versions/a08fa8de1545_transfer_stats_table.py +55 -0
  286. rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +76 -0
  287. rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +47 -0
  288. rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +121 -0
  289. rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +59 -0
  290. rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +52 -0
  291. rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +54 -0
  292. rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +64 -0
  293. rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +49 -0
  294. rucio/db/sqla/migrate_repo/versions/b0070f3695c8_add_deletedidmeta_table.py +57 -0
  295. rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +43 -0
  296. rucio/db/sqla/migrate_repo/versions/b5493606bbf5_fix_primary_key_for_subscription_history.py +41 -0
  297. rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +91 -0
  298. rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +40 -0
  299. rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +43 -0
  300. rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +143 -0
  301. rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +76 -0
  302. rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +50 -0
  303. rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +72 -0
  304. rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +55 -0
  305. rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +43 -0
  306. rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +65 -0
  307. rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +47 -0
  308. rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +146 -0
  309. rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +104 -0
  310. rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +44 -0
  311. rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +43 -0
  312. rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +103 -0
  313. rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +49 -0
  314. rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +104 -0
  315. rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +29 -0
  316. rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +74 -0
  317. rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +47 -0
  318. rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +43 -0
  319. rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +37 -0
  320. rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +43 -0
  321. rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +43 -0
  322. rucio/db/sqla/models.py +1743 -0
  323. rucio/db/sqla/sautils.py +55 -0
  324. rucio/db/sqla/session.py +529 -0
  325. rucio/db/sqla/types.py +206 -0
  326. rucio/db/sqla/util.py +543 -0
  327. rucio/gateway/__init__.py +13 -0
  328. rucio/gateway/account.py +345 -0
  329. rucio/gateway/account_limit.py +363 -0
  330. rucio/gateway/authentication.py +381 -0
  331. rucio/gateway/config.py +227 -0
  332. rucio/gateway/credential.py +70 -0
  333. rucio/gateway/did.py +987 -0
  334. rucio/gateway/dirac.py +83 -0
  335. rucio/gateway/exporter.py +60 -0
  336. rucio/gateway/heartbeat.py +76 -0
  337. rucio/gateway/identity.py +189 -0
  338. rucio/gateway/importer.py +46 -0
  339. rucio/gateway/lifetime_exception.py +121 -0
  340. rucio/gateway/lock.py +153 -0
  341. rucio/gateway/meta_conventions.py +98 -0
  342. rucio/gateway/permission.py +74 -0
  343. rucio/gateway/quarantined_replica.py +79 -0
  344. rucio/gateway/replica.py +538 -0
  345. rucio/gateway/request.py +330 -0
  346. rucio/gateway/rse.py +632 -0
  347. rucio/gateway/rule.py +437 -0
  348. rucio/gateway/scope.py +100 -0
  349. rucio/gateway/subscription.py +280 -0
  350. rucio/gateway/vo.py +126 -0
  351. rucio/rse/__init__.py +96 -0
  352. rucio/rse/protocols/__init__.py +13 -0
  353. rucio/rse/protocols/bittorrent.py +194 -0
  354. rucio/rse/protocols/cache.py +111 -0
  355. rucio/rse/protocols/dummy.py +100 -0
  356. rucio/rse/protocols/gfal.py +708 -0
  357. rucio/rse/protocols/globus.py +243 -0
  358. rucio/rse/protocols/http_cache.py +82 -0
  359. rucio/rse/protocols/mock.py +123 -0
  360. rucio/rse/protocols/ngarc.py +209 -0
  361. rucio/rse/protocols/posix.py +250 -0
  362. rucio/rse/protocols/protocol.py +361 -0
  363. rucio/rse/protocols/rclone.py +365 -0
  364. rucio/rse/protocols/rfio.py +145 -0
  365. rucio/rse/protocols/srm.py +338 -0
  366. rucio/rse/protocols/ssh.py +414 -0
  367. rucio/rse/protocols/storm.py +195 -0
  368. rucio/rse/protocols/webdav.py +594 -0
  369. rucio/rse/protocols/xrootd.py +302 -0
  370. rucio/rse/rsemanager.py +881 -0
  371. rucio/rse/translation.py +260 -0
  372. rucio/tests/__init__.py +13 -0
  373. rucio/tests/common.py +280 -0
  374. rucio/tests/common_server.py +149 -0
  375. rucio/transfertool/__init__.py +13 -0
  376. rucio/transfertool/bittorrent.py +200 -0
  377. rucio/transfertool/bittorrent_driver.py +50 -0
  378. rucio/transfertool/bittorrent_driver_qbittorrent.py +134 -0
  379. rucio/transfertool/fts3.py +1600 -0
  380. rucio/transfertool/fts3_plugins.py +152 -0
  381. rucio/transfertool/globus.py +201 -0
  382. rucio/transfertool/globus_library.py +181 -0
  383. rucio/transfertool/mock.py +89 -0
  384. rucio/transfertool/transfertool.py +221 -0
  385. rucio/vcsversion.py +11 -0
  386. rucio/version.py +45 -0
  387. rucio/web/__init__.py +13 -0
  388. rucio/web/rest/__init__.py +13 -0
  389. rucio/web/rest/flaskapi/__init__.py +13 -0
  390. rucio/web/rest/flaskapi/authenticated_bp.py +27 -0
  391. rucio/web/rest/flaskapi/v1/__init__.py +13 -0
  392. rucio/web/rest/flaskapi/v1/accountlimits.py +236 -0
  393. rucio/web/rest/flaskapi/v1/accounts.py +1103 -0
  394. rucio/web/rest/flaskapi/v1/archives.py +102 -0
  395. rucio/web/rest/flaskapi/v1/auth.py +1644 -0
  396. rucio/web/rest/flaskapi/v1/common.py +426 -0
  397. rucio/web/rest/flaskapi/v1/config.py +304 -0
  398. rucio/web/rest/flaskapi/v1/credentials.py +213 -0
  399. rucio/web/rest/flaskapi/v1/dids.py +2340 -0
  400. rucio/web/rest/flaskapi/v1/dirac.py +116 -0
  401. rucio/web/rest/flaskapi/v1/export.py +75 -0
  402. rucio/web/rest/flaskapi/v1/heartbeats.py +127 -0
  403. rucio/web/rest/flaskapi/v1/identities.py +285 -0
  404. rucio/web/rest/flaskapi/v1/import.py +132 -0
  405. rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +312 -0
  406. rucio/web/rest/flaskapi/v1/locks.py +358 -0
  407. rucio/web/rest/flaskapi/v1/main.py +91 -0
  408. rucio/web/rest/flaskapi/v1/meta_conventions.py +241 -0
  409. rucio/web/rest/flaskapi/v1/metrics.py +36 -0
  410. rucio/web/rest/flaskapi/v1/nongrid_traces.py +97 -0
  411. rucio/web/rest/flaskapi/v1/ping.py +88 -0
  412. rucio/web/rest/flaskapi/v1/redirect.py +366 -0
  413. rucio/web/rest/flaskapi/v1/replicas.py +1894 -0
  414. rucio/web/rest/flaskapi/v1/requests.py +998 -0
  415. rucio/web/rest/flaskapi/v1/rses.py +2250 -0
  416. rucio/web/rest/flaskapi/v1/rules.py +854 -0
  417. rucio/web/rest/flaskapi/v1/scopes.py +159 -0
  418. rucio/web/rest/flaskapi/v1/subscriptions.py +650 -0
  419. rucio/web/rest/flaskapi/v1/templates/auth_crash.html +80 -0
  420. rucio/web/rest/flaskapi/v1/templates/auth_granted.html +82 -0
  421. rucio/web/rest/flaskapi/v1/traces.py +137 -0
  422. rucio/web/rest/flaskapi/v1/types.py +20 -0
  423. rucio/web/rest/flaskapi/v1/vos.py +278 -0
  424. rucio/web/rest/main.py +18 -0
  425. rucio/web/rest/metrics.py +27 -0
  426. rucio/web/rest/ping.py +27 -0
  427. rucio-37.0.0rc1.data/data/rucio/etc/alembic.ini.template +71 -0
  428. rucio-37.0.0rc1.data/data/rucio/etc/alembic_offline.ini.template +74 -0
  429. rucio-37.0.0rc1.data/data/rucio/etc/globus-config.yml.template +5 -0
  430. rucio-37.0.0rc1.data/data/rucio/etc/ldap.cfg.template +30 -0
  431. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approval_request.tmpl +38 -0
  432. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +4 -0
  433. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_user.tmpl +17 -0
  434. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +6 -0
  435. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_user.tmpl +17 -0
  436. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +19 -0
  437. rucio-37.0.0rc1.data/data/rucio/etc/rse-accounts.cfg.template +25 -0
  438. rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.atlas.client.template +43 -0
  439. rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.template +241 -0
  440. rucio-37.0.0rc1.data/data/rucio/etc/rucio_multi_vo.cfg.template +217 -0
  441. rucio-37.0.0rc1.data/data/rucio/requirements.server.txt +297 -0
  442. rucio-37.0.0rc1.data/data/rucio/tools/bootstrap.py +34 -0
  443. rucio-37.0.0rc1.data/data/rucio/tools/merge_rucio_configs.py +144 -0
  444. rucio-37.0.0rc1.data/data/rucio/tools/reset_database.py +40 -0
  445. rucio-37.0.0rc1.data/scripts/rucio +133 -0
  446. rucio-37.0.0rc1.data/scripts/rucio-abacus-account +74 -0
  447. rucio-37.0.0rc1.data/scripts/rucio-abacus-collection-replica +46 -0
  448. rucio-37.0.0rc1.data/scripts/rucio-abacus-rse +78 -0
  449. rucio-37.0.0rc1.data/scripts/rucio-admin +97 -0
  450. rucio-37.0.0rc1.data/scripts/rucio-atropos +60 -0
  451. rucio-37.0.0rc1.data/scripts/rucio-auditor +206 -0
  452. rucio-37.0.0rc1.data/scripts/rucio-automatix +50 -0
  453. rucio-37.0.0rc1.data/scripts/rucio-bb8 +57 -0
  454. rucio-37.0.0rc1.data/scripts/rucio-cache-client +141 -0
  455. rucio-37.0.0rc1.data/scripts/rucio-cache-consumer +42 -0
  456. rucio-37.0.0rc1.data/scripts/rucio-conveyor-finisher +58 -0
  457. rucio-37.0.0rc1.data/scripts/rucio-conveyor-poller +66 -0
  458. rucio-37.0.0rc1.data/scripts/rucio-conveyor-preparer +37 -0
  459. rucio-37.0.0rc1.data/scripts/rucio-conveyor-receiver +44 -0
  460. rucio-37.0.0rc1.data/scripts/rucio-conveyor-stager +76 -0
  461. rucio-37.0.0rc1.data/scripts/rucio-conveyor-submitter +139 -0
  462. rucio-37.0.0rc1.data/scripts/rucio-conveyor-throttler +104 -0
  463. rucio-37.0.0rc1.data/scripts/rucio-dark-reaper +53 -0
  464. rucio-37.0.0rc1.data/scripts/rucio-dumper +160 -0
  465. rucio-37.0.0rc1.data/scripts/rucio-follower +44 -0
  466. rucio-37.0.0rc1.data/scripts/rucio-hermes +54 -0
  467. rucio-37.0.0rc1.data/scripts/rucio-judge-cleaner +89 -0
  468. rucio-37.0.0rc1.data/scripts/rucio-judge-evaluator +137 -0
  469. rucio-37.0.0rc1.data/scripts/rucio-judge-injector +44 -0
  470. rucio-37.0.0rc1.data/scripts/rucio-judge-repairer +44 -0
  471. rucio-37.0.0rc1.data/scripts/rucio-kronos +44 -0
  472. rucio-37.0.0rc1.data/scripts/rucio-minos +53 -0
  473. rucio-37.0.0rc1.data/scripts/rucio-minos-temporary-expiration +50 -0
  474. rucio-37.0.0rc1.data/scripts/rucio-necromancer +120 -0
  475. rucio-37.0.0rc1.data/scripts/rucio-oauth-manager +63 -0
  476. rucio-37.0.0rc1.data/scripts/rucio-reaper +83 -0
  477. rucio-37.0.0rc1.data/scripts/rucio-replica-recoverer +248 -0
  478. rucio-37.0.0rc1.data/scripts/rucio-rse-decommissioner +66 -0
  479. rucio-37.0.0rc1.data/scripts/rucio-storage-consistency-actions +74 -0
  480. rucio-37.0.0rc1.data/scripts/rucio-transmogrifier +77 -0
  481. rucio-37.0.0rc1.data/scripts/rucio-undertaker +76 -0
  482. rucio-37.0.0rc1.dist-info/METADATA +92 -0
  483. rucio-37.0.0rc1.dist-info/RECORD +487 -0
  484. rucio-37.0.0rc1.dist-info/WHEEL +5 -0
  485. rucio-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
  486. rucio-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
  487. rucio-37.0.0rc1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,854 @@
1
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from json import dumps
16
+ from typing import Any
17
+
18
+ from flask import Flask, Response, request
19
+
20
+ from rucio.common.exception import (
21
+ AccessDenied,
22
+ AccountNotFound,
23
+ DataIdentifierNotFound,
24
+ DuplicateRule,
25
+ InputValidationError,
26
+ InsufficientAccountLimit,
27
+ InsufficientTargetRSEs,
28
+ InvalidObject,
29
+ InvalidReplicationRule,
30
+ InvalidRSEExpression,
31
+ InvalidRuleWeight,
32
+ ManualRuleApprovalBlocked,
33
+ ReplicationRuleCreationTemporaryFailed,
34
+ RuleNotFound,
35
+ RuleReplaceFailed,
36
+ ScratchDiskLifetimeConflict,
37
+ StagingAreaRuleRequiresLifetime,
38
+ UnsupportedOperation,
39
+ )
40
+ from rucio.common.utils import APIEncoder, render_json
41
+ from rucio.gateway.lock import get_replica_locks_for_rule_id
42
+ from rucio.gateway.rule import (
43
+ add_replication_rule,
44
+ delete_replication_rule,
45
+ examine_replication_rule,
46
+ get_replication_rule,
47
+ list_replication_rule_full_history,
48
+ list_replication_rule_history,
49
+ list_replication_rules,
50
+ move_replication_rule,
51
+ reduce_replication_rule,
52
+ update_replication_rule,
53
+ )
54
+ from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
55
+ from rucio.web.rest.flaskapi.v1.common import ErrorHandlingMethodView, check_accept_header_wrapper_flask, generate_http_error_flask, json_parameters, param_get, parse_scope_name, response_headers, try_stream
56
+
57
+
58
+ class Rule(ErrorHandlingMethodView):
59
+ """ REST APIs for replication rules. """
60
+
61
+ @check_accept_header_wrapper_flask(['application/json'])
62
+ def get(self, rule_id):
63
+ """
64
+ ---
65
+ summary: Return a Rule
66
+ tags:
67
+ - Rule
68
+ parameters:
69
+ - name: rule_id
70
+ in: path
71
+ description: The id of the replication rule.
72
+ schema:
73
+ type: string
74
+ style: simple
75
+ responses:
76
+ 200:
77
+ description: OK
78
+ content:
79
+ application/json:
80
+ schema:
81
+ type: string
82
+ 406:
83
+ description: Not Acceptable
84
+ 401:
85
+ description: Invalid Auth Token
86
+ 404:
87
+ description: No rule found for the given id
88
+ """
89
+ parameters = json_parameters(optional=True)
90
+ estimate_ttc = param_get(parameters, 'estimate_ttc', default=False)
91
+ if estimate_ttc:
92
+ return generate_http_error_flask(501, "NotImplemented", exc_msg="estimate_ttc is not implemented!")
93
+
94
+ try:
95
+ rule = get_replication_rule(rule_id, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
96
+ except RuleNotFound as error:
97
+ return generate_http_error_flask(404, error)
98
+
99
+ return Response(render_json(**rule), content_type="application/json")
100
+
101
+ def put(self, rule_id):
102
+ """
103
+ ---
104
+ summary: Update the replication rules parameters
105
+ tags:
106
+ - Rule
107
+ parameters:
108
+ - name: rule_id
109
+ in: path
110
+ description: The id of the replication rule.
111
+ schema:
112
+ type: string
113
+ style: simple
114
+ requestBody:
115
+ description: Parameters for the new rule.
116
+ content:
117
+ 'application/json':
118
+ schema:
119
+ type: object
120
+ required:
121
+ - options
122
+ properties:
123
+ options:
124
+ description: The parameters to change.
125
+ type: object
126
+ properties:
127
+ lifetime:
128
+ description: The time in which the rule will expire in seconds.
129
+ type: integer
130
+ account:
131
+ description: The account of the replication rule.
132
+ type: string
133
+ state:
134
+ description: The state of the replication rule.
135
+ type: string
136
+ cancel_requests:
137
+ description: Cancels all requests if used together with state.
138
+ type: boolean
139
+ priority:
140
+ description: The priority of a rule.
141
+ type: integer
142
+ child_rule_id:
143
+ description: The child rule. Parent and child rule must be on the same dataset.
144
+ type: string
145
+ meta:
146
+ description: The meta of a rule.
147
+ type: object
148
+ boost_rule:
149
+ description: Boosts the processing of a rule.
150
+ type: object
151
+ locked:
152
+ description: The locked state of the replication rule.
153
+ type: boolean
154
+ comment:
155
+ description: The comment of the replication rule.
156
+ type: string
157
+ activity:
158
+ description: The activity of a replication rule.
159
+ type: string
160
+ source_replica_expression:
161
+ description: The source replica expression of a replication rule.
162
+ type: string
163
+ eol_at:
164
+ description: The end of life of a replication rule.
165
+ type: string
166
+ purge_replicas:
167
+ description: Purge replicas
168
+ type: boolean
169
+ responses:
170
+ 200:
171
+ description: OK
172
+ 401:
173
+ description: Invalid Auth Token
174
+ 404:
175
+ description: No rule found for the given id
176
+ """
177
+ parameters = json_parameters()
178
+ options: dict[str, Any] = param_get(parameters, 'options')
179
+ try:
180
+ update_replication_rule(rule_id=rule_id, options=options, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
181
+ except AccessDenied as error:
182
+ return generate_http_error_flask(401, error)
183
+ except (RuleNotFound, AccountNotFound) as error:
184
+ return generate_http_error_flask(404, error)
185
+ except (ScratchDiskLifetimeConflict,
186
+ UnsupportedOperation, InputValidationError) as error:
187
+ return generate_http_error_flask(409, error)
188
+
189
+ return '', 200
190
+
191
+ def delete(self, rule_id):
192
+ """
193
+ ---
194
+ summary: Delete a replication rule
195
+ tags:
196
+ - Rule
197
+ parameters:
198
+ - name: rule_id
199
+ in: path
200
+ description: The id of the replication rule.
201
+ schema:
202
+ type: string
203
+ style: simple
204
+ responses:
205
+ 200:
206
+ description: OK
207
+ 401:
208
+ description: Invalid Auth Token
209
+ 404:
210
+ description: No rule found for the given id
211
+ """
212
+ parameters = json_parameters()
213
+ purge_replicas = param_get(parameters, 'purge_replicas', default=None)
214
+ try:
215
+ delete_replication_rule(rule_id=rule_id, purge_replicas=purge_replicas, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
216
+ except (AccessDenied, UnsupportedOperation) as error:
217
+ return generate_http_error_flask(401, error)
218
+ except RuleNotFound as error:
219
+ return generate_http_error_flask(404, error)
220
+
221
+ return '', 200
222
+
223
+
224
+ class AllRule(ErrorHandlingMethodView):
225
+ """ REST APIs for all rules. """
226
+
227
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
228
+ def get(self):
229
+ """
230
+ ---
231
+ summary: Return all rules for a given account
232
+ tags:
233
+ - Rule
234
+ responses:
235
+ 200:
236
+ description: OK
237
+ content:
238
+ application/json:
239
+ schema:
240
+ type: string
241
+ 401:
242
+ description: Invalid Auth Token
243
+ 404:
244
+ description: No rule found for the given id
245
+ 406:
246
+ description: Not Acceptable
247
+ """
248
+ try:
249
+ def generate(filters, vo):
250
+ for rule in list_replication_rules(filters=filters, vo=vo):
251
+ yield dumps(rule, cls=APIEncoder) + '\n'
252
+
253
+ return try_stream(generate(filters=dict(request.args.items(multi=False)), vo=request.environ.get('vo')))
254
+ except RuleNotFound as error:
255
+ return generate_http_error_flask(404, error)
256
+
257
+ def post(self):
258
+ """
259
+ ---
260
+ summary: Create a new replication rule
261
+ tags:
262
+ - Rule
263
+ requestBody:
264
+ description: Parameters for the new rule.
265
+ content:
266
+ 'application/json':
267
+ schema:
268
+ type: object
269
+ required:
270
+ - dids
271
+ - account
272
+ - copies
273
+ - rse_expression
274
+ properties:
275
+ dids:
276
+ description: The list of data identifiers.
277
+ type: array
278
+ items:
279
+ type: object
280
+ properties:
281
+ scope:
282
+ description: The scope of the data identifier
283
+ type: string
284
+ name:
285
+ description: The name of the data identifier
286
+ type: string
287
+ account:
288
+ description: The account of the issuer.
289
+ type: string
290
+ copies:
291
+ description: The number of replicas.
292
+ type: integer
293
+ rse_expression:
294
+ description: The rse expression which gets resolved into a list of RSEs.
295
+ type: string
296
+ grouping:
297
+ description: The grouping of the files to take into account. (ALL, DATASET, NONE)
298
+ type: string
299
+ weight:
300
+ description: Weighting scheme to be used.
301
+ type: number
302
+ lifetime:
303
+ description: The lifetime of the replication rule in seconds.
304
+ type: integer
305
+ locked:
306
+ description: If the rule is locked.
307
+ type: boolean
308
+ subscription_id:
309
+ description: The subscription_id, if the rule is created by a subscription.
310
+ type: string
311
+ sourse_replica_expression:
312
+ description: Only use replicas as source from these RSEs.
313
+ type: string
314
+ activity:
315
+ description: Activity to be passed to the conveyor.
316
+ type: string
317
+ notify:
318
+ description: Notification setting of the rule ('Y', 'N', 'C'; None = 'N').
319
+ type: string
320
+ purge_replicas:
321
+ description: Purge setting if a replica should be directly deleted after the rule is deleted.
322
+ type: boolean
323
+ ignore_availability:
324
+ description: Option to ignore the availability of RSEs.
325
+ type: boolean
326
+ comments:
327
+ description: Comment about the rule.
328
+ type: string
329
+ ask_approval:
330
+ description: Ask for approval for this rule.
331
+ type: boolean
332
+ asynchronous:
333
+ description: Create replication rule asynchronously by the judge-injector.
334
+ type: boolean
335
+ priority:
336
+ description: Priority of the rule and the transfers which should be submitted.
337
+ type: integer
338
+ split_container:
339
+ description: Should a container rule be split into individual dataset rules.
340
+ type: boolean
341
+ meta:
342
+ description: Dictionary with metadata from the WFMS.
343
+ type: string
344
+ responses:
345
+ 201:
346
+ description: Rule created.
347
+ content:
348
+ application/json:
349
+ schema:
350
+ type: array
351
+ items:
352
+ type: string
353
+ description: Id of each created rule.
354
+ 401:
355
+ description: Invalid Auth Token
356
+ 404:
357
+ description: No rule found for the given id
358
+ 409:
359
+ description: |
360
+ - Invalid Replication Rule
361
+ - Duplicate Replication Rule
362
+ - Insufficient Target RSEs
363
+ - Insufficient Account Limit
364
+ - Invalid RSE Expression
365
+ - Replication Rule Creation Temporary Failed,
366
+ - Invalid Rule Weight
367
+ - Staging Area Rule Requires Lifetime
368
+ - Scratch Disk Lifetime Conflict
369
+ - Manual Rule Approval Blocked
370
+ - Invalid Object
371
+ """
372
+ parameters = json_parameters()
373
+ dids = param_get(parameters, 'dids')
374
+ account = param_get(parameters, 'account')
375
+ copies = param_get(parameters, 'copies')
376
+ rse_expression = param_get(parameters, 'rse_expression')
377
+ try:
378
+ rule_ids = add_replication_rule(
379
+ dids=dids,
380
+ copies=copies,
381
+ rse_expression=rse_expression,
382
+ weight=param_get(parameters, 'weight', default=None),
383
+ lifetime=param_get(parameters, 'lifetime', default=None),
384
+ grouping=param_get(parameters, 'grouping', default='DATASET'),
385
+ account=account,
386
+ locked=param_get(parameters, 'locked', default=False),
387
+ subscription_id=param_get(parameters, 'subscription_id', default=None),
388
+ source_replica_expression=param_get(parameters, 'source_replica_expression', default=None),
389
+ activity=param_get(parameters, 'activity', default=None),
390
+ notify=param_get(parameters, 'notify', default=None),
391
+ purge_replicas=param_get(parameters, 'purge_replicas', default=False),
392
+ ignore_availability=param_get(parameters, 'ignore_availability', default=False),
393
+ comment=param_get(parameters, 'comment', default=None),
394
+ ask_approval=param_get(parameters, 'ask_approval', default=False),
395
+ asynchronous=param_get(parameters, 'asynchronous', default=False),
396
+ delay_injection=param_get(parameters, 'delay_injection', default=None),
397
+ priority=param_get(parameters, 'priority', default=3),
398
+ split_container=param_get(parameters, 'split_container', default=False),
399
+ meta=param_get(parameters, 'meta', default=None),
400
+ issuer=request.environ.get('issuer'),
401
+ vo=request.environ.get('vo'),
402
+ )
403
+ except (
404
+ InvalidReplicationRule,
405
+ DuplicateRule,
406
+ InsufficientTargetRSEs,
407
+ InsufficientAccountLimit,
408
+ InvalidRSEExpression,
409
+ ReplicationRuleCreationTemporaryFailed,
410
+ InvalidRuleWeight,
411
+ StagingAreaRuleRequiresLifetime,
412
+ ScratchDiskLifetimeConflict,
413
+ ManualRuleApprovalBlocked,
414
+ InvalidObject,
415
+ ) as error:
416
+ return generate_http_error_flask(409, error)
417
+ except DataIdentifierNotFound as error:
418
+ return generate_http_error_flask(404, error)
419
+
420
+ return Response(dumps(rule_ids), status=201)
421
+
422
+
423
+ class ReplicaLocks(ErrorHandlingMethodView):
424
+ """ REST APIs for replica locks. """
425
+
426
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
427
+ def get(self, rule_id):
428
+ """
429
+ ---
430
+ summary: Return all locks for a Rule
431
+ tags:
432
+ - Rule
433
+ parameters:
434
+ - name: rule_id
435
+ in: path
436
+ description: The id of the replication rule.
437
+ schema:
438
+ type: string
439
+ style: simple
440
+ responses:
441
+ 200:
442
+ description: OK
443
+ content:
444
+ application/json:
445
+ schema:
446
+ type: array
447
+ items:
448
+ type: object
449
+ properties:
450
+ scope:
451
+ description: The scope of the lock.
452
+ type: string
453
+ name:
454
+ description: The name of the lock.
455
+ type: string
456
+ rse_id:
457
+ description: The rse_id of the lock.
458
+ type: string
459
+ rse:
460
+ description: Information about the rse of the lock.
461
+ type: object
462
+ state:
463
+ description: The state of the lock.
464
+ type: string
465
+ rule_id:
466
+ description: The rule_id of the lock.
467
+ type: string
468
+ 401:
469
+ description: Invalid Auth Token
470
+ 404:
471
+ description: No rule found for the given id
472
+ 406:
473
+ description: Not Acceptable
474
+ """
475
+
476
+ def generate(vo):
477
+ for lock in get_replica_locks_for_rule_id(rule_id, vo=vo):
478
+ yield render_json(**lock) + '\n'
479
+
480
+ return try_stream(generate(vo=request.environ.get('vo')))
481
+
482
+
483
+ class ReduceRule(ErrorHandlingMethodView):
484
+ """ REST APIs for reducing rules. """
485
+
486
+ def post(self, rule_id):
487
+ """
488
+ ---
489
+ summary: Reduce a replication rule
490
+ tags:
491
+ - Rule
492
+ parameters:
493
+ - name: rule_id
494
+ in: path
495
+ description: The id of the replication rule.
496
+ schema:
497
+ type: string
498
+ style: simple
499
+ requestBody:
500
+ content:
501
+ 'application/json':
502
+ schema:
503
+ type: object
504
+ required:
505
+ - copies
506
+ properties:
507
+ copies:
508
+ description: Number of copies to keep.
509
+ type: integer
510
+ responses:
511
+ 200:
512
+ description: OK
513
+ content:
514
+ application/json:
515
+ schema:
516
+ type: array
517
+ items:
518
+ type: string
519
+ description: Rule id.
520
+ 401:
521
+ description: Invalid Auth Token
522
+ 404:
523
+ description: No rule found for the given id
524
+ 409:
525
+ description: Rule replace failed.
526
+ """
527
+ parameters = json_parameters()
528
+ copies = param_get(parameters, 'copies')
529
+ exclude_expression = param_get(parameters, 'exclude_expression', default=None)
530
+ try:
531
+ rule_ids = reduce_replication_rule(rule_id=rule_id,
532
+ copies=copies,
533
+ exclude_expression=exclude_expression,
534
+ issuer=request.environ.get('issuer'),
535
+ vo=request.environ.get('vo'))
536
+ # TODO: Add all other error cases here
537
+ except RuleReplaceFailed as error:
538
+ return generate_http_error_flask(409, error)
539
+ except RuleNotFound as error:
540
+ return generate_http_error_flask(404, error)
541
+
542
+ return Response(dumps(rule_ids), status=201)
543
+
544
+
545
+ class MoveRule(ErrorHandlingMethodView):
546
+ """ REST APIs for moving rules. """
547
+
548
+ def post(self, rule_id):
549
+ """
550
+ ---
551
+ summary: Move a replication Rule
552
+ tags:
553
+ - Rule
554
+ parameters:
555
+ - name: rule_id
556
+ in: path
557
+ description: The id of the replication rule.
558
+ schema:
559
+ type: string
560
+ style: simple
561
+ requestBody:
562
+ content:
563
+ 'application/json':
564
+ schema:
565
+ type: object
566
+ required:
567
+ - rse_expression
568
+ properties:
569
+ rse_expression:
570
+ description: The new rse expression.
571
+ type: string
572
+ rule_id:
573
+ description: The rule_id of the rule to moves. If specified, overrides the `rule_id` parameter.
574
+ type: string
575
+ activity:
576
+ description: The `activity` of the moved rule.
577
+ type: string
578
+ source_replica_expression:
579
+ description: The `source_replica_expression` of the moved rule.
580
+ type: string
581
+ responses:
582
+ 200:
583
+ description: OK
584
+ content:
585
+ application/json:
586
+ schema:
587
+ type: array
588
+ items:
589
+ type: string
590
+ description: Rule id.
591
+ 401:
592
+ description: Invalid Auth Token
593
+ 404:
594
+ description: No rule found for the given id
595
+ 409:
596
+ description: Rule replace failed.
597
+ """
598
+ parameters = json_parameters()
599
+ rse_expression = param_get(parameters, 'rse_expression')
600
+ rule_id = param_get(parameters, 'rule_id', default=rule_id)
601
+ override = param_get(parameters, 'override', default={})
602
+
603
+ # For backwards-compatibility, deprecate in the future.
604
+ activity = param_get(parameters, 'activity', default=None)
605
+ if activity and 'activity' not in override:
606
+ override['activity'] = activity
607
+ source_replica_expression = param_get(parameters, 'source_replica_expression', default=None)
608
+ if source_replica_expression and 'source_replica_expression' not in override:
609
+ override['source_replica_expression'] = source_replica_expression
610
+
611
+ try:
612
+ rule_ids = move_replication_rule(rule_id=rule_id,
613
+ rse_expression=rse_expression,
614
+ override=override,
615
+ issuer=request.environ.get('issuer'),
616
+ vo=request.environ.get('vo'))
617
+ except RuleReplaceFailed as error:
618
+ return generate_http_error_flask(409, error)
619
+ except RuleNotFound as error:
620
+ return generate_http_error_flask(404, error)
621
+
622
+ return Response(dumps(rule_ids), status=201)
623
+
624
+
625
+ class RuleHistory(ErrorHandlingMethodView):
626
+ """ REST APIs for rule history. """
627
+
628
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
629
+ def get(self, rule_id):
630
+ """
631
+ ---
632
+ summary: Get the history of a rule
633
+ tags:
634
+ - Rule
635
+ parameters:
636
+ - name: rule_id
637
+ in: path
638
+ description: The id of the replication rule.
639
+ schema:
640
+ type: string
641
+ style: simple
642
+ responses:
643
+ 200:
644
+ description: OK
645
+ content:
646
+ application/json:
647
+ schema:
648
+ type: array
649
+ items:
650
+ type: object
651
+ description: Rule history object.
652
+ properties:
653
+ updated_at:
654
+ type: string
655
+ description: The date of the update.
656
+ state:
657
+ type: string
658
+ description: The state of the update.
659
+ locks_ok_cnt:
660
+ type: integer
661
+ description: The number of locks which are ok.
662
+ locks_stuck_cnt:
663
+ type: integer
664
+ description: The number of locks which are stuck.
665
+ locks_replicating_cnt:
666
+ type: integer
667
+ description: The number of locks which are replicating.
668
+ 401:
669
+ description: Invalid Auth Token
670
+ 404:
671
+ description: No rule found for the given id
672
+ 406:
673
+ description: Not acceptable.
674
+ """
675
+ def generate(issuer, vo):
676
+ for history in list_replication_rule_history(rule_id, issuer=issuer, vo=vo):
677
+ yield render_json(**history) + '\n'
678
+
679
+ return try_stream(generate(issuer=request.environ.get('issuer'), vo=request.environ.get('vo')))
680
+
681
+
682
+ class RuleHistoryFull(ErrorHandlingMethodView):
683
+ """ REST APIs for rule history for DIDs. """
684
+
685
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
686
+ def get(self, scope_name):
687
+ """
688
+ ---
689
+ summary: Get the history of a DID
690
+ tags:
691
+ - Rule
692
+ parameters:
693
+ - name: scope_name
694
+ in: path
695
+ description: The data identifier of scope-name to retrieve the history from. ((scope)/(name))
696
+ schema:
697
+ type: string
698
+ style: simple
699
+ responses:
700
+ 200:
701
+ description: OK
702
+ content:
703
+ application/x-json-stream:
704
+ schema:
705
+ type: array
706
+ items:
707
+ type: object
708
+ description: Rule history object.
709
+ properties:
710
+ rule_id:
711
+ type: string
712
+ description: The id of the rule.
713
+ updated_at:
714
+ type: string
715
+ description: The date of the update.
716
+ created_at:
717
+ type: string
718
+ description: The date of the creation.
719
+ rse_expression:
720
+ type: string
721
+ description: The rse expression.
722
+ state:
723
+ type: string
724
+ description: The state of the update.
725
+ account:
726
+ type: string
727
+ description: The account who initiated the change.
728
+ locks_ok_cnt:
729
+ type: integer
730
+ description: The number of locks which are ok.
731
+ locks_stuck_cnt:
732
+ type: integer
733
+ description: The number of locks which are stuck.
734
+ locks_replicating_cnt:
735
+ type: integer
736
+ description: The number of locks which are replicating.
737
+ 401:
738
+ description: Invalid Auth Token
739
+ 406:
740
+ description: Not acceptable.
741
+ """
742
+ try:
743
+ scope, name = parse_scope_name(scope_name, request.environ.get('vo'))
744
+
745
+ def generate(vo):
746
+ for history in list_replication_rule_full_history(scope, name, vo=vo):
747
+ yield render_json(**history) + '\n'
748
+
749
+ return try_stream(generate(vo=request.environ.get('vo')))
750
+ except ValueError as error:
751
+ return generate_http_error_flask(400, error)
752
+
753
+
754
+ class RuleAnalysis(ErrorHandlingMethodView):
755
+ """ REST APIs for rule analysis. """
756
+
757
+ @check_accept_header_wrapper_flask(['application/json'])
758
+ def get(self, rule_id):
759
+ """
760
+ ---
761
+ summary: Get the analysis of a rule
762
+ tags:
763
+ - Rule
764
+ parameters:
765
+ - name: rule_id
766
+ in: path
767
+ description: The id of the replication rule.
768
+ schema:
769
+ type: string
770
+ style: simple
771
+ responses:
772
+ 200:
773
+ description: OK
774
+ content:
775
+ application/json:
776
+ schema:
777
+ type: object
778
+ properties:
779
+ rule_error:
780
+ type: string
781
+ description: The state of the rule.
782
+ transfers:
783
+ type: array
784
+ description: List of all transfer errors.
785
+ items:
786
+ type: object
787
+ properties:
788
+ scope:
789
+ type: string
790
+ description: The scope of the transfer.
791
+ name:
792
+ type: string
793
+ description: The name of the lock.
794
+ rse_id:
795
+ type: string
796
+ description: The rse_id of the transferred lock.
797
+ rse:
798
+ type: object
799
+ description: Information about the rse of the transferred lock.
800
+ attempts:
801
+ type: integer
802
+ description: The number of attempts.
803
+ last_error:
804
+ type: string
805
+ description: The last error that occurred.
806
+ last_source:
807
+ type: string
808
+ description: The last source.
809
+ sources:
810
+ type: array
811
+ description: All available rse sources.
812
+ last_time:
813
+ type: string
814
+ description: The time of the last transfer.
815
+ 401:
816
+ description: Invalid Auth Token
817
+ 404:
818
+ description: No rule found for the given id
819
+ 406:
820
+ description: Not acceptable.
821
+ """
822
+ analysis = examine_replication_rule(rule_id, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
823
+ return Response(render_json(**analysis), content_type='application/json')
824
+
825
+
826
+ def blueprint():
827
+ bp = AuthenticatedBlueprint('rules', __name__, url_prefix='/rules')
828
+
829
+ rule_view = Rule.as_view('rule')
830
+ bp.add_url_rule('/<rule_id>', view_func=rule_view, methods=['get', 'put', 'delete'])
831
+ all_rule_view = AllRule.as_view('all_rule')
832
+ bp.add_url_rule('/', view_func=all_rule_view, methods=['get', 'post'])
833
+ replica_locks_view = ReplicaLocks.as_view('replica_locks')
834
+ bp.add_url_rule('/<rule_id>/locks', view_func=replica_locks_view, methods=['get', ])
835
+ reduce_rule_view = ReduceRule.as_view('reduce_rule')
836
+ bp.add_url_rule('/<rule_id>/reduce', view_func=reduce_rule_view, methods=['post', ])
837
+ move_rule_view = MoveRule.as_view('move_rule')
838
+ bp.add_url_rule('/<rule_id>/move', view_func=move_rule_view, methods=['post', ])
839
+ rule_history_view = RuleHistory.as_view('rule_history')
840
+ bp.add_url_rule('/<rule_id>/history', view_func=rule_history_view, methods=['get', ])
841
+ rule_history_full_view = RuleHistoryFull.as_view('rule_history_full')
842
+ bp.add_url_rule('/<path:scope_name>/history', view_func=rule_history_full_view, methods=['get', ])
843
+ rule_analysis_view = RuleAnalysis.as_view('rule_analysis')
844
+ bp.add_url_rule('/<rule_id>/analysis', view_func=rule_analysis_view, methods=['get', ])
845
+
846
+ bp.after_request(response_headers)
847
+ return bp
848
+
849
+
850
+ def make_doc():
851
+ """ Only used for sphinx documentation """
852
+ doc_app = Flask(__name__)
853
+ doc_app.register_blueprint(blueprint())
854
+ return doc_app