rucio 37.5.0__py3-none-any.whl → 37.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rucio might be problematic. Click here for more details.
- rucio/cli/bin_legacy/rucio.py +41 -22
- rucio/cli/bin_legacy/rucio_admin.py +1 -1
- rucio/cli/did.py +2 -2
- rucio/cli/rse.py +2 -3
- rucio/cli/rule.py +9 -5
- rucio/cli/subscription.py +1 -1
- rucio/client/baseclient.py +9 -4
- rucio/client/didclient.py +16 -16
- rucio/client/downloadclient.py +16 -15
- rucio/client/exportclient.py +45 -4
- rucio/client/lockclient.py +3 -3
- rucio/client/pingclient.py +35 -4
- rucio/client/replicaclient.py +2 -2
- rucio/client/touchclient.py +3 -2
- rucio/client/uploadclient.py +728 -183
- rucio/common/cache.py +1 -2
- rucio/common/client.py +4 -30
- rucio/common/config.py +27 -3
- rucio/common/constants.py +5 -1
- rucio/common/didtype.py +2 -2
- rucio/common/dumper/__init__.py +1 -1
- rucio/common/pcache.py +20 -25
- rucio/common/plugins.py +12 -19
- rucio/common/policy.py +3 -2
- rucio/common/schema/__init__.py +11 -8
- rucio/common/types.py +7 -5
- rucio/common/utils.py +1 -1
- rucio/core/account.py +2 -1
- rucio/core/account_limit.py +3 -2
- rucio/core/authentication.py +1 -1
- rucio/core/credential.py +1 -1
- rucio/core/did.py +62 -61
- rucio/core/did_meta_plugins/__init__.py +10 -10
- rucio/core/did_meta_plugins/did_column_meta.py +9 -9
- rucio/core/did_meta_plugins/did_meta_plugin_interface.py +3 -3
- rucio/core/did_meta_plugins/elasticsearch_meta.py +7 -7
- rucio/core/did_meta_plugins/json_meta.py +2 -2
- rucio/core/did_meta_plugins/mongo_meta.py +9 -9
- rucio/core/did_meta_plugins/postgres_meta.py +7 -7
- rucio/core/dirac.py +3 -2
- rucio/core/distance.py +2 -1
- rucio/core/exporter.py +3 -2
- rucio/core/importer.py +5 -5
- rucio/core/lifetime_exception.py +2 -2
- rucio/core/lock.py +7 -7
- rucio/core/meta_conventions.py +2 -2
- rucio/core/monitor.py +1 -1
- rucio/core/naming_convention.py +1 -1
- rucio/core/nongrid_trace.py +2 -2
- rucio/core/oidc.py +2 -2
- rucio/core/permission/__init__.py +9 -6
- rucio/core/permission/generic.py +2 -2
- rucio/core/permission/generic_multi_vo.py +2 -2
- rucio/core/replica.py +22 -22
- rucio/core/request.py +2 -2
- rucio/core/rse.py +7 -7
- rucio/core/rule.py +38 -38
- rucio/core/rule_grouping.py +2 -3
- rucio/core/scope.py +1 -1
- rucio/core/trace.py +2 -2
- rucio/core/transfer.py +2 -2
- rucio/core/vo.py +2 -1
- rucio/daemons/atropos/atropos.py +2 -1
- rucio/daemons/auditor/__init__.py +1 -1
- rucio/daemons/automatix/automatix.py +5 -5
- rucio/daemons/badreplicas/minos.py +12 -5
- rucio/daemons/badreplicas/minos_temporary_expiration.py +5 -2
- rucio/daemons/badreplicas/necromancer.py +9 -3
- rucio/daemons/bb8/bb8.py +2 -1
- rucio/daemons/bb8/common.py +1 -1
- rucio/daemons/bb8/nuclei_background_rebalance.py +3 -3
- rucio/daemons/bb8/t2_background_rebalance.py +1 -1
- rucio/daemons/cache/consumer.py +1 -1
- rucio/daemons/conveyor/common.py +3 -3
- rucio/daemons/conveyor/finisher.py +13 -4
- rucio/daemons/conveyor/poller.py +5 -2
- rucio/daemons/conveyor/receiver.py +1 -1
- rucio/daemons/conveyor/submitter.py +2 -1
- rucio/daemons/follower/follower.py +1 -1
- rucio/daemons/hermes/hermes.py +29 -8
- rucio/daemons/judge/cleaner.py +2 -2
- rucio/daemons/judge/evaluator.py +7 -7
- rucio/daemons/judge/injector.py +2 -2
- rucio/daemons/judge/repairer.py +2 -2
- rucio/daemons/reaper/dark_reaper.py +5 -4
- rucio/daemons/reaper/reaper.py +7 -7
- rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +4 -4
- rucio/daemons/storage/consistency/actions.py +3 -3
- rucio/daemons/tracer/kronos.py +3 -2
- rucio/daemons/transmogrifier/transmogrifier.py +71 -69
- rucio/daemons/undertaker/undertaker.py +8 -7
- rucio/db/sqla/constants.py +4 -3
- rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +1 -1
- rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +1 -1
- rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +1 -1
- rucio/db/sqla/models.py +3 -3
- rucio/db/sqla/session.py +7 -7
- rucio/db/sqla/util.py +3 -2
- rucio/gateway/account.py +77 -101
- rucio/gateway/account_limit.py +90 -116
- rucio/gateway/authentication.py +9 -8
- rucio/gateway/config.py +11 -10
- rucio/gateway/credential.py +2 -1
- rucio/gateway/did.py +58 -58
- rucio/gateway/dirac.py +3 -2
- rucio/gateway/exporter.py +2 -1
- rucio/gateway/heartbeat.py +3 -2
- rucio/gateway/identity.py +4 -3
- rucio/gateway/importer.py +2 -1
- rucio/gateway/lifetime_exception.py +5 -4
- rucio/gateway/lock.py +6 -5
- rucio/gateway/meta_conventions.py +3 -2
- rucio/gateway/permission.py +2 -1
- rucio/gateway/quarantined_replica.py +2 -1
- rucio/gateway/replica.py +20 -20
- rucio/gateway/request.py +10 -10
- rucio/gateway/rse.py +27 -26
- rucio/gateway/rule.py +12 -11
- rucio/gateway/scope.py +4 -3
- rucio/gateway/subscription.py +7 -6
- rucio/gateway/vo.py +5 -4
- rucio/rse/__init__.py +7 -6
- rucio/rse/protocols/ngarc.py +2 -2
- rucio/rse/protocols/srm.py +1 -1
- rucio/rse/protocols/webdav.py +8 -1
- rucio/rse/rsemanager.py +5 -4
- rucio/rse/translation.py +2 -2
- rucio/tests/common.py +6 -5
- rucio/vcsversion.py +3 -3
- rucio/web/rest/flaskapi/v1/accountlimits.py +5 -5
- rucio/web/rest/flaskapi/v1/accounts.py +20 -20
- rucio/web/rest/flaskapi/v1/archives.py +4 -3
- rucio/web/rest/flaskapi/v1/common.py +5 -4
- rucio/web/rest/flaskapi/v1/dids.py +382 -331
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +5 -5
- rucio/web/rest/flaskapi/v1/locks.py +13 -13
- rucio/web/rest/flaskapi/v1/main.py +1 -0
- rucio/web/rest/flaskapi/v1/redirect.py +2 -2
- rucio/web/rest/flaskapi/v1/replicas.py +16 -16
- rucio/web/rest/flaskapi/v1/requests.py +16 -16
- rucio/web/rest/flaskapi/v1/subscriptions.py +7 -7
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-abacus-account +8 -1
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-abacus-rse +8 -1
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-auditor +1 -1
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-conveyor-throttler +7 -1
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-follower +1 -1
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-judge-cleaner +9 -1
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-necromancer +7 -1
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-replica-recoverer +31 -9
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-undertaker +8 -2
- {rucio-37.5.0.dist-info → rucio-37.7.0.dist-info}/METADATA +1 -1
- {rucio-37.5.0.dist-info → rucio-37.7.0.dist-info}/RECORD +202 -202
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/alembic.ini.template +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/rucio.cfg.template +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/requirements.server.txt +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/tools/bootstrap.py +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/data/rucio/tools/reset_database.py +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-abacus-collection-replica +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-admin +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-atropos +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-automatix +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-bb8 +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-cache-client +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-cache-consumer +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-conveyor-finisher +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-conveyor-poller +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-conveyor-preparer +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-conveyor-receiver +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-conveyor-stager +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-conveyor-submitter +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-dark-reaper +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-dumper +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-hermes +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-judge-evaluator +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-judge-injector +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-judge-repairer +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-kronos +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-minos +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-oauth-manager +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-reaper +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-rse-decommissioner +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-storage-consistency-actions +0 -0
- {rucio-37.5.0.data → rucio-37.7.0.data}/scripts/rucio-transmogrifier +0 -0
- {rucio-37.5.0.dist-info → rucio-37.7.0.dist-info}/WHEEL +0 -0
- {rucio-37.5.0.dist-info → rucio-37.7.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {rucio-37.5.0.dist-info → rucio-37.7.0.dist-info}/licenses/LICENSE +0 -0
- {rucio-37.5.0.dist-info → rucio-37.7.0.dist-info}/top_level.txt +0 -0
rucio/gateway/account_limit.py
CHANGED
|
@@ -12,48 +12,41 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from typing import
|
|
15
|
+
from typing import Any, Optional, Union
|
|
16
16
|
|
|
17
17
|
import rucio.common.exception
|
|
18
18
|
import rucio.gateway.permission
|
|
19
|
+
from rucio.common.constants import DEFAULT_VO
|
|
19
20
|
from rucio.common.types import InternalAccount, RSEResolvedGlobalAccountLimitDict
|
|
20
21
|
from rucio.common.utils import gateway_update_return_dict
|
|
21
22
|
from rucio.core import account_limit as account_limit_core
|
|
22
23
|
from rucio.core.account import account_exists
|
|
23
24
|
from rucio.core.rse import get_rse_id, get_rse_name
|
|
24
|
-
from rucio.db.sqla.
|
|
25
|
+
from rucio.db.sqla.constants import DatabaseOperationType
|
|
26
|
+
from rucio.db.sqla.session import db_session
|
|
25
27
|
|
|
26
|
-
if TYPE_CHECKING:
|
|
27
|
-
from sqlalchemy.orm import Session
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
@read_session
|
|
31
29
|
def get_rse_account_usage(
|
|
32
30
|
rse: str,
|
|
33
|
-
vo: str =
|
|
34
|
-
*,
|
|
35
|
-
session: "Session"
|
|
31
|
+
vo: str = DEFAULT_VO,
|
|
36
32
|
) -> list[dict[str, Any]]:
|
|
37
33
|
"""
|
|
38
34
|
Returns the account limit and usage for all for all accounts on a RSE.
|
|
39
35
|
|
|
40
36
|
:param rse: The RSE name.
|
|
41
37
|
:param vo: The VO to act on.
|
|
42
|
-
:param session: The database session in use.
|
|
43
38
|
:return: List of dictionaries.
|
|
44
39
|
"""
|
|
45
|
-
|
|
40
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
41
|
+
rse_id = get_rse_id(rse=rse, vo=vo, session=session)
|
|
46
42
|
|
|
47
|
-
|
|
43
|
+
return [gateway_update_return_dict(d, session=session) for d in account_limit_core.get_rse_account_usage(rse_id=rse_id, session=session)]
|
|
48
44
|
|
|
49
45
|
|
|
50
|
-
@read_session
|
|
51
46
|
def get_local_account_limit(
|
|
52
47
|
account: str,
|
|
53
48
|
rse: Optional[str] = None,
|
|
54
|
-
vo: str =
|
|
55
|
-
*,
|
|
56
|
-
session: "Session"
|
|
49
|
+
vo: str = DEFAULT_VO,
|
|
57
50
|
) -> dict[str, Union[int, float, None]]:
|
|
58
51
|
"""
|
|
59
52
|
Lists the limitation names/values for the specified account name.
|
|
@@ -65,30 +58,27 @@ def get_local_account_limit(
|
|
|
65
58
|
:param account: The account name.
|
|
66
59
|
:param rse: The RSE name (optional).
|
|
67
60
|
:param vo: The VO to act on.
|
|
68
|
-
:param session: The database session in use.
|
|
69
61
|
|
|
70
62
|
:returns: A dictionary of account limits with RSE names as keys and limits as values.
|
|
71
63
|
"""
|
|
72
64
|
|
|
73
65
|
internal_account = InternalAccount(account, vo=vo)
|
|
74
66
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
67
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
68
|
+
if rse:
|
|
69
|
+
# Single RSE lookup
|
|
70
|
+
rse_id = get_rse_id(rse=rse, vo=vo, session=session)
|
|
71
|
+
return {rse: account_limit_core.get_local_account_limit(account=internal_account, rse_ids=rse_id, session=session)}
|
|
72
|
+
else:
|
|
73
|
+
# Fetch all RSE limits
|
|
74
|
+
limits = account_limit_core.get_local_account_limit(account=internal_account, rse_ids=None, session=session)
|
|
75
|
+
return {get_rse_name(rse_id=rse_id, session=session): limit for rse_id, limit in limits.items()}
|
|
83
76
|
|
|
84
77
|
|
|
85
|
-
@read_session
|
|
86
78
|
def get_global_account_limit(
|
|
87
79
|
account: str,
|
|
88
80
|
rse_expression: Optional[str] = None,
|
|
89
|
-
vo: str =
|
|
90
|
-
*,
|
|
91
|
-
session: "Session"
|
|
81
|
+
vo: str = DEFAULT_VO,
|
|
92
82
|
) -> Union[dict[str, RSEResolvedGlobalAccountLimitDict], dict[str, dict[str, RSEResolvedGlobalAccountLimitDict]]]:
|
|
93
83
|
"""
|
|
94
84
|
Lists the global account limitation names/values for the specified account.
|
|
@@ -100,7 +90,6 @@ def get_global_account_limit(
|
|
|
100
90
|
:param account: The account name.
|
|
101
91
|
:param rse_expression: The RSE expression (optional; if not provided, all limits will be fetched).
|
|
102
92
|
:param vo: The VO to act on.
|
|
103
|
-
:param session: The database session in use.
|
|
104
93
|
|
|
105
94
|
:returns:
|
|
106
95
|
- If `rse_expression` is provided: `{rse_expression: {...}}`
|
|
@@ -109,23 +98,21 @@ def get_global_account_limit(
|
|
|
109
98
|
|
|
110
99
|
internal_account = InternalAccount(account, vo=vo)
|
|
111
100
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
101
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
102
|
+
if rse_expression:
|
|
103
|
+
return {rse_expression: account_limit_core.get_global_account_limit(
|
|
104
|
+
account=internal_account, rse_expression=rse_expression, session=session
|
|
105
|
+
)}
|
|
116
106
|
|
|
117
|
-
|
|
107
|
+
return account_limit_core.get_global_account_limit(account=internal_account, session=session)
|
|
118
108
|
|
|
119
109
|
|
|
120
|
-
@transactional_session
|
|
121
110
|
def set_local_account_limit(
|
|
122
111
|
account: str,
|
|
123
112
|
rse: str,
|
|
124
113
|
bytes_: int,
|
|
125
114
|
issuer: str,
|
|
126
|
-
vo: str =
|
|
127
|
-
*,
|
|
128
|
-
session: "Session"
|
|
115
|
+
vo: str = DEFAULT_VO,
|
|
129
116
|
) -> None:
|
|
130
117
|
"""
|
|
131
118
|
Set an account limit.
|
|
@@ -135,32 +122,29 @@ def set_local_account_limit(
|
|
|
135
122
|
:param bytes_: The limit in bytes.
|
|
136
123
|
:param issuer: The issuer account_core.
|
|
137
124
|
:param vo: The VO to act on.
|
|
138
|
-
:param session: The database session in use.
|
|
139
125
|
"""
|
|
140
|
-
|
|
126
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
127
|
+
rse_id = get_rse_id(rse=rse, vo=vo, session=session)
|
|
141
128
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
129
|
+
kwargs = {'account': account, 'rse': rse, 'rse_id': rse_id, 'bytes': bytes_}
|
|
130
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='set_local_account_limit', kwargs=kwargs, session=session)
|
|
131
|
+
if not auth_result.allowed:
|
|
132
|
+
raise rucio.common.exception.AccessDenied('Account %s can not set account limits. %s' % (issuer, auth_result.message))
|
|
146
133
|
|
|
147
|
-
|
|
134
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
148
135
|
|
|
149
|
-
|
|
150
|
-
|
|
136
|
+
if not account_exists(account=internal_account, session=session):
|
|
137
|
+
raise rucio.common.exception.AccountNotFound('Account %s does not exist' % (internal_account))
|
|
151
138
|
|
|
152
|
-
|
|
139
|
+
account_limit_core.set_local_account_limit(account=internal_account, rse_id=rse_id, bytes_=bytes_, session=session)
|
|
153
140
|
|
|
154
141
|
|
|
155
|
-
@transactional_session
|
|
156
142
|
def set_global_account_limit(
|
|
157
143
|
account: str,
|
|
158
144
|
rse_expression: str,
|
|
159
145
|
bytes_: int,
|
|
160
146
|
issuer: str,
|
|
161
|
-
vo: str =
|
|
162
|
-
*,
|
|
163
|
-
session: "Session"
|
|
147
|
+
vo: str = DEFAULT_VO,
|
|
164
148
|
) -> None:
|
|
165
149
|
"""
|
|
166
150
|
Set a global account limit.
|
|
@@ -170,30 +154,27 @@ def set_global_account_limit(
|
|
|
170
154
|
:param bytes_: The limit in bytes.
|
|
171
155
|
:param issuer: The issuer account_core.
|
|
172
156
|
:param vo: The VO to act on.
|
|
173
|
-
:param session: The database session in use.
|
|
174
157
|
"""
|
|
175
158
|
|
|
176
159
|
kwargs = {'account': account, 'rse_expression': rse_expression, 'bytes': bytes_}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
160
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
161
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='set_global_account_limit', kwargs=kwargs, session=session)
|
|
162
|
+
if not auth_result.allowed:
|
|
163
|
+
raise rucio.common.exception.AccessDenied('Account %s can not set account limits. %s' % (issuer, auth_result.message))
|
|
180
164
|
|
|
181
|
-
|
|
165
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
182
166
|
|
|
183
|
-
|
|
184
|
-
|
|
167
|
+
if not account_exists(account=internal_account, session=session):
|
|
168
|
+
raise rucio.common.exception.AccountNotFound('Account %s does not exist' % (internal_account))
|
|
185
169
|
|
|
186
|
-
|
|
170
|
+
account_limit_core.set_global_account_limit(account=internal_account, rse_expression=rse_expression, bytes_=bytes_, session=session)
|
|
187
171
|
|
|
188
172
|
|
|
189
|
-
@transactional_session
|
|
190
173
|
def delete_local_account_limit(
|
|
191
174
|
account: str,
|
|
192
175
|
rse: str,
|
|
193
176
|
issuer: str,
|
|
194
|
-
vo: str =
|
|
195
|
-
*,
|
|
196
|
-
session: "Session"
|
|
177
|
+
vo: str = DEFAULT_VO,
|
|
197
178
|
) -> bool:
|
|
198
179
|
"""
|
|
199
180
|
Delete an account limit.
|
|
@@ -202,33 +183,30 @@ def delete_local_account_limit(
|
|
|
202
183
|
:param rse: The rse name.
|
|
203
184
|
:param issuer: The issuer account_core.
|
|
204
185
|
:param vo: The VO to act on.
|
|
205
|
-
:param session: The database session in use.
|
|
206
186
|
|
|
207
187
|
:returns: True if successful; False otherwise.
|
|
208
188
|
"""
|
|
209
189
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
190
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
191
|
+
rse_id = get_rse_id(rse=rse, vo=vo, session=session)
|
|
192
|
+
kwargs = {'account': account, 'rse': rse, 'rse_id': rse_id}
|
|
193
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='delete_local_account_limit', kwargs=kwargs, session=session)
|
|
194
|
+
if not auth_result.allowed:
|
|
195
|
+
raise rucio.common.exception.AccessDenied('Account %s can not delete account limits. %s' % (issuer, auth_result.message))
|
|
215
196
|
|
|
216
|
-
|
|
197
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
217
198
|
|
|
218
|
-
|
|
219
|
-
|
|
199
|
+
if not account_exists(account=internal_account, session=session):
|
|
200
|
+
raise rucio.common.exception.AccountNotFound('Account %s does not exist' % (internal_account))
|
|
220
201
|
|
|
221
|
-
|
|
202
|
+
return account_limit_core.delete_local_account_limit(account=internal_account, rse_id=rse_id, session=session)
|
|
222
203
|
|
|
223
204
|
|
|
224
|
-
@transactional_session
|
|
225
205
|
def delete_global_account_limit(
|
|
226
206
|
account: str,
|
|
227
207
|
rse_expression: str,
|
|
228
208
|
issuer: str,
|
|
229
|
-
vo: str =
|
|
230
|
-
*,
|
|
231
|
-
session: "Session"
|
|
209
|
+
vo: str = DEFAULT_VO,
|
|
232
210
|
) -> bool:
|
|
233
211
|
"""
|
|
234
212
|
Delete a global account limit..
|
|
@@ -237,32 +215,30 @@ def delete_global_account_limit(
|
|
|
237
215
|
:param rse_expression: The rse expression.
|
|
238
216
|
:param issuer: The issuer account_core.
|
|
239
217
|
:param vo: The VO to act on.
|
|
240
|
-
:param session: The database session in use.
|
|
241
218
|
|
|
242
219
|
:returns: True if successful; False otherwise.
|
|
243
220
|
"""
|
|
244
221
|
|
|
245
222
|
kwargs = {'account': account, 'rse_expression': rse_expression}
|
|
246
|
-
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='delete_global_account_limit', kwargs=kwargs, session=session)
|
|
247
|
-
if not auth_result.allowed:
|
|
248
|
-
raise rucio.common.exception.AccessDenied('Account %s can not delete global account limits. %s' % (issuer, auth_result.message))
|
|
249
223
|
|
|
250
|
-
|
|
224
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
225
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='delete_global_account_limit', kwargs=kwargs, session=session)
|
|
226
|
+
if not auth_result.allowed:
|
|
227
|
+
raise rucio.common.exception.AccessDenied('Account %s can not delete global account limits. %s' % (issuer, auth_result.message))
|
|
228
|
+
|
|
229
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
251
230
|
|
|
252
|
-
|
|
253
|
-
|
|
231
|
+
if not account_exists(account=internal_account, session=session):
|
|
232
|
+
raise rucio.common.exception.AccountNotFound('Account %s does not exist' % (internal_account))
|
|
254
233
|
|
|
255
|
-
|
|
234
|
+
return account_limit_core.delete_global_account_limit(account=internal_account, rse_expression=rse_expression, session=session)
|
|
256
235
|
|
|
257
236
|
|
|
258
|
-
@read_session
|
|
259
237
|
def get_local_account_usage(
|
|
260
238
|
account: str,
|
|
261
|
-
rse: str,
|
|
239
|
+
rse: Optional[str],
|
|
262
240
|
issuer: str,
|
|
263
|
-
vo: str =
|
|
264
|
-
*,
|
|
265
|
-
session: "Session"
|
|
241
|
+
vo: str = DEFAULT_VO,
|
|
266
242
|
) -> list[dict[str, Any]]:
|
|
267
243
|
"""
|
|
268
244
|
Get the account usage and connect it with (if available) the account limits of the account.
|
|
@@ -271,36 +247,33 @@ def get_local_account_usage(
|
|
|
271
247
|
:param rse: The rse to read (If none, get all).
|
|
272
248
|
:param issuer: The issuer account.
|
|
273
249
|
:param vo: The VO to act on.
|
|
274
|
-
:param session: The database session in use.
|
|
275
250
|
|
|
276
251
|
:returns: List of dicts {'rse_id', 'rse', 'bytes', 'files', 'bytes_limit', 'bytes_remaining'}
|
|
277
252
|
"""
|
|
278
253
|
|
|
279
254
|
rse_id = None
|
|
280
255
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
256
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
257
|
+
if rse:
|
|
258
|
+
rse_id = get_rse_id(rse=rse, vo=vo, session=session)
|
|
259
|
+
kwargs = {'account': account, 'rse': rse, 'rse_id': rse_id}
|
|
260
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='get_local_account_usage', kwargs=kwargs, session=session)
|
|
261
|
+
if not auth_result.allowed:
|
|
262
|
+
raise rucio.common.exception.AccessDenied('Account %s can not list account usage. %s' % (issuer, auth_result.message))
|
|
287
263
|
|
|
288
|
-
|
|
264
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
289
265
|
|
|
290
|
-
|
|
291
|
-
|
|
266
|
+
if not account_exists(account=internal_account, session=session):
|
|
267
|
+
raise rucio.common.exception.AccountNotFound('Account %s does not exist' % (internal_account))
|
|
292
268
|
|
|
293
|
-
|
|
269
|
+
return [gateway_update_return_dict(d, session=session) for d in account_limit_core.get_local_account_usage(account=internal_account, rse_id=rse_id, session=session)]
|
|
294
270
|
|
|
295
271
|
|
|
296
|
-
@read_session
|
|
297
272
|
def get_global_account_usage(
|
|
298
273
|
account: str,
|
|
299
|
-
rse_expression: str,
|
|
274
|
+
rse_expression: Optional[str],
|
|
300
275
|
issuer: str,
|
|
301
|
-
vo: str =
|
|
302
|
-
*,
|
|
303
|
-
session: "Session"
|
|
276
|
+
vo: str = DEFAULT_VO,
|
|
304
277
|
) -> list[dict[str, Any]]:
|
|
305
278
|
"""
|
|
306
279
|
Get the account usage and connect it with (if available) the account limits of the account.
|
|
@@ -309,19 +282,20 @@ def get_global_account_usage(
|
|
|
309
282
|
:param rse_expression: The rse expression to read (If none, get all).
|
|
310
283
|
:param issuer: The issuer account.
|
|
311
284
|
:param vo: The VO to act on.
|
|
312
|
-
:param session: The database session in use.
|
|
313
285
|
|
|
314
286
|
:returns: List of dicts {'rse_id', 'rse', 'bytes', 'files', 'bytes_limit', 'bytes_remaining'}
|
|
315
287
|
"""
|
|
316
288
|
|
|
317
289
|
kwargs = {'account': account, 'rse_expression': rse_expression}
|
|
318
|
-
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='get_global_account_usage', kwargs=kwargs, session=session)
|
|
319
|
-
if not auth_result.allowed:
|
|
320
|
-
raise rucio.common.exception.AccessDenied('Account %s can not list global account usage. %s' % (issuer, auth_result.message))
|
|
321
290
|
|
|
322
|
-
|
|
291
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
292
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='get_global_account_usage', kwargs=kwargs, session=session)
|
|
293
|
+
if not auth_result.allowed:
|
|
294
|
+
raise rucio.common.exception.AccessDenied('Account %s can not list global account usage. %s' % (issuer, auth_result.message))
|
|
295
|
+
|
|
296
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
323
297
|
|
|
324
|
-
|
|
325
|
-
|
|
298
|
+
if not account_exists(account=internal_account, session=session):
|
|
299
|
+
raise rucio.common.exception.AccountNotFound('Account %s does not exist' % (internal_account))
|
|
326
300
|
|
|
327
|
-
|
|
301
|
+
return [gateway_update_return_dict(d, session=session) for d in account_limit_core.get_global_account_usage(account=internal_account, rse_expression=rse_expression, session=session)]
|
rucio/gateway/authentication.py
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
from typing import Any, Optional
|
|
16
16
|
|
|
17
17
|
from rucio.common import exception
|
|
18
|
+
from rucio.common.constants import DEFAULT_VO
|
|
18
19
|
from rucio.common.types import InternalAccount, TokenDict
|
|
19
20
|
from rucio.common.utils import gateway_update_return_dict
|
|
20
21
|
from rucio.core import authentication, identity, oidc
|
|
@@ -26,7 +27,7 @@ from rucio.gateway import permission
|
|
|
26
27
|
def refresh_cli_auth_token(
|
|
27
28
|
token_string: str,
|
|
28
29
|
account: str,
|
|
29
|
-
vo: str =
|
|
30
|
+
vo: str = DEFAULT_VO,
|
|
30
31
|
) -> Optional[tuple[str, int]]:
|
|
31
32
|
"""
|
|
32
33
|
Checks if there is active refresh token and if so returns
|
|
@@ -66,7 +67,7 @@ def redirect_auth_oidc(
|
|
|
66
67
|
|
|
67
68
|
def get_auth_oidc(
|
|
68
69
|
account: str,
|
|
69
|
-
vo: str =
|
|
70
|
+
vo: str = DEFAULT_VO,
|
|
70
71
|
**kwargs
|
|
71
72
|
) -> str:
|
|
72
73
|
"""
|
|
@@ -134,7 +135,7 @@ def get_auth_token_user_pass(
|
|
|
134
135
|
password: str,
|
|
135
136
|
appid: str,
|
|
136
137
|
ip: Optional[str] = None,
|
|
137
|
-
vo: str =
|
|
138
|
+
vo: str = DEFAULT_VO,
|
|
138
139
|
) -> Optional[TokenDict]:
|
|
139
140
|
"""
|
|
140
141
|
Authenticate a Rucio account temporarily via username and password.
|
|
@@ -167,7 +168,7 @@ def get_auth_token_gss(
|
|
|
167
168
|
gsscred: str,
|
|
168
169
|
appid: str,
|
|
169
170
|
ip: Optional[str] = None,
|
|
170
|
-
vo: str =
|
|
171
|
+
vo: str = DEFAULT_VO,
|
|
171
172
|
) -> Optional[TokenDict]:
|
|
172
173
|
"""
|
|
173
174
|
Authenticate a Rucio account temporarily via a GSS token.
|
|
@@ -199,7 +200,7 @@ def get_auth_token_x509(
|
|
|
199
200
|
dn: str,
|
|
200
201
|
appid: str,
|
|
201
202
|
ip: Optional[str] = None,
|
|
202
|
-
vo: str =
|
|
203
|
+
vo: str = DEFAULT_VO,
|
|
203
204
|
) -> Optional[TokenDict]:
|
|
204
205
|
"""
|
|
205
206
|
Authenticate a Rucio account temporarily via an x509 certificate.
|
|
@@ -235,7 +236,7 @@ def get_auth_token_ssh(
|
|
|
235
236
|
signature: str,
|
|
236
237
|
appid: str,
|
|
237
238
|
ip: Optional[str] = None,
|
|
238
|
-
vo: str =
|
|
239
|
+
vo: str = DEFAULT_VO,
|
|
239
240
|
) -> Optional[TokenDict]:
|
|
240
241
|
"""
|
|
241
242
|
Authenticate a Rucio account temporarily via SSH key exchange.
|
|
@@ -267,7 +268,7 @@ def get_ssh_challenge_token(
|
|
|
267
268
|
account: str,
|
|
268
269
|
appid: str,
|
|
269
270
|
ip: Optional[str] = None,
|
|
270
|
-
vo: str =
|
|
271
|
+
vo: str = DEFAULT_VO,
|
|
271
272
|
) -> Optional[TokenDict]:
|
|
272
273
|
"""
|
|
273
274
|
Get a challenge token for subsequent SSH public key authentication.
|
|
@@ -299,7 +300,7 @@ def get_auth_token_saml(
|
|
|
299
300
|
saml_nameid: str,
|
|
300
301
|
appid: str,
|
|
301
302
|
ip: Optional[str] = None,
|
|
302
|
-
vo: str =
|
|
303
|
+
vo: str = DEFAULT_VO,
|
|
303
304
|
) -> Optional[TokenDict]:
|
|
304
305
|
"""
|
|
305
306
|
Authenticate a Rucio account temporarily via SSO.
|
rucio/gateway/config.py
CHANGED
|
@@ -16,6 +16,7 @@ from typing import Any
|
|
|
16
16
|
|
|
17
17
|
from rucio.common import exception
|
|
18
18
|
from rucio.common.config import convert_to_any_type
|
|
19
|
+
from rucio.common.constants import DEFAULT_VO
|
|
19
20
|
from rucio.core import config
|
|
20
21
|
from rucio.db.sqla.constants import DatabaseOperationType
|
|
21
22
|
from rucio.db.sqla.session import db_session
|
|
@@ -29,7 +30,7 @@ ConfigParser compatible interface.
|
|
|
29
30
|
"""
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
def sections(issuer: str, vo: str =
|
|
33
|
+
def sections(issuer: str, vo: str = DEFAULT_VO) -> list[str]:
|
|
33
34
|
"""
|
|
34
35
|
Return a list of the sections available.
|
|
35
36
|
|
|
@@ -46,7 +47,7 @@ def sections(issuer: str, vo: str = 'def') -> list[str]:
|
|
|
46
47
|
return config.sections(session=session)
|
|
47
48
|
|
|
48
49
|
|
|
49
|
-
def add_section(section: str, issuer: str, vo: str =
|
|
50
|
+
def add_section(section: str, issuer: str, vo: str = DEFAULT_VO) -> None:
|
|
50
51
|
"""
|
|
51
52
|
Add a section to the configuration.
|
|
52
53
|
|
|
@@ -63,7 +64,7 @@ def add_section(section: str, issuer: str, vo: str = 'def') -> None:
|
|
|
63
64
|
return config.add_section(section, session=session)
|
|
64
65
|
|
|
65
66
|
|
|
66
|
-
def has_section(section: str, issuer: str, vo: str =
|
|
67
|
+
def has_section(section: str, issuer: str, vo: str = DEFAULT_VO) -> bool:
|
|
67
68
|
"""
|
|
68
69
|
Indicates whether the named section is present in the configuration.
|
|
69
70
|
|
|
@@ -81,7 +82,7 @@ def has_section(section: str, issuer: str, vo: str = 'def') -> bool:
|
|
|
81
82
|
return config.has_section(section, session=session)
|
|
82
83
|
|
|
83
84
|
|
|
84
|
-
def options(section: str, issuer: str, vo: str =
|
|
85
|
+
def options(section: str, issuer: str, vo: str = DEFAULT_VO) -> list[str]:
|
|
85
86
|
"""
|
|
86
87
|
Returns a list of options available in the specified section.
|
|
87
88
|
|
|
@@ -99,7 +100,7 @@ def options(section: str, issuer: str, vo: str = 'def') -> list[str]:
|
|
|
99
100
|
return config.options(section, session=session)
|
|
100
101
|
|
|
101
102
|
|
|
102
|
-
def has_option(section: str, option: str, issuer: str, vo: str =
|
|
103
|
+
def has_option(section: str, option: str, issuer: str, vo: str = DEFAULT_VO) -> bool:
|
|
103
104
|
"""
|
|
104
105
|
Check if the given section exists and contains the given option.
|
|
105
106
|
|
|
@@ -118,7 +119,7 @@ def has_option(section: str, option: str, issuer: str, vo: str = 'def') -> bool:
|
|
|
118
119
|
return config.has_option(section, option, session=session)
|
|
119
120
|
|
|
120
121
|
|
|
121
|
-
def get(section: str, option: str, issuer: str, vo: str =
|
|
122
|
+
def get(section: str, option: str, issuer: str, vo: str = DEFAULT_VO) -> Any:
|
|
122
123
|
"""
|
|
123
124
|
Get an option value for the named section. Value can be auto-coerced to int, float, and bool; string otherwise.
|
|
124
125
|
|
|
@@ -140,7 +141,7 @@ def get(section: str, option: str, issuer: str, vo: str = 'def') -> Any:
|
|
|
140
141
|
return config.get(section, option, session=session, convert_type_fnc=convert_to_any_type)
|
|
141
142
|
|
|
142
143
|
|
|
143
|
-
def items(section: str, issuer: str, vo: str =
|
|
144
|
+
def items(section: str, issuer: str, vo: str = DEFAULT_VO) -> list[tuple[str, Any]]:
|
|
144
145
|
"""
|
|
145
146
|
Return a list of (option, value) pairs for each option in the given section. Values are auto-coerced as in get().
|
|
146
147
|
|
|
@@ -159,7 +160,7 @@ def items(section: str, issuer: str, vo: str = 'def') -> list[tuple[str, Any]]:
|
|
|
159
160
|
return config.items(section, session=session, convert_type_fnc=convert_to_any_type)
|
|
160
161
|
|
|
161
162
|
|
|
162
|
-
def set(section: str, option: str, value: Any, issuer: str, vo: str =
|
|
163
|
+
def set(section: str, option: str, value: Any, issuer: str, vo: str = DEFAULT_VO) -> None:
|
|
163
164
|
"""
|
|
164
165
|
Set the given option to the specified value.
|
|
165
166
|
|
|
@@ -178,7 +179,7 @@ def set(section: str, option: str, value: Any, issuer: str, vo: str = 'def') ->
|
|
|
178
179
|
return config.set(section, option, value, session=session)
|
|
179
180
|
|
|
180
181
|
|
|
181
|
-
def remove_section(section: str, issuer: str, vo: str =
|
|
182
|
+
def remove_section(section: str, issuer: str, vo: str = DEFAULT_VO) -> bool:
|
|
182
183
|
"""
|
|
183
184
|
Remove the specified option from the specified section.
|
|
184
185
|
|
|
@@ -196,7 +197,7 @@ def remove_section(section: str, issuer: str, vo: str = 'def') -> bool:
|
|
|
196
197
|
return config.remove_section(section, session=session)
|
|
197
198
|
|
|
198
199
|
|
|
199
|
-
def remove_option(section: str, option: str, issuer: str, vo: str =
|
|
200
|
+
def remove_option(section: str, option: str, issuer: str, vo: str = DEFAULT_VO) -> bool:
|
|
200
201
|
"""
|
|
201
202
|
Remove the specified section from the configuration.
|
|
202
203
|
|
rucio/gateway/credential.py
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
from typing import TYPE_CHECKING
|
|
16
16
|
|
|
17
17
|
from rucio.common import exception
|
|
18
|
+
from rucio.common.constants import DEFAULT_VO
|
|
18
19
|
from rucio.core import credential
|
|
19
20
|
from rucio.core.rse import get_rse_id
|
|
20
21
|
from rucio.db.sqla.constants import DatabaseOperationType
|
|
@@ -32,7 +33,7 @@ def get_signed_url(
|
|
|
32
33
|
operation: 'RSE_BASE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL',
|
|
33
34
|
url: str,
|
|
34
35
|
lifetime: int,
|
|
35
|
-
vo: str =
|
|
36
|
+
vo: str = DEFAULT_VO,
|
|
36
37
|
) -> str:
|
|
37
38
|
"""
|
|
38
39
|
Get a signed URL for a particular service and operation.
|