rucio-clients 36.4.0__tar.gz → 37.0.0rc1__tar.gz

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-clients might be problematic. Click here for more details.

Files changed (220) hide show
  1. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/AUTHORS.rst +2 -0
  2. rucio_clients-37.0.0rc1/ChangeLog +1 -0
  3. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/PKG-INFO +20 -18
  4. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/bin/rucio +6 -6
  5. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/bin/rucio-admin +8 -14
  6. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/etc/rucio.cfg.template +1 -18
  7. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/alembicrevision.py +1 -1
  8. rucio_clients-37.0.0rc1/lib/rucio/cli/__init__.py +14 -0
  9. rucio_clients-37.0.0rc1/lib/rucio/cli/account.py +216 -0
  10. {rucio_clients-36.4.0/lib/rucio/client/commands → rucio_clients-37.0.0rc1/lib/rucio/cli}/bin_legacy/rucio.py +22 -17
  11. {rucio_clients-36.4.0/lib/rucio/client/commands → rucio_clients-37.0.0rc1/lib/rucio/cli}/bin_legacy/rucio_admin.py +9 -3
  12. rucio_clients-37.0.0rc1/lib/rucio/cli/command.py +272 -0
  13. rucio_clients-37.0.0rc1/lib/rucio/cli/config.py +72 -0
  14. rucio_clients-37.0.0rc1/lib/rucio/cli/did.py +191 -0
  15. rucio_clients-37.0.0rc1/lib/rucio/cli/download.py +128 -0
  16. rucio_clients-37.0.0rc1/lib/rucio/cli/lifetime_exception.py +33 -0
  17. rucio_clients-37.0.0rc1/lib/rucio/cli/replica.py +162 -0
  18. rucio_clients-37.0.0rc1/lib/rucio/cli/rse.py +293 -0
  19. rucio_clients-37.0.0rc1/lib/rucio/cli/rule.py +158 -0
  20. rucio_clients-37.0.0rc1/lib/rucio/cli/scope.py +40 -0
  21. rucio_clients-37.0.0rc1/lib/rucio/cli/subscription.py +73 -0
  22. rucio_clients-37.0.0rc1/lib/rucio/cli/upload.py +60 -0
  23. {rucio_clients-36.4.0/lib/rucio/client/commands → rucio_clients-37.0.0rc1/lib/rucio/cli}/utils.py +11 -11
  24. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/didclient.py +5 -3
  25. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/richclient.py +6 -13
  26. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/uploadclient.py +22 -11
  27. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/checksum.py +27 -10
  28. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/exception.py +10 -0
  29. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/policy.py +12 -3
  30. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/schema/__init__.py +15 -7
  31. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/schema/generic.py +0 -17
  32. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/schema/generic_multi_vo.py +0 -17
  33. rucio_clients-37.0.0rc1/lib/rucio/common/stomp_utils.py +423 -0
  34. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/test_rucio_server.py +5 -5
  35. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/types.py +24 -2
  36. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/utils.py +22 -5
  37. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/bittorrent.py +0 -3
  38. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/cache.py +0 -11
  39. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/dummy.py +0 -11
  40. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/gfal.py +6 -2
  41. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/globus.py +1 -1
  42. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/http_cache.py +1 -1
  43. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/posix.py +1 -1
  44. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/protocol.py +72 -23
  45. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/rfio.py +1 -1
  46. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/storm.py +2 -13
  47. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/webdav.py +60 -20
  48. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/rsemanager.py +160 -46
  49. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/translation.py +38 -51
  50. rucio_clients-37.0.0rc1/lib/rucio/vcsversion.py +11 -0
  51. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio_clients.egg-info/SOURCES.txt +17 -20
  52. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/pyproject.toml +3 -0
  53. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/requirements/requirements.client.txt +10 -9
  54. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/setup.cfg +1 -3
  55. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/setup.py +5 -7
  56. rucio_clients-37.0.0rc1/setuputil.py +126 -0
  57. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_bin_rucio.py +37 -1
  58. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_cli_client_structure.py +154 -88
  59. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_conveyor.py +1 -1
  60. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_curl.py +6 -1
  61. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_daemons.py +0 -2
  62. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_did_meta_plugins.py +116 -2
  63. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_impl_upload_download.py +2 -2
  64. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_lifetime.py +4 -0
  65. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_policy_package.py +6 -0
  66. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rucio_server.py +4 -4
  67. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rule.py +3 -9
  68. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_trace.py +38 -0
  69. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_transfer_plugins.py +61 -1
  70. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_undertaker.py +2 -5
  71. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_upload.py +13 -3
  72. rucio_clients-36.4.0/ChangeLog +0 -1
  73. rucio_clients-36.4.0/lib/rucio/client/commands/__init__.py +0 -25
  74. rucio_clients-36.4.0/lib/rucio/client/commands/account.py +0 -220
  75. rucio_clients-36.4.0/lib/rucio/client/commands/command.py +0 -263
  76. rucio_clients-36.4.0/lib/rucio/client/commands/command_base.py +0 -193
  77. rucio_clients-36.4.0/lib/rucio/client/commands/config.py +0 -58
  78. rucio_clients-36.4.0/lib/rucio/client/commands/did.py +0 -202
  79. rucio_clients-36.4.0/lib/rucio/client/commands/download.py +0 -92
  80. rucio_clients-36.4.0/lib/rucio/client/commands/lifetime_exception.py +0 -53
  81. rucio_clients-36.4.0/lib/rucio/client/commands/replica.py +0 -166
  82. rucio_clients-36.4.0/lib/rucio/client/commands/rse.py +0 -285
  83. rucio_clients-36.4.0/lib/rucio/client/commands/rule.py +0 -123
  84. rucio_clients-36.4.0/lib/rucio/client/commands/scope.py +0 -51
  85. rucio_clients-36.4.0/lib/rucio/client/commands/subscription.py +0 -72
  86. rucio_clients-36.4.0/lib/rucio/client/commands/upload.py +0 -62
  87. rucio_clients-36.4.0/lib/rucio/common/stomp_utils.py +0 -159
  88. rucio_clients-36.4.0/lib/rucio/rse/protocols/gsiftp.py +0 -107
  89. rucio_clients-36.4.0/lib/rucio/vcsversion.py +0 -11
  90. rucio_clients-36.4.0/pylintrc +0 -507
  91. rucio_clients-36.4.0/setuputil.py +0 -176
  92. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/LICENSE +0 -0
  93. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/MANIFEST.in +0 -0
  94. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/README.md +0 -0
  95. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/etc/rse-accounts.cfg.template +0 -0
  96. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/etc/rucio.cfg.atlas.client.template +0 -0
  97. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/__init__.py +0 -0
  98. {rucio_clients-36.4.0/lib/rucio/client/commands → rucio_clients-37.0.0rc1/lib/rucio/cli}/bin_legacy/__init__.py +0 -0
  99. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/__init__.py +0 -0
  100. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/accountclient.py +0 -0
  101. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/accountlimitclient.py +0 -0
  102. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/baseclient.py +0 -0
  103. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/client.py +0 -0
  104. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/configclient.py +0 -0
  105. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/credentialclient.py +0 -0
  106. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/diracclient.py +0 -0
  107. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/downloadclient.py +0 -0
  108. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/exportclient.py +0 -0
  109. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/fileclient.py +0 -0
  110. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/importclient.py +0 -0
  111. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/lifetimeclient.py +0 -0
  112. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/lockclient.py +0 -0
  113. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/metaconventionsclient.py +0 -0
  114. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/pingclient.py +0 -0
  115. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/replicaclient.py +0 -0
  116. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/requestclient.py +0 -0
  117. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/rseclient.py +0 -0
  118. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/ruleclient.py +0 -0
  119. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/scopeclient.py +0 -0
  120. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/subscriptionclient.py +0 -0
  121. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/client/touchclient.py +0 -0
  122. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/__init__.py +0 -0
  123. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/bittorrent.py +0 -0
  124. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/cache.py +0 -0
  125. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/client.py +0 -0
  126. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/config.py +0 -0
  127. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/constants.py +0 -0
  128. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/constraints.py +0 -0
  129. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/didtype.py +0 -0
  130. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/extra.py +0 -0
  131. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/logging.py +0 -0
  132. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/pcache.py +0 -0
  133. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/plugins.py +0 -0
  134. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/common/stopwatch.py +0 -0
  135. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/__init__.py +0 -0
  136. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/__init__.py +0 -0
  137. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/mock.py +0 -0
  138. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/ngarc.py +0 -0
  139. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/rclone.py +0 -0
  140. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/srm.py +0 -0
  141. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/ssh.py +0 -0
  142. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/rse/protocols/xrootd.py +0 -0
  143. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/lib/rucio/version.py +0 -0
  144. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_abacus_account.py +0 -0
  145. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_abacus_collection_replica.py +0 -0
  146. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_abacus_rse.py +0 -0
  147. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_account.py +0 -0
  148. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_account_limits.py +0 -0
  149. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_archive.py +0 -0
  150. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_auditor.py +0 -0
  151. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_auditor_hdfs.py +0 -0
  152. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_auditor_srmdumps.py +0 -0
  153. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_authentication.py +0 -0
  154. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_automatix.py +0 -0
  155. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_bad_replica.py +0 -0
  156. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_bb8.py +0 -0
  157. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_belleii.py +0 -0
  158. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_boolean.py +0 -0
  159. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_clients.py +0 -0
  160. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_config.py +0 -0
  161. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_conveyor_submitter.py +0 -0
  162. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_counter.py +0 -0
  163. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_credential.py +0 -0
  164. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_dataset_replicas.py +0 -0
  165. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_db.py +0 -0
  166. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_did.py +0 -0
  167. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_download.py +0 -0
  168. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_dumper.py +0 -0
  169. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_filter_engine.py +0 -0
  170. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_gateway_external_representation.py +0 -0
  171. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_heartbeat.py +0 -0
  172. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_hermes.py +0 -0
  173. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_identity.py +0 -0
  174. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_import_export.py +0 -0
  175. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_judge_cleaner.py +0 -0
  176. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_judge_evaluator.py +0 -0
  177. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_judge_injector.py +0 -0
  178. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_judge_repairer.py +0 -0
  179. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_message.py +0 -0
  180. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_meta_conventions.py +0 -0
  181. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_meta_did.py +0 -0
  182. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_module_import.py +0 -0
  183. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_monitor.py +0 -0
  184. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_multi_vo.py +0 -0
  185. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_naming_convention.py +0 -0
  186. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_oauthmanager.py +0 -0
  187. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_oidc.py +0 -0
  188. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_permission.py +0 -0
  189. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_pfns.py +0 -0
  190. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_ping.py +0 -0
  191. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_preparer.py +0 -0
  192. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_qos.py +0 -0
  193. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_quarantined_replica.py +0 -0
  194. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_reaper.py +0 -0
  195. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_redirect.py +0 -0
  196. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_replica.py +0 -0
  197. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_replica_recoverer.py +0 -0
  198. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_replica_sorting.py +0 -0
  199. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_request.py +0 -0
  200. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_root_proxy.py +0 -0
  201. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse.py +0 -0
  202. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_expression_parser.py +0 -0
  203. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_lfn2path.py +0 -0
  204. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_protocol_gfal2.py +0 -0
  205. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_protocol_gfal2_impl.py +0 -0
  206. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_protocol_posix.py +0 -0
  207. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_protocol_rclone.py +0 -0
  208. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_protocol_rsync.py +0 -0
  209. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_protocol_srm.py +0 -0
  210. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_protocol_ssh.py +0 -0
  211. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_protocol_webdav.py +0 -0
  212. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_protocol_xrootd.py +0 -0
  213. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_rse_selector.py +0 -0
  214. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_scope.py +0 -0
  215. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_subscription.py +0 -0
  216. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_throttler.py +0 -0
  217. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_tpc.py +0 -0
  218. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_transfer.py +0 -0
  219. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tests/test_utils.py +0 -0
  220. {rucio_clients-36.4.0 → rucio_clients-37.0.0rc1}/tools/merge_rucio_configs.py +0 -0
