rucio-clients 34.1.0__tar.gz → 34.3.0__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 (192) hide show
  1. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/PKG-INFO +1 -1
  2. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/bin/rucio +3 -3
  3. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/bin/rucio-admin +11 -10
  4. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/accountclient.py +1 -1
  5. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/baseclient.py +154 -131
  6. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/didclient.py +1 -1
  7. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/downloadclient.py +14 -13
  8. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/rseclient.py +5 -5
  9. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/ruleclient.py +2 -1
  10. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/uploadclient.py +6 -5
  11. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/cache.py +3 -1
  12. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/config.py +48 -46
  13. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/constants.py +61 -1
  14. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/didtype.py +23 -20
  15. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/pcache.py +2 -2
  16. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/plugins.py +10 -9
  17. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/policy.py +4 -3
  18. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/__init__.py +11 -7
  19. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/types.py +14 -1
  20. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/utils.py +28 -29
  21. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/bittorrent.py +1 -1
  22. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/cache.py +1 -1
  23. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/dummy.py +1 -1
  24. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/gfal.py +7 -7
  25. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/globus.py +6 -5
  26. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/gsiftp.py +2 -2
  27. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/http_cache.py +1 -1
  28. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/mock.py +1 -1
  29. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/ngarc.py +1 -1
  30. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/posix.py +7 -7
  31. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/protocol.py +13 -12
  32. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/rclone.py +4 -4
  33. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/rfio.py +4 -4
  34. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/srm.py +6 -6
  35. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/ssh.py +6 -6
  36. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/storm.py +1 -1
  37. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/webdav.py +2 -2
  38. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/xrootd.py +4 -4
  39. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/vcsversion.py +3 -3
  40. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/version.py +4 -4
  41. rucio_clients-34.3.0/pyproject.toml +101 -0
  42. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/requirements.txt +1 -0
  43. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_account.py +3 -3
  44. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_authentication.py +3 -5
  45. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_bad_replica.py +1 -1
  46. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_bin_rucio.py +41 -41
  47. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_clients.py +68 -16
  48. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_config.py +2 -2
  49. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_conveyor.py +26 -25
  50. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_conveyor_submitter.py +6 -5
  51. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_credential.py +2 -1
  52. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_dataset_replicas.py +1 -1
  53. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_dumper_data_model.py +2 -2
  54. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_identity.py +2 -2
  55. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_import_export.py +6 -5
  56. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_judge_repairer.py +1 -1
  57. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_multi_vo.py +6 -5
  58. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_oidc.py +9 -9
  59. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_preparer.py +7 -6
  60. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_reaper.py +1 -1
  61. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_replica.py +6 -5
  62. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_replica_recoverer.py +4 -4
  63. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_replica_sorting.py +3 -2
  64. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_request.py +6 -5
  65. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_root_proxy.py +3 -2
  66. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse.py +4 -3
  67. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_expression_parser.py +2 -2
  68. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_lfn2path.py +1 -1
  69. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rule.py +8 -7
  70. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_schema_cms.py +1 -1
  71. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_scope.py +2 -2
  72. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_subscription.py +4 -3
  73. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_transfer_plugins.py +1 -1
  74. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_upload.py +2 -1
  75. rucio-clients-34.1.0/pyproject.toml +0 -61
  76. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/AUTHORS.rst +0 -0
  77. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/ChangeLog +0 -0
  78. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/LICENSE +0 -0
  79. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/MANIFEST.in +0 -0
  80. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/README.rst +0 -0
  81. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/etc/rse-accounts.cfg.template +0 -0
  82. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/etc/rucio.cfg.atlas.client.template +0 -0
  83. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/etc/rucio.cfg.template +0 -0
  84. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/__init__.py +0 -0
  85. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/alembicrevision.py +0 -0
  86. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/__init__.py +0 -0
  87. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/accountlimitclient.py +0 -0
  88. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/client.py +0 -0
  89. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/configclient.py +0 -0
  90. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/credentialclient.py +0 -0
  91. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/diracclient.py +0 -0
  92. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/exportclient.py +0 -0
  93. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/fileclient.py +0 -0
  94. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/importclient.py +0 -0
  95. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/lifetimeclient.py +0 -0
  96. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/lockclient.py +0 -0
  97. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/metaconventionsclient.py +0 -0
  98. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/pingclient.py +0 -0
  99. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/replicaclient.py +0 -0
  100. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/requestclient.py +0 -0
  101. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/scopeclient.py +0 -0
  102. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/subscriptionclient.py +0 -0
  103. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/client/touchclient.py +0 -0
  104. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/__init__.py +0 -0
  105. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/constraints.py +0 -0
  106. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/exception.py +0 -0
  107. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/extra.py +0 -0
  108. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/logging.py +0 -0
  109. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/atlas.py +0 -0
  110. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/belleii.py +0 -0
  111. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/cms.py +0 -0
  112. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/domatpc.py +0 -0
  113. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/escape.py +0 -0
  114. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/generic.py +0 -0
  115. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
  116. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/icecube.py +0 -0
  117. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/schema/lsst.py +0 -0
  118. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/stomp_utils.py +0 -0
  119. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/stopwatch.py +0 -0
  120. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/common/test_rucio_server.py +0 -0
  121. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/__init__.py +0 -0
  122. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/protocols/__init__.py +0 -0
  123. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio/rse/rsemanager.py +0 -0
  124. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/lib/rucio_clients.egg-info/SOURCES.txt +0 -0
  125. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/pylintrc +0 -0
  126. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/setup.cfg +0 -0
  127. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/setup.py +0 -0
  128. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/setuputil.py +0 -0
  129. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_abacus_account.py +0 -0
  130. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_abacus_collection_replica.py +0 -0
  131. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_abacus_rse.py +0 -0
  132. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_account_limits.py +0 -0
  133. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_api_external_representation.py +0 -0
  134. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_archive.py +0 -0
  135. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_auditor.py +0 -0
  136. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_auditor_hdfs.py +0 -0
  137. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_auditor_srmdumps.py +0 -0
  138. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_automatix.py +0 -0
  139. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_bb8.py +0 -0
  140. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_belleii.py +0 -0
  141. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_boolean.py +0 -0
  142. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_common_types.py +0 -0
  143. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_counter.py +0 -0
  144. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_curl.py +0 -0
  145. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_daemons.py +0 -0
  146. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_db.py +0 -0
  147. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_did.py +0 -0
  148. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_did_meta_plugins.py +0 -0
  149. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_didtype.py +0 -0
  150. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_download.py +0 -0
  151. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_dumper.py +0 -0
  152. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_dumper_consistency.py +0 -0
  153. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_dumper_path_parsing.py +0 -0
  154. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_filter_engine.py +0 -0
  155. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_heartbeat.py +0 -0
  156. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_hermes.py +0 -0
  157. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_impl_upload_download.py +0 -0
  158. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_judge_cleaner.py +0 -0
  159. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_judge_evaluator.py +0 -0
  160. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_judge_injector.py +0 -0
  161. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_lifetime.py +0 -0
  162. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_message.py +0 -0
  163. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_meta_conventions.py +0 -0
  164. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_meta_did.py +0 -0
  165. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_module_import.py +0 -0
  166. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_monitor.py +0 -0
  167. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_naming_convention.py +0 -0
  168. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_oauthmanager.py +0 -0
  169. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_permission.py +0 -0
  170. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_pfns.py +0 -0
  171. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_ping.py +0 -0
  172. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_qos.py +0 -0
  173. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_quarantined_replica.py +0 -0
  174. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_redirect.py +0 -0
  175. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_protocol_gfal2.py +0 -0
  176. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
  177. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_protocol_posix.py +0 -0
  178. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_protocol_rclone.py +0 -0
  179. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_protocol_rsync.py +0 -0
  180. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_protocol_srm.py +0 -0
  181. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_protocol_ssh.py +0 -0
  182. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_protocol_webdav.py +0 -0
  183. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_protocol_xrootd.py +0 -0
  184. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rse_selector.py +0 -0
  185. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_rucio_server.py +0 -0
  186. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_throttler.py +0 -0
  187. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_tpc.py +0 -0
  188. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_trace.py +0 -0
  189. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_transfer.py +0 -0
  190. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_undertaker.py +0 -0
  191. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tests/test_utils.py +0 -0
  192. {rucio-clients-34.1.0 → rucio_clients-34.3.0}/tools/merge_rucio_configs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rucio-clients
