rucio 37.0.0rc1__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (487) hide show
  1. rucio/__init__.py +17 -0
  2. rucio/alembicrevision.py +15 -0
  3. rucio/cli/__init__.py +14 -0
  4. rucio/cli/account.py +216 -0
  5. rucio/cli/bin_legacy/__init__.py +13 -0
  6. rucio/cli/bin_legacy/rucio.py +2825 -0
  7. rucio/cli/bin_legacy/rucio_admin.py +2500 -0
  8. rucio/cli/command.py +272 -0
  9. rucio/cli/config.py +72 -0
  10. rucio/cli/did.py +191 -0
  11. rucio/cli/download.py +128 -0
  12. rucio/cli/lifetime_exception.py +33 -0
  13. rucio/cli/replica.py +162 -0
  14. rucio/cli/rse.py +293 -0
  15. rucio/cli/rule.py +158 -0
  16. rucio/cli/scope.py +40 -0
  17. rucio/cli/subscription.py +73 -0
  18. rucio/cli/upload.py +60 -0
  19. rucio/cli/utils.py +226 -0
  20. rucio/client/__init__.py +15 -0
  21. rucio/client/accountclient.py +432 -0
  22. rucio/client/accountlimitclient.py +183 -0
  23. rucio/client/baseclient.py +983 -0
  24. rucio/client/client.py +120 -0
  25. rucio/client/configclient.py +126 -0
  26. rucio/client/credentialclient.py +59 -0
  27. rucio/client/didclient.py +868 -0
  28. rucio/client/diracclient.py +56 -0
  29. rucio/client/downloadclient.py +1783 -0
  30. rucio/client/exportclient.py +44 -0
  31. rucio/client/fileclient.py +50 -0
  32. rucio/client/importclient.py +42 -0
  33. rucio/client/lifetimeclient.py +90 -0
  34. rucio/client/lockclient.py +109 -0
  35. rucio/client/metaconventionsclient.py +140 -0
  36. rucio/client/pingclient.py +44 -0
  37. rucio/client/replicaclient.py +452 -0
  38. rucio/client/requestclient.py +125 -0
  39. rucio/client/richclient.py +317 -0
  40. rucio/client/rseclient.py +746 -0
  41. rucio/client/ruleclient.py +294 -0
  42. rucio/client/scopeclient.py +90 -0
  43. rucio/client/subscriptionclient.py +173 -0
  44. rucio/client/touchclient.py +82 -0
  45. rucio/client/uploadclient.py +969 -0
  46. rucio/common/__init__.py +13 -0
  47. rucio/common/bittorrent.py +234 -0
  48. rucio/common/cache.py +111 -0
  49. rucio/common/checksum.py +168 -0
  50. rucio/common/client.py +122 -0
  51. rucio/common/config.py +788 -0
  52. rucio/common/constants.py +217 -0
  53. rucio/common/constraints.py +17 -0
  54. rucio/common/didtype.py +237 -0
  55. rucio/common/dumper/__init__.py +342 -0
  56. rucio/common/dumper/consistency.py +497 -0
  57. rucio/common/dumper/data_models.py +362 -0
  58. rucio/common/dumper/path_parsing.py +75 -0
  59. rucio/common/exception.py +1208 -0
  60. rucio/common/extra.py +31 -0
  61. rucio/common/logging.py +420 -0
  62. rucio/common/pcache.py +1409 -0
  63. rucio/common/plugins.py +185 -0
  64. rucio/common/policy.py +93 -0
  65. rucio/common/schema/__init__.py +200 -0
  66. rucio/common/schema/generic.py +416 -0
  67. rucio/common/schema/generic_multi_vo.py +395 -0
  68. rucio/common/stomp_utils.py +423 -0
  69. rucio/common/stopwatch.py +55 -0
  70. rucio/common/test_rucio_server.py +154 -0
  71. rucio/common/types.py +483 -0
  72. rucio/common/utils.py +1688 -0
  73. rucio/core/__init__.py +13 -0
  74. rucio/core/account.py +496 -0
  75. rucio/core/account_counter.py +236 -0
  76. rucio/core/account_limit.py +425 -0
  77. rucio/core/authentication.py +620 -0
  78. rucio/core/config.py +437 -0
  79. rucio/core/credential.py +224 -0
  80. rucio/core/did.py +3004 -0
  81. rucio/core/did_meta_plugins/__init__.py +252 -0
  82. rucio/core/did_meta_plugins/did_column_meta.py +331 -0
  83. rucio/core/did_meta_plugins/did_meta_plugin_interface.py +165 -0
  84. rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
  85. rucio/core/did_meta_plugins/filter_engine.py +672 -0
  86. rucio/core/did_meta_plugins/json_meta.py +240 -0
  87. rucio/core/did_meta_plugins/mongo_meta.py +229 -0
  88. rucio/core/did_meta_plugins/postgres_meta.py +352 -0
  89. rucio/core/dirac.py +237 -0
  90. rucio/core/distance.py +187 -0
  91. rucio/core/exporter.py +59 -0
  92. rucio/core/heartbeat.py +363 -0
  93. rucio/core/identity.py +301 -0
  94. rucio/core/importer.py +260 -0
  95. rucio/core/lifetime_exception.py +377 -0
  96. rucio/core/lock.py +577 -0
  97. rucio/core/message.py +288 -0
  98. rucio/core/meta_conventions.py +203 -0
  99. rucio/core/monitor.py +448 -0
  100. rucio/core/naming_convention.py +195 -0
  101. rucio/core/nongrid_trace.py +136 -0
  102. rucio/core/oidc.py +1463 -0
  103. rucio/core/permission/__init__.py +161 -0
  104. rucio/core/permission/generic.py +1124 -0
  105. rucio/core/permission/generic_multi_vo.py +1144 -0
  106. rucio/core/quarantined_replica.py +224 -0
  107. rucio/core/replica.py +4483 -0
  108. rucio/core/replica_sorter.py +362 -0
  109. rucio/core/request.py +3091 -0
  110. rucio/core/rse.py +2079 -0
  111. rucio/core/rse_counter.py +185 -0
  112. rucio/core/rse_expression_parser.py +459 -0
  113. rucio/core/rse_selector.py +304 -0
  114. rucio/core/rule.py +4484 -0
  115. rucio/core/rule_grouping.py +1620 -0
  116. rucio/core/scope.py +181 -0
  117. rucio/core/subscription.py +362 -0
  118. rucio/core/topology.py +490 -0
  119. rucio/core/trace.py +375 -0
  120. rucio/core/transfer.py +1531 -0
  121. rucio/core/vo.py +169 -0
  122. rucio/core/volatile_replica.py +151 -0
  123. rucio/daemons/__init__.py +13 -0
  124. rucio/daemons/abacus/__init__.py +13 -0
  125. rucio/daemons/abacus/account.py +116 -0
  126. rucio/daemons/abacus/collection_replica.py +124 -0
  127. rucio/daemons/abacus/rse.py +117 -0
  128. rucio/daemons/atropos/__init__.py +13 -0
  129. rucio/daemons/atropos/atropos.py +242 -0
  130. rucio/daemons/auditor/__init__.py +289 -0
  131. rucio/daemons/auditor/hdfs.py +97 -0
  132. rucio/daemons/auditor/srmdumps.py +355 -0
  133. rucio/daemons/automatix/__init__.py +13 -0
  134. rucio/daemons/automatix/automatix.py +304 -0
  135. rucio/daemons/badreplicas/__init__.py +13 -0
  136. rucio/daemons/badreplicas/minos.py +322 -0
  137. rucio/daemons/badreplicas/minos_temporary_expiration.py +171 -0
  138. rucio/daemons/badreplicas/necromancer.py +196 -0
  139. rucio/daemons/bb8/__init__.py +13 -0
  140. rucio/daemons/bb8/bb8.py +353 -0
  141. rucio/daemons/bb8/common.py +759 -0
  142. rucio/daemons/bb8/nuclei_background_rebalance.py +153 -0
  143. rucio/daemons/bb8/t2_background_rebalance.py +153 -0
  144. rucio/daemons/cache/__init__.py +13 -0
  145. rucio/daemons/cache/consumer.py +133 -0
  146. rucio/daemons/common.py +405 -0
  147. rucio/daemons/conveyor/__init__.py +13 -0
  148. rucio/daemons/conveyor/common.py +562 -0
  149. rucio/daemons/conveyor/finisher.py +529 -0
  150. rucio/daemons/conveyor/poller.py +394 -0
  151. rucio/daemons/conveyor/preparer.py +205 -0
  152. rucio/daemons/conveyor/receiver.py +179 -0
  153. rucio/daemons/conveyor/stager.py +133 -0
  154. rucio/daemons/conveyor/submitter.py +403 -0
  155. rucio/daemons/conveyor/throttler.py +532 -0
  156. rucio/daemons/follower/__init__.py +13 -0
  157. rucio/daemons/follower/follower.py +101 -0
  158. rucio/daemons/hermes/__init__.py +13 -0
  159. rucio/daemons/hermes/hermes.py +534 -0
  160. rucio/daemons/judge/__init__.py +13 -0
  161. rucio/daemons/judge/cleaner.py +159 -0
  162. rucio/daemons/judge/evaluator.py +185 -0
  163. rucio/daemons/judge/injector.py +162 -0
  164. rucio/daemons/judge/repairer.py +154 -0
  165. rucio/daemons/oauthmanager/__init__.py +13 -0
  166. rucio/daemons/oauthmanager/oauthmanager.py +198 -0
  167. rucio/daemons/reaper/__init__.py +13 -0
  168. rucio/daemons/reaper/dark_reaper.py +282 -0
  169. rucio/daemons/reaper/reaper.py +739 -0
  170. rucio/daemons/replicarecoverer/__init__.py +13 -0
  171. rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +626 -0
  172. rucio/daemons/rsedecommissioner/__init__.py +13 -0
  173. rucio/daemons/rsedecommissioner/config.py +81 -0
  174. rucio/daemons/rsedecommissioner/profiles/__init__.py +24 -0
  175. rucio/daemons/rsedecommissioner/profiles/atlas.py +60 -0
  176. rucio/daemons/rsedecommissioner/profiles/generic.py +452 -0
  177. rucio/daemons/rsedecommissioner/profiles/types.py +93 -0
  178. rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
  179. rucio/daemons/storage/__init__.py +13 -0
  180. rucio/daemons/storage/consistency/__init__.py +13 -0
  181. rucio/daemons/storage/consistency/actions.py +848 -0
  182. rucio/daemons/tracer/__init__.py +13 -0
  183. rucio/daemons/tracer/kronos.py +511 -0
  184. rucio/daemons/transmogrifier/__init__.py +13 -0
  185. rucio/daemons/transmogrifier/transmogrifier.py +762 -0
  186. rucio/daemons/undertaker/__init__.py +13 -0
  187. rucio/daemons/undertaker/undertaker.py +137 -0
  188. rucio/db/__init__.py +13 -0
  189. rucio/db/sqla/__init__.py +52 -0
  190. rucio/db/sqla/constants.py +206 -0
  191. rucio/db/sqla/migrate_repo/__init__.py +13 -0
  192. rucio/db/sqla/migrate_repo/env.py +110 -0
  193. rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +70 -0
  194. rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +47 -0
  195. rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +59 -0
  196. rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +43 -0
  197. rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +91 -0
  198. rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +76 -0
  199. rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +43 -0
  200. rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +50 -0
  201. rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +68 -0
  202. rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +40 -0
  203. rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +45 -0
  204. rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +60 -0
  205. rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +40 -0
  206. rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +140 -0
  207. rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +73 -0
  208. rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +74 -0
  209. rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +43 -0
  210. rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +50 -0
  211. rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +134 -0
  212. rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +64 -0
  213. rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +39 -0
  214. rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +64 -0
  215. rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +51 -0
  216. rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +41 -0
  217. rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +43 -0
  218. rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +44 -0
  219. rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +53 -0
  220. rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +38 -0
  221. rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +47 -0
  222. rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +45 -0
  223. rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +45 -0
  224. rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +57 -0
  225. rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +45 -0
  226. rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +69 -0
  227. rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +43 -0
  228. rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +42 -0
  229. rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +47 -0
  230. rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +46 -0
  231. rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +40 -0
  232. rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +67 -0
  233. rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
  234. rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +44 -0
  235. rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +77 -0
  236. rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +60 -0
  237. rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +72 -0
  238. rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +42 -0
  239. rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +65 -0
  240. rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +133 -0
  241. rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +55 -0
  242. rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +76 -0
  243. rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +60 -0
  244. rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +44 -0
  245. rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +43 -0
  246. rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +64 -0
  247. rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +40 -0
  248. rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +43 -0
  249. rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +44 -0
  250. rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +78 -0
  251. rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +41 -0
  252. rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +59 -0
  253. rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +44 -0
  254. rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +43 -0
  255. rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +49 -0
  256. rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +40 -0
  257. rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +63 -0
  258. rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +43 -0
  259. rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +55 -0
  260. rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +45 -0
  261. rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +43 -0
  262. rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +43 -0
  263. rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +45 -0
  264. rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +47 -0
  265. rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +58 -0
  266. rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +45 -0
  267. rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +106 -0
  268. rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +55 -0
  269. rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +50 -0
  270. rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +47 -0
  271. rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +43 -0
  272. rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +41 -0
  273. rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +91 -0
  274. rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +72 -0
  275. rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +49 -0
  276. rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +43 -0
  277. rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +43 -0
  278. rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +53 -0
  279. rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +45 -0
  280. rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +68 -0
  281. rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +45 -0
  282. rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +94 -0
  283. rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +54 -0
  284. rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +72 -0
  285. rucio/db/sqla/migrate_repo/versions/a08fa8de1545_transfer_stats_table.py +55 -0
  286. rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +76 -0
  287. rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +47 -0
  288. rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +121 -0
  289. rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +59 -0
  290. rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +52 -0
  291. rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +54 -0
  292. rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +64 -0
  293. rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +49 -0
  294. rucio/db/sqla/migrate_repo/versions/b0070f3695c8_add_deletedidmeta_table.py +57 -0
  295. rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +43 -0
  296. rucio/db/sqla/migrate_repo/versions/b5493606bbf5_fix_primary_key_for_subscription_history.py +41 -0
  297. rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +91 -0
  298. rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +40 -0
  299. rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +43 -0
  300. rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +143 -0
  301. rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +76 -0
  302. rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +50 -0
  303. rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +72 -0
  304. rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +55 -0
  305. rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +43 -0
  306. rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +65 -0
  307. rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +47 -0
  308. rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +146 -0
  309. rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +104 -0
  310. rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +44 -0
  311. rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +43 -0
  312. rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +103 -0
  313. rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +49 -0
  314. rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +104 -0
  315. rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +29 -0
  316. rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +74 -0
  317. rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +47 -0
  318. rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +43 -0
  319. rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +37 -0
  320. rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +43 -0
  321. rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +43 -0
  322. rucio/db/sqla/models.py +1743 -0
  323. rucio/db/sqla/sautils.py +55 -0
  324. rucio/db/sqla/session.py +529 -0
  325. rucio/db/sqla/types.py +206 -0
  326. rucio/db/sqla/util.py +543 -0
  327. rucio/gateway/__init__.py +13 -0
  328. rucio/gateway/account.py +345 -0
  329. rucio/gateway/account_limit.py +363 -0
  330. rucio/gateway/authentication.py +381 -0
  331. rucio/gateway/config.py +227 -0
  332. rucio/gateway/credential.py +70 -0
  333. rucio/gateway/did.py +987 -0
  334. rucio/gateway/dirac.py +83 -0
  335. rucio/gateway/exporter.py +60 -0
  336. rucio/gateway/heartbeat.py +76 -0
  337. rucio/gateway/identity.py +189 -0
  338. rucio/gateway/importer.py +46 -0
  339. rucio/gateway/lifetime_exception.py +121 -0
  340. rucio/gateway/lock.py +153 -0
  341. rucio/gateway/meta_conventions.py +98 -0
  342. rucio/gateway/permission.py +74 -0
  343. rucio/gateway/quarantined_replica.py +79 -0
  344. rucio/gateway/replica.py +538 -0
  345. rucio/gateway/request.py +330 -0
  346. rucio/gateway/rse.py +632 -0
  347. rucio/gateway/rule.py +437 -0
  348. rucio/gateway/scope.py +100 -0
  349. rucio/gateway/subscription.py +280 -0
  350. rucio/gateway/vo.py +126 -0
  351. rucio/rse/__init__.py +96 -0
  352. rucio/rse/protocols/__init__.py +13 -0
  353. rucio/rse/protocols/bittorrent.py +194 -0
  354. rucio/rse/protocols/cache.py +111 -0
  355. rucio/rse/protocols/dummy.py +100 -0
  356. rucio/rse/protocols/gfal.py +708 -0
  357. rucio/rse/protocols/globus.py +243 -0
  358. rucio/rse/protocols/http_cache.py +82 -0
  359. rucio/rse/protocols/mock.py +123 -0
  360. rucio/rse/protocols/ngarc.py +209 -0
  361. rucio/rse/protocols/posix.py +250 -0
  362. rucio/rse/protocols/protocol.py +361 -0
  363. rucio/rse/protocols/rclone.py +365 -0
  364. rucio/rse/protocols/rfio.py +145 -0
  365. rucio/rse/protocols/srm.py +338 -0
  366. rucio/rse/protocols/ssh.py +414 -0
  367. rucio/rse/protocols/storm.py +195 -0
  368. rucio/rse/protocols/webdav.py +594 -0
  369. rucio/rse/protocols/xrootd.py +302 -0
  370. rucio/rse/rsemanager.py +881 -0
  371. rucio/rse/translation.py +260 -0
  372. rucio/tests/__init__.py +13 -0
  373. rucio/tests/common.py +280 -0
  374. rucio/tests/common_server.py +149 -0
  375. rucio/transfertool/__init__.py +13 -0
  376. rucio/transfertool/bittorrent.py +200 -0
  377. rucio/transfertool/bittorrent_driver.py +50 -0
  378. rucio/transfertool/bittorrent_driver_qbittorrent.py +134 -0
  379. rucio/transfertool/fts3.py +1600 -0
  380. rucio/transfertool/fts3_plugins.py +152 -0
  381. rucio/transfertool/globus.py +201 -0
  382. rucio/transfertool/globus_library.py +181 -0
  383. rucio/transfertool/mock.py +89 -0
  384. rucio/transfertool/transfertool.py +221 -0
  385. rucio/vcsversion.py +11 -0
  386. rucio/version.py +45 -0
  387. rucio/web/__init__.py +13 -0
  388. rucio/web/rest/__init__.py +13 -0
  389. rucio/web/rest/flaskapi/__init__.py +13 -0
  390. rucio/web/rest/flaskapi/authenticated_bp.py +27 -0
  391. rucio/web/rest/flaskapi/v1/__init__.py +13 -0
  392. rucio/web/rest/flaskapi/v1/accountlimits.py +236 -0
  393. rucio/web/rest/flaskapi/v1/accounts.py +1103 -0
  394. rucio/web/rest/flaskapi/v1/archives.py +102 -0
  395. rucio/web/rest/flaskapi/v1/auth.py +1644 -0
  396. rucio/web/rest/flaskapi/v1/common.py +426 -0
  397. rucio/web/rest/flaskapi/v1/config.py +304 -0
  398. rucio/web/rest/flaskapi/v1/credentials.py +213 -0
  399. rucio/web/rest/flaskapi/v1/dids.py +2340 -0
  400. rucio/web/rest/flaskapi/v1/dirac.py +116 -0
  401. rucio/web/rest/flaskapi/v1/export.py +75 -0
  402. rucio/web/rest/flaskapi/v1/heartbeats.py +127 -0
  403. rucio/web/rest/flaskapi/v1/identities.py +285 -0
  404. rucio/web/rest/flaskapi/v1/import.py +132 -0
  405. rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +312 -0
  406. rucio/web/rest/flaskapi/v1/locks.py +358 -0
  407. rucio/web/rest/flaskapi/v1/main.py +91 -0
  408. rucio/web/rest/flaskapi/v1/meta_conventions.py +241 -0
  409. rucio/web/rest/flaskapi/v1/metrics.py +36 -0
  410. rucio/web/rest/flaskapi/v1/nongrid_traces.py +97 -0
  411. rucio/web/rest/flaskapi/v1/ping.py +88 -0
  412. rucio/web/rest/flaskapi/v1/redirect.py +366 -0
  413. rucio/web/rest/flaskapi/v1/replicas.py +1894 -0
  414. rucio/web/rest/flaskapi/v1/requests.py +998 -0
  415. rucio/web/rest/flaskapi/v1/rses.py +2250 -0
  416. rucio/web/rest/flaskapi/v1/rules.py +854 -0
  417. rucio/web/rest/flaskapi/v1/scopes.py +159 -0
  418. rucio/web/rest/flaskapi/v1/subscriptions.py +650 -0
  419. rucio/web/rest/flaskapi/v1/templates/auth_crash.html +80 -0
  420. rucio/web/rest/flaskapi/v1/templates/auth_granted.html +82 -0
  421. rucio/web/rest/flaskapi/v1/traces.py +137 -0
  422. rucio/web/rest/flaskapi/v1/types.py +20 -0
  423. rucio/web/rest/flaskapi/v1/vos.py +278 -0
  424. rucio/web/rest/main.py +18 -0
  425. rucio/web/rest/metrics.py +27 -0
  426. rucio/web/rest/ping.py +27 -0
  427. rucio-37.0.0rc1.data/data/rucio/etc/alembic.ini.template +71 -0
  428. rucio-37.0.0rc1.data/data/rucio/etc/alembic_offline.ini.template +74 -0
  429. rucio-37.0.0rc1.data/data/rucio/etc/globus-config.yml.template +5 -0
  430. rucio-37.0.0rc1.data/data/rucio/etc/ldap.cfg.template +30 -0
  431. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approval_request.tmpl +38 -0
  432. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +4 -0
  433. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_user.tmpl +17 -0
  434. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +6 -0
  435. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_user.tmpl +17 -0
  436. rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +19 -0
  437. rucio-37.0.0rc1.data/data/rucio/etc/rse-accounts.cfg.template +25 -0
  438. rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.atlas.client.template +43 -0
  439. rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.template +241 -0
  440. rucio-37.0.0rc1.data/data/rucio/etc/rucio_multi_vo.cfg.template +217 -0
  441. rucio-37.0.0rc1.data/data/rucio/requirements.server.txt +297 -0
  442. rucio-37.0.0rc1.data/data/rucio/tools/bootstrap.py +34 -0
  443. rucio-37.0.0rc1.data/data/rucio/tools/merge_rucio_configs.py +144 -0
  444. rucio-37.0.0rc1.data/data/rucio/tools/reset_database.py +40 -0
  445. rucio-37.0.0rc1.data/scripts/rucio +133 -0
  446. rucio-37.0.0rc1.data/scripts/rucio-abacus-account +74 -0
  447. rucio-37.0.0rc1.data/scripts/rucio-abacus-collection-replica +46 -0
  448. rucio-37.0.0rc1.data/scripts/rucio-abacus-rse +78 -0
  449. rucio-37.0.0rc1.data/scripts/rucio-admin +97 -0
  450. rucio-37.0.0rc1.data/scripts/rucio-atropos +60 -0
  451. rucio-37.0.0rc1.data/scripts/rucio-auditor +206 -0
  452. rucio-37.0.0rc1.data/scripts/rucio-automatix +50 -0
  453. rucio-37.0.0rc1.data/scripts/rucio-bb8 +57 -0
  454. rucio-37.0.0rc1.data/scripts/rucio-cache-client +141 -0
  455. rucio-37.0.0rc1.data/scripts/rucio-cache-consumer +42 -0
  456. rucio-37.0.0rc1.data/scripts/rucio-conveyor-finisher +58 -0
  457. rucio-37.0.0rc1.data/scripts/rucio-conveyor-poller +66 -0
  458. rucio-37.0.0rc1.data/scripts/rucio-conveyor-preparer +37 -0
  459. rucio-37.0.0rc1.data/scripts/rucio-conveyor-receiver +44 -0
  460. rucio-37.0.0rc1.data/scripts/rucio-conveyor-stager +76 -0
  461. rucio-37.0.0rc1.data/scripts/rucio-conveyor-submitter +139 -0
  462. rucio-37.0.0rc1.data/scripts/rucio-conveyor-throttler +104 -0
  463. rucio-37.0.0rc1.data/scripts/rucio-dark-reaper +53 -0
  464. rucio-37.0.0rc1.data/scripts/rucio-dumper +160 -0
  465. rucio-37.0.0rc1.data/scripts/rucio-follower +44 -0
  466. rucio-37.0.0rc1.data/scripts/rucio-hermes +54 -0
  467. rucio-37.0.0rc1.data/scripts/rucio-judge-cleaner +89 -0
  468. rucio-37.0.0rc1.data/scripts/rucio-judge-evaluator +137 -0
  469. rucio-37.0.0rc1.data/scripts/rucio-judge-injector +44 -0
  470. rucio-37.0.0rc1.data/scripts/rucio-judge-repairer +44 -0
  471. rucio-37.0.0rc1.data/scripts/rucio-kronos +44 -0
  472. rucio-37.0.0rc1.data/scripts/rucio-minos +53 -0
  473. rucio-37.0.0rc1.data/scripts/rucio-minos-temporary-expiration +50 -0
  474. rucio-37.0.0rc1.data/scripts/rucio-necromancer +120 -0
  475. rucio-37.0.0rc1.data/scripts/rucio-oauth-manager +63 -0
  476. rucio-37.0.0rc1.data/scripts/rucio-reaper +83 -0
  477. rucio-37.0.0rc1.data/scripts/rucio-replica-recoverer +248 -0
  478. rucio-37.0.0rc1.data/scripts/rucio-rse-decommissioner +66 -0
  479. rucio-37.0.0rc1.data/scripts/rucio-storage-consistency-actions +74 -0
  480. rucio-37.0.0rc1.data/scripts/rucio-transmogrifier +77 -0
  481. rucio-37.0.0rc1.data/scripts/rucio-undertaker +76 -0
  482. rucio-37.0.0rc1.dist-info/METADATA +92 -0
  483. rucio-37.0.0rc1.dist-info/RECORD +487 -0
  484. rucio-37.0.0rc1.dist-info/WHEEL +5 -0
  485. rucio-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
  486. rucio-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
  487. rucio-37.0.0rc1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,650 @@