@@ -68,6 +68,7 @@ Individual contributors to the source code
68
68
  - Elena Gazzarrini <gazzarrini.elena@gmail.com>, 2022-2023
69
69
  - Maximilian Linhoff, <maximilian.linhoff@tu-dortmund.de>, 2024
70
70
  - Eric Banzuzi, <eric.banzuzi@gmail.com>, 2024
71
+ - Paul Millar, <paul.millar@desy.de>, 2025
71
72
 
72
73
  Organisations employing contributors
73
74
  ------------------------------------
@@ -96,3 +97,4 @@ Organisations employing contributors
96
97
  - University of Chicago (USA)
97
98
  - Purdue University (USA)
98
99
  - TU Dortmund University (Germany)
100
+ - Deutsches Elektronen-Synchrotron DESY (Germany)
@@ -0,0 +1 @@
1
+ Release notes may be found at: https://rucio.cern.ch/documentation/release-notes/
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: rucio-clients
3
- Version: 36.4.0
3
+ Version: 37.0.0rc1
4
4
  Summary: Rucio Client Lite Package
5
5
  Home-page: https://rucio.cern.ch/
6
6
  Author: Rucio
@@ -19,33 +19,35 @@ Classifier: Programming Language :: Python :: 3.10
19
19
  Requires-Python: >=3.9, <4