3
- Version: 34.1.0
3
+ Version: 34.3.0
4
4
  Summary: Rucio Client Lite Package
5
5
  Home-page: https://rucio.cern.ch/
6
6
  Author: Rucio
@@ -166,7 +166,7 @@ def exception_handler(function):
166
166
  used_account = '%s (from rucio.cfg)' % config_get('client', 'account')
167
167
  except:
168
168
  pass
169
- try: # are we overriden by the environment?
169
+ try: # are we overridden by the environment?
170
170
  used_account = '%s (from RUCIO_ACCOUNT)' % os.environ['RUCIO_ACCOUNT']
171
171
  except:
172
172
  pass
@@ -1151,7 +1151,7 @@ def set_metadata(args):
1151
1151
  client = get_client(args)
1152
1152
  value = args.value
1153
1153
  if args.key == 'lifetime':
1154
- value = float(args.value)
1154
+ value = None if args.value.lower() == 'none' else float(args.value)
1155
1155
  scope, name = get_scope(args.did, client)
1156
1156
  client.set_metadata(scope=scope, name=name, key=args.key, value=value)
1157
1157
  return SUCCESS
@@ -1550,7 +1550,7 @@ def list_rse_attributes(args):
1550
1550
  """
1551
1551
  client = get_client(args)
1552
1552
  attributes = client.list_rse_attributes(rse=args.rse)
1553
- table = [(k + ':', str(v)) for (k, v) in sorted(attributes.items())] # columns hav mixed datatypes
1553
+ table = [(k + ':', str(v)) for (k, v) in sorted(attributes.items())] # columns have mixed datatypes
1554
1554
  print(tabulate(table, tablefmt='plain', disable_numparse=True)) # disabling number parsing
1555
1555
  return SUCCESS
1556
1556
 
@@ -33,6 +33,7 @@ from tabulate import tabulate
33
33
  from rucio import version
34
34
  from rucio.client import Client
35
35
  from rucio.common.config import config_get
36
+ from rucio.common.constants import RseAttr
36
37
  from rucio.common.exception import (
37
38
  AccessDenied,
38
39
  AccountNotFound,
@@ -385,7 +386,7 @@ def set_limits(args):
385
386
  try:
386
387
  byte_limit = int(limit_input)
387
388
  except ValueError:
388
- logger.error('The limit could not be set. Either you misspelled infinity or your input could not be converted to integer or you used a wrong pattern. Please use a format like 10GB with B,KB,MB,GB,TB,PB as units (not case sensistive)')
389
+ logger.error('The limit could not be set. Either you misspelled infinity or your input could not be converted to integer or you used a wrong pattern. Please use a format like 10GB with B,KB,MB,GB,TB,PB as units (not case sensitive)')
389
390
  return FAILURE
390
391
 
391
392
  client.set_account_limit(account=args.account, rse=args.rse, bytes_=byte_limit, locality=locality)
@@ -1244,7 +1245,7 @@ def list_pfns(args):
1244
1245
  if not rse_info['deterministic']:
1245
1246
  logger.warning('This is a non-deterministic site, so the real PFN might be different from the on suggested')
1246
1247
  rse_attr = client.list_rse_attributes(rse)
1247
- naming_convention = rse_attr.get('naming_convention', None)
1248
+ naming_convention = rse_attr.get(RseAttr.NAMING_CONVENTION, None)
1248
1249
  parents = [did for did in client.list_parent_dids(scope, name)]
1249
1250
  if len(parents) > 1:
1250
1251
  logger.warning('The file has multiple parents')
@@ -1383,7 +1384,7 @@ def get_parser():
1383
1384
  oparser.add_argument('--oidc-refresh-lifetime', dest='oidc_refresh_lifetime', default=None, help='Max lifetime in hours for this an access token will be refreshed by asynchronous Rucio daemon. '
1384
1385
  + 'If not specified, refresh will be stopped after 4 days. This option is effective only if --oidc-scope includes offline_access scope for a refresh token to be granted to Rucio.') # NOQA: W503
1385
1386
  oparser.add_argument('--oidc-issuer', dest='oidc_issuer', default=None,
1386
- help='Defines which Identity Provider is goign to be used. The issuer string must correspond '
1387
+ help='Defines which Identity Provider is going to be used. The issuer string must correspond '
1387
1388
  + 'to the keys configured in the /etc/idpsecrets.json auth server configuration file.') # NOQA: W503
1388
1389
 
1389
1390
  # Options for the x509 auth_strategy
@@ -1432,7 +1433,7 @@ def get_parser():
1432
1433
  '"""""""""""""\n'
1433
1434
  '::\n'
1434
1435
  '\n'
1435
- ' $ rucio-admin account list --type \'user\'\n'
1436
+ ' $ rucio-admin account list --type USER\n'
1436
1437
  '\n')
1437
1438
  list_account_parser.add_argument('--type', dest='account_type', action='store', help='Account Type (USER, GROUP, SERVICE)')
1438
1439
  list_account_parser.add_argument('--id', dest='identity', action='store', help='Identity (e.g. DN)')
@@ -1708,7 +1709,7 @@ def get_parser():
1708
1709
  ' $ rucio-admin identity delete --account jdoe --type X509 --id \'CN=Joe Doe,CN=707658,CN=jdoe,OU=Users,OU=Organic Units,DC=cern,DC=ch\'\n'
1709
1710
  ' Deleted identity: CN=Joe Doe,CN=707658,CN=jdoe,OU=Users,OU=Organic Units,DC=cern,DC=ch\n'
1710
1711
  '\n'
1711
- 'Note: if the identity was accidentaly deleted, use add option.\n'
1712
+ 'Note: if the identity was accidentally deleted, use add option.\n'
1712
1713
  '\n')
1713
1714
  identity_delete_parser.set_defaults(which='identity_delete')
1714
1715
  identity_delete_parser.add_argument('--account', dest='account', action='store', help='Account name', required=True)
@@ -1956,7 +1957,7 @@ def get_parser():
1956
1957
  ' $ rucio-admin rse add-protocol --hostname jdoes.test.org --scheme gsiftp --prefix \'/atlasdatadisk/rucio/\' --port 8443 JDOE_DATADISK\n'
1957
1958
  '\n'
1958
1959
  'Note: no printed stdout.\n'
1959
- 'Note: examples of optional parametres::\n'
1960
+ 'Note: examples of optional parameters::\n'
1960
1961
  '\n'
1961
1962
  ' --space-token DATADISK\n'
1962
1963
  ' --web-service-path \'/srm/managerv2?SFN=\'\n'
@@ -2110,7 +2111,7 @@ def get_parser():
2110
2111
 
2111
2112
  # The config subparser
2112
2113
  config_parser = subparsers.add_parser('config',
2113
- help='Configuration methods. The global configuration of data mangement system can by modified.',
2114
+ help='Configuration methods. The global configuration of data management system can by modified.',
2114
2115
  formatter_class=argparse.RawDescriptionHelpFormatter,
2115
2116
  epilog='''e.g. quotas, daemons, rses''')
2116
2117
  config_subparser = config_parser.add_subparsers(dest='config_subcommand', **required_arg)
@@ -2311,9 +2312,9 @@ def get_parser():
2311
2312
  declare_bad_file_replicas_parser.add_argument('--inputfile', dest='inputfile', nargs='?', action='store', help='File containing list of bad items')
2312
2313
  declare_bad_file_replicas_parser.add_argument('--allow-collection', dest='allow_collection', action='store_true', help='Allow passing a collection DID as bad item')
2313
2314
 
2314
- declare_bad_file_replicas_parser.add_argument('--lfns', dest='lfns', nargs='?', action='store', help='File cotaining list of LFNs for bad replicas. Requires --rse and --scope')
2315
- declare_bad_file_replicas_parser.add_argument('--scope', dest='scope', nargs='?', action='store', help='Common scope for bad replicas secified with LFN list, ignored wthout --lfns')
2316
- declare_bad_file_replicas_parser.add_argument('--rse', dest='rse', nargs='?', action='store', help='Common RSE for bad replicas secified with LFN list, ignored wthout --lfns')
2315
+ declare_bad_file_replicas_parser.add_argument('--lfns', dest='lfns', nargs='?', action='store', help='File containing list of LFNs for bad replicas. Requires --rse and --scope')
2316
+ declare_bad_file_replicas_parser.add_argument('--scope', dest='scope', nargs='?', action='store', help='Common scope for bad replicas specified with LFN list, ignored without --lfns')
2317
+ declare_bad_file_replicas_parser.add_argument('--rse', dest='rse', nargs='?', action='store', help='Common RSE for bad replicas specified with LFN list, ignored without --lfns')
2317
2318
 
2318
2319
  # The declare-temporary-unavailable command
2319
2320
  declare_temporary_unavailable_replicas_parser = rep_subparser.add_parser('declare-temporary-unavailable',
@@ -112,7 +112,7 @@ class AccountClient(BaseClient):
112
112
 
113
113
  :param type: The account type
114
114
  :param identity: The identity key name. For example x509 DN, or a username.
115
- :param filters: A dictionnary key:account attribute to use for the filtering
115
+ :param filters: A dictionary key:account attribute to use for the filtering
116
116
 
117
117
  :return: a list containing account info dictionary for all rucio accounts.
118
118
  :raises AccountNotFound: if account doesn't exist.
@@ -19,15 +19,19 @@
19
19
  import errno
20
20
  import getpass
21
21
  import os
22
- import random
22
+ import secrets
23
23
  import sys
24
24
  import time
25
+ from collections.abc import Generator
25
26
  from configparser import NoOptionError, NoSectionError
27
+ from logging import Logger
26
28
  from os import environ, fdopen, geteuid, makedirs, path
27
29
  from shutil import move
28
30
  from tempfile import mkstemp
31
+ from typing import Any, Optional
29
32
  from urllib.parse import urlparse
30
33
 
34
+ import requests
31
35
  from dogpile.cache import make_region
32
36
  from requests import Response, Session
33
37
  from requests.exceptions import ConnectionError
@@ -36,7 +40,7 @@ from requests.status_codes import codes
36
40
  from rucio import version
37
41
  from rucio.common import exception
38
42
  from rucio.common.config import config_get, config_get_bool, config_get_int
39
- from rucio.common.exception import CannotAuthenticate, ClientProtocolNotSupported, MissingClientParameter, MissingModuleException, NoAuthInformation, ServerConnectionException
43
+ from rucio.common.exception import CannotAuthenticate, ClientProtocolNotSupported, ConfigNotFound, MissingClientParameter, MissingModuleException, NoAuthInformation, ServerConnectionException
40
44
  from rucio.common.extra import import_extras
41
45
  from rucio.common.utils import build_url, get_tmp_dir, my_key_generator, parse_response, setup_logger, ssh_sign
42
46
 
@@ -64,7 +68,7 @@ def choice(hosts):
64
68
  :param hosts: Lost of hosts
65
69
  :return: A randomly selected host.
66
70
  """
