rucio-clients 38.1.0__tar.gz → 38.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.
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/PKG-INFO +1 -1
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/bin_legacy/rucio.py +26 -23
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/command.py +36 -26
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/config.py +22 -7
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/did.py +1 -1
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/download.py +1 -1
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/opendata.py +60 -9
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/utils.py +13 -1
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/configclient.py +23 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/richclient.py +6 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/constants.py +5 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/exception.py +10 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/plugins.py +24 -8
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/utils.py +3 -3
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/translation.py +3 -3
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/vcsversion.py +3 -3
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_bin_rucio.py +8 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_cli_client_structure.py +81 -11
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_config.py +20 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_judge_evaluator.py +1 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_opendata.py +24 -8
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_policy_package.py +21 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/AUTHORS.rst +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/ChangeLog +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/LICENSE +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/MANIFEST.in +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/README.md +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/bin/rucio +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/bin/rucio-admin +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/etc/rse-accounts.cfg.template +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/etc/rucio.cfg.template +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/__init__.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/alembicrevision.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/__init__.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/account.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/bin_legacy/__init__.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/bin_legacy/rucio_admin.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/lifetime_exception.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/replica.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/rse.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/rule.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/scope.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/subscription.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/cli/upload.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/__init__.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/accountclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/accountlimitclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/baseclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/client.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/credentialclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/didclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/diracclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/downloadclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/exportclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/importclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/lifetimeclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/lockclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/metaconventionsclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/opendataclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/pingclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/replicaclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/requestclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/rseclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/ruleclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/scopeclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/subscriptionclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/touchclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/client/uploadclient.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/__init__.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/bittorrent.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/cache.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/checksum.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/client.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/config.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/constraints.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/didtype.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/extra.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/logging.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/pcache.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/policy.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/schema/__init__.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/schema/generic.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/stomp_utils.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/stopwatch.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/test_rucio_server.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/common/types.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/__init__.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/__init__.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/bittorrent.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/cache.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/dummy.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/gfal.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/globus.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/http_cache.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/mock.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/ngarc.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/posix.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/protocol.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/rclone.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/rfio.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/srm.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/ssh.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/storm.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/webdav.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/protocols/xrootd.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/rse/rsemanager.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio/version.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/lib/rucio_clients.egg-info/SOURCES.txt +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/pyproject.toml +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/requirements/requirements.client.txt +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/setup.cfg +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/setup.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/setuputil.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_abacus_account.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_abacus_collection_replica.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_abacus_rse.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_account.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_account_limits.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_archive.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_auditor.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_auditor_hdfs.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_auditor_srmdumps.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_authentication.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_automatix.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_bad_replica.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_bb8.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_belleii.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_boolean.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_clients.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_conveyor.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_conveyor_submitter.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_counter.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_credential.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_curl.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_daemons.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_dataset_replicas.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_db.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_did.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_did_meta_plugins.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_download.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_dumper.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_filter_engine.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_gateway_external_representation.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_heartbeat.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_hermes.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_identity.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_impl_upload_download.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_import_export.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_judge_cleaner.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_judge_injector.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_judge_repairer.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_lifetime.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_message.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_meta_conventions.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_meta_did.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_module_import.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_monitor.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_multi_vo.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_naming_convention.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_oauthmanager.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_oidc.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_permission.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_pfns.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_ping.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_preparer.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_qos.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_quarantined_replica.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_reaper.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_redirect.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_replica.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_replica_recoverer.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_replica_sorting.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_request.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_root_proxy.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_expression_parser.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_lfn2path.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_protocol_gfal2.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_protocol_posix.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_protocol_rclone.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_protocol_rsync.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_protocol_srm.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_protocol_ssh.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_protocol_webdav.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_protocol_xrootd.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rse_selector.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rucio_server.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_rule.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_scope.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_subscription.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_throttler.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_tpc.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_trace.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_transfer.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_transfer_plugins.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_undertaker.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_upload.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tests/test_utils.py +0 -0
- {rucio_clients-38.1.0 → rucio_clients-38.3.0}/tools/merge_rucio_configs.py +0 -0
|
@@ -449,7 +449,6 @@ def list_dids(args, client, logger, console, spinner):
|
|
|
449
449
|
"""
|
|
450
450
|
|
|
451
451
|
filters = {}
|
|
452
|
-
type_ = 'collection'
|
|
453
452
|
table_data = []
|
|
454
453
|
|
|
455
454
|
try:
|
|
@@ -482,19 +481,17 @@ def list_dids(args, client, logger, console, spinner):
|
|
|
482
481
|
else:
|
|
483
482
|
table_data.append([f"{did['scope']}:{did['name']}", did['did_type']])
|
|
484
483
|
|
|
485
|
-
if
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
else:
|
|
489
|
-
table = generate_table(table_data, headers=['SCOPE:NAME', '[DID TYPE]'], col_alignments=['left', 'left'])
|
|
490
|
-
spinner.stop()
|
|
491
|
-
print_output(table, console=console, no_pager=args.no_pager)
|
|
484
|
+
if args.short:
|
|
485
|
+
for did, _ in table_data:
|
|
486
|
+
print(did)
|
|
492
487
|
else:
|
|
493
|
-
if
|
|
494
|
-
|
|
495
|
-
|
|
488
|
+
if cli_config == 'rich':
|
|
489
|
+
table = generate_table(table_data, headers=['SCOPE:NAME', '[DID TYPE]'], col_alignments=['left', 'left'])
|
|
490
|
+
spinner.stop()
|
|
491
|
+
print_output(table, console=console, no_pager=args.no_pager)
|
|
496
492
|
else:
|
|
497
493
|
print(tabulate(table_data, tablefmt=tablefmt, headers=['SCOPE:NAME', '[DID TYPE]']))
|
|
494
|
+
|
|
498
495
|
return SUCCESS
|
|
499
496
|
|
|
500
497
|
|
|
@@ -657,19 +654,17 @@ def list_content(args, client, logger, console, spinner):
|
|
|
657
654
|
else:
|
|
658
655
|
table_data.append([f"{content['scope']}:{content['name']}", content['type'].upper()])
|
|
659
656
|
|
|
660
|
-
if
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
else:
|
|
664
|
-
table = generate_table(table_data, headers=['SCOPE:NAME', '[DID TYPE]'], col_alignments=['left', 'left'])
|
|
665
|
-
spinner.stop()
|
|
666
|
-
print_output(table, console=console, no_pager=args.no_pager)
|
|
657
|
+
if args.short:
|
|
658
|
+
for did, dummy in table_data:
|
|
659
|
+
print(did)
|
|
667
660
|
else:
|
|
668
|
-
if
|
|
669
|
-
|
|
670
|
-
|
|
661
|
+
if cli_config == 'rich':
|
|
662
|
+
table = generate_table(table_data, headers=['SCOPE:NAME', '[DID TYPE]'], col_alignments=['left', 'left'])
|
|
663
|
+
spinner.stop()
|
|
664
|
+
print_output(table, console=console, no_pager=args.no_pager)
|
|
671
665
|
else:
|
|
672
666
|
print(tabulate(table_data, tablefmt=tablefmt, headers=['SCOPE:NAME', '[DID TYPE]']))
|
|
667
|
+
|
|
673
668
|
return SUCCESS
|
|
674
669
|
|
|
675
670
|
|
|
@@ -1011,6 +1006,8 @@ def download(args, client, logger, console, spinner):
|
|
|
1011
1006
|
items = []
|
|
1012
1007
|
if args.dids:
|
|
1013
1008
|
for did in args.dids:
|
|
1009
|
+
if args.scope:
|
|
1010
|
+
did = f"{args.scope}:{did}"
|
|
1014
1011
|
item = {'did': did}
|
|
1015
1012
|
item.update(item_defaults)
|
|
1016
1013
|
items.append(item)
|
|
@@ -1043,9 +1040,15 @@ def download(args, client, logger, console, spinner):
|
|
|
1043
1040
|
item_defaults['did'] = did_str
|
|
1044
1041
|
if args.rses is None:
|
|
1045
1042
|
logger.warning("No RSE was given, selecting one.")
|
|
1043
|
+
if not args.scope:
|
|
1044
|
+
scope = did_str.split(':')[0]
|
|
1045
|
+
did = did_str.split(':')[-1]
|
|
1046
|
+
else:
|
|
1047
|
+
scope = args.scope
|
|
1048
|
+
did = did_str.split(':')[-1]
|
|
1046
1049
|
|
|
1047
1050
|
replicas = client.list_replicas(
|
|
1048
|
-
[{"scope":
|
|
1051
|
+
[{"scope": scope, "name": did}],
|
|
1049
1052
|
schemes=args.protocol,
|
|
1050
1053
|
ignore_availability=False,
|
|
1051
1054
|
client_location=detect_client_location(),
|
|
@@ -2473,7 +2476,7 @@ You can filter by key/value, e.g.::
|
|
|
2473
2476
|
selected_parser.add_argument('--trace_taskid', '--trace-taskid', new_option_string='--trace-taskid', dest='trace_taskid', action=StoreAndDeprecateWarningAction, default=os.environ.get('RUCIO_TRACE_TASKID', None), help=argparse.SUPPRESS)
|
|
2474
2477
|
selected_parser.add_argument('--trace_usrdn', '--trace-usrdn', new_option_string='--trace-usrdn', dest='trace_usrdn', action=StoreAndDeprecateWarningAction, default=os.environ.get('RUCIO_TRACE_USRDN', None), help=argparse.SUPPRESS)
|
|
2475
2478
|
selected_parser.add_argument('--filter', dest='filter', action='store', help='Filter files by key-value pairs like guid=2e2232aafac8324db452070304f8d745.')
|
|
2476
|
-
selected_parser.add_argument('--scope', dest='scope', action='store', help='Scope
|
|
2479
|
+
selected_parser.add_argument('--scope', dest='scope', action='store', help='Scope to use as a filter or to use with DID names.')
|
|
2477
2480
|
selected_parser.add_argument('--metalink', dest='metalink_file', action='store', help='Path to a metalink file.')
|
|
2478
2481
|
selected_parser.add_argument('--deactivate-file-download-exceptions', dest='deactivate_file_download_exceptions', action='store_true', help='Does not raise NoFilesDownloaded, NotAllFilesDownloaded or incorrect number of output queue files Exception.') # NOQA: E501
|
|
2479
2482
|
selected_parser.add_argument('--replica-selection', dest='sort', action='store', help='Select the best replica using a replica sorting algorithm provided by replica sorter (e.g., random, geoip).')
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
import importlib
|
|
15
15
|
import signal
|
|
16
|
+
import sys
|
|
16
17
|
import time
|
|
17
18
|
|
|
18
19
|
import click
|
|
@@ -61,6 +62,16 @@ class LazyGroup(click.Group):
|
|
|
61
62
|
raise ValueError(f"Lazy loading of {import_path} failed by returning " "a non-command object")
|
|
62
63
|
return cmd_object
|
|
63
64
|
|
|
65
|
+
@exception_handler
|
|
66
|
+
def _invoke_with_handler(self, ctx: click.Context):
|
|
67
|
+
return super().invoke(ctx)
|
|
68
|
+
|
|
69
|
+
def invoke(self, ctx: click.Context):
|
|
70
|
+
result = self._invoke_with_handler(ctx)
|
|
71
|
+
if result not in (None, 0):
|
|
72
|
+
sys.exit(1 if result != 2 else 2)
|
|
73
|
+
return result
|
|
74
|
+
|
|
64
75
|
|
|
65
76
|
@click.group(
|
|
66
77
|
cls=LazyGroup,
|
|
@@ -87,7 +98,7 @@ class LazyGroup(click.Group):
|
|
|
87
98
|
@click.option("--ca-certificate", help="CA certificate to verify peer against (SSL)")
|
|
88
99
|
@click.option("--certificate", help="Client certificate file")
|
|
89
100
|
@click.option("--client-key", help="Client key for x509 Authentication")
|
|
90
|
-
@click.option("--config", help="The Rucio configuration file to use")
|
|
101
|
+
@click.option("--config", help="The Rucio configuration file to use", envvar="RUCIO_CONFIG")
|
|
91
102
|
@click.option("-H", "--host", help="The Rucio API host")
|
|
92
103
|
# oidc auth
|
|
93
104
|
@click.option("--oidc-user", help="OIDC username")
|
|
@@ -146,33 +157,32 @@ class LazyGroup(click.Group):
|
|
|
146
157
|
@click.version_option(version.version_string(), message="%(prog)s %(version)s")
|
|
147
158
|
# Hidden options at the end
|
|
148
159
|
@click.option("--no-pager", is_flag=True, default=False, hidden=True)
|
|
149
|
-
@exception_handler
|
|
150
160
|
@click.pass_context
|
|
151
161
|
def main(
|
|
152
|
-
ctx,
|
|
153
|
-
config,
|
|
154
|
-
verbose,
|
|
155
|
-
host,
|
|
156
|
-
auth_host,
|
|
157
|
-
issuer,
|
|
158
|
-
auth_strategy,
|
|
159
|
-
timeout,
|
|
160
|
-
user_agent,
|
|
161
|
-
vo,
|
|
162
|
-
no_pager,
|
|
163
|
-
user,
|
|
164
|
-
password,
|
|
165
|
-
oidc_user,
|
|
166
|
-
oidc_password,
|
|
167
|
-
oidc_scope,
|
|
168
|
-
oidc_audience,
|
|
169
|
-
oidc_auto,
|
|
170
|
-
oidc_polling,
|
|
171
|
-
oidc_refresh_lifetime,
|
|
172
|
-
oidc_issuer,
|
|
173
|
-
certificate,
|
|
174
|
-
client_key,
|
|
175
|
-
ca_certificate,
|
|
162
|
+
ctx: click.Context,
|
|
163
|
+
config: str,
|
|
164
|
+
verbose: bool,
|
|
165
|
+
host: str,
|
|
166
|
+
auth_host: str,
|
|
167
|
+
issuer: str,
|
|
168
|
+
auth_strategy: str,
|
|
169
|
+
timeout: float,
|
|
170
|
+
user_agent: str,
|
|
171
|
+
vo: str,
|
|
172
|
+
no_pager: bool,
|
|
173
|
+
user: str,
|
|
174
|
+
password: str,
|
|
175
|
+
oidc_user: str,
|
|
176
|
+
oidc_password: str,
|
|
177
|
+
oidc_scope: str,
|
|
178
|
+
oidc_audience: str,
|
|
179
|
+
oidc_auto: str,
|
|
180
|
+
oidc_polling: str,
|
|
181
|
+
oidc_refresh_lifetime: str,
|
|
182
|
+
oidc_issuer: str,
|
|
183
|
+
certificate: str,
|
|
184
|
+
client_key: str,
|
|
185
|
+
ca_certificate: str,
|
|
176
186
|
):
|
|
177
187
|
ctx.ensure_object(Arguments)
|
|
178
188
|
ctx.obj.start_time = time.time()
|
|
@@ -27,18 +27,17 @@ def config():
|
|
|
27
27
|
@click.option("-s", "--section", help="Filter by sections")
|
|
28
28
|
@click.option("-k", "--key", help="Show key's value, section required.")
|
|
29
29
|
@click.pass_context
|
|
30
|
-
def list_(ctx, section, key):
|
|
30
|
+
def list_(ctx: click.Context, section: str, key: str):
|
|
31
31
|
"""List the sections or content of sections in the rucio.cfg"""
|
|
32
32
|
get_config(Arguments({"no_pager": ctx.obj.no_pager, "section": section, "key": key}), ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
# TODO Change to only add new fields and cannot modify an existing field
|
|
36
35
|
@config.command("add")
|
|
37
36
|
@click.option("-s", "--section", help="Section name", required=True)
|
|
38
37
|
@click.option('--key', help='Attribute key', required=True)
|
|
39
38
|
@click.option('--value', help='Attribute value', required=True)
|
|
40
39
|
@click.pass_context
|
|
41
|
-
def add_(ctx, section, key, value):
|
|
40
|
+
def add_(ctx: click.Context, section: str, key: str, value: str):
|
|
42
41
|
"""
|
|
43
42
|
Add a new key/value to a section.
|
|
44
43
|
|
|
@@ -46,6 +45,12 @@ def add_(ctx, section, key, value):
|
|
|
46
45
|
Example, Add a key to an existing section:
|
|
47
46
|
$ rucio config add --section my-section --key key --value value
|
|
48
47
|
"""
|
|
48
|
+
has_option = ctx.obj.client.get_config().get(section, {}).get(key) is not None
|
|
49
|
+
if has_option:
|
|
50
|
+
msg = f"Config already has field {section}: {key}, please use \n\
|
|
51
|
+
rucio config update --section {section} --key {key} --value {value}"
|
|
52
|
+
raise ValueError(msg)
|
|
53
|
+
|
|
49
54
|
args = Arguments({"no_pager": ctx.obj.no_pager, "section": section, "option": key, "value": value})
|
|
50
55
|
set_config_option(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
|
|
51
56
|
|
|
@@ -54,7 +59,7 @@ def add_(ctx, section, key, value):
|
|
|
54
59
|
@click.option("-s", "--section", help="Section", required=True)
|
|
55
60
|
@click.option("-k", "--key", help="Key in section", required=True)
|
|
56
61
|
@click.pass_context
|
|
57
|
-
def remove(ctx, section, key):
|
|
62
|
+
def remove(ctx: click.Context, section: str, key: str):
|
|
58
63
|
"""Remove the section.key from the config."""
|
|
59
64
|
args = Arguments({"no_pager": ctx.obj.no_pager, "section": section, "option": key})
|
|
60
65
|
delete_config_option(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
|
|
@@ -66,7 +71,17 @@ def show(ctx):
|
|
|
66
71
|
"""Show a single sections options"""
|
|
67
72
|
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
@config.command("update")
|
|
75
|
+
@click.option("-s", "--section", required=True)
|
|
76
|
+
@click.option("-k", "--key", help='Attribute key', required=True)
|
|
77
|
+
@click.option("-v", "--value", help='Attribute value', required=True)
|
|
78
|
+
@click.pass_context
|
|
79
|
+
def update(ctx: click.Context, section: str, key: str, value: str):
|
|
71
80
|
"""Modify an existing command"""
|
|
72
|
-
|
|
81
|
+
has_option = ctx.obj.client.get_config().get(section, {}).get(key) is not None
|
|
82
|
+
if has_option:
|
|
83
|
+
ctx.obj.client.set_config_option(section, key, value)
|
|
84
|
+
else:
|
|
85
|
+
msg = f"{section} {key} not present. Please use \n\
|
|
86
|
+
rucio config add --section {section} --key {key} --value {value}"
|
|
87
|
+
raise ValueError(msg)
|
|
@@ -34,7 +34,7 @@ def did():
|
|
|
34
34
|
are used: ";" represents the logical OR operator; "," represents the logical AND operator',
|
|
35
35
|
""",
|
|
36
36
|
) # TODO Shorten this help and make supplying this easier
|
|
37
|
-
@click.option("--short", is_flag=True, default=False, help="
|
|
37
|
+
@click.option("--short", is_flag=True, default=False, help="Just dump the list of DIDs.")
|
|
38
38
|
@click.argument("did-pattern", nargs=-1)
|
|
39
39
|
@click.option("--parent", default=False, is_flag=True, help="List the parents of the DID - must use a full DID scope and name")
|
|
40
40
|
@click.pass_context
|
|
@@ -52,7 +52,7 @@ from rucio.common.config import config_get_float
|
|
|
52
52
|
@click.option("--trace-taskid", default=os.environ.get("RUCIO_TRACE_TASKID", None), hidden=True)
|
|
53
53
|
@click.option("--trace-usrdn", default=os.environ.get("RUCIO_TRACE_USRDN", None), hidden=True)
|
|
54
54
|
@click.option("--filter", help="Filter files by key-value pairs like guid=2e2232aafac8324db452070304f8d745.")
|
|
55
|
-
@click.option("--scope", help="Scope
|
|
55
|
+
@click.option("--scope", help="Scope to use as a filter or to use with DID names.")
|
|
56
56
|
@click.option("--metalink", help="Path to a metalink file.")
|
|
57
57
|
@click.option("--no-show-download-exceptions", default=False, is_flag=True, help="Does not raise NoFilesDownloaded, NotAllFilesDownloaded or incorrect number of output queue files Exception.") # NOQA: E501
|
|
58
58
|
@click.option("--replica-selection", help="Select the best replica using a replica sorting algorithm provided by replica sorter (e.g., random, geoip).")
|
|
@@ -16,8 +16,11 @@ import json
|
|
|
16
16
|
from typing import TYPE_CHECKING, Optional
|
|
17
17
|
|
|
18
18
|
import click
|
|
19
|
+
from rich.text import Text
|
|
20
|
+
from tabulate import tabulate
|
|
19
21
|
|
|
20
22
|
from rucio.cli.utils import JSONType
|
|
23
|
+
from rucio.client.richclient import CLITheme, generate_table, get_cli_config, print_output
|
|
21
24
|
from rucio.common.constants import OPENDATA_DID_STATE_LITERAL_LIST
|
|
22
25
|
from rucio.common.utils import extract_scope
|
|
23
26
|
|
|
@@ -26,6 +29,8 @@ if TYPE_CHECKING:
|
|
|
26
29
|
|
|
27
30
|
from rucio.common.constants import OPENDATA_DID_STATE_LITERAL
|
|
28
31
|
|
|
32
|
+
cli_config = get_cli_config()
|
|
33
|
+
|
|
29
34
|
|
|
30
35
|
def is_valid_json(s: str) -> bool:
|
|
31
36
|
try:
|
|
@@ -50,15 +55,42 @@ def opendata_did() -> None:
|
|
|
50
55
|
help="Filter on Opendata state")
|
|
51
56
|
@click.option("--public", required=False, is_flag=True, default=False,
|
|
52
57
|
help="Perform request against the public endpoint")
|
|
58
|
+
@click.option("--short", is_flag=True, default=False, help="Dump the list of Opendata DIDs")
|
|
53
59
|
@click.pass_context
|
|
54
|
-
def list_opendata_dids(ctx: "Context", state: Optional["OPENDATA_DID_STATE_LITERAL"], public: bool
|
|
60
|
+
def list_opendata_dids(ctx: "Context", state: Optional["OPENDATA_DID_STATE_LITERAL"], public: bool,
|
|
61
|
+
short: bool) -> None:
|
|
55
62
|
"""
|
|
56
63
|
List Opendata DIDs, optionally filtered by state and public/private access
|
|
57
64
|
"""
|
|
58
65
|
|
|
59
66
|
client = ctx.obj.client
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
spinner = ctx.obj.spinner
|
|
68
|
+
|
|
69
|
+
dids_list = client.list_opendata_dids(state=state, public=public)
|
|
70
|
+
|
|
71
|
+
table_data = []
|
|
72
|
+
|
|
73
|
+
if cli_config == 'rich':
|
|
74
|
+
spinner.update(status='Fetching Opendata DIDs')
|
|
75
|
+
spinner.start()
|
|
76
|
+
|
|
77
|
+
for did in dids_list["dids"]:
|
|
78
|
+
if cli_config == 'rich':
|
|
79
|
+
table_data.append([f"{did['scope']}:{did['name']}",
|
|
80
|
+
Text(did['state'], style=CLITheme.OPENDATA_DID_STATE.get(did['state'], 'default'))])
|
|
81
|
+
else:
|
|
82
|
+
table_data.append([f"{did['scope']}:{did['name']}", did['state']])
|
|
83
|
+
|
|
84
|
+
if short:
|
|
85
|
+
for did, _ in table_data:
|
|
86
|
+
print(did)
|
|
87
|
+
else:
|
|
88
|
+
if cli_config == 'rich':
|
|
89
|
+
table = generate_table(table_data, headers=['SCOPE:NAME', '[STATE]'], col_alignments=['left', 'left'])
|
|
90
|
+
spinner.stop()
|
|
91
|
+
print_output(table, console=ctx.obj.console, no_pager=ctx.obj.no_pager)
|
|
92
|
+
else:
|
|
93
|
+
print(tabulate(table_data, tablefmt="psql", headers=['SCOPE:NAME', '[STATE]']))
|
|
62
94
|
|
|
63
95
|
|
|
64
96
|
@opendata_did.command("add")
|
|
@@ -95,18 +127,37 @@ def remove_opendata_did(ctx: "Context", did: str) -> None:
|
|
|
95
127
|
@click.option("--public", required=False, is_flag=True, default=False,
|
|
96
128
|
help="Perform request against the public endpoint")
|
|
97
129
|
@click.pass_context
|
|
98
|
-
def get_opendata_did(ctx: "Context", did: str,
|
|
130
|
+
def get_opendata_did(ctx: "Context", did: str, files: bool, meta: bool, public: bool) -> None:
|
|
99
131
|
"""
|
|
100
132
|
Get information about an Opendata DID, optionally including files and metadata.
|
|
101
133
|
"""
|
|
102
134
|
|
|
103
135
|
client = ctx.obj.client
|
|
136
|
+
spinner = ctx.obj.spinner
|
|
137
|
+
console = ctx.obj.console
|
|
138
|
+
|
|
104
139
|
scope, name = extract_scope(did)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
140
|
+
info = client.get_opendata_did(scope=scope, name=name, public=public,
|
|
141
|
+
include_files=files, include_metadata=meta,
|
|
142
|
+
include_doi=True)
|
|
143
|
+
|
|
144
|
+
output = []
|
|
145
|
+
if cli_config == 'rich':
|
|
146
|
+
spinner.update(status='Fetching Opendata DID stats')
|
|
147
|
+
spinner.start()
|
|
148
|
+
keyword_styles = {**CLITheme.BOOLEAN, **CLITheme.OPENDATA_DID_STATE}
|
|
149
|
+
|
|
150
|
+
table_data = [(k, Text(str(v), style=keyword_styles.get(str(v), 'default'))) for (k, v) in
|
|
151
|
+
sorted(info.items())]
|
|
152
|
+
table = generate_table(table_data, row_styles=['none'], col_alignments=['left', 'left'])
|
|
153
|
+
output.append(table)
|
|
154
|
+
else:
|
|
155
|
+
table = [(k + ':', str(v)) for (k, v) in sorted(info.items())]
|
|
156
|
+
print(tabulate(table, tablefmt='plain', disable_numparse=True))
|
|
157
|
+
|
|
158
|
+
if cli_config == 'rich':
|
|
159
|
+
spinner.stop()
|
|
160
|
+
print_output(*output, console=console, no_pager=ctx.obj.no_pager)
|
|
110
161
|
|
|
111
162
|
|
|
112
163
|
@opendata_did.command("update")
|
|
@@ -57,7 +57,19 @@ def exception_handler(function):
|
|
|
57
57
|
def new_funct(*args, **kwargs):
|
|
58
58
|
try:
|
|
59
59
|
return function(*args, **kwargs)
|
|
60
|
-
except
|
|
60
|
+
except click.exceptions.Exit as error:
|
|
61
|
+
# Exit is evoked every time click ends a program without running anything
|
|
62
|
+
# This error is raised when the help menu is called
|
|
63
|
+
logger.debug("Exited click context")
|
|
64
|
+
if ("-h" not in sys.argv) or ("--help" not in sys.argv):
|
|
65
|
+
return error.exit_code
|
|
66
|
+
return SUCCESS
|
|
67
|
+
except click.MissingParameter as error:
|
|
68
|
+
error.show()
|
|
69
|
+
msg = f"{error}. Please check the command help (-h/--help)."
|
|
70
|
+
logger.error(msg)
|
|
71
|
+
return 2 # Always return an error 2 for an incorrect specification
|
|
72
|
+
except (InputValidationError, click.exceptions.UsageError) as error:
|
|
61
73
|
logger.error(error)
|
|
62
74
|
logger.debug("This means that one you provided an invalid combination of parameters, or incorrect types. Please check the command help (-h/--help).")
|
|
63
75
|
return FAILURE
|
|
@@ -147,3 +147,26 @@ class ConfigClient(BaseClient):
|
|
|
147
147
|
else:
|
|
148
148
|
exc_cls, exc_msg = self._get_exception(headers=r.headers, status_code=r.status_code, data=r.content)
|
|
149
149
|
raise exc_cls(exc_msg)
|
|
150
|
+
|
|
151
|
+
def delete_config_section(self, section: str):
|
|
152
|
+
"""
|
|
153
|
+
Delete a whole section from the config
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
section :
|
|
158
|
+
The name of the section.
|
|
159
|
+
|
|
160
|
+
Returns
|
|
161
|
+
-------
|
|
162
|
+
True if option was removed successfully.
|
|
163
|
+
"""
|
|
164
|
+
path = '/'.join([self.CONFIG_BASEURL, section])
|
|
165
|
+
url = build_url(choice(self.list_hosts), path=path)
|
|
166
|
+
r = self._send_request(url, type_='DEL')
|
|
167
|
+
|
|
168
|
+
if r.status_code == codes.ok:
|
|
169
|
+
return True
|
|
170
|
+
else:
|
|
171
|
+
exc_cls, exc_msg = self._get_exception(headers=r.headers, status_code=r.status_code, data=r.content)
|
|
172
|
+
raise exc_cls(exc_msg)
|
|
@@ -29,6 +29,8 @@ RESERVED_KEYS = ['scope', 'name', 'account', 'did_type', 'is_open', 'monotonic',
|
|
|
29
29
|
|
|
30
30
|
DEFAULT_VO = 'def'
|
|
31
31
|
|
|
32
|
+
DEFAULT_ACTIVITY = 'User Subscriptions'
|
|
33
|
+
|
|
32
34
|
KEY_TYPES = ['ALL', 'COLLECTION', 'FILE', 'DERIVED']
|
|
33
35
|
# all(container, dataset, file), collection(dataset or container), file, derived(compute from file for collection)
|
|
34
36
|
|
|
@@ -219,3 +221,6 @@ SUPPORTED_SIGN_URL_SERVICES = list(get_args(SUPPORTED_SIGN_URL_SERVICES_LITERAL)
|
|
|
219
221
|
|
|
220
222
|
OPENDATA_DID_STATE_LITERAL = Literal['draft', 'public', 'suspended']
|
|
221
223
|
OPENDATA_DID_STATE_LITERAL_LIST = list(get_args(OPENDATA_DID_STATE_LITERAL))
|
|
224
|
+
|
|
225
|
+
POLICY_ALGORITHM_TYPES_LITERAL = Literal['non_deterministic_pfn', 'scope', 'lfn2pfn', 'pfn2lfn', 'fts3_tape_metadata_plugins', 'fts3_plugins_init', 'auto_approve']
|
|
226
|
+
POLICY_ALGORITHM_TYPES = list(get_args(POLICY_ALGORITHM_TYPES_LITERAL))
|
|
@@ -1261,3 +1261,13 @@ class OpenDataInvalidStateUpdate(OpenDataError):
|
|
|
1261
1261
|
super(OpenDataInvalidStateUpdate, self).__init__(*args)
|
|
1262
1262
|
self._message = "Invalid state update attempted on open data entry."
|
|
1263
1263
|
self.error_code = 119
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
class InvalidPolicyPackageAlgorithmType(RucioException):
|
|
1267
|
+
"""
|
|
1268
|
+
Thrown when an unknown algorithm type name is encountered.
|
|
1269
|
+
"""
|
|
1270
|
+
def __init__(self, param: str, *args):
|
|
1271
|
+
super(InvalidPolicyPackageAlgorithmType, self).__init__(*args)
|
|
1272
|
+
self._message = f"Invalid policy package algorithm type '{param}'."
|
|
1273
|
+
self.error_code = 120
|
|
@@ -22,8 +22,8 @@ from packaging.specifiers import SpecifierSet
|
|
|
22
22
|
|
|
23
23
|
from rucio.common import config
|
|
24
24
|
from rucio.common.client import get_client_vo
|
|
25
|
-
from rucio.common.constants import DEFAULT_VO
|
|
26
|
-
from rucio.common.exception import InvalidAlgorithmName, PolicyPackageIsNotVersioned, PolicyPackageVersionError
|
|
25
|
+
from rucio.common.constants import DEFAULT_VO, POLICY_ALGORITHM_TYPES, POLICY_ALGORITHM_TYPES_LITERAL
|
|
26
|
+
from rucio.common.exception import InvalidAlgorithmName, InvalidPolicyPackageAlgorithmType, PolicyPackageIsNotVersioned, PolicyPackageVersionError
|
|
27
27
|
from rucio.version import current_version
|
|
28
28
|
|
|
29
29
|
if TYPE_CHECKING:
|
|
@@ -75,7 +75,7 @@ class PolicyPackageAlgorithms:
|
|
|
75
75
|
- the key is the algorithm type
|
|
76
76
|
- the value is a dictionary of algorithm names and their callables
|
|
77
77
|
"""
|
|
78
|
-
_ALGORITHMS: dict[
|
|
78
|
+
_ALGORITHMS: dict[POLICY_ALGORITHM_TYPES_LITERAL, dict[str, 'Callable[..., Any]']] = {}
|
|
79
79
|
_loaded_policy_modules = False
|
|
80
80
|
_default_algorithms: dict[str, 'Callable[..., Any]'] = {}
|
|
81
81
|
|
|
@@ -85,12 +85,15 @@ class PolicyPackageAlgorithms:
|
|
|
85
85
|
self._loaded_policy_modules = True
|
|
86
86
|
|
|
87
87
|
@classmethod
|
|
88
|
-
def _get_default_algorithm(cls: type[PolicyPackageAlgorithmsT], algorithm_type:
|
|
88
|
+
def _get_default_algorithm(cls: type[PolicyPackageAlgorithmsT], algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL, vo: str = "") -> Optional['Callable[..., Any]']:
|
|
89
89
|
"""
|
|
90
90
|
Gets the default algorithm of this type, if present in the policy package.
|
|
91
91
|
The default algorithm is the function named algorithm_type within the module named algorithm_type.
|
|
92
92
|
Returns None if no default algorithm present.
|
|
93
93
|
"""
|
|
94
|
+
if algorithm_type not in POLICY_ALGORITHM_TYPES:
|
|
95
|
+
raise InvalidPolicyPackageAlgorithmType(algorithm_type)
|
|
96
|
+
|
|
94
97
|
# check if default algorithm for this VO is already cached
|
|
95
98
|
type_for_vo = vo + "_" + algorithm_type
|
|
96
99
|
if type_for_vo in cls._default_algorithms:
|
|
@@ -116,38 +119,51 @@ class PolicyPackageAlgorithms:
|
|
|
116
119
|
return default_algorithm
|
|
117
120
|
|
|
118
121
|
@classmethod
|
|
119
|
-
def _get_one_algorithm(cls: type[PolicyPackageAlgorithmsT], algorithm_type:
|
|
122
|
+
def _get_one_algorithm(cls: type[PolicyPackageAlgorithmsT], algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL, name: str) -> 'Callable[..., Any]':
|
|
120
123
|
"""
|
|
121
124
|
Get the algorithm from the dictionary of algorithms
|
|
122
125
|
"""
|
|
126
|
+
if algorithm_type not in POLICY_ALGORITHM_TYPES:
|
|
127
|
+
raise InvalidPolicyPackageAlgorithmType(algorithm_type)
|
|
123
128
|
return cls._ALGORITHMS[algorithm_type][name]
|
|
124
129
|
|
|
125
130
|
@classmethod
|
|
126
|
-
def _get_algorithms(cls: type[PolicyPackageAlgorithmsT], algorithm_type:
|
|
131
|
+
def _get_algorithms(cls: type[PolicyPackageAlgorithmsT], algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL) -> dict[str, 'Callable[..., Any]']:
|
|
127
132
|
"""
|
|
128
133
|
Get the dictionary of algorithms for a given type
|
|
129
134
|
"""
|
|
135
|
+
if algorithm_type not in POLICY_ALGORITHM_TYPES:
|
|
136
|
+
raise InvalidPolicyPackageAlgorithmType(algorithm_type)
|
|
130
137
|
return cls._ALGORITHMS[algorithm_type]
|
|
131
138
|
|
|
132
139
|
@classmethod
|
|
133
140
|
def _register(
|
|
134
141
|
cls: type[PolicyPackageAlgorithmsT],
|
|
135
|
-
algorithm_type:
|
|
142
|
+
algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL,
|
|
143
|
+
algorithm_dict: dict[str, 'Callable[..., Any]']) -> None:
|
|
136
144
|
"""
|
|
137
145
|
Provided a dictionary of callable function,
|
|
138
146
|
and the associated algorithm type,
|
|
139
147
|
register it as one of the valid algorithms.
|
|
140
148
|
"""
|
|
149
|
+
if algorithm_type not in POLICY_ALGORITHM_TYPES:
|
|
150
|
+
raise InvalidPolicyPackageAlgorithmType(algorithm_type)
|
|
151
|
+
|
|
141
152
|
if algorithm_type in cls._ALGORITHMS:
|
|
142
153
|
cls._ALGORITHMS[algorithm_type].update(algorithm_dict)
|
|
143
154
|
else:
|
|
144
155
|
cls._ALGORITHMS[algorithm_type] = algorithm_dict
|
|
145
156
|
|
|
146
157
|
@classmethod
|
|
147
|
-
def _supports(
|
|
158
|
+
def _supports(
|
|
159
|
+
cls: type[PolicyPackageAlgorithmsT],
|
|
160
|
+
algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL,
|
|
161
|
+
name: str) -> bool:
|
|
148
162
|
"""
|
|
149
163
|
Check if a algorithm is supported by the plugin
|
|
150
164
|
"""
|
|
165
|
+
if algorithm_type not in POLICY_ALGORITHM_TYPES:
|
|
166
|
+
raise InvalidPolicyPackageAlgorithmType(algorithm_type)
|
|
151
167
|
return name in cls._ALGORITHMS.get(algorithm_type, {})
|
|
152
168
|
|
|
153
169
|
@classmethod
|
|
@@ -46,7 +46,7 @@ import requests
|
|
|
46
46
|
from typing_extensions import ParamSpec
|
|
47
47
|
|
|
48
48
|
from rucio.common.config import config_get, config_get_bool
|
|
49
|
-
from rucio.common.constants import BASE_SCHEME_MAP, DEFAULT_VO
|
|
49
|
+
from rucio.common.constants import BASE_SCHEME_MAP, DEFAULT_VO, POLICY_ALGORITHM_TYPES_LITERAL
|
|
50
50
|
from rucio.common.exception import DIDFilterSyntaxError, DuplicateCriteriaInDIDFilter, InputValidationError, InvalidType, MetalinkJsonParsingError, MissingModuleException, RucioException
|
|
51
51
|
from rucio.common.extra import import_extras
|
|
52
52
|
from rucio.common.plugins import PolicyPackageAlgorithms
|
|
@@ -392,7 +392,7 @@ class NonDeterministicPFNAlgorithms(PolicyPackageAlgorithms):
|
|
|
392
392
|
from policy packages
|
|
393
393
|
"""
|
|
394
394
|
|
|
395
|
-
_algorithm_type = 'non_deterministic_pfn'
|
|
395
|
+
_algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL = 'non_deterministic_pfn'
|
|
396
396
|
|
|
397
397
|
def __init__(self, vo: str = DEFAULT_VO) -> None:
|
|
398
398
|
"""
|
|
@@ -560,7 +560,7 @@ class ScopeExtractionAlgorithms(PolicyPackageAlgorithms):
|
|
|
560
560
|
Handle scope extraction algorithms
|
|
561
561
|
"""
|
|
562
562
|
|
|
563
|
-
_algorithm_type = 'scope'
|
|
563
|
+
_algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL = 'scope'
|
|
564
564
|
|
|
565
565
|
def __init__(self, vo: str = DEFAULT_VO) -> None:
|
|
566
566
|
"""
|
|
@@ -18,7 +18,7 @@ from configparser import NoOptionError, NoSectionError
|
|
|
18
18
|
from typing import TYPE_CHECKING, Any, Optional
|
|
19
19
|
|
|
20
20
|
from rucio.common import config
|
|
21
|
-
from rucio.common.constants import DEFAULT_VO, RseAttr
|
|
21
|
+
from rucio.common.constants import DEFAULT_VO, POLICY_ALGORITHM_TYPES_LITERAL, RseAttr
|
|
22
22
|
from rucio.common.exception import ConfigNotFound
|
|
23
23
|
from rucio.common.plugins import PolicyPackageAlgorithms
|
|
24
24
|
|
|
@@ -33,7 +33,7 @@ class RSEDeterministicScopeTranslation(PolicyPackageAlgorithms):
|
|
|
33
33
|
Translates a pfn dictionary into a scope and name
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
|
-
_algorithm_type = "pfn2lfn"
|
|
36
|
+
_algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL = "pfn2lfn"
|
|
37
37
|
|
|
38
38
|
def __init__(self, vo: str = DEFAULT_VO):
|
|
39
39
|
super().__init__()
|
|
@@ -111,7 +111,7 @@ class RSEDeterministicTranslation(PolicyPackageAlgorithms):
|
|
|
111
111
|
"""
|
|
112
112
|
|
|
113
113
|
_DEFAULT_LFN2PFN = "hash"
|
|
114
|
-
_algorithm_type = "lfn2pfn"
|
|
114
|
+
_algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL = "lfn2pfn"
|
|
115
115
|
|
|
116
116
|
def __init__(
|
|
117
117
|
self,
|
|
@@ -4,8 +4,8 @@ This file is automatically generated; Do not edit it. :)
|
|
|
4
4
|
'''
|
|
5
5
|
VERSION_INFO = {
|
|
6
6
|
'final': True,
|
|
7
|
-
'version': '38.
|
|
7
|
+
'version': '38.3.0',
|
|
8
8
|
'branch_nick': 'release-38-LTS',
|
|
9
|
-
'revision_id': '
|
|
10
|
-
'revno':
|
|
9
|
+
'revision_id': '5eebc4e67a544dcb2d689bd45260cb73fb10066a',
|
|
10
|
+
'revno': 14003
|
|
11
11
|
}
|