20
20
  License-File: LICENSE
21
21
  License-File: AUTHORS.rst
22
- Requires-Dist: requests>=2.32.2
23
- Requires-Dist: urllib3>=1.26.18
24
- Requires-Dist: dogpile-cache>=1.2.2
25
- Requires-Dist: tabulate>=0.9.0
26
- Requires-Dist: jsonschema>=4.20.0
27
- Requires-Dist: packaging>=24.1
28
- Requires-Dist: rich>=13.7.1
29
- Requires-Dist: typing-extensions>=4.12.2
22
+ Requires-Dist: requests
23
+ Requires-Dist: urllib3
24
+ Requires-Dist: dogpile-cache
25
+ Requires-Dist: packaging
26
+ Requires-Dist: tabulate
27
+ Requires-Dist: jsonschema
28
+ Requires-Dist: dataclasses
29
+ Requires-Dist: rich
30
+ Requires-Dist: typing_extensions
30
31
  Provides-Extra: ssh
31
- Requires-Dist: paramiko>=3.4.0; extra == "ssh"
32
+ Requires-Dist: paramiko; extra == "ssh"
32
33
  Provides-Extra: kerberos
33
- Requires-Dist: kerberos>=1.3.1; extra == "kerberos"
34
- Requires-Dist: pykerberos>=1.2.4; extra == "kerberos"
35
- Requires-Dist: requests-kerberos>=0.14.0; extra == "kerberos"
34
+ Requires-Dist: kerberos; extra == "kerberos"
35
+ Requires-Dist: pykerberos; extra == "kerberos"
36
+ Requires-Dist: requests-kerberos; extra == "kerberos"
36
37
  Provides-Extra: swift
37
- Requires-Dist: python-swiftclient>=4.4.0; extra == "swift"
38
+ Requires-Dist: python-swiftclient; extra == "swift"
38
39
  Provides-Extra: argcomplete
39
- Requires-Dist: argcomplete>=3.1.6; extra == "argcomplete"
40
+ Requires-Dist: argcomplete; extra == "argcomplete"
40
41
  Provides-Extra: sftp
41
- Requires-Dist: paramiko>=3.4.0; extra == "sftp"
42
+ Requires-Dist: paramiko; extra == "sftp"
42
43
  Provides-Extra: dumper