67
- return random.choice(hosts)
71
+ return secrets.choice(hosts)
68
72
 
69
73
 
70
74
  class BaseClient:
@@ -76,7 +80,17 @@ class BaseClient:
76
80
  TOKEN_PREFIX = 'auth_token_'
77
81
  TOKEN_EXP_PREFIX = 'auth_token_exp_'
78
82
 
79
- def __init__(self, rucio_host=None, auth_host=None, account=None, ca_cert=None, auth_type=None, creds=None, timeout=600, user_agent='rucio-clients', vo=None, logger=None):
83
+ def __init__(self,
84
+ rucio_host: Optional[str] = None,
85
+ auth_host: Optional[str] = None,
86
+ account: Optional[str] = None,
87
+ ca_cert: Optional[str] = None,
88
+ auth_type: Optional[str] = None,
89
+ creds: Optional[dict[str, Any]] = None,
90
+ timeout: Optional[int] = 600,
91
+ user_agent: Optional[str] = 'rucio-clients',
92
+ vo: Optional[str] = None,
93
+ logger: Logger = LOG) -> None:
80
94
  """
81
95
  Constructor of the BaseClient.
82
96
  :param rucio_host: The address of the rucio server, if None it is read from the config file.
@@ -94,9 +108,8 @@ class BaseClient:
94
108
  """
