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
rucio/api/did.py ADDED
@@ -0,0 +1,726 @@
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 copy import deepcopy
17
+ from typing import TYPE_CHECKING
18
+
19
+ import rucio.api.permission
20
+ from rucio.common.constants import RESERVED_KEYS
21
+ from rucio.common.exception import RucioException
22
+ from rucio.common.schema import validate_schema
23
+ from rucio.common.types import InternalAccount, InternalScope
24
+ from rucio.common.utils import api_update_return_dict
25
+ from rucio.core import did, naming_convention, meta as meta_core
26
+ from rucio.core.rse import get_rse_id
27
+ from rucio.db.sqla.constants import DIDType
28
+ from rucio.db.sqla.session import read_session, stream_session, transactional_session
29
+
30
+ if TYPE_CHECKING:
31
+ from typing import Any, Optional
32
+ from sqlalchemy.orm import Session
33
+
34
+
35
+ @stream_session
36
+ def list_dids(scope, filters, did_type='collection', ignore_case=False, limit=None, offset=None, long=False, recursive=False, vo='def', *, session: "Session"):
37
+ """
38
+ List dids in a scope.
39
+
40
+ :param scope: The scope name.
41
+ :param filters: Filter arguments in form supported by the filter engine.
42
+ :param did_type: The type of the did: all(container, dataset, file), collection(dataset or container), dataset, container
43
+ :param ignore_case: Ignore case distinctions.
44
+ :param limit: The maximum number of DIDs returned.
45
+ :param offset: Offset number.
46
+ :param long: Long format option to display more information for each DID.
47
+ :param recursive: Recursively list DIDs content.
48
+ :param vo: The VO to act on.
49
+ :param session: The database session in use.
50
+ """
51
+ scope = InternalScope(scope, vo=vo)
52
+
53
+ # replace account and scope in filters with internal representation
54
+ for or_group in filters:
55
+ if 'account' in or_group:
56
+ or_group['account'] = InternalAccount(or_group['account'], vo=vo)
57
+ if 'scope' in or_group:
58
+ or_group['account'] = InternalScope(or_group['scope'], vo=vo)
59
+
60
+ result = did.list_dids(scope=scope, filters=filters, did_type=did_type, ignore_case=ignore_case,
61
+ limit=limit, offset=offset, long=long, recursive=recursive, session=session)
62
+
63
+ for d in result:
64
+ yield api_update_return_dict(d, session=session)
65
+
66
+
67
+ @transactional_session
68
+ def add_did(scope, name, did_type, issuer, account=None, statuses={}, meta={}, rules=[], lifetime=None, dids=[], rse=None, vo='def', *, session: "Session"):
69
+ """
70
+ Add data did.
71
+
72
+ :param scope: The scope name.
73
+ :param name: The data identifier name.
74
+ :param did_type: The data identifier type.
75
+ :param issuer: The issuer account.
76
+ :param account: The account owner. If None, then issuer is selected as owner.
77
+ :param statuses: Dictionary with statuses, e.g.g {'monotonic':True}.
78
+ :meta: Meta-data associated with the data identifier is represented using key/value pairs in a dictionary.
79
+ :rules: Replication rules associated with the data did. A list of dictionaries, e.g., [{'copies': 2, 'rse_expression': 'TIERS1'}, ].
80
+ :param lifetime: DID's lifetime (in seconds).
81
+ :param dids: The content.
82
+ :param rse: The RSE name when registering replicas.
83
+ :param vo: The VO to act on.
84
+ :param session: The database session in use.
85
+ """
86
+ v_did = {'name': name, 'type': did_type.upper(), 'scope': scope}
87
+ validate_schema(name='did', obj=v_did, vo=vo)
88
+ validate_schema(name='dids', obj=dids, vo=vo)
89
+ validate_schema(name='rse', obj=rse, vo=vo)
90
+ kwargs = {'scope': scope, 'name': name, 'type': did_type, 'issuer': issuer, 'account': account, 'statuses': statuses, 'meta': meta, 'rules': rules, 'lifetime': lifetime}
91
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='add_did', kwargs=kwargs, session=session):
92
+ raise rucio.common.exception.AccessDenied('Account %s can not add data identifier to scope %s' % (issuer, scope))
93
+
94
+ if account is not None:
95
+ account = InternalAccount(account, vo=vo)
96
+ issuer = InternalAccount(issuer, vo=vo)
97
+ scope = InternalScope(scope, vo=vo)
98
+ for d in dids:
99
+ d['scope'] = InternalScope(d['scope'], vo=vo)
100
+ for r in rules:
101
+ r['account'] = InternalAccount(r['account'], vo=vo)
102
+
103
+ rse_id = None
104
+ if rse is not None:
105
+ rse_id = get_rse_id(rse=rse, vo=vo, session=session)
106
+
107
+ if did_type == 'DATASET':
108
+ # naming_convention validation
109
+ extra_meta = naming_convention.validate_name(scope=scope, name=name, did_type='D', session=session)
110
+
111
+ # merge extra_meta with meta
112
+ for k in extra_meta or {}:
113
+ if k not in meta:
114
+ meta[k] = extra_meta[k]
115
+ elif meta[k] != extra_meta[k]:
116
+ print("Provided metadata %s doesn't match the naming convention: %s != %s" % (k, meta[k], extra_meta[k]))
117
+ raise rucio.common.exception.InvalidObject("Provided metadata %s doesn't match the naming convention: %s != %s" % (k, meta[k], extra_meta[k]))
118
+
119
+ # Validate metadata
120
+ meta_core.validate_meta(meta=meta, did_type=DIDType[did_type.upper()], session=session)
121
+
122
+ return did.add_did(scope=scope, name=name, did_type=DIDType[did_type.upper()], account=account or issuer,
123
+ statuses=statuses, meta=meta, rules=rules, lifetime=lifetime,
124
+ dids=dids, rse_id=rse_id, session=session)
125
+
126
+
127
+ @transactional_session
128
+ def add_dids(dids, issuer, vo='def', *, session: "Session"):
129
+ """
130
+ Bulk Add did.
131
+
132
+ :param dids: A list of dids.
133
+ :param issuer: The issuer account.
134
+ :param vo: The VO to act on.
135
+ :param session: The database session in use.
136
+ """
137
+ for d in dids:
138
+ if 'rse' in d:
139
+ rse_id = None
140
+ if d['rse'] is not None:
141
+ rse_id = get_rse_id(rse=d['rse'], vo=vo, session=session)
142
+ d['rse_id'] = rse_id
143
+
144
+ kwargs = {'issuer': issuer, 'dids': dids}
145
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='add_dids', kwargs=kwargs, session=session):
146
+ raise rucio.common.exception.AccessDenied('Account %s can not bulk add data identifier' % (issuer))
147
+
148
+ issuer = InternalAccount(issuer, vo=vo)
149
+ for d in dids:
150
+ d['scope'] = InternalScope(d['scope'], vo=vo)
151
+ if 'account' in d.keys():
152
+ d['account'] = InternalAccount(d['account'], vo=vo)
153
+ if 'dids' in d.keys():
154
+ for child in d['dids']:
155
+ child['scope'] = InternalScope(child['scope'], vo=vo)
156
+ return did.add_dids(dids, account=issuer, session=session)
157
+
158
+
159
+ @transactional_session
160
+ def attach_dids(scope, name, attachment, issuer, vo='def', *, session: "Session"):
161
+ """
162
+ Append content to data did.
163
+
164
+ :param attachment: The attachment.
165
+ :param issuer: The issuer account.
166
+ :param vo: The VO to act on.
167
+ :param session: The database session in use.
168
+ """
169
+ validate_schema(name='attachment', obj=attachment, vo=vo)
170
+
171
+ rse_id = None
172
+ if 'rse' in attachment:
173
+ if attachment['rse'] is not None:
174
+ rse_id = get_rse_id(rse=attachment['rse'], vo=vo, session=session)
175
+ attachment['rse_id'] = rse_id
176
+
177
+ kwargs = {'scope': scope, 'name': name, 'attachment': attachment}
178
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='attach_dids', kwargs=kwargs, session=session):
179
+ raise rucio.common.exception.AccessDenied('Account %s can not add data identifiers to %s:%s' % (issuer, scope, name))
180
+
181
+ scope = InternalScope(scope, vo=vo)
182
+ issuer = InternalAccount(issuer, vo=vo)
183
+ if 'account' in attachment.keys():
184
+ attachment['account'] = InternalAccount(attachment['account'], vo=vo)
185
+ for d in attachment['dids']:
186
+ d['scope'] = InternalScope(d['scope'], vo=vo)
187
+ if 'account' in d.keys():
188
+ d['account'] = InternalAccount(d['account'], vo=vo)
189
+
190
+ if rse_id is not None:
191
+ dids = did.attach_dids(scope=scope, name=name, dids=attachment['dids'],
192
+ account=attachment.get('account', issuer), rse_id=rse_id, session=session)
193
+ else:
194
+ dids = did.attach_dids(scope=scope, name=name, dids=attachment['dids'],
195
+ account=attachment.get('account', issuer), session=session)
196
+
197
+ return dids
198
+
199
+
200
+ @transactional_session
201
+ def attach_dids_to_dids(attachments, issuer, ignore_duplicate=False, vo='def', *, session: "Session"):
202
+ """
203
+ Append content to dids.
204
+
205
+ :param attachments: The contents.
206
+ :param issuer: The issuer account.
207
+ :param ignore_duplicate: If True, ignore duplicate entries.
208
+ :param vo: The VO to act on.
209
+ :param session: The database session in use.
210
+ """
211
+ validate_schema(name='attachments', obj=attachments, vo=vo)
212
+
213
+ for a in attachments:
214
+ if 'rse' in a:
215
+ rse_id = None
216
+ if a['rse'] is not None:
217
+ rse_id = get_rse_id(rse=a['rse'], vo=vo, session=session)
218
+ a['rse_id'] = rse_id
219
+
220
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='attach_dids_to_dids', kwargs={'attachments': attachments}, session=session):
221
+ raise rucio.common.exception.AccessDenied('Account %s can not add data identifiers' % (issuer))
222
+
223
+ issuer = InternalAccount(issuer, vo=vo)
224
+ for attachment in attachments:
225
+ attachment['scope'] = InternalScope(attachment['scope'], vo=vo)
226
+ for d in attachment['dids']:
227
+ d['scope'] = InternalScope(d['scope'], vo=vo)
228
+ if 'account' in d.keys():
229
+ d['account'] = InternalAccount(d['account'], vo=vo)
230
+
231
+ return did.attach_dids_to_dids(attachments=attachments, account=issuer,
232
+ ignore_duplicate=ignore_duplicate, session=session)
233
+
234
+
235
+ @transactional_session
236
+ def detach_dids(scope, name, dids, issuer, vo='def', *, session: "Session"):
237
+ """
238
+ Detach data identifier
239
+
240
+ :param scope: The scope name.
241
+ :param name: The data identifier name.
242
+ :param dids: The content.
243
+ :param issuer: The issuer account.
244
+ :param vo: The VO to act on.
245
+ :param session: The database session in use.
246
+ """
247
+ kwargs = {'scope': scope, 'name': name, 'dids': dids, 'issuer': issuer}
248
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='detach_dids', kwargs=kwargs, session=session):
249
+ raise rucio.common.exception.AccessDenied('Account %s can not detach data identifiers from %s:%s' % (issuer, scope, name))
250
+
251
+ scope = InternalScope(scope, vo=vo)
252
+ for d in dids:
253
+ d['scope'] = InternalScope(d['scope'], vo=vo)
254
+
255
+ return did.detach_dids(scope=scope, name=name, dids=dids, session=session)
256
+
257
+
258
+ @stream_session
259
+ def list_new_dids(did_type=None, thread=None, total_threads=None, chunk_size=1000, vo='def', *, session: "Session"):
260
+ """
261
+ List recent identifiers.
262
+
263
+ :param did_type : The DID type.
264
+ :param thread: The assigned thread for this necromancer.
265
+ :param total_threads: The total number of threads of all necromancers.
266
+ :param chunk_size: Number of requests to return per yield.
267
+ :param vo: The VO to act on.
268
+ :param session: The database session in use.
269
+ """
270
+ dids = did.list_new_dids(did_type=did_type and DIDType[did_type.upper()], thread=thread, total_threads=total_threads, chunk_size=chunk_size, session=session)
271
+ for d in dids:
272
+ if d['scope'].vo == vo:
273
+ yield api_update_return_dict(d, session=session)
274
+
275
+
276
+ @transactional_session
277
+ def set_new_dids(dids, new_flag=True, vo='def', *, session: "Session"):
278
+ """
279
+ Set/reset the flag new
280
+
281
+ :param scope: The scope name.
282
+ :param name: The data identifier name.
283
+ :param new_flag: A boolean to flag new DIDs.
284
+ :param vo: The VO to act on.
285
+ :param session: The database session in use.
286
+ """
287
+ for d in dids:
288
+ d['scope'] = InternalScope(d['scope'], vo=vo)
289
+
290
+ return did.set_new_dids(dids, new_flag, session=session)
291
+
292
+
293
+ @stream_session
294
+ def list_content(scope, name, vo='def', *, session: "Session"):
295
+ """
296
+ List data identifier contents.
297
+
298
+ :param scope: The scope name.
299
+ :param name: The data identifier name.
300
+ :param vo: The VO to act on.
301
+ :param session: The database session in use.
302
+ """
303
+
304
+ scope = InternalScope(scope, vo=vo)
305
+
306
+ dids = did.list_content(scope=scope, name=name, session=session)
307
+ for d in dids:
308
+ yield api_update_return_dict(d, session=session)
309
+
310
+
311
+ @stream_session
312
+ def list_content_history(scope, name, vo='def', *, session: "Session"):
313
+ """
314
+ List data identifier contents history.
315
+
316
+ :param scope: The scope name.
317
+ :param name: The data identifier name.
318
+ :param vo: The VO to act on.
319
+ :param session: The database session in use.
320
+ """
321
+
322
+ scope = InternalScope(scope, vo=vo)
323
+
324
+ dids = did.list_content_history(scope=scope, name=name, session=session)
325
+
326
+ for d in dids:
327
+ yield api_update_return_dict(d, session=session)
328
+
329
+
330
+ @stream_session
331
+ def list_files(scope, name, long, vo='def', *, session: "Session"):
332
+ """
333
+ List data identifier file contents.
334
+
335
+ :param scope: The scope name.
336
+ :param name: The data identifier name.
337
+ :param long: A boolean to choose if GUID is returned or not.
338
+ :param vo: The VO to act on.
339
+ :param session: The database session in use.
340
+ """
341
+
342
+ scope = InternalScope(scope, vo=vo)
343
+
344
+ dids = did.list_files(scope=scope, name=name, long=long, session=session)
345
+
346
+ for d in dids:
347
+ yield api_update_return_dict(d, session=session)
348
+
349
+
350
+ @stream_session
351
+ def scope_list(scope, name=None, recursive=False, vo='def', *, session: "Session"):
352
+ """
353
+ List data identifiers in a scope.
354
+
355
+ :param scope: The scope name.
356
+ :param name: The data identifier name.
357
+ :param recursive: boolean, True or False.
358
+ :param vo: The VO to act on.
359
+ :param session: The database session in use.
360
+ """
361
+
362
+ scope = InternalScope(scope, vo=vo)
363
+
364
+ dids = did.scope_list(scope, name=name, recursive=recursive, session=session)
365
+
366
+ for d in dids:
367
+ ret_did = deepcopy(d)
368
+ ret_did['scope'] = ret_did['scope'].external
369
+ if ret_did['parent'] is not None:
370
+ ret_did['parent']['scope'] = ret_did['parent']['scope'].external
371
+ yield ret_did
372
+
373
+
374
+ @read_session
375
+ def get_did(scope: str, name: str, dynamic_depth: "Optional[DIDType]" = None, vo: str = 'def', *, session: "Session") -> "dict[str, Any]":
376
+ """
377
+ Retrieve a single data did.
378
+
379
+ :param scope: The scope name.
380
+ :param name: The data identifier name.
381
+ :param dynamic_depth: the DID type to use as source for estimation of this DIDs length/bytes.
382
+ If set to None, or to a value which doesn't make sense (ex: requesting depth = CONTAINER for a did of type DATASET)
383
+ will not compute the size dynamically.
384
+ :param vo: The VO to act on.
385
+ :return did: Dictionary containing {'name', 'scope', 'type'}, Exception otherwise
386
+ :param session: The database session in use.
387
+ """
388
+
389
+ scope = InternalScope(scope, vo=vo)
390
+
391
+ d = did.get_did(scope=scope, name=name, dynamic_depth=dynamic_depth, session=session)
392
+ return api_update_return_dict(d, session=session)
393
+
394
+
395
+ @transactional_session
396
+ def set_metadata(scope, name, key, value, issuer, recursive=False, vo='def', *, session: "Session"):
397
+ """
398
+ Add metadata to data did.
399
+
400
+ :param scope: The scope name.
401
+ :param name: The data identifier name.
402
+ :param key: the key.
403
+ :param value: the value.
404
+ :param issuer: The issuer account.
405
+ :param recursive: Option to propagate the metadata update to content.
406
+ :param vo: The VO to act on.
407
+ :param session: The database session in use.
408
+ """
409
+ kwargs = {'scope': scope, 'name': name, 'key': key, 'value': value, 'issuer': issuer}
410
+
411
+ if key in RESERVED_KEYS:
412
+ raise rucio.common.exception.AccessDenied('Account %s can not change this metadata value to data identifier %s:%s' % (issuer, scope, name))
413
+
414
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='set_metadata', kwargs=kwargs, session=session):
415
+ raise rucio.common.exception.AccessDenied('Account %s can not add metadata to data identifier %s:%s' % (issuer, scope, name))
416
+
417
+ scope = InternalScope(scope, vo=vo)
418
+ return did.set_metadata(scope=scope, name=name, key=key, value=value, recursive=recursive, session=session)
419
+
420
+
421
+ @transactional_session
422
+ def set_metadata_bulk(scope, name, meta, issuer, recursive=False, vo='def', *, session: "Session"):
423
+ """
424
+ Add metadata to data did.
425
+
426
+ :param scope: The scope name.
427
+ :param name: The data identifier name.
428
+ :param meta: the key-values.
429
+ :param issuer: The issuer account.
430
+ :param recursive: Option to propagate the metadata update to content.
431
+ :param vo: The VO to act on.
432
+ :param session: The database session in use.
433
+ """
434
+ kwargs = {'scope': scope, 'name': name, 'meta': meta, 'issuer': issuer}
435
+
436
+ for key in meta:
437
+ if key in RESERVED_KEYS:
438
+ raise rucio.common.exception.AccessDenied('Account %s can not change the value of the metadata key %s to data identifier %s:%s' % (issuer, key, scope, name))
439
+
440
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='set_metadata_bulk', kwargs=kwargs, session=session):
441
+ raise rucio.common.exception.AccessDenied('Account %s can not add metadata to data identifier %s:%s' % (issuer, scope, name))
442
+
443
+ scope = InternalScope(scope, vo=vo)
444
+ return did.set_metadata_bulk(scope=scope, name=name, meta=meta, recursive=recursive, session=session)
445
+
446
+
447
+ @transactional_session
448
+ def set_dids_metadata_bulk(dids, issuer, recursive=False, vo='def', *, session: "Session"):
449
+ """
450
+ Add metadata to a list of data identifiers.
451
+
452
+ :param issuer: The issuer account.
453
+ :param dids: A list of dids including metadata.
454
+ :param recursive: Option to propagate the metadata update to content.
455
+ :param vo: The VO to act on.
456
+ :param session: The database session in use.
457
+ """
458
+
459
+ for entry in dids:
460
+ kwargs = {'scope': entry['scope'], 'name': entry['name'], 'meta': entry['meta'], 'issuer': issuer}
461
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='set_metadata_bulk', kwargs=kwargs, session=session):
462
+ raise rucio.common.exception.AccessDenied('Account %s can not add metadata to data identifier %s:%s' % (issuer, entry['scope'], entry['name']))
463
+ entry['scope'] = InternalScope(entry['scope'], vo=vo)
464
+ meta = entry['meta']
465
+ for key in meta:
466
+ if key in RESERVED_KEYS:
467
+ raise rucio.common.exception.AccessDenied('Account %s can not change the value of the metadata key %s to data identifier %s:%s' % (issuer, key, entry['scope'], entry['name']))
468
+
469
+ return did.set_dids_metadata_bulk(dids=dids, recursive=recursive, session=session)
470
+
471
+
472
+ @read_session
473
+ def get_metadata(scope, name, plugin='DID_COLUMN', vo='def', *, session: "Session"):
474
+ """
475
+ Get data identifier metadata
476
+
477
+ :param scope: The scope name.
478
+ :param name: The data identifier name.
479
+ :param vo: The VO to act on.
480
+ :param session: The database session in use.
481
+ """
482
+
483
+ scope = InternalScope(scope, vo=vo)
484
+
485
+ d = did.get_metadata(scope=scope, name=name, plugin=plugin, session=session)
486
+ return api_update_return_dict(d, session=session)
487
+
488
+
489
+ @stream_session
490
+ def get_metadata_bulk(dids, inherit=False, vo='def', *, session: "Session"):
491
+ """
492
+ Get metadata for a list of dids
493
+ :param dids: A list of dids.
494
+ :param inherit: A boolean. If set to true, the metadata of the parent are concatenated.
495
+ :param vo: The VO to act on.
496
+ :param session: The database session in use.
497
+ """
498
+
499
+ validate_schema(name='dids', obj=dids, vo=vo)
500
+ for entry in dids:
501
+ entry['scope'] = InternalScope(entry['scope'], vo=vo)
502
+ meta = did.get_metadata_bulk(dids, inherit=inherit, session=session)
503
+ for met in meta:
504
+ yield api_update_return_dict(met, session=session)
505
+
506
+
507
+ @transactional_session
508
+ def delete_metadata(scope, name, key, vo='def', *, session: "Session"):
509
+ """
510
+ Delete a key from the metadata column
511
+
512
+ :param scope: the scope of did
513
+ :param name: the name of the did
514
+ :param key: the key to be deleted
515
+ :param vo: The VO to act on.
516
+ :param session: The database session in use.
517
+ """
518
+
519
+ scope = InternalScope(scope, vo=vo)
520
+ return did.delete_metadata(scope=scope, name=name, key=key, session=session)
521
+
522
+
523
+ @transactional_session
524
+ def set_status(scope, name, issuer, vo='def', *, session: "Session", **kwargs):
525
+ """
526
+ Set data identifier status
527
+
528
+ :param scope: The scope name.
529
+ :param name: The data identifier name.
530
+ :param issuer: The issuer account.
531
+ :param kwargs: Keyword arguments of the form status_name=value.
532
+ :param vo: The VO to act on.
533
+ :param session: The database session in use.
534
+ """
535
+
536
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='set_status', kwargs={'scope': scope, 'name': name, 'issuer': issuer}, session=session):
537
+ raise rucio.common.exception.AccessDenied('Account %s can not set status on data identifier %s:%s' % (issuer, scope, name))
538
+
539
+ scope = InternalScope(scope, vo=vo)
540
+
541
+ return did.set_status(scope=scope, name=name, session=session, **kwargs)
542
+
543
+
544
+ @stream_session
545
+ def get_dataset_by_guid(guid, vo='def', *, session: "Session"):
546
+ """
547
+ Get the parent datasets for a given GUID.
548
+ :param guid: The GUID.
549
+ :param vo: The VO to act on.
550
+ :param session: The database session in use.
551
+
552
+ :returns: A did
553
+ """
554
+ dids = did.get_dataset_by_guid(guid=guid, session=session)
555
+
556
+ for d in dids:
557
+ if d['scope'].vo != vo:
558
+ raise RucioException('GUID unavailable on VO {}'.format(vo))
559
+ yield api_update_return_dict(d, session=session)
560
+
561
+
562
+ @stream_session
563
+ def list_parent_dids(scope, name, vo='def', *, session: "Session"):
564
+ """
565
+ List parent datasets and containers of a did.
566
+
567
+ :param scope: The scope.
568
+ :param name: The name.
569
+ :param vo: The VO to act on.
570
+ :param session: The database session in use.
571
+ """
572
+
573
+ scope = InternalScope(scope, vo=vo)
574
+
575
+ dids = did.list_parent_dids(scope=scope, name=name, session=session)
576
+
577
+ for d in dids:
578
+ yield api_update_return_dict(d, session=session)
579
+
580
+
581
+ @transactional_session
582
+ def create_did_sample(input_scope, input_name, output_scope, output_name, issuer, nbfiles, vo='def', *, session: "Session"):
583
+ """
584
+ Create a sample from an input collection.
585
+
586
+ :param input_scope: The scope of the input DID.
587
+ :param input_name: The name of the input DID.
588
+ :param output_scope: The scope of the output dataset.
589
+ :param output_name: The name of the output dataset.
590
+ :param account: The account.
591
+ :param nbfiles: The number of files to register in the output dataset.
592
+ :param issuer: The issuer account.
593
+ :param vo: The VO to act on.
594
+ :param session: The database session in use.
595
+ """
596
+ kwargs = {'issuer': issuer, 'scope': output_scope}
597
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='create_did_sample', kwargs=kwargs, session=session):
598
+ raise rucio.common.exception.AccessDenied('Account %s can not bulk add data identifier' % (issuer))
599
+
600
+ input_scope = InternalScope(input_scope, vo=vo)
601
+ output_scope = InternalScope(output_scope, vo=vo)
602
+
603
+ issuer = InternalAccount(issuer, vo=vo)
604
+
605
+ return did.create_did_sample(input_scope=input_scope, input_name=input_name, output_scope=output_scope, output_name=output_name,
606
+ account=issuer, nbfiles=nbfiles, session=session)
607
+
608
+
609
+ @transactional_session
610
+ def resurrect(dids, issuer, vo='def', *, session: "Session"):
611
+ """
612
+ Resurrect DIDs.
613
+
614
+ :param dids: A list of dids.
615
+ :param issuer: The issuer account.
616
+ :param vo: The VO to act on.
617
+ :param session: The database session in use.
618
+ """
619
+ kwargs = {'issuer': issuer}
620
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='resurrect', kwargs=kwargs, session=session):
621
+ raise rucio.common.exception.AccessDenied('Account %s can not resurrect data identifiers' % (issuer))
622
+ validate_schema(name='dids', obj=dids, vo=vo)
623
+
624
+ for d in dids:
625
+ d['scope'] = InternalScope(d['scope'], vo=vo)
626
+
627
+ return did.resurrect(dids=dids, session=session)
628
+
629
+
630
+ @stream_session
631
+ def list_archive_content(scope, name, vo='def', *, session: "Session"):
632
+ """
633
+ List archive contents.
634
+
635
+ :param scope: The archive scope name.
636
+ :param name: The archive data identifier name.
637
+ :param vo: The VO to act on.
638
+ :param session: The database session in use.
639
+ """
640
+
641
+ scope = InternalScope(scope, vo=vo)
642
+
643
+ dids = did.list_archive_content(scope=scope, name=name, session=session)
644
+ for d in dids:
645
+ yield api_update_return_dict(d, session=session)
646
+
647
+
648
+ @transactional_session
649
+ def add_did_to_followed(scope, name, account, *, session: "Session", vo='def'):
650
+ """
651
+ Mark a did as followed by the given account
652
+
653
+ :param scope: The scope name.
654
+ :param name: The data identifier name.
655
+ :param account: The account owner.
656
+ :param session: The database session in use.
657
+ """
658
+ scope = InternalScope(scope, vo=vo)
659
+ account = InternalAccount(account, vo=vo)
660
+ return did.add_did_to_followed(scope=scope, name=name, account=account, session=session)
661
+
662
+
663
+ @transactional_session
664
+ def add_dids_to_followed(dids, account, *, session: "Session", vo='def'):
665
+ """
666
+ Bulk mark datasets as followed
667
+
668
+ :param dids: A list of dids.
669
+ :param account: The account owner.
670
+ :param session: The database session in use.
671
+ """
672
+ account = InternalAccount(account, vo=vo)
673
+ return did.add_dids_to_followed(dids=dids, account=account, session=session)
674
+
675
+
676
+ @stream_session
677
+ def get_users_following_did(name, scope, *, session: "Session", vo='def'):
678
+ """
679
+ Return list of users following a did
680
+
681
+ :param scope: The scope name.
682
+ :param name: The data identifier name.
683
+ :param session: The database session in use.
684
+ """
685
+ scope = InternalScope(scope, vo=vo)
686
+ users = did.get_users_following_did(name=name, scope=scope, session=session)
687
+ for user in users:
688
+ user['user'] = user['user'].external
689
+ yield user
690
+
691
+
692
+ @transactional_session
693
+ def remove_did_from_followed(scope, name, account, issuer, *, session: "Session", vo='def'):
694
+ """
695
+ Mark a did as not followed
696
+
697
+ :param scope: The scope name.
698
+ :param name: The data identifier name.
699
+ :param account: The account owner.
700
+ :param session: The database session in use.
701
+ :param issuer: The issuer account
702
+ """
703
+ kwargs = {'scope': scope, 'issuer': issuer}
704
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='remove_did_from_followed', kwargs=kwargs, session=session):
705
+ raise rucio.common.exception.AccessDenied('Account %s can not remove data identifiers from followed table' % (issuer))
706
+
707
+ scope = InternalScope(scope, vo=vo)
708
+ account = InternalAccount(account, vo=vo)
709
+ return did.remove_did_from_followed(scope=scope, name=name, account=account, session=session)
710
+
711
+
712
+ @transactional_session
713
+ def remove_dids_from_followed(dids, account, issuer, *, session: "Session", vo='def'):
714
+ """
715
+ Bulk mark datasets as not followed
716
+
717
+ :param dids: A list of dids.
718
+ :param account: The account owner.
719
+ :param session: The database session in use.
720
+ """
721
+ kwargs = {'dids': dids, 'issuer': issuer}
722
+ if not rucio.api.permission.has_permission(issuer=issuer, vo=vo, action='remove_dids_from_followed', kwargs=kwargs, session=session):
723
+ raise rucio.common.exception.AccessDenied('Account %s can not bulk remove data identifiers from followed table' % (issuer))
724
+
725
+ account = InternalAccount(account, vo=vo)
726
+ return did.remove_dids_from_followed(dids=dids, account=account, session=session)