43
- Requires-Dist: python-magic>=0.4.27; extra == "dumper"
44
+ Requires-Dist: python-magic; extra == "dumper"
44
45
  Dynamic: author
45
46
  Dynamic: author-email
46
47
  Dynamic: classifier
47
48
  Dynamic: home-page
48
49
  Dynamic: license
50
+ Dynamic: license-file
49
51
  Dynamic: provides-extra
50
52
  Dynamic: requires-dist
51
53
  Dynamic: requires-python
@@ -17,8 +17,8 @@ import argparse
17
17
  import sys
18
18
  from typing import TYPE_CHECKING, Optional
19
19
 
20
- from rucio.client.commands.bin_legacy.rucio import main as main_legacy
21
- from rucio.client.commands.command import main
20
+ from rucio.cli.bin_legacy.rucio import main as main_legacy
21
+ from rucio.cli.command import main
22
22
  from rucio.common.utils import setup_logger
23
23
 
24
24
  if TYPE_CHECKING:
@@ -60,7 +60,7 @@ def map_legacy_command() -> Optional[list[str]]:
60
60
  "detach": ["did", "content", "remove"],
61
61
  "ls": ["did", "list"],
62
62
  "list-dids": ["did", "list"],
63
- "list-parent-dids": ["did", "show", "--parent"],
63
+ "list-parent-dids": ["did", "list", "--parent"],
64
64
  "list-scopes": ["scope", "list"],
65
65
  "close": ["did", "update", "--close"],
66
66
  "reopen": ["did", "update", "--open"],
@@ -83,7 +83,7 @@ def map_legacy_command() -> Optional[list[str]]:
83
83
  "list-rules": ["rule", "list"],
84
84
  "list-rules-history": ["rule", "history"],
85
85
  "update-rule": ["rule", "update"],
86
- "move-rule": ["rule", "update", "--move"],
86
+ "move-rule": ["rule", "move"],
87
87
  "list-rses": ["rse", "list"],
88
88
  "list-suspicious-replicas": ["replica", "state", "suspicious"],
89
89
  "list-rse-attributes": ["rse", "attribute", "list"],
@@ -115,7 +115,7 @@ if __name__ == "__main__":
115
115
  main_legacy()
116
116
 
117
117
  elif (any(arg in commands for arg in sys.argv)) or args.help or args.version:
118
- main()
118
+ main() # pylint: disable=E1120
119
119
 
120
120
  else:
121
121
  make_warning(logger)
@@ -130,4 +130,4 @@ if __name__ == "__main__":
130
130
  else:
131
131
  sys.argv = ["rucio", "-h"]
132
132
 
133
- main()
133
+ main() # pylint: disable=E1120
@@ -12,9 +12,10 @@
12
12
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
+
15
16
  import sys
16
17
 
17
- from rucio.client.commands.bin_legacy.rucio_admin import main as main_legacy
18
+ from rucio.cli.bin_legacy.rucio_admin import main as main_legacy
18
19
  from rucio.common.utils import setup_logger
19
20
 
20
21
 
@@ -32,7 +33,7 @@ def make_warning():
32
33
  except IndexError:
33
34
  second_command = "-h"
34
35
 