95
109
 
96
110
  self.host = rucio_host
97
- self.list_hosts = []
98
111
  self.auth_host = auth_host
99
- self.logger = logger or LOG
112
+ self.logger = logger
100
113
  self.session = Session()
101
114
  self.user_agent = "%s/%s" % (user_agent, version.version_string()) # e.g. "rucio-clients/0.2.13"
102
115
  sys.argv[0] = sys.argv[0].split('/')[-1]
@@ -113,110 +126,26 @@ class BaseClient:
113
126
 
114
127
  try:
115
128
  self.trace_host = config_get('trace', 'trace_host')
116
- except (NoOptionError, NoSectionError):
129
+ except (NoOptionError, NoSectionError, ConfigNotFound):
117
130
  self.trace_host = self.host
118
131
  self.logger.debug('No trace_host passed. Using rucio_host instead')
119
132
 
133
+ self.list_hosts = [self.host]
120
134
  self.account = account
121
135
  self.vo = vo
122
136
  self.ca_cert = ca_cert
123
- self.auth_type = auth_type
124
- self.creds = creds
125
- self.auth_token = None
126
- self.auth_token_file_path = config_get('client', 'auth_token_file_path', False, None)
137
+ self.auth_token = ""
127
138
  self.headers = {}
128
139
  self.timeout = timeout
129
140
  self.request_retries = self.REQUEST_RETRIES
130
141
  self.token_exp_epoch = None
131
- self.token_exp_epoch_file = None
132
142
  self.auth_oidc_refresh_active = config_get_bool('client', 'auth_oidc_refresh_active', False, False)
143
+
133
144
  # defining how many minutes before token expires, oidc refresh (if active) should start
134
145
  self.auth_oidc_refresh_before_exp = config_get_int('client', 'auth_oidc_refresh_before_exp', False, 20)
135
146
 
