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,824 @@
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
+ from typing import Any
18
+
19
+ from flask import Flask, request, Response
20
+
21
+ from rucio.api.lock import get_replica_locks_for_rule_id
22
+ from rucio.api.rule import add_replication_rule, delete_replication_rule, get_replication_rule, \
23
+ update_replication_rule, reduce_replication_rule, list_replication_rule_history, \
24
+ list_replication_rule_full_history, list_replication_rules, examine_replication_rule, move_replication_rule
25
+ from rucio.common.exception import InputValidationError, InsufficientAccountLimit, RuleNotFound, AccessDenied, InvalidRSEExpression, \
26
+ InvalidReplicationRule, DataIdentifierNotFound, InsufficientTargetRSEs, ReplicationRuleCreationTemporaryFailed, \
27
+ InvalidRuleWeight, StagingAreaRuleRequiresLifetime, DuplicateRule, InvalidObject, AccountNotFound, \
28
+ RuleReplaceFailed, ScratchDiskLifetimeConflict, ManualRuleApprovalBlocked, UnsupportedOperation
29
+ from rucio.common.utils import render_json, APIEncoder
30
+ from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
31
+ from rucio.web.rest.flaskapi.v1.common import check_accept_header_wrapper_flask, parse_scope_name, try_stream, \
32
+ response_headers, generate_http_error_flask, ErrorHandlingMethodView, json_parameters, param_get
33
+
34
+
35
+ class Rule(ErrorHandlingMethodView):
36
+ """ REST APIs for replication rules. """
37
+
38
+ @check_accept_header_wrapper_flask(['application/json'])
39
+ def get(self, rule_id):
40
+ """
41
+ ---
42
+ summary: Return a Rule
43
+ tags:
44
+ - Rule
45
+ parameters:
46
+ - name: rule_id
47
+ in: path
48
+ description: The id of the replication rule.
49
+ schema:
50
+ type: string
51
+ style: simple
52
+ responses:
53
+ 200:
54
+ description: OK
55
+ content:
56
+ application/json:
57
+ schema:
58
+ type: string
59
+ 406:
60
+ description: Not Acceptable
61
+ 401:
62
+ description: Invalid Auth Token
63
+ 404:
64
+ description: No rule found for the given id
65
+ """
66
+ parameters = json_parameters(optional=True)
67
+ estimate_ttc = param_get(parameters, 'estimate_ttc', default=False)
68
+ if estimate_ttc:
69
+ return generate_http_error_flask(501, "NotImplemented", exc_msg="estimate_ttc is not implemented!")
70
+
71
+ try:
72
+ rule = get_replication_rule(rule_id, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
73
+ except RuleNotFound as error:
74
+ return generate_http_error_flask(404, error)
75
+
76
+ return Response(render_json(**rule), content_type="application/json")
77
+
78
+ def put(self, rule_id):
79
+ """
80
+ ---
81
+ summary: Update the replication rules parameters
82
+ tags:
83
+ - Rule
84
+ parameters:
85
+ - name: rule_id
86
+ in: path
87
+ description: The id of the replication rule.
88
+ schema:
89
+ type: string
90
+ style: simple
91
+ requestBody:
92
+ description: Parameters for the new rule.
93
+ content:
94
+ 'application/json':
95
+ schema:
96
+ type: object
97
+ required:
98
+ - options
99
+ properties:
100
+ options:
101
+ description: The parameters to change.
102
+ type: object
103
+ properties:
104
+ lifetime:
105
+ description: The time in which the rule will expire in seconds.
106
+ type: integer
107
+ account:
108
+ description: The account of the replication rule.
109
+ type: string
110
+ state:
111
+ description: The state of the replication rule.
112
+ type: string
113
+ cancel_requests:
114
+ description: Cancels all requests if used together with state.
115
+ type: boolean
116
+ priority:
117
+ description: The priority of a rule.
118
+ type: integer
119
+ child_rule_id:
120
+ description: The child rule. Parent and child rule must be on the same dataset.
121
+ type: string
122
+ meta:
123
+ description: The meta of a rule.
124
+ type: object
125
+ boost_rule:
126
+ description: Boosts the processing of a rule.
127
+ type: object
128
+ locked:
129
+ description: The locked state of the replication rule.
130
+ type: boolean
131
+ comment:
132
+ description: The comment of the replication rule.
133
+ type: string
134
+ activity:
135
+ description: The activity of a replication rule.
136
+ type: string
137
+ source_replica_expression:
138
+ description: The source replica expression of a replication rule.
139
+ type: string
140
+ eol_at:
141
+ description: The end of life of a replication rule.
142
+ type: string
143
+ purge_replicas:
144
+ description: Purge replicas
145
+ type: boolean
146
+ responses:
147
+ 200:
148
+ description: OK
149
+ 401:
150
+ description: Invalid Auth Token
151
+ 404:
152
+ description: No rule found for the given id
153
+ """
154
+ parameters = json_parameters()
155
+ options: dict[str, Any] = param_get(parameters, 'options')
156
+ try:
157
+ update_replication_rule(rule_id=rule_id, options=options, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
158
+ except AccessDenied as error:
159
+ return generate_http_error_flask(401, error)
160
+ except (RuleNotFound, AccountNotFound) as error:
161
+ return generate_http_error_flask(404, error)
162
+ except (ScratchDiskLifetimeConflict,
163
+ UnsupportedOperation, InputValidationError) as error:
164
+ return generate_http_error_flask(409, error)
165
+
166
+ return '', 200
167
+
168
+ def delete(self, rule_id):
169
+ """
170
+ ---
171
+ summary: Delete a replication rule
172
+ tags:
173
+ - Rule
174
+ parameters:
175
+ - name: rule_id
176
+ in: path
177
+ description: The id of the replication rule.
178
+ schema:
179
+ type: string
180
+ style: simple
181
+ responses:
182
+ 200:
183
+ description: OK
184
+ 401:
185
+ description: Invalid Auth Token
186
+ 404:
187
+ description: No rule found for the given id
188
+ """
189
+ parameters = json_parameters()
190
+ purge_replicas = param_get(parameters, 'purge_replicas', default=None)
191
+ try:
192
+ delete_replication_rule(rule_id=rule_id, purge_replicas=purge_replicas, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
193
+ except (AccessDenied, UnsupportedOperation) as error:
194
+ return generate_http_error_flask(401, error)
195
+ except RuleNotFound as error:
196
+ return generate_http_error_flask(404, error)
197
+
198
+ return '', 200
199
+
200
+
201
+ class AllRule(ErrorHandlingMethodView):
202
+ """ REST APIs for all rules. """
203
+
204
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
205
+ def get(self):
206
+ """
207
+ ---
208
+ summary: Return all rules for a given account
209
+ tags:
210
+ - Rule
211
+ responses:
212
+ 200:
213
+ description: OK
214
+ content:
215
+ application/json:
216
+ schema:
217
+ type: string
218
+ 401:
219
+ description: Invalid Auth Token
220
+ 404:
221
+ description: No rule found for the given id
222
+ 406:
223
+ description: Not Acceptable
224
+ """
225
+ try:
226
+ def generate(filters, vo):
227
+ for rule in list_replication_rules(filters=filters, vo=vo):
228
+ yield dumps(rule, cls=APIEncoder) + '\n'
229
+
230
+ return try_stream(generate(filters=dict(request.args.items(multi=False)), vo=request.environ.get('vo')))
231
+ except RuleNotFound as error:
232
+ return generate_http_error_flask(404, error)
233
+
234
+ def post(self):
235
+ """
236
+ ---
237
+ summary: Create a new replication rule
238
+ tags:
239
+ - Rule
240
+ requestBody:
241
+ description: Parameters for the new rule.
242
+ content:
243
+ 'application/json':
244
+ schema:
245
+ type: object
246
+ required:
247
+ - dids
248
+ - account
249
+ - copies
250
+ - rse_expression
251
+ properties:
252
+ dids:
253
+ description: The list of data identifiers.
254
+ type: array
255
+ items:
256
+ type: string
257
+ account:
258
+ description: The account of the issuer.
259
+ type: string
260
+ copies:
261
+ description: The number of replicas.
262
+ type: integer
263
+ rse_expression:
264
+ description: The rse expression which gets resolved into a list of RSEs.
265
+ type: string
266
+ grouping:
267
+ description: The grouping of the files to take into account. (ALL, DATASET, NONE)
268
+ type: string
269
+ weight:
270
+ description: Weighting scheme to be used.
271
+ type: number
272
+ lifetime:
273
+ description: The lifetime of the replication rule in seconds.
274
+ type: integer
275
+ locked:
276
+ description: If the rule is locked.
277
+ type: boolean
278
+ subscription_id:
279
+ description: The subscription_id, if the rule is created by a subscription.
280
+ type: string
281
+ sourse_replica_expression:
282
+ description: Only use replicas as source from these RSEs.
283
+ type: string
284
+ activity:
285
+ description: Activity to be passed to the conveyor.
286
+ type: string
287
+ notify:
288
+ description: Notification setting of the rule ('Y', 'N', 'C'; None = 'N').
289
+ type: string
290
+ purge_replicas:
291
+ description: Purge setting if a replica should be directly deleted after the rule is deleted.
292
+ type: boolean
293
+ ignore_availability:
294
+ description: Option to ignore the availability of RSEs.
295
+ type: boolean
296
+ comments:
297
+ description: Comment about the rule.
298
+ type: string
299
+ ask_approval:
300
+ description: Ask for approval for this rule.
301
+ type: boolean
302
+ asynchronous:
303
+ description: Create replication rule asynchronously by the judge-injector.
304
+ type: boolean
305
+ priority:
306
+ description: Priority of the rule and the transfers which should be submitted.
307
+ type: integer
308
+ split_container:
309
+ description: Should a container rule be split into individual dataset rules.
310
+ type: boolean
311
+ meta:
312
+ description: Dictionary with metadata from the WFMS.
313
+ type: string
314
+ responses:
315
+ 201:
316
+ description: Rule created.
317
+ content:
318
+ application/json:
319
+ schema:
320
+ type: array
321
+ items:
322
+ type: string
323
+ description: Id of each created rule.
324
+ 401:
325
+ description: Invalid Auth Token
326
+ 404:
327
+ description: No rule found for the given id
328
+ 409:
329
+ description: |
330
+ - Invalid Replication Rule
331
+ - Duplicate Replication Rule
332
+ - Insufficient Target RSEs
333
+ - Insufficient Account Limit
334
+ - Invalid RSE Expression
335
+ - Replication Rule Creation Temporary Failed,
336
+ - Invalid Rule Weight
337
+ - Staging Area Rule Requires Lifetime
338
+ - Scratch Disk Lifetime Conflict
339
+ - Manual Rule Approval Blocked
340
+ - Invalid Object
341
+ """
342
+ parameters = json_parameters()
343
+ dids = param_get(parameters, 'dids')
344
+ account = param_get(parameters, 'account')
345
+ copies = param_get(parameters, 'copies')
346
+ rse_expression = param_get(parameters, 'rse_expression')
347
+ try:
348
+ rule_ids = add_replication_rule(
349
+ dids=dids,
350
+ copies=copies,
351
+ rse_expression=rse_expression,
352
+ weight=param_get(parameters, 'weight', default=None),
353
+ lifetime=param_get(parameters, 'lifetime', default=None),
354
+ grouping=param_get(parameters, 'grouping', default='DATASET'),
355
+ account=account,
356
+ locked=param_get(parameters, 'locked', default=False),
357
+ subscription_id=param_get(parameters, 'subscription_id', default=None),
358
+ source_replica_expression=param_get(parameters, 'source_replica_expression', default=None),
359
+ activity=param_get(parameters, 'activity', default=None),
360
+ notify=param_get(parameters, 'notify', default=None),
361
+ purge_replicas=param_get(parameters, 'purge_replicas', default=False),
362
+ ignore_availability=param_get(parameters, 'ignore_availability', default=False),
363
+ comment=param_get(parameters, 'comment', default=None),
364
+ ask_approval=param_get(parameters, 'ask_approval', default=False),
365
+ asynchronous=param_get(parameters, 'asynchronous', default=False),
366
+ delay_injection=param_get(parameters, 'delay_injection', default=None),
367
+ priority=param_get(parameters, 'priority', default=3),
368
+ split_container=param_get(parameters, 'split_container', default=False),
369
+ meta=param_get(parameters, 'meta', default=None),
370
+ issuer=request.environ.get('issuer'),
371
+ vo=request.environ.get('vo'),
372
+ )
373
+ except (
374
+ InvalidReplicationRule,
375
+ DuplicateRule,
376
+ InsufficientTargetRSEs,
377
+ InsufficientAccountLimit,
378
+ InvalidRSEExpression,
379
+ ReplicationRuleCreationTemporaryFailed,
380
+ InvalidRuleWeight,
381
+ StagingAreaRuleRequiresLifetime,
382
+ ScratchDiskLifetimeConflict,
383
+ ManualRuleApprovalBlocked,
384
+ InvalidObject,
385
+ ) as error:
386
+ return generate_http_error_flask(409, error)
387
+ except DataIdentifierNotFound as error:
388
+ return generate_http_error_flask(404, error)
389
+
390
+ return Response(dumps(rule_ids), status=201)
391
+
392
+
393
+ class ReplicaLocks(ErrorHandlingMethodView):
394
+ """ REST APIs for replica locks. """
395
+
396
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
397
+ def get(self, rule_id):
398
+ """
399
+ ---
400
+ summary: Return all locks for a Rule
401
+ tags:
402
+ - Rule
403
+ parameters:
404
+ - name: rule_id
405
+ in: path
406
+ description: The id of the replication rule.
407
+ schema:
408
+ type: string
409
+ style: simple
410
+ responses:
411
+ 200:
412
+ description: OK
413
+ content:
414
+ application/json:
415
+ schema:
416
+ type: array
417
+ items:
418
+ type: object
419
+ properties:
420
+ scope:
421
+ description: The scope of the lock.
422
+ type: string
423
+ name:
424
+ description: The name of the lock.
425
+ type: string
426
+ rse_id:
427
+ description: The rse_id of the lock.
428
+ type: string
429
+ rse:
430
+ description: Information about the rse of the lock.
431
+ type: object
432
+ state:
433
+ description: The state of the lock.
434
+ type: string
435
+ rule_id:
436
+ description: The rule_id of the lock.
437
+ type: string
438
+ 401:
439
+ description: Invalid Auth Token
440
+ 404:
441
+ description: No rule found for the given id
442
+ 406:
443
+ description: Not Acceptable
444
+ """
445
+
446
+ def generate(vo):
447
+ for lock in get_replica_locks_for_rule_id(rule_id, vo=vo):
448
+ yield render_json(**lock) + '\n'
449
+
450
+ return try_stream(generate(vo=request.environ.get('vo')))
451
+
452
+
453
+ class ReduceRule(ErrorHandlingMethodView):
454
+ """ REST APIs for reducing rules. """
455
+
456
+ def post(self, rule_id):
457
+ """
458
+ ---
459
+ summary: Reduce a replication rule
460
+ tags:
461
+ - Rule
462
+ parameters:
463
+ - name: rule_id
464
+ in: path
465
+ description: The id of the replication rule.
466
+ schema:
467
+ type: string
468
+ style: simple
469
+ requestBody:
470
+ content:
471
+ 'application/json':
472
+ schema:
473
+ type: object
474
+ required:
475
+ - copies
476
+ properties:
477
+ copies:
478
+ description: Number of copies to keep.
479
+ type: integer
480
+ responses:
481
+ 200:
482
+ description: OK
483
+ content:
484
+ application/json:
485
+ schema:
486
+ type: array
487
+ items:
488
+ type: string
489
+ description: Rule id.
490
+ 401:
491
+ description: Invalid Auth Token
492
+ 404:
493
+ description: No rule found for the given id
494
+ 409:
495
+ description: Rule replace failed.
496
+ """
497
+ parameters = json_parameters()
498
+ copies = param_get(parameters, 'copies')
499
+ exclude_expression = param_get(parameters, 'exclude_expression', default=None)
500
+ try:
501
+ rule_ids = reduce_replication_rule(rule_id=rule_id,
502
+ copies=copies,
503
+ exclude_expression=exclude_expression,
504
+ issuer=request.environ.get('issuer'),
505
+ vo=request.environ.get('vo'))
506
+ # TODO: Add all other error cases here
507
+ except RuleReplaceFailed as error:
508
+ return generate_http_error_flask(409, error)
509
+ except RuleNotFound as error:
510
+ return generate_http_error_flask(404, error)
511
+
512
+ return Response(dumps(rule_ids), status=201)
513
+
514
+
515
+ class MoveRule(ErrorHandlingMethodView):
516
+ """ REST APIs for moving rules. """
517
+
518
+ def post(self, rule_id):
519
+ """
520
+ ---
521
+ summary: Move a replication Rule
522
+ tags:
523
+ - Rule
524
+ parameters:
525
+ - name: rule_id
526
+ in: path
527
+ description: The id of the replication rule.
528
+ schema:
529
+ type: string
530
+ style: simple
531
+ requestBody:
532
+ content:
533
+ 'application/json':
534
+ schema:
535
+ type: object
536
+ required:
537
+ - rse_expression
538
+ properties:
539
+ rse_expression:
540
+ description: The new rse expression.
541
+ type: string
542
+ rule_id:
543
+ description: The rule_id of the rule to moves. If specified, overrides the `rule_id` parameter.
544
+ type: string
545
+ activity:
546
+ description: The `activity` of the moved rule.
547
+ type: string
548
+ source_replica_expression:
549
+ description: The `source_replica_expression` of the moved rule.
550
+ type: string
551
+ responses:
552
+ 200:
553
+ description: OK
554
+ content:
555
+ application/json:
556
+ schema:
557
+ type: array
558
+ items:
559
+ type: string
560
+ description: Rule id.
561
+ 401:
562
+ description: Invalid Auth Token
563
+ 404:
564
+ description: No rule found for the given id
565
+ 409:
566
+ description: Rule replace failed.
567
+ """
568
+ parameters = json_parameters()
569
+ rse_expression = param_get(parameters, 'rse_expression')
570
+ rule_id = param_get(parameters, 'rule_id', default=rule_id)
571
+ override = param_get(parameters, 'override', default={})
572
+
573
+ # For backwards-compatibility, deprecate in the future.
574
+ activity = param_get(parameters, 'activity', default=None)
575
+ if activity and 'activity' not in override:
576
+ override['activity'] = activity
577
+ source_replica_expression = param_get(parameters, 'source_replica_expression', default=None)
578
+ if source_replica_expression and 'source_replica_expression' not in override:
579
+ override['source_replica_expression'] = source_replica_expression
580
+
581
+ try:
582
+ rule_ids = move_replication_rule(rule_id=rule_id,
583
+ rse_expression=rse_expression,
584
+ override=override,
585
+ issuer=request.environ.get('issuer'),
586
+ vo=request.environ.get('vo'))
587
+ except RuleReplaceFailed as error:
588
+ return generate_http_error_flask(409, error)
589
+ except RuleNotFound as error:
590
+ return generate_http_error_flask(404, error)
591
+
592
+ return Response(dumps(rule_ids), status=201)
593
+
594
+
595
+ class RuleHistory(ErrorHandlingMethodView):
596
+ """ REST APIs for rule history. """
597
+
598
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
599
+ def get(self, rule_id):
600
+ """
601
+ ---
602
+ summary: Get the history of a rule
603
+ tags:
604
+ - Rule
605
+ parameters:
606
+ - name: rule_id
607
+ in: path
608
+ description: The id of the replication rule.
609
+ schema:
610
+ type: string
611
+ style: simple
612
+ responses:
613
+ 200:
614
+ description: OK
615
+ content:
616
+ application/json:
617
+ schema:
618
+ type: array
619
+ items:
620
+ type: object
621
+ description: Rule history object.
622
+ properties:
623
+ updated_at:
624
+ type: string
625
+ description: The date of the update.
626
+ state:
627
+ type: string
628
+ description: The state of the update.
629
+ locks_ok_cnt:
630
+ type: integer
631
+ description: The number of locks which are ok.
632
+ locks_stuck_cnt:
633
+ type: integer
634
+ description: The number of locks which are stuck.
635
+ locks_replicating_cnt:
636
+ type: integer
637
+ description: The number of locks which are replicating.
638
+ 401:
639
+ description: Invalid Auth Token
640
+ 404:
641
+ description: No rule found for the given id
642
+ 406:
643
+ description: Not acceptable.
644
+ """
645
+ def generate(issuer, vo):
646
+ for history in list_replication_rule_history(rule_id, issuer=issuer, vo=vo):
647
+ yield render_json(**history) + '\n'
648
+
649
+ return try_stream(generate(issuer=request.environ.get('issuer'), vo=request.environ.get('vo')))
650
+
651
+
652
+ class RuleHistoryFull(ErrorHandlingMethodView):
653
+ """ REST APIs for rule history for DIDs. """
654
+
655
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
656
+ def get(self, scope_name):
657
+ """
658
+ ---
659
+ summary: Get the history of a DID
660
+ tags:
661
+ - Rule
662
+ parameters:
663
+ - name: scope_name
664
+ in: path
665
+ description: The data identifier of scope-name to retrieve the history from. ((scope)/(name))
666
+ schema:
667
+ type: string
668
+ style: simple
669
+ responses:
670
+ 200:
671
+ description: OK
672
+ content:
673
+ application/x-json-stream:
674
+ schema:
675
+ type: array
676
+ items:
677
+ type: object
678
+ description: Rule history object.
679
+ properties:
680
+ rule_id:
681
+ type: string
682
+ description: The id of the rule.
683
+ updated_at:
684
+ type: string
685
+ description: The date of the update.
686
+ created_at:
687
+ type: string
688
+ description: The date of the creation.
689
+ rse_expression:
690
+ type: string
691
+ description: The rse expression.
692
+ state:
693
+ type: string
694
+ description: The state of the update.
695
+ account:
696
+ type: string
697
+ description: The account who initiated the change.
698
+ locks_ok_cnt:
699
+ type: integer
700
+ description: The number of locks which are ok.
701
+ locks_stuck_cnt:
702
+ type: integer
703
+ description: The number of locks which are stuck.
704
+ locks_replicating_cnt:
705
+ type: integer
706
+ description: The number of locks which are replicating.
707
+ 401:
708
+ description: Invalid Auth Token
709
+ 406:
710
+ description: Not acceptable.
711
+ """
712
+ try:
713
+ scope, name = parse_scope_name(scope_name, request.environ.get('vo'))
714
+
715
+ def generate(vo):
716
+ for history in list_replication_rule_full_history(scope, name, vo=vo):
717
+ yield render_json(**history) + '\n'
718
+
719
+ return try_stream(generate(vo=request.environ.get('vo')))
720
+ except ValueError as error:
721
+ return generate_http_error_flask(400, error)
722
+
723
+
724
+ class RuleAnalysis(ErrorHandlingMethodView):
725
+ """ REST APIs for rule analysis. """
726
+
727
+ @check_accept_header_wrapper_flask(['application/json'])
728
+ def get(self, rule_id):
729
+ """
730
+ ---
731
+ summary: Get the analysis of a rule
732
+ tags:
733
+ - Rule
734
+ parameters:
735
+ - name: rule_id
736
+ in: path
737
+ description: The id of the replication rule.
738
+ schema:
739
+ type: string
740
+ style: simple
741
+ responses:
742
+ 200:
743
+ description: OK
744
+ content:
745
+ application/json:
746
+ schema:
747
+ type: object
748
+ properties:
749
+ rule_error:
750
+ type: string
751
+ description: The state of the rule.
752
+ transfers:
753
+ type: array
754
+ description: List of all transfer errors.
755
+ items:
756
+ type: object
757
+ properties:
758
+ scope:
759
+ type: string
760
+ description: The scope of the transfer.
761
+ name:
762
+ type: string
763
+ description: The name of the lock.
764
+ rse_id:
765
+ type: string
766
+ description: The rse_id of the transfered lock.
767
+ rse:
768
+ type: object
769
+ description: Information about the rse of the transfered lock.
770
+ attempts:
771
+ type: integer
772
+ description: The number of attempts.
773
+ last_error:
774
+ type: string
775
+ description: The last error that occured.
776
+ last_source:
777
+ type: string
778
+ description: The last source.
779
+ sources:
780
+ type: array
781
+ description: All available rse sources.
782
+ last_time:
783
+ type: string
784
+ description: The time of the last transfer.
785
+ 401:
786
+ description: Invalid Auth Token
787
+ 404:
788
+ description: No rule found for the given id
789
+ 406:
790
+ description: Not acceptable.
791
+ """
792
+ analysis = examine_replication_rule(rule_id, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
793
+ return Response(render_json(**analysis), content_type='application/json')
794
+
795
+
796
+ def blueprint():
797
+ bp = AuthenticatedBlueprint('rules', __name__, url_prefix='/rules')
798
+
799
+ rule_view = Rule.as_view('rule')
800
+ bp.add_url_rule('/<rule_id>', view_func=rule_view, methods=['get', 'put', 'delete'])
801
+ all_rule_view = AllRule.as_view('all_rule')
802
+ bp.add_url_rule('/', view_func=all_rule_view, methods=['get', 'post'])
803
+ replica_locks_view = ReplicaLocks.as_view('replica_locks')
804
+ bp.add_url_rule('/<rule_id>/locks', view_func=replica_locks_view, methods=['get', ])
805
+ reduce_rule_view = ReduceRule.as_view('reduce_rule')
806
+ bp.add_url_rule('/<rule_id>/reduce', view_func=reduce_rule_view, methods=['post', ])
807
+ move_rule_view = MoveRule.as_view('move_rule')
808
+ bp.add_url_rule('/<rule_id>/move', view_func=move_rule_view, methods=['post', ])
809
+ rule_history_view = RuleHistory.as_view('rule_history')
810
+ bp.add_url_rule('/<rule_id>/history', view_func=rule_history_view, methods=['get', ])
811
+ rule_history_full_view = RuleHistoryFull.as_view('rule_history_full')
812
+ bp.add_url_rule('/<path:scope_name>/history', view_func=rule_history_full_view, methods=['get', ])
813
+ rule_analysis_view = RuleAnalysis.as_view('rule_analysis')
814
+ bp.add_url_rule('/<rule_id>/analysis', view_func=rule_analysis_view, methods=['get', ])
815
+
816
+ bp.after_request(response_headers)
817
+ return bp
818
+
819
+
820
+ def make_doc():
821
+ """ Only used for sphinx documentation """
822
+ doc_app = Flask(__name__)
823
+ doc_app.register_blueprint(blueprint())
824
+ return doc_app