1
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from json import dumps
16
+
17
+ from flask import Flask, Response, request
18
+
19
+ from rucio.common.exception import AccessDenied, InvalidObject, RuleNotFound, SubscriptionDuplicate, SubscriptionNotFound
20
+ from rucio.common.utils import APIEncoder, render_json
21
+ from rucio.gateway.rule import list_replication_rules
22
+ from rucio.gateway.subscription import add_subscription, get_subscription_by_id, list_subscription_rule_states, list_subscriptions, update_subscription
23
+ from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
24
+ from rucio.web.rest.flaskapi.v1.common import ErrorHandlingMethodView, check_accept_header_wrapper_flask, generate_http_error_flask, json_parameters, param_get, response_headers, try_stream
25
+
26
+
27
+ class Subscription(ErrorHandlingMethodView):
28
+ """ REST APIs for subscriptions. """
29
+
30
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
31
+ def get(self, account=None, name=None):
32
+ """
33
+ ---
34
+ summary: Get Subscription
35
+ description: Retrieve a subscription.
36
+ tags:
37
+ - Replicas
38
+ parameters:
39
+ - name: account
40
+ in: path
41
+ description: The account name.
42
+ schema:
43
+ type: string
44
+ style: simple
45
+ - name: name
46
+ in: path
47
+ description: The subscription name.
48
+ schema:
49
+ type: string
50
+ style: simple
51
+ responses:
52
+ 200:
53
+ description: OK
54
+ content:
55
+ application/x-json-stream:
56
+ schema:
57
+ description: A list of subscriptions.
58
+ type: array
59
+ items:
60
+ description: A subscription.
61
+ type: object
62
+ properties:
63
+ id:
64
+ description: The id of the subscription.
65
+ type: string
66
+ name:
67
+ description: The name of the subscription.
68
+ type: string
69
+ filter:
70
+ description: The filter for the subscription.
71
+ type: string
72
+ replication_rules:
73
+ description: The replication rules for the subscription.
74
+ type: string
75
+ policyid:
76
+ description: The policyid for the subscription.
77
+ type: integer
78
+ state:
79
+ description: The state of the subscription.
80
+ type: string
81
+ enum: ["A", "I", "N", "U", "B"]
82
+ last_processed:
83
+ description: The time the subscription was processed last.
84
+ type: string
85
+ format: date-time
86
+ account:
87
+ description: The account for the subscription.
88
+ type: string
89
+ lifetime:
90
+ description: The lifetime for the subscription.
91
+ type: string
92
+ format: date-time
93
+ comments:
94
+ description: The comments for the subscription.
95
+ type: string
96
+ retroactive:
97
+ description: If the subscription is retroactive.
98
+ type: boolean
99
+ expired_at:
100
+ description: The date-time of the expiration for the subscription.
101
+ type: string
102
+ format: date-time
103
+ 401:
104
+ description: Invalid Auth Token
105
+ 404:
106
+ description: Subscription Not found
107
+ 406:
108
+ description: Not acceptable
109
+ """
110
+ try:
111
+ def generate(vo):
112
+ for subscription in list_subscriptions(name=name, account=account, vo=vo):
113
+ yield render_json(**subscription) + '\n'
114
+
115
+ return try_stream(generate(vo=request.environ.get('vo')))
116
+ except SubscriptionNotFound as error:
117
+ return generate_http_error_flask(404, error)
118
+
119
+ def put(self, account, name):
120
+ """
121
+ ---
122
+ summary: Update subscription
123
+ description: Update an existing subscription.
124
+ tags:
125
+ - Replicas
126
+ parameters:
127
+ - name: account
128
+ in: path
129
+ description: The account name.
130
+ schema:
131
+ type: string
132
+ style: simple
133
+ required: true
134
+ - name: name
135
+ in: path
136
+ description: The subscription name.
137
+ schema:
138
+ type: string
139
+ style: simple
140
+ required: true
141
+ requestBody:
142
+ content:
143
+ application/json:
144
+ schema:
145
+ type: object
146
+ required:
147
+ - options
148
+ properties:
149
+ options:
150
+ description: The values for the new subscription.
151
+ type: object
152
+ properties:
153
+ filter:
154
+ description: The filter for the subscription.
155
+ type: string
156
+ replication_rules:
157
+ description: The replication rules for the subscription.
158
+ type: string
159
+ comments:
160
+ description: The comments for the subscription.
161
+ type: string
162
+ lifetime:
163
+ description: The lifetime for the subscription.
164
+ type: string
165
+ format: date-time
166
+ retroactive:
167
+ description: If the retroactive is activated for a subscription.
168
+ type: boolean
169
+ priority:
170
+ description: The priority/policyid for the subscription. Stored as policyid.
171
+ type: integer
172
+ responses:
173
+ 201:
174
+ description: OK
175
+ 400:
176
+ description: Cannot decode json parameter list.
177
+ 401:
178
+ description: Invalid Auth Token
179
+ 404:
180
+ description: Not found
181
+ """
182
+ parameters = json_parameters()
183
+ options = param_get(parameters, 'options')
184
+ metadata = {
185
+ 'filter': None,
186
+ 'replication_rules': None,
187
+ 'comments': None,
188
+ 'lifetime': None,
189
+ 'retroactive': None,
190
+ 'priority': None,
191
+ }
192
+ for keyword in list(metadata):
193
+ metadata[keyword] = param_get(options, keyword, default=metadata[keyword])
194
+
195
+ try:
196
+ update_subscription(name=name, account=account, metadata=metadata, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
197
+ except (InvalidObject, TypeError) as error:
198
+ return generate_http_error_flask(400, InvalidObject.__name__, error.args[0])
199
+ except AccessDenied as error:
200
+ return generate_http_error_flask(401, error)
201
+ except SubscriptionNotFound as error:
202
+ return generate_http_error_flask(404, error)
203
+
204
+ return 'Created', 201
205
+
206
+ def post(self, account, name):
207
+ """
208
+ ---
209
+ summary: Create subscription
210
+ description: Create a new subscription
211
+ tags:
212
+ - Replicas
213
+ parameters:
214
+ - name: account
215
+ in: path
216
+ description: The account name.
217
+ schema:
218
+ type: string
219
+ style: simple
220
+ required: true
221
+ - name: name
222
+ in: path
223
+ description: The subscription name.
224
+ schema:
225
+ type: string
226
+ style: simple
227
+ required: true
228
+ requestBody:
229
+ content:
230
+ application/json:
231
+ schema:
232
+ type: object
233
+ required:
234
+ - options
235
+ properties:
236
+ options:
237
+ description: The values for the new subscription.
238
+ type: object
239
+ required:
240
+ - filter
241
+ - replication_rules
242
+ - comments
243
+ - lifetime
244
+ - retroactive
245
+ properties:
246
+ filter:
247
+ description: The filter for the subscription.
248
+ type: string
249
+ replication_rules:
250
+ description: The replication rules for the subscription.
251
+ type: string
252
+ comments:
253
+ description: The comments for the subscription.
254
+ type: string
255
+ lifetime:
256
+ description: The lifetime for the subscription.
257
+ type: string
258
+ format: date-time
259
+ retroactive:
260
+ description: If the retroactive is activated for a subscription.
261
+ type: boolean
262
+ priority:
263
+ description: The priority/policyid for the subscription. Stored as policyid.
264
+ type: integer
265
+ dry_run:
266
+ description: The priority/policyid for the subscription. Stored as policyid.
267
+ type: boolean
268
+ default: false
269
+ responses:
270
+ 200:
271
+ description: OK
272
+ content:
273
+ application/json:
274
+ schema:
275
+ description: The subscription Id for the new subscription.
276
+ type: string
277
+ 400:
278
+ description: Cannot decode json parameter list.
279
+ 401:
280
+ description: Invalid Auth Token
281
+ 404:
282
+ description: Not found
283
+ 406:
284
+ description: Not acceptable
285
+ """
286
+ parameters = json_parameters()
287
+ options = param_get(parameters, 'options')
288
+ filter_param = param_get(options, 'filter')
289
+ replication_rules = param_get(options, 'replication_rules')
290
+ comments = param_get(options, 'comments')
291
+ lifetime = param_get(options, 'lifetime')
292
+ retroactive = param_get(options, 'retroactive')
293
+ dry_run = param_get(options, 'dry_run', default=False)
294
+ priority = param_get(options, 'priority', default=False)
295
+ if not priority:
296
+ priority = 3
297
+
298
+ try:
299
+ subscription_id = add_subscription(
300
+ name=name,
301
+ account=account,
302
+ filter_=filter_param,
303
+ replication_rules=replication_rules,
304
+ comments=comments,
305
+ lifetime=lifetime,
306
+ retroactive=retroactive,
307
+ dry_run=dry_run,
308
+ priority=priority,
309
+ issuer=request.environ.get('issuer'),
310
+ vo=request.environ.get('vo'),
311
+ )
312
+ except (InvalidObject, TypeError) as error:
313
+ return generate_http_error_flask(400, InvalidObject.__name__, error.args[0])
314
+ except AccessDenied as error:
315
+ return generate_http_error_flask(401, error)
316
+ except SubscriptionDuplicate as error:
317
+ return generate_http_error_flask(409, error)
318
+
319
+ return Response(subscription_id, status=201)
320
+
321
+
322
+ class SubscriptionName(ErrorHandlingMethodView):
323
+
324
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
325
+ def get(self, name=None):
326
+ """
327
+ ---
328
+ summary: Get Subscription by Name
329
+ description: Retrieve a subscription by name.
330
+ tags:
331
+ - Replicas
332
+ parameters:
333
+ - name: name
334
+ in: path
335
+ description: The subscription name.
336
+ schema:
337
+ type: string
338
+ style: simple
339
+ responses:
340
+ 200:
341
+ description: OK
342
+ content:
343
+ application/x-json-stream:
344
+ schema:
345
+ description: A list of subscriptions.
346
+ type: array
347
+ items:
348
+ description: A subscription.
349
+ type: object
350
+ properties:
351
+ id:
352
+ description: The id of the subscription.
353
+ type: string
354
+ name:
355
+ description: The name of the subscription.
356
+ type: string
357
+ filter:
358
+ description: The filter for the subscription.
359
+ type: string
360
+ replication_rules:
361
+ description: The replication rules for the subscription.
362
+ type: string
363
+ policyid:
364
+ description: The policyid for the subscription.
365
+ type: integer
366
+ state:
367
+ description: The state of the subscription.
368
+ type: string
369
+ enum: ["A", "I", "N", "U", "B"]
370
+ last_processed:
371
+ description: The time the subscription was processed last.
372
+ type: string
373
+ format: date-time
374
+ account:
375
+ description: The account for the subscription.
376
+ type: string
377
+ lifetime:
378
+ description: The lifetime for the subscription.
379
+ type: string
380
+ format: date-time
381
+ comments:
382
+ description: The comments for the subscription.
383
+ type: string
384
+ retroactive:
385
+ description: If the subscription is retroactive.
386
+ type: boolean
387
+ expired_at:
388
+ description: The date-time of the expiration for the subscription.
389
+ type: string
390
+ format: date-time
391
+ 401:
392
+ description: Invalid Auth Token
393
+ 404:
394
+ description: Not found
395
+ 406:
396
+ description: Not acceptable
397
+ """
398
+ try:
399
+ def generate(vo):
400
+ for subscription in list_subscriptions(name=name, vo=vo):
401
+ yield render_json(**subscription) + '\n'
402
+
403
+ return try_stream(generate(vo=request.environ.get('vo')))
404
+ except SubscriptionNotFound as error:
405
+ return generate_http_error_flask(404, error)
406
+
407
+
408
+ class Rules(ErrorHandlingMethodView):
409
+
410
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
411
+ def get(self, account, name):
412
+ """
413
+ ---
414
+ summary: Get Replication Rules
415
+ description: Return all rules of a given subscription id.
416
+ tags:
417
+ - Replicas
418
+ parameters:
419
+ - name: account
420
+ in: path
421
+ description: The account name.
422
+ schema:
423
+ type: string
424
+ style: simple
425
+ required: true
426
+ - name: name
427
+ in: path
428
+ description: The subscription name.
429
+ schema:
430
+ type: string
431
+ style: simple
432
+ required: true
433
+ - name: state
434
+ in: query
435
+ description: The subscription state to filter for.
436
+ schema:
437
+ type: string
438
+ responses:
439
+ 200:
440
+ description: OK
441
+ content:
442
+ application/x-json-stream:
443
+ schema:
444
+ description: A list with the associated replication rules.
445
+ type: array
446
+ items:
447
+ description: A subscription rule.
448
+ 401:
449
+ description: Invalid Auth Token
450
+ 404:
451
+ description: Rule or Subscription not found
452
+ 406:
453
+ description: Not acceptable
454
+ """
455
+ state = request.args.get('state', default=None)
456
+ try:
457
+ subscriptions = [subscription['id'] for subscription in list_subscriptions(name=name, account=account, vo=request.environ.get('vo'))]
458
+
459
+ def generate(vo):
460
+ if len(subscriptions) > 0:
461
+ if state:
462
+ for rule in list_replication_rules({'subscription_id': subscriptions[0], 'state': state}, vo=vo):
463
+ yield render_json(**rule) + '\n'
464
+ else:
465
+ for rule in list_replication_rules({'subscription_id': subscriptions[0]}, vo=vo):
466
+ yield render_json(**rule) + '\n'
467
+
468
+ return try_stream(generate(vo=request.environ.get('vo')))
469
+ except (RuleNotFound, SubscriptionNotFound) as error:
470
+ return generate_http_error_flask(404, error)
471
+
472
+
473
+ class States(ErrorHandlingMethodView):
474
+
475
+ @check_accept_header_wrapper_flask(['application/x-json-stream'])
476
+ def get(self, account, name=None):
477
+ """
478
+ ---
479
+ summary: Get states
480
+ description: Return a summary of the states of all rules of a given subscription id.
481
+ tags:
482
+ - Replicas
483
+ parameters:
484
+ - name: account
485
+ in: path
486
+ description: The account name.
487
+ schema:
488
+ type: string
489
+ style: simple
490
+ required: true
491
+ - name: name
492
+ in: path
493
+ description: The subscription name.
494
+ schema:
495
+ type: string
496
+ style: simple
497
+ responses:
498
+ 200:
499
+ description: OK
500
+ content:
501
+ application/x-json-stream:
502
+ schema:
503
+ description: A list of rule states with counts for each subscription.
504
+ type: array
505
+ items:
506
+ type: object
507
+ properties:
508
+ account:
509
+ description: The account for the subscription.
510
+ type: string
511
+ name:
512
+ description: The name of the subscription.
513
+ type: string
514
+ state:
515
+ description: The state of the rules.
516
+ type: string
517
+ enum: ["R", "O", "S", "U", "W", "I"]
518
+ count:
519
+ description: The number of rules with that state.
520
+ type: integer
521
+ 401:
522
+ description: Invalid Auth Token
523
+ 404:
524
+ description: Not found
525
+ 406:
526
+ description: Not acceptable
527
+ """
528
+ def generate(vo):
529
+ for row in list_subscription_rule_states(name=name, account=account, vo=vo):
530
+ yield dumps(row, cls=APIEncoder) + '\n'
531
+
532
+ return try_stream(generate(vo=request.environ.get('vo')))
533
+
534
+
535
+ class SubscriptionId(ErrorHandlingMethodView):
536
+
537
+ @check_accept_header_wrapper_flask(['application/json'])
538
+ def get(self, subscription_id):
539
+ """
540
+ ---
541
+ summary: Get Subscription from ID
542
+ description: Retrieve a subscription matching the given subscription id.
543
+ tags:
544
+ - Replicas
545
+ parameters:
546
+ - name: subscription_id
547
+ in: path
548
+ description: The subscription id.
549
+ schema:
550
+ type: string
551
+ style: simple
552
+ required: true
553
+ responses:
554
+ 200:
555
+ description: OK
556
+ content:
557
+ application/json:
558
+ schema:
559
+ description: The subscription.
560
+ type: object
561
+ properties:
562
+ id:
563
+ description: The id of the subscription.
564
+ type: string
565
+ name:
566
+ description: The name of the subscription.
567
+ type: string
568
+ filter:
569
+ description: The filter for the subscription.
570
+ type: string
571
+ replication_rules:
572
+ description: The replication rules for the subscription.
573
+ type: string
574
+ policyid:
575
+ description: The policyid for the subscription.
576
+ type: integer
577
+ state:
578
+ description: The state of the subscription.
579
+ type: string
580
+ enum: ["A", "I", "N", "U", "B"]
581
+ last_processed:
582
+ description: The time the subscription was processed last.
583
+ type: string
584
+ format: date-time
585
+ account:
586
+ description: The account for the subscription.
587
+ type: string
588
+ lifetime:
589
+ description: The lifetime for the subscription.
590
+ type: string
591
+ format: date-time
592
+ comments:
593
+ description: The comments for the subscription.
594
+ type: string
595
+ retroactive:
596
+ description: If the subscription is retroactive.
597
+ type: boolean
598
+ expired_at:
599
+ description: The date-time of the expiration for the subscription.
600
+ type: string
601
+ format: date-time
602
+ 401:
603
+ description: Invalid Auth Token
604
+ 404:
605
+ description: Subscription not found
606
+ 406:
607
+ description: Not acceptable
608
+ """
609
+ try:
610
+ subscription = get_subscription_by_id(subscription_id, vo=request.environ.get('vo'))
611
+ except SubscriptionNotFound as error:
612
+ return generate_http_error_flask(404, error)
613
+
614
+ return Response(render_json(**subscription), content_type="application/json")
615
+
616
+
617
+ def blueprint():
618
+ bp = AuthenticatedBlueprint('subscriptions', __name__, url_prefix='/subscriptions')
619
+
620
+ subscription_id_view = SubscriptionId.as_view('subscription_id')
621
+ bp.add_url_rule('/id/<subscription_id>', view_func=subscription_id_view, methods=['get', ])
622
+ states_view = States.as_view('states')
623
+ bp.add_url_rule('/<account>/<name>/rules/states', view_func=states_view, methods=['get', ])
624
+ bp.add_url_rule('/<account>/rules/states', view_func=states_view, methods=['get', ])
625
+ rules_view = Rules.as_view('rules')
626
+ bp.add_url_rule('/<account>/<name>/rules', view_func=rules_view, methods=['get', ])
627
+ subscription_view = Subscription.as_view('subscription')
628
+ bp.add_url_rule('/<account>/<name>', view_func=subscription_view, methods=['get', 'post', 'put'])
629
+ bp.add_url_rule('/<account>', view_func=subscription_view, methods=['get', ])
630
+ bp.add_url_rule('/', view_func=subscription_view, methods=['get', ])
631
+ subscription_name_view = SubscriptionName.as_view('subscription_name')
632
+ bp.add_url_rule('/name/<name>', view_func=subscription_name_view, methods=['get', ])
633
+
634
+ # Legacy url support
635
+ # TODO: Take out with Rucio 38
636
+ bp.add_url_rule('/Id/<subscription_id>', view_func=subscription_id_view, methods=['get', ])
637
+ bp.add_url_rule('/<account>/<name>/Rules/States', view_func=states_view, methods=['get', ])
638
+ bp.add_url_rule('/<account>/Rules/States', view_func=states_view, methods=['get', ])
639
+ bp.add_url_rule('/<account>/<name>/Rules', view_func=rules_view, methods=['get', ])
640
+ bp.add_url_rule('/Name/<name>', view_func=subscription_name_view, methods=['get', ])
641
+
642
+ bp.after_request(response_headers)
643
+ return bp
644
+
645
+
646
+ def make_doc():
647
+ """ Only used for sphinx documentation """
648
+ doc_app = Flask(__name__)
649
+ doc_app.register_blueprint(blueprint())
650
+ return doc_app