136
- if auth_type is None:
137
- self.logger.debug('No auth_type passed. Trying to get it from the environment variable RUCIO_AUTH_TYPE and config file.')
138
- if 'RUCIO_AUTH_TYPE' in environ:
139
- if environ['RUCIO_AUTH_TYPE'] not in ['userpass', 'x509', 'x509_proxy', 'gss', 'ssh', 'saml', 'oidc']:
140
- raise MissingClientParameter('Possible RUCIO_AUTH_TYPE values: userpass, x509, x509_proxy, gss, ssh, saml, oidc, vs. ' + environ['RUCIO_AUTH_TYPE'])
141
- self.auth_type = environ['RUCIO_AUTH_TYPE']
142
- else:
143
- try:
144
- self.auth_type = config_get('client', 'auth_type')
145
- except (NoOptionError, NoSectionError) as error:
146
- raise MissingClientParameter('Option \'%s\' cannot be found in config file' % error.args[0])
147
-
148
- if self.auth_type == 'oidc':
149
- if not self.creds:
150
- self.creds = {}
151
- # if there are defautl values, check if rucio.cfg does not specify them, otherwise put default
152
- if 'oidc_refresh_lifetime' not in self.creds or self.creds['oidc_refresh_lifetime'] is None:
153
- self.creds['oidc_refresh_lifetime'] = config_get('client', 'oidc_refresh_lifetime', False, None)
154
- if 'oidc_issuer' not in self.creds or self.creds['oidc_issuer'] is None:
155
- self.creds['oidc_issuer'] = config_get('client', 'oidc_issuer', False, None)
156
- if 'oidc_audience' not in self.creds or self.creds['oidc_audience'] is None:
157
- self.creds['oidc_audience'] = config_get('client', 'oidc_audience', False, None)
158
- if 'oidc_auto' not in self.creds or self.creds['oidc_auto'] is False:
159
- self.creds['oidc_auto'] = config_get_bool('client', 'oidc_auto', False, False)
160
- if self.creds['oidc_auto']:
161
- if 'oidc_username' not in self.creds or self.creds['oidc_username'] is None:
162
- self.creds['oidc_username'] = config_get('client', 'oidc_username', False, None)
163
- if 'oidc_password' not in self.creds or self.creds['oidc_password'] is None:
164
- self.creds['oidc_password'] = config_get('client', 'oidc_password', False, None)
165
- if 'oidc_scope' not in self.creds or self.creds['oidc_scope'] == 'openid profile':
166
- self.creds['oidc_scope'] = config_get('client', 'oidc_scope', False, 'openid profile')
167
- if 'oidc_polling' not in self.creds or self.creds['oidc_polling'] is False:
168
- self.creds['oidc_polling'] = config_get_bool('client', 'oidc_polling', False, False)
169
-
170
- if not self.creds:
171
- self.logger.debug('No creds passed. Trying to get it from the config file.')
172
- self.creds = {}
173
- try:
174
- if self.auth_type in ['userpass', 'saml']:
175
- self.creds['username'] = config_get('client', 'username')
176
- self.creds['password'] = config_get('client', 'password')
177
- elif self.auth_type == 'x509':
178
- if "RUCIO_CLIENT_CERT" in environ:
179
- client_cert = environ["RUCIO_CLIENT_CERT"]
180
- else:
181
- client_cert = config_get('client', 'client_cert')
182
- self.creds['client_cert'] = path.abspath(path.expanduser(path.expandvars(client_cert)))
183
- if not path.exists(self.creds['client_cert']):
184
- raise MissingClientParameter('X.509 client certificate not found: %s' % self.creds['client_cert'])
185
-
186
- if "RUCIO_CLIENT_KEY" in environ:
187
- client_key = environ["RUCIO_CLIENT_KEY"]
188
- else:
189
- client_key = config_get('client', 'client_key')
190
- self.creds['client_key'] = path.abspath(path.expanduser(path.expandvars(client_key)))
191
- if not path.exists(self.creds['client_key']):
192
- raise MissingClientParameter('X.509 client key not found: %s' % self.creds['client_key'])
193
- else:
194
- perms = oct(os.stat(self.creds['client_key']).st_mode)[-3:]
195
- if perms not in ['400', '600']:
196
- raise CannotAuthenticate('X.509 authentication selected, but private key (%s) permissions are liberal (required: 400 or 600, found: %s)' % (self.creds['client_key'], perms))
197
-
198
- elif self.auth_type == 'x509_proxy':
199
- try:
200
- self.creds['client_proxy'] = path.abspath(path.expanduser(path.expandvars(config_get('client', 'client_x509_proxy'))))
201
- except NoOptionError:
202
- # Recreate the classic GSI logic for locating the proxy:
203
- # - $X509_USER_PROXY, if it is set.
204
- # - /tmp/x509up_u`id -u` otherwise.
205
- # If neither exists (at this point, we don't care if it exists but is invalid), then rethrow
206
- if 'X509_USER_PROXY' in environ:
207
- self.creds['client_proxy'] = environ['X509_USER_PROXY']
208
- else:
209
- fname = '/tmp/x509up_u%d' % geteuid()
210
- if path.exists(fname):
211
- self.creds['client_proxy'] = fname
212
- else:
213
- raise MissingClientParameter('Cannot find a valid X509 proxy; not in %s, $X509_USER_PROXY not set, and '
214
- '\'x509_proxy\' not set in the configuration file.' % fname)
215
- elif self.auth_type == 'ssh':
216
- self.creds['ssh_private_key'] = path.abspath(path.expanduser(path.expandvars(config_get('client', 'ssh_private_key'))))
217
- except (NoOptionError, NoSectionError) as error:
218
- if error.args[0] != 'client_key':
219
- raise MissingClientParameter('Option \'%s\' cannot be found in config file' % error.args[0])
147
+ self.auth_type = self._get_auth_type(auth_type)
148
+ self.creds = self._get_creds(creds)
220
149
 