35
- if first_command not in ("-h", "--version", "--help"):
36
+ if (first_command not in ("-h", "--version", "--help")) and (first_command is not None):
36
37
  command_map = {
37
38
  "data": {"import": "upload", "export": "download"},
38
39
  "account": {
@@ -44,8 +45,8 @@ def make_warning():
44
45
  "set-limits": "account limit add",
45
46
  "get-limits": "account limit list",
46
47
  "delete-limits": "account limit remove",
47
- "ban": "account update --ban True",
48
- "unban": "account update --ban False",
48
+ "ban": "account update --ban",
49
+ "unban": "account update --unban",
49
50
  "list-attributes": "account attribute list",
50
51
  "add-attribute": "account attribute add",
51
52
  "delete-attribute": "account attribute remove",
@@ -60,7 +61,8 @@ def make_warning():
60
61
  "set-attribute": "rse attribute add",
61
62
  "delete-attribute": "rse attribute remove",
62
63
  "delete-distance": "rse distance remove",
63
- "get-distance": "rse distance list",
64
+ "get-distance": "rse distance show",
65
+ "set-distance": "rse distance update",
64
66
  "get-attribute": "rse attribute list",
65
67
  "add-protocol": "rse protocol add",
66
68
  "delete-protocol": "rse protocol remove",
@@ -75,15 +77,7 @@ def make_warning():
75
77
  "scope": {"-h": "scope -h", "add": "scope add", "list": "scope list"},
76
78
  "config": {"-h": "config -h", "get": "config list", "set": "config add", "delete": "config remove"},
77
79
  "subscription": {"-h": "subscription -h", "add": "subscription add", "list": "subscription", "update": "subscription update", "reevaluate": "subscription touch"},
78
- "replicas": {
79
- "-h": "replica -h",
80
- "quarantine": "replica state quarantine",
81
- "declare-bad": "replica state bad",
82
- "declare-temporary-unavailable":
83
- "replica state unavailable",
84
- "set-tombstone": "replica remove",
85
- "list-pfns": "replica list file --pfns"
86
- },
80
+ "replicas": {"-h": "replica -h", "quarantine": "replica state update quarantine", "declare-bad": "replica state update bad", "declare-temporary-unavailable": "replica state update unavailable", "set-tombstone": "replica remove"},
87
81
  }
88
82
  try:
89
83
  new_command = command_map[first_command]
@@ -77,7 +77,7 @@ default = sqlite:////tmp/rucio.db
77
77
  #default = oracle://_____________:___________@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=______))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=_____________)))
78
78
  #schema=atlas_rucio # only for cern oracle
79
79
  #default = mysql+pymysql://rucio:rucio@localhost/rucio
80
- #default = postgresql://rucio:rucio@localhost/rucio
80
+ #default = postgresql+psycopg://rucio:rucio@localhost/rucio
81
81
  pool_recycle=3600
82
82
  echo=0
83
83
  pool_reset_on_return=rollback
@@ -211,23 +211,6 @@ fts_servers = https://fts3-pilot.cern.ch:8446, https://fts3-devel.cern.ch:8446,
211
211
  cache = /opt/rucio/auditor-cache
212
212
  results = /opt/rucio/auditor-results
213
213
 
214
- [c3po]
215
- placement_algorithm = t2_free_space
216
- elastic_url = http://aianalytics01.cern.ch:9200
217
- redis_host = localhost
218
- redis_port = 6379
219
-
220
- [c3po-popularity]
221
- elastic_url = http://rucio-logger-prod-01.cern.ch:9200
222
-
223
- [c3po-site-mapper]
224
- panda_url = http://atlas-agis-api.cern.ch/request/pandaqueue/query/list/?json
225
- ddm_url = http://atlas-agis-api.cern.ch/request/ddmendpoint/query/list/?json
226
-
227
- [c3po-workload]
228
- panda_url = http://bigpanda.cern.ch/jobs/?category=analysis&jobstatus=running
229
- window = 604800
230
-
231
214
  [policy]
232
215
  package = atlas_rucio_policy_package
233
216
  permission = atlas
@@ -12,4 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- ALEMBIC_REVISION = 'b0070f3695c8' # the current alembic head revision
15
+ ALEMBIC_REVISION = '30d5206e9cad' # the current alembic head revision
@@ -0,0 +1,14 @@
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
+ from rucio.cli import command # noqa: F401
@@ -0,0 +1,216 @@
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
+ import click
15
+
16
+ from rucio.cli.bin_legacy.rucio import list_account_usage
17
+ from rucio.cli.bin_legacy.rucio_admin import (
18
+ add_account,
19
+ add_account_attribute,
20
+ ban_account,
21
+ delete_account,
22
+ delete_account_attribute,
23
+ delete_limits,
24
+ identity_delete,
25
+ info_account,
26
+ list_account_attributes,
27
+ list_accounts,
28
+ list_identities,
29
+ set_limits,
30
+ unban_account,
31
+ update_account,
32
+ )
33
+ from rucio.cli.bin_legacy.rucio_admin import identity_add as legacy_identity_add
34
+ from rucio.cli.utils import Arguments
35
+
36
+
37
+ @click.group()
38
+ def account():
39
+ """Methods to add or change accounts for users, groups, and services. Used to assign privileges"""
40
+
41
+
42
+ @account.command("add")
43
+ @click.argument("account-name")
44
+ @click.argument("account-type", type=click.Choice(["USER", "GROUP", "SERVICE"]))
45
+ @click.option("--email", type=str, help="Email address associated with the account")
46
+ @click.pass_context
47
+ def add_(ctx, account_type, account_name, email):
48
+ """Add an account of type [ACCOUNT-TYPE] with the name [ACCOUNT-NAME]
49
+
50
+ \b
51
+ Example:
52
+ $ rucio account add
53
+ """
54
+ args = Arguments({"account_type": account_type, "account": account_name, "email": email})
55
+ add_account(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
56
+
57
+
58
+ @account.command("list")
59
+ @click.option("--type", "type_", type=click.Choice(["USER", "GROUP", "SERVICE"]))
60
+ @click.option("--id", help="Filter by identity (e.g. DN)")
61
+ @click.option("--filter", help="Filter arguments in form `key=value,another_key=next_value`") # TODO Explicit numeration of these possible keys
62
+ @click.pass_context
63
+ def list_(ctx, type_, id, filter):
64
+ """List all accounts that match given filters"""
65
+ args = Arguments({"account_type": type_, "identity": id, "filters": filter})
66
+ list_accounts(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
67
+
68
+
69
+ @account.command("show")
70
+ @click.argument("account-name")
71
+ @click.pass_context
72
+ def show(ctx, account_name):
73
+ """
74
+ Show info about a single account
75
+ """
76
+ info_account(Arguments({"account": account_name}), ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
77
+
78
+
79
+ @account.command("remove")
80
+ @click.argument("account-name")
81
+ @click.pass_context
82
+ def remove(ctx, account_name):
83
+ """
84
+ Remove an account
85
+ (WARNING: Permanently disables the account. If you want to temporarily disable, use `account update [account-name] --ban`)
86
+ """
87
+ delete_account(Arguments({"account": account_name}), ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
88
+
89
+
90
+ @account.command("update")
91
+ @click.argument("account-name")
92
+ @click.option("--email", help="Email address associated with the account")
93
+ @click.option("--ban/--unban", default=None, help="Temporarily disable/enable an account")
94
+ @click.pass_context
95
+ def update(ctx, ban, account_name, email):
96
+ """Update account settings"""
97
+ args = Arguments({"account": account_name, "key": "email", "value": email})
98
+ if ban is not None:
99
+ if ban:
100
+ ban_account(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
101
+ else:
102
+ unban_account(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
103
+ else:
104
+ update_account(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
105
+
106
+
107
+ @account.group()
108
+ def attribute():
109
+ """View or modify account attributes"""
110
+
111
+
112
+ @attribute.command("list")
113
+ @click.argument("account-name")
114
+ @click.pass_context
115
+ def attribute_list(ctx, account_name):
116
+ "List the attributes for a given account"
117
+ list_account_attributes(Arguments({"account": account_name}), ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
118
+
119
+
120
+ @attribute.command("add")
121
+ @click.argument("account-name")
122
+ @click.option('--key', help='Attribute key', required=True)
123
+ @click.option('--value', help='Attribute value', required=True)
124
+ @click.pass_context
125
+ def attribute_add(ctx, account_name, key, value):
126
+ """Add a new attribute [key] to an account"""
127
+ add_account_attribute(Arguments({"account": account_name, "key": key, "value": value}), ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
128
+
129
+
130
+ @attribute.command("remove")
131
+ @click.argument("account-name")
132
+ @click.option("--key", help="Attribute key", required=True)
133
+ @click.pass_context
134
+ def attribute_remove(ctx, account_name, key):
135
+ """Remove an attribute from an account without reassigning it"""
136
+ delete_account_attribute(Arguments({"account": account_name, "key": key}), ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
137
+
138
+
139
+ @account.group("limit")
140
+ def limit():
141
+ """View or modify account limits - limit how much data an account can store on an RSE"""
142
+
143
+
144
+ @limit.command("list", help="Shows the space used, the quota limit and the quota left for an account for every RSE where the user have quota.")
145
+ @click.argument("account-name")
146
+ @click.option("--rse", "--rse-name", help="Show usage for only for this RSE.")
147
+ @click.pass_context
148
+ def limit_list(ctx, account_name, rse):
149
+ """List the limits and current usage for an account"""
150
+ args = Arguments({"usage_account": account_name, "rse": rse})
151
+ list_account_usage(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
152
+
153
+
154
+ @limit.command("add")
155
+ @click.argument(
156
+ "account-name",
157
+ )
158
+ @click.option("--rse", "--rse-name", help="Full RSE name", required=True) # TODO Separate RSE (local) and RSE Expression (global)
159
+ @click.option("--bytes", "bytes_", help='Value of the limit; can be specified in bytes ("10000"), with a storage unit ("10GB"), or "infinity"', required=True)
160
+ @click.option("--locality", type=click.Choice(["local", "global"]), help="Global or local limit scope", default="local")
161
+ @click.pass_context
162
+ def limit_add(ctx, account_name, rse, bytes_, locality):
163
+ """Add a new limit for an account on an RSE. An account can have both local and global limits on the same RSE."""
164
+ args = Arguments({"account": account_name, "rse": rse, "bytes": bytes_, "locality": locality})
165
+ set_limits(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
166
+
167
+
168
+ @limit.command("remove")
169
+ @click.argument(
170
+ "account-name",
171
+ )
172
+ @click.option("--rse", "--rse-name", help="Full RSE name", required=True)
173
+ @click.option("--locality", type=click.Choice(["local", "global"]), help="Global or local limit scope", default="local")
174
+ @click.pass_context
175
+ def limit_remove(ctx, account_name, rse, locality):
176
+ """Remove existing limits for an account on an RSE"""
177
+ args = Arguments({"account": account_name, "rse": rse, "locality": locality})
178
+ delete_limits(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
179
+
180
+
181
+ @account.group("identity")
182
+ def identity():
183
+ """Manage identities for an account - used to login"""
184
+
185
+
186
+ @identity.command("list")
187
+ @click.argument("account-name", required=True)
188
+ @click.pass_context
189
+ def identity_list(ctx, account_name):
190
+ """See all the IDs for [account-name]"""
191
+ args = Arguments({"account": account_name})
192
+ list_identities(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
193
+
194
+
195
+ @identity.command("add")
196
+ @click.argument("account-name", required=True)
197
+ @click.option("--type", "type_", type=click.Choice(["X509", "GSS", "USERPASS", "SSH", "SAML", "OIDC"]), help="Authentication type", required=True)
198
+ @click.option("--id", help="Identity", required=True)
199
+ @click.option("--email", help="Email address associated with the identity", required=True)
200
+ @click.option("--password", help="Password if authtype is USERPASS")
201
+ @click.pass_context
202
+ def identity_add(ctx, account_name, type_, id, email, password):
203
+ """Add a new identity for [account-name]"""
204
+ args = Arguments({"account": account_name, "authtype": type_, "identity": id, "email": email, "password": password})
205
+ legacy_identity_add(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
206
+
207
+
208
+ @identity.command("remove")
209
+ @click.argument("account-name", required=True)
210
+ @click.option("--type", "type_", type=click.Choice(["X509", "GSS", "USERPASS", "SSH", "SAML", "OIDC"]), help="Authentication type", required=True)
211
+ @click.option("--id", help="Identity", required=True)
212
+ @click.pass_context
213
+ def identity_remove(ctx, account_name, type_, id):
214
+ """Revoke a given ID's access from an account"""
215
+ args = Arguments({"account": account_name, "authtype": type_, "id": id})
216
+ identity_delete(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
@@ -39,7 +39,7 @@ from tabulate import tabulate
39
39
 
40
40
  # rucio module has the same name as this executable module, so this rule fails. pylint: disable=no-name-in-module
41
41
  from rucio import version
42
- from rucio.client.commands.utils import exception_handler, get_client, setup_gfal2_logger, signal_handler
42
+ from rucio.cli.utils import exception_handler, get_client, setup_gfal2_logger, signal_handler
43
43
  from rucio.client.richclient import MAX_TRACEBACK_WIDTH, MIN_CONSOLE_WIDTH, CLITheme, generate_table, get_cli_config, get_pager, print_output, setup_rich_logger
44
44
  from rucio.common.client import detect_client_location
45
45
  from rucio.common.config import config_get, config_get_float
@@ -1671,7 +1671,9 @@ def list_rses(args, client, logger, console, spinner):
1671
1671
  spinner.start()
1672
1672
 
1673
1673
  rses = client.list_rses(args.rses)
1674
- if cli_config == 'rich':
1674
+ if args.csv:
1675
+ print(*(rse['rse'] for rse in rses), sep='\n')
1676
+ elif cli_config == 'rich':
1675
1677
  table = generate_table([[rse['rse']] for rse in sorted(rses, key=lambda elem: elem['rse'])], headers=['RSE'], col_alignments=['left'])
1676
1678
  spinner.stop()
1677
1679
  print_output(table, console=console, no_pager=args.no_pager)
@@ -1985,20 +1987,22 @@ def add_lifetime_exception(args, client, logger, console, spinner):
1985
1987
  logger.error('inputfile is mandatory')
1986
1988
  return FAILURE
1987
1989
  with open(args.inputfile) as infile:
1988
- dids = list(set(line.strip() for line in infile))
1990
+ # Deduplicate the content of the input file and ignore empty lines.
1991
+ dids = set(did for line in infile if (did := line.strip()))
1989
1992
 
1990
1993
  dids_list = []
1991
1994
  containers = []
1992
1995
  datasets = []
1993
- error_types = ['Total DIDs',
1994
- 'DID not submitted because it is a file',
1995
- 'DID that are containers and were resolved',
1996
- 'DID not submitted because it is not part of the lifetime campaign',
1997
- 'DID successfully submitted including the one from containers resolved']
1998
1996
  for did in dids:
1999
1997
  scope, name = get_scope(did, client)
2000
1998
  dids_list.append({'scope': scope, 'name': name})
2001
- summary = {0: len(dids_list), 1: 0, 2: 0, 3: 0, 4: 0}
1999
+ error_summary = {
2000
+ "total_dids": {"description": "Total DIDs", "count": len(dids_list)},
2001
+ "files_ignored": {"description": "DID not submitted because it is a file", "count": 0},
2002
+ "containers_resolved": {"description": "DID that are containers and were resolved", "count": 0},
2003
+ "not_in_lifetime_model": {"description": "DID not submitted because it is not part of the lifetime campaign", "count": 0},
2004
+ "successfully_submitted": {"description": "DID successfully submitted including the one from containers resolved", "count": 0},
2005
+ }
2002
2006
  chunk_limit = 500 # Server should be able to accept 1000
2003
2007
  dids_list_copy = deepcopy(dids_list)
2004
2008
  for chunk in chunks(dids_list_copy, chunk_limit):
@@ -2007,18 +2011,18 @@ def add_lifetime_exception(args, client, logger, console, spinner):
2007
2011
  dids_list.remove({'scope': scope, 'name': name})
2008
2012
  if meta['did_type'] == 'FILE':
2009
2013
  logger.warning('%s:%s is a file. Will be ignored' % (scope, name))
2010
- summary[1] += 1
2014
+ error_summary["files_ignored"]["count"] += 1
2011
2015
  elif meta['did_type'] == 'CONTAINER':
2012
2016
  logger.warning('%s:%s is a container. It needs to be resolved' % (scope, name))
2013
2017
  containers.append({'scope': scope, 'name': name})
2014
- summary[2] += 1
2018
+ error_summary["containers_resolved"]["count"] += 1
2015
2019
  elif not meta['eol_at']:
2016
2020
  logger.warning('%s:%s is not affected by the lifetime model' % (scope, name))
2017
- summary[3] += 1
2021
+ error_summary["not_in_lifetime_model"]["count"] += 1
2018
2022
  else:
2019
2023
  logger.info('%s:%s will be declared' % (scope, name))
2020
2024
  datasets.append({'scope': scope, 'name': name})
2021
- summary[4] += 1
2025
+ error_summary["successfully_submitted"]["count"] += 1
2022
2026
 
2023
2027
  for did in dids_list:
2024
2028
  scope = did['scope']
@@ -2036,11 +2040,11 @@ def add_lifetime_exception(args, client, logger, console, spinner):
2036
2040
  logger.debug('%s:%s' % (scope, name))
2037
2041
  if not meta['eol_at']:
2038
2042
  logger.warning('%s:%s is not affected by the lifetime model' % (scope, name))
2039
- summary[3] += 1
2043
+ error_summary["not_in_lifetime_model"]["count"] += 1
2040
2044
  else:
2041
2045
  logger.info('%s:%s will be declared' % (scope, name))
2042
2046
  datasets.append({'scope': scope, 'name': name})
2043
-
2047
+ error_summary["successfully_submitted"]["count"] += 1
2044
2048
  if not datasets:
2045
2049
  logger.error('Nothing to submit')
2046
2050
  return SUCCESS
@@ -2062,8 +2066,8 @@ def add_lifetime_exception(args, client, logger, console, spinner):
2062
2066
  return FAILURE
2063
2067
 
2064
2068
  logger.info('Exception successfully submitted. Summary below:')
2065
- for cnt, error in enumerate(error_types):
2066
- print('{0:100} {1:6d}'.format(error, summary[cnt]))
2069
+ for key, data in error_summary.items():
2070
+ print('{0:100} {1:6d}'.format(data["description"], data["count"]))
2067
2071
  return SUCCESS
2068
2072
 
2069
2073
 
@@ -2713,6 +2717,7 @@ You can filter by account::
2713
2717
  list_rses_parser.set_defaults(function=list_rses)
2714
2718
  list_rses_parser.add_argument('--rses', dest='rses', action='store', help='The RSE filter expression. A comprehensive help about RSE expressions \
2715
2719
  can be found in ' + Color.BOLD + 'https://rucio.cern.ch/documentation/started/concepts/rse_expressions' + Color.END)
2720
+ list_rses_parser.add_argument("--csv", action='store_true', help='Output a list of RSEs as a csv')
2716
2721
 
2717
2722
  # The list-suspicious-replicas command
2718
2723
  list_suspicious_replicas_parser = subparsers.add_parser('list-suspicious-replicas', help='Show the list of all replicas marked "suspicious".')
@@ -33,7 +33,7 @@ from rich.tree import Tree
33
33
  from tabulate import tabulate
34
34
 
35
35
  from rucio import version
36
- from rucio.client.commands.utils import exception_handler, get_client, setup_gfal2_logger, signal_handler
36
+ from rucio.cli.utils import exception_handler, get_client, setup_gfal2_logger, signal_handler
37
37
  from rucio.client.richclient import MAX_TRACEBACK_WIDTH, MIN_CONSOLE_WIDTH, CLITheme, generate_table, get_cli_config, get_pager, print_output, setup_rich_logger
38
38
  from rucio.common.constants import RseAttr
39
39
  from rucio.common.exception import (
@@ -151,7 +151,9 @@ def list_accounts(args, client, logger, console, spinner):
151
151
  for key, value in [(_.split('=')[0], _.split('=')[1]) for _ in args.filters.split(',')]:
152
152
  filters[key] = value
153
153
  accounts = client.list_accounts(identity=args.identity, account_type=args.account_type, filters=filters)
154
- if cli_config == 'rich':
154
+ if args.csv:
155
+ print(*(account['account'] for account in accounts), sep=',')
156
+ elif cli_config == 'rich':
155
157
  table = generate_table([[account['account']] for account in accounts], headers=['ACCOUNT'], col_alignments=['left'])
156
158
  spinner.stop()
157
159
  print_output(table, console=console, no_pager=args.no_pager)
@@ -327,7 +329,9 @@ def list_rses(args, client, logger, console, spinner):
327
329
  spinner.start()
328
330
 
329
331
  rses = client.list_rses()
330
- if cli_config == 'rich':
332
+ if args.csv:
333
+ print(*(rse['rse'] for rse in rses), sep='\n')
334
+ elif cli_config == 'rich':
331
335
  table_data = [[rse['rse']] for rse in sorted(rses, key=lambda elem: elem['rse'])]
332
336
  table = generate_table(table_data, headers=['RSE'], col_alignments=['left'])
333
337
  spinner.stop()
@@ -1455,6 +1459,7 @@ def get_parser():
1455
1459
  list_account_parser.add_argument('--type', dest='account_type', action='store', help='Account Type (USER, GROUP, SERVICE)')
1456
1460
  list_account_parser.add_argument('--id', dest='identity', action='store', help='Identity (e.g. DN)')
1457
1461
  list_account_parser.add_argument('--filters', dest='filters', action='store', help='Filter arguments in form `key=value,another_key=next_value`')
1462
+ list_account_parser.add_argument("--csv", action='store_true', help='List result as a csv')
1458
1463
  list_account_parser.set_defaults(which='list_accounts')
1459
1464
 
1460
1465
  # The list_account_attributes command
@@ -1753,6 +1758,7 @@ def get_parser():
1753
1758
  '\n'
1754
1759
  ' $ rucio list-rses --rses \"tier=2&type=DATADISK\"\n'
1755
1760
  '\n')
1761
+ list_rse_parser.add_argument("--csv", action='store_true', help='Output a list of RSEs as a csv')
1756
1762
  list_rse_parser.set_defaults(which='list_rses')
1757
1763
 
1758
1764
  # The add_rse command