221
150
  rucio_scheme = urlparse(self.host).scheme
222
151
  auth_scheme = urlparse(self.auth_host).scheme
@@ -238,8 +167,6 @@ class BaseClient:
238
167
  self.logger.debug('No ca_cert found in configuration. Falling back to Mozilla default CA bundle (certifi).')
239
168
  self.ca_cert = True
240
169
 
241
- self.list_hosts = [self.host]
242
-
243
170
  if account is None:
244
171
  self.logger.debug('No account passed. Trying to get it from the RUCIO_ACCOUNT environment variable or the config file.')
245
172
  try:
@@ -262,30 +189,126 @@ class BaseClient:
262
189
  self.logger.debug('No VO found. Using default VO.')
263
190
  self.vo = 'def'
264
191
 
265
- token_filename_suffix = "for_default_account" if self.account is None else "for_account_" + self.account
192
+ self.auth_token_file_path, self.token_exp_epoch_file, self.token_file, self.token_path = self._get_auth_tokens()
193
+ self.__authenticate()
266
194
 
195
+ try:
196
+ self.request_retries = config_get_int('client', 'request_retries')
197
+ except (NoOptionError, ConfigNotFound):
198
+ self.logger.debug('request_retries not specified in config file. Taking default.')
199
+ except ValueError:
200
+ self.logger.debug('request_retries must be an integer. Taking default.')
201
+
202
+ def _get_auth_tokens(self) -> tuple[Optional[str], str, str, str]:
267
203
  # if token file path is defined in the rucio.cfg file, use that file. Currently this prevents authenticating as another user or VO.
268
- if self.auth_token_file_path:
269
- self.token_file = self.auth_token_file_path
270
- self.token_path = '/'.join(self.token_file.split('/')[:-1])
204
+ auth_token_file_path = config_get('client', 'auth_token_file_path', False, None)
205
+ token_filename_suffix = "for_default_account" if self.account is None else "for_account_" + self.account
206
+
207
+ if auth_token_file_path:
208
+ token_file = auth_token_file_path
209
+ token_path = '/'.join(auth_token_file_path.split('/')[:-1])
210
+
271
211
  else:
272
- self.token_path = self.TOKEN_PATH_PREFIX + getpass.getuser()
212
+ token_path = self.TOKEN_PATH_PREFIX + getpass.getuser()
273
213
  if self.vo != 'def':
274
- self.token_path += '@%s' % self.vo
275
- self.token_file = self.token_path + '/' + self.TOKEN_PREFIX + token_filename_suffix
214
+ token_path += '@%s' % self.vo
276
215
 
277
- self.token_exp_epoch_file = self.token_path + '/' + self.TOKEN_EXP_PREFIX + token_filename_suffix
216
+ token_file = token_path + '/' + self.TOKEN_PREFIX + token_filename_suffix
278
217
 
279
- self.__authenticate()
218
+ token_exp_epoch_file = token_path + '/' + self.TOKEN_EXP_PREFIX + token_filename_suffix
219
+ return auth_token_file_path, token_exp_epoch_file, token_file, token_path
280
220
 
281
- try:
282
- self.request_retries = config_get_int('client', 'request_retries')
283
- except (NoOptionError, RuntimeError):
284
- LOG.debug('request_retries not specified in config file. Taking default.')
285
- except ValueError:
286
- self.logger.debug('request_retries must be an integer. Taking default.')
221
+ def _get_auth_type(self, auth_type: Optional[str]) -> str:
222
+ if auth_type is None:
223
+ self.logger.debug('No auth_type passed. Trying to get it from the environment variable RUCIO_AUTH_TYPE and config file.')
224
+ if 'RUCIO_AUTH_TYPE' in environ:
225
+ if environ['RUCIO_AUTH_TYPE'] not in ['userpass', 'x509', 'x509_proxy', 'gss', 'ssh', 'saml', 'oidc']:
226
+ raise MissingClientParameter('Possible RUCIO_AUTH_TYPE values: userpass, x509, x509_proxy, gss, ssh, saml, oidc, vs. ' + environ['RUCIO_AUTH_TYPE'])
227
+ auth_type = environ['RUCIO_AUTH_TYPE']
228
+ else:
229
+ try:
230
+ auth_type = config_get('client', 'auth_type')
231
+ except (NoOptionError, NoSectionError) as error:
232
+ raise MissingClientParameter('Option \'%s\' cannot be found in config file' % error.args[0])
233
+ return auth_type
234
+
235
+ def _get_creds(self, creds: Optional[dict[str, Any]]) -> dict[str, Any]:
236
+ if self.auth_type == 'oidc':
237
+ if not creds:
238
+ creds = {}
239
+ # if there are default values, check if rucio.cfg does not specify them, otherwise put default
240
+ if 'oidc_refresh_lifetime' not in creds or creds['oidc_refresh_lifetime'] is None:
241
+ creds['oidc_refresh_lifetime'] = config_get('client', 'oidc_refresh_lifetime', False, None)
242
+ if 'oidc_issuer' not in creds or creds['oidc_issuer'] is None:
243
+ creds['oidc_issuer'] = config_get('client', 'oidc_issuer', False, None)
244
+ if 'oidc_audience' not in creds or creds['oidc_audience'] is None:
245
+ creds['oidc_audience'] = config_get('client', 'oidc_audience', False, None)
246
+ if 'oidc_auto' not in creds or creds['oidc_auto'] is False:
247
+ creds['oidc_auto'] = config_get_bool('client', 'oidc_auto', False, False)
248
+ if creds['oidc_auto']:
249
+ if 'oidc_username' not in creds or creds['oidc_username'] is None:
250
+ creds['oidc_username'] = config_get('client', 'oidc_username', False, None)
251
+ if 'oidc_password' not in creds or creds['oidc_password'] is None:
252
+ creds['oidc_password'] = config_get('client', 'oidc_password', False, None)
253
+ if 'oidc_scope' not in creds or creds['oidc_scope'] == 'openid profile':
254
+ creds['oidc_scope'] = config_get('client', 'oidc_scope', False, 'openid profile')
255
+ if 'oidc_polling' not in creds or creds['oidc_polling'] is False:
256
+ creds['oidc_polling'] = config_get_bool('client', 'oidc_polling', False, False)
257
+
258
+ if creds is None:
259
+ self.logger.debug('No creds passed. Trying to get it from the config file.')
260
+ creds = {}
261
+ try:
262
+ if self.auth_type in ['userpass', 'saml']:
263
+ creds['username'] = config_get('client', 'username')
264
+ creds['password'] = config_get('client', 'password')
265
+ elif self.auth_type == 'x509':
266
+ if "RUCIO_CLIENT_CERT" in environ:
267
+ client_cert = environ["RUCIO_CLIENT_CERT"]
268
+ else:
269
+ client_cert = config_get('client', 'client_cert')
270
+ creds['client_cert'] = path.abspath(path.expanduser(path.expandvars(client_cert)))
271
+ if not path.exists(creds['client_cert']):
272
+ raise MissingClientParameter('X.509 client certificate not found: %s' % creds['client_cert'])
273
+
274
+ if "RUCIO_CLIENT_KEY" in environ:
275
+ client_key = environ["RUCIO_CLIENT_KEY"]
276
+ else:
277
+ client_key = config_get('client', 'client_key')
278
+ creds['client_key'] = path.abspath(path.expanduser(path.expandvars(client_key)))
279
+ if not path.exists(creds['client_key']):
280
+ raise MissingClientParameter('X.509 client key not found: %s' % creds['client_key'])
281
+ else:
282
+ perms = oct(os.stat(creds['client_key']).st_mode)[-3:]
283
+ if perms not in ['400', '600']:
284
+ raise CannotAuthenticate('X.509 authentication selected, but private key (%s) permissions are liberal (required: 400 or 600, found: %s)' % (creds['client_key'], perms))
285
+
286
+ elif self.auth_type == 'x509_proxy':
287
+ try:
288
+ creds['client_proxy'] = path.abspath(path.expanduser(path.expandvars(config_get('client', 'client_x509_proxy'))))
289
+ except NoOptionError:
290
+ # Recreate the classic GSI logic for locating the proxy:
291
+ # - $X509_USER_PROXY, if it is set.
292
+ # - /tmp/x509up_u`id -u` otherwise.
293
+ # If neither exists (at this point, we don't care if it exists but is invalid), then rethrow
294
+ if 'X509_USER_PROXY' in environ:
295
+ creds['client_proxy'] = environ['X509_USER_PROXY']
296
+ else:
297
+ fname = '/tmp/x509up_u%d' % geteuid()
298
+ if path.exists(fname):
299
+ creds['client_proxy'] = fname
300
+ else:
301
+ raise MissingClientParameter(
302
+ 'Cannot find a valid X509 proxy; not in %s, $X509_USER_PROXY not set, and '
303
+ '\'x509_proxy\' not set in the configuration file.' % fname)
304
+ elif self.auth_type == 'ssh':
305
+ creds['ssh_private_key'] = path.abspath(path.expanduser(path.expandvars(config_get('client', 'ssh_private_key'))))
306
+ except (NoOptionError, NoSectionError) as error:
307
+ if error.args[0] != 'client_key':
308
+ raise MissingClientParameter('Option \'%s\' cannot be found in config file' % error.args[0])
309
+ return creds
287
310
 
288
- def _get_exception(self, headers, status_code=None, data=None):
311
+ def _get_exception(self, headers: dict[str, str], status_code: Optional[int] = None, data=None) -> tuple[type[exception.RucioException], str]:
289
312
  """
290
313
  Helper method to parse an error string send by the server and transform it into the corresponding rucio exception.
291
314
 
@@ -316,7 +339,7 @@ class BaseClient:
316
339
  else:
317
340
  return exception.RucioException, "%s: %s" % (exc_cls, exc_msg)
318
341
 
319
- def _load_json_data(self, response):
342
+ def _load_json_data(self, response: requests.Response) -> Generator[Any, Any, Any]:
320
343
  """
321
344
  Helper method to correctly load json data based on the content type of the http response.
322
345
 
@@ -332,13 +355,13 @@ class BaseClient:
332
355
  if response.text:
333
356
  yield response.text
334
357
 
335
- def _reduce_data(self, data, maxlen=132):
358
+ def _reduce_data(self, data, maxlen: int = 132) -> str:
336
359
  text = data if isinstance(data, str) else data.decode("utf-8")
337
360
  if len(text) > maxlen:
338
361
  text = "%s ... %s" % (text[:maxlen - 15], text[-10:])
339
362
  return text
340
363
 
341
- def _back_off(self, retry_number, reason):
364
+ def _back_off(self, retry_number: int, reason: str) -> None:
342
365
  """
343
366
  Sleep a certain amount of time which increases with the retry count
344
367
  :param retry_number: the retry iteration
@@ -433,7 +456,7 @@ class BaseClient:
433
456
  raise ServerConnectionException
434
457
  return result
435
458
 
436
- def __get_token_userpass(self):
459
+ def __get_token_userpass(self) -> bool:
437
460
  """
438
461
  Sends a request to get an auth token from the server and stores it as a class attribute. Uses username/password.
439
462
 
@@ -469,7 +492,7 @@ class BaseClient:
469
492
  self.auth_token = result.headers['x-rucio-auth-token']
470
493
  return True
471
494
 
472
- def __refresh_token_OIDC(self):
495
+ def __refresh_token_OIDC(self) -> bool:
473
496
  """
474
497
  Checks if there is active refresh token and if so returns
475
498
  either active token with expiration timestamp or requests a new
@@ -523,7 +546,7 @@ class BaseClient:
523
546
  \nRucio Auth Server when attempting token refresh.")
524
547
  return False
525
548
 
526
- def __get_token_OIDC(self):
549
+ def __get_token_OIDC(self) -> bool:
527
550
  """
528
551
  First authenticates the user via a Identity Provider server
529
552
  (with user's username & password), by specifying oidc_scope,
@@ -593,7 +616,7 @@ class BaseClient:
593
616
 
594
617
  else:
595
618
  print("\nAccording to the OAuth2/OIDC standard you should NOT be sharing \n"
596
- + "your password with any 3rd party appplication, therefore, \n" # NOQA: W503
619
+ + "your password with any 3rd party application, therefore, \n" # NOQA: W503
597
620
  + "we strongly discourage you from following this --oidc-auto approach.") # NOQA: W503
598
621
  print("-------------------------------------------------------------------------")
599
622
  auth_res = self._send_request(auth_url, get_token=True)
@@ -636,7 +659,7 @@ class BaseClient:
636
659
 
637
660
  self.auth_token = result.headers['x-rucio-auth-token']
638
661
  if self.auth_oidc_refresh_active:
639
- self.logger.debug("Reseting the token expiration epoch file content.")
662
+ self.logger.debug("Resetting the token expiration epoch file content.")
640
663
  # reset the token expiration epoch file content
641
664
  # at new CLI OIDC authentication
642
665
  self.token_exp_epoch = None
@@ -647,7 +670,7 @@ class BaseClient:
647
670
  self.__refresh_token_OIDC()
648
671
  return True
649
672
 
650
- def __get_token_x509(self):
673
+ def __get_token_x509(self) -> bool:
651
674
  """
652
675
  Sends a request to get an auth token from the server and stores it as a class attribute. Uses x509 authentication.
653
676
 
@@ -664,7 +687,7 @@ class BaseClient:
664
687
  url = build_url(self.auth_host, path='auth/x509_proxy')
665
688
  client_cert = self.creds['client_proxy']
666
689
 
667
- if not path.exists(client_cert):
690
+ if (client_cert is not None) and not (path.exists(client_cert)):
668
691
  self.logger.error('given client cert (%s) doesn\'t exist' % client_cert)
669
692
  return False
670
693
  if client_key is not None and not path.exists(client_key):
@@ -692,7 +715,7 @@ class BaseClient:
692
715
  self.auth_token = result.headers['x-rucio-auth-token']
693
716
  return True
694
717
 
695
- def __get_token_ssh(self):
718
+ def __get_token_ssh(self) -> bool:
696
719
  """
697
720
  Sends a request to get an auth token from the server and stores it as a class attribute. Uses SSH key exchange authentication.
698
721
 
@@ -748,7 +771,7 @@ class BaseClient:
748
771
  self.auth_token = result.headers['x-rucio-auth-token']
749
772
  return True
750
773
 
751
- def __get_token_gss(self):
774
+ def __get_token_gss(self) -> bool:
752
775
  """
753
776
  Sends a request to get an auth token from the server and stores it as a class attribute. Uses Kerberos authentication.
754
777
 
@@ -774,7 +797,7 @@ class BaseClient:
774
797
  self.auth_token = result.headers['x-rucio-auth-token']
775
798
  return True
776
799
 
777
- def __get_token_saml(self):
800
+ def __get_token_saml(self) -> bool:
778
801
  """
779
802
  Sends a request to get an auth token from the server and stores it as a class attribute. Uses saml authentication.
780
803
 
@@ -804,7 +827,7 @@ class BaseClient:
804
827
  self.auth_token = result.headers['X-Rucio-Auth-Token']
805
828
  return True
806
829
 
807
- def __get_token(self):
830
+ def __get_token(self) -> None:
808
831
  """
809
832
  Calls the corresponding method to receive an auth token depending on the auth type. To be used if a 401 - Unauthorized error is received.
810
833
  """
@@ -846,7 +869,7 @@ class BaseClient:
846
869
  if self.auth_token is None:
847
870
  raise CannotAuthenticate('cannot get an auth token from server')
848
871
 
849
- def __read_token(self):
872
+ def __read_token(self) -> bool:
850
873
  """
851
874
  Checks if a local token file exists and reads the token from it.
852
875
 
@@ -868,7 +891,7 @@ class BaseClient:
868
891
  self.logger.debug('got token from file')
869
892
  return True
870
893
 
871
- def __write_token(self):
894
+ def __write_token(self) -> None:
872
895
  """
873
896
  Write the current auth_token to the local token file.
874
897
  """
@@ -895,7 +918,7 @@ class BaseClient:
895
918
  except Exception:
896
919
  raise
897
920
 
898
- def __authenticate(self):
921
+ def __authenticate(self) -> None:
899
922
  """
900
923
  Main method for authentication. It first tries to read a locally saved token. If not available it requests a new one.
901
924
  """
@@ -47,7 +47,7 @@ class DIDClient(BaseClient):
47
47
  path = '/'.join([self.DIDS_BASEURL, quote_plus(scope), 'dids', 'search'])
48
48
 
49
49
  # stringify dates.
50
- if isinstance(filters, dict): # backwards compatability for filters as single {}
50
+ if isinstance(filters, dict): # backwards compatibility for filters as single {}
51
51
  filters = [filters]
52
52
  for or_group in filters:
53
53
  for key, value in or_group.items():