rucio 37.3.0__py3-none-any.whl → 37.5.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/rule.py +1 -1
- rucio/client/accountclient.py +205 -60
- rucio/client/accountlimitclient.py +84 -25
- rucio/client/baseclient.py +85 -48
- rucio/client/client.py +49 -41
- rucio/client/configclient.py +36 -13
- rucio/client/credentialclient.py +16 -6
- rucio/client/didclient.py +321 -133
- rucio/client/diracclient.py +13 -6
- rucio/client/downloadclient.py +435 -165
- rucio/client/exportclient.py +8 -2
- rucio/client/fileclient.py +10 -3
- rucio/client/importclient.py +4 -1
- rucio/client/lifetimeclient.py +48 -31
- rucio/client/lockclient.py +22 -7
- rucio/client/metaconventionsclient.py +59 -21
- rucio/client/pingclient.py +3 -1
- rucio/client/replicaclient.py +213 -96
- rucio/client/requestclient.py +124 -16
- rucio/client/rseclient.py +385 -160
- rucio/client/ruleclient.py +147 -51
- rucio/client/scopeclient.py +35 -10
- rucio/client/subscriptionclient.py +60 -27
- rucio/client/touchclient.py +16 -7
- rucio/common/constants.py +14 -17
- rucio/common/utils.py +18 -2
- rucio/core/permission/generic.py +40 -1
- rucio/core/replica.py +6 -6
- rucio/core/request.py +2 -2
- rucio/core/rule.py +5 -3
- rucio/core/transfer.py +4 -5
- rucio/daemons/conveyor/throttler.py +2 -1
- rucio/daemons/judge/evaluator.py +1 -1
- rucio/db/sqla/constants.py +3 -3
- rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +1 -1
- rucio/db/sqla/models.py +1 -1
- rucio/gateway/replica.py +129 -41
- rucio/gateway/request.py +177 -103
- rucio/gateway/subscription.py +90 -108
- rucio/rse/rsemanager.py +2 -2
- rucio/vcsversion.py +3 -3
- rucio/web/rest/flaskapi/v1/accountlimits.py +22 -22
- rucio/web/rest/flaskapi/v1/accounts.py +157 -157
- rucio/web/rest/flaskapi/v1/archives.py +10 -10
- rucio/web/rest/flaskapi/v1/auth.py +106 -106
- rucio/web/rest/flaskapi/v1/config.py +37 -37
- rucio/web/rest/flaskapi/v1/credentials.py +25 -25
- rucio/web/rest/flaskapi/v1/dids.py +381 -381
- rucio/web/rest/flaskapi/v1/dirac.py +8 -8
- rucio/web/rest/flaskapi/v1/export.py +6 -6
- rucio/web/rest/flaskapi/v1/heartbeats.py +14 -14
- rucio/web/rest/flaskapi/v1/identities.py +25 -25
- rucio/web/rest/flaskapi/v1/import.py +19 -19
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +54 -54
- rucio/web/rest/flaskapi/v1/locks.py +60 -60
- rucio/web/rest/flaskapi/v1/meta_conventions.py +29 -29
- rucio/web/rest/flaskapi/v1/nongrid_traces.py +4 -4
- rucio/web/rest/flaskapi/v1/ping.py +4 -4
- rucio/web/rest/flaskapi/v1/redirect.py +17 -17
- rucio/web/rest/flaskapi/v1/replicas.py +282 -282
- rucio/web/rest/flaskapi/v1/requests.py +424 -229
- rucio/web/rest/flaskapi/v1/rses.py +427 -427
- rucio/web/rest/flaskapi/v1/rules.py +129 -129
- rucio/web/rest/flaskapi/v1/scopes.py +21 -21
- rucio/web/rest/flaskapi/v1/subscriptions.py +122 -122
- rucio/web/rest/flaskapi/v1/traces.py +18 -18
- rucio/web/rest/flaskapi/v1/vos.py +32 -32
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/rucio.cfg.template +0 -1
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -1
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/requirements.server.txt +1 -1
- {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/METADATA +1 -1
- {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/RECORD +128 -128
- {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/WHEEL +1 -1
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/alembic.ini.template +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/tools/bootstrap.py +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/tools/reset_database.py +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-abacus-account +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-abacus-collection-replica +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-abacus-rse +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-admin +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-atropos +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-auditor +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-automatix +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-bb8 +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-cache-client +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-cache-consumer +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-finisher +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-poller +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-preparer +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-receiver +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-stager +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-submitter +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-throttler +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-dark-reaper +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-dumper +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-follower +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-hermes +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-judge-cleaner +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-judge-evaluator +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-judge-injector +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-judge-repairer +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-kronos +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-minos +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-necromancer +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-oauth-manager +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-reaper +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-replica-recoverer +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-rse-decommissioner +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-storage-consistency-actions +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-transmogrifier +0 -0
- {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-undertaker +0 -0
- {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/licenses/LICENSE +0 -0
- {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/top_level.txt +0 -0
rucio/gateway/request.py
CHANGED
|
@@ -19,28 +19,25 @@ Interface for the requests abstraction layer
|
|
|
19
19
|
from typing import TYPE_CHECKING, Any, Optional
|
|
20
20
|
|
|
21
21
|
from rucio.common import exception
|
|
22
|
+
from rucio.common.constants import TransferLimitDirection
|
|
22
23
|
from rucio.common.types import InternalAccount, InternalScope, RequestGatewayDict
|
|
23
24
|
from rucio.common.utils import gateway_update_return_dict
|
|
24
25
|
from rucio.core import request
|
|
25
26
|
from rucio.core.rse import get_rse_id
|
|
26
|
-
from rucio.db.sqla.
|
|
27
|
+
from rucio.db.sqla.constants import DatabaseOperationType
|
|
28
|
+
from rucio.db.sqla.session import db_session
|
|
27
29
|
from rucio.gateway import permission
|
|
28
30
|
|
|
29
31
|
if TYPE_CHECKING:
|
|
30
32
|
from collections.abc import Iterable, Iterator, Sequence
|
|
31
33
|
|
|
32
|
-
from sqlalchemy.orm import Session
|
|
33
|
-
|
|
34
34
|
from rucio.db.sqla.constants import RequestState, RequestType
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
@transactional_session
|
|
38
37
|
def queue_requests(
|
|
39
38
|
requests: "Iterable[RequestGatewayDict]",
|
|
40
39
|
issuer: str,
|
|
41
40
|
vo: str = 'def',
|
|
42
|
-
*,
|
|
43
|
-
session: "Session"
|
|
44
41
|
) -> list[dict[str, Any]]:
|
|
45
42
|
"""
|
|
46
43
|
Submit transfer or deletion requests on destination RSEs for data identifiers.
|
|
@@ -48,32 +45,29 @@ def queue_requests(
|
|
|
48
45
|
:param requests: List of dictionaries containing 'scope', 'name', 'dest_rse_id', 'request_type', 'attributes'
|
|
49
46
|
:param issuer: Issuing account as a string.
|
|
50
47
|
:param vo: The VO to act on.
|
|
51
|
-
:param session: The database session in use.
|
|
52
48
|
:returns: List of Request-IDs as 32 character hex strings
|
|
53
49
|
"""
|
|
54
50
|
|
|
55
51
|
kwargs = {'requests': requests, 'issuer': issuer}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
53
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='queue_requests', kwargs=kwargs, session=session)
|
|
54
|
+
if not auth_result.allowed:
|
|
55
|
+
raise exception.AccessDenied(f'{issuer} can not queue request. {auth_result.message}')
|
|
59
56
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
for req in requests:
|
|
58
|
+
req['scope'] = InternalScope(req['scope'], vo=vo) # type: ignore (type reassignment)
|
|
59
|
+
if 'account' in req:
|
|
60
|
+
req['account'] = InternalAccount(req['account'], vo=vo) # type: ignore (type reassignment)
|
|
64
61
|
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
new_requests = request.queue_requests(requests, session=session)
|
|
63
|
+
return [gateway_update_return_dict(r, session=session) for r in new_requests]
|
|
67
64
|
|
|
68
65
|
|
|
69
|
-
@transactional_session
|
|
70
66
|
def cancel_request(
|
|
71
67
|
request_id: str,
|
|
72
68
|
issuer: str,
|
|
73
69
|
account: str,
|
|
74
70
|
vo: str = 'def',
|
|
75
|
-
*,
|
|
76
|
-
session: "Session"
|
|
77
71
|
) -> None:
|
|
78
72
|
"""
|
|
79
73
|
Cancel a request.
|
|
@@ -82,18 +76,17 @@ def cancel_request(
|
|
|
82
76
|
:param issuer: Issuing account as a string.
|
|
83
77
|
:param account: Account identifier as a string.
|
|
84
78
|
:param vo: The VO to act on.
|
|
85
|
-
:param session: The database session in use.
|
|
86
79
|
"""
|
|
87
80
|
|
|
88
81
|
kwargs = {'account': account, 'issuer': issuer, 'request_id': request_id}
|
|
89
|
-
|
|
82
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
83
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='cancel_request_', kwargs=kwargs, session=session)
|
|
90
84
|
if not auth_result.allowed:
|
|
91
85
|
raise exception.AccessDenied('%s cannot cancel request %s. %s' % (account, request_id, auth_result.message))
|
|
92
86
|
|
|
93
87
|
raise NotImplementedError
|
|
94
88
|
|
|
95
89
|
|
|
96
|
-
@transactional_session
|
|
97
90
|
def cancel_request_did(
|
|
98
91
|
scope: str,
|
|
99
92
|
name: str,
|
|
@@ -102,8 +95,6 @@ def cancel_request_did(
|
|
|
102
95
|
issuer: str,
|
|
103
96
|
account: str,
|
|
104
97
|
vo: str = 'def',
|
|
105
|
-
*,
|
|
106
|
-
session: "Session"
|
|
107
98
|
) -> dict[str, Any]:
|
|
108
99
|
"""
|
|
109
100
|
Cancel a request based on a DID and request type.
|
|
@@ -115,29 +106,26 @@ def cancel_request_did(
|
|
|
115
106
|
:param issuer: Issuing account as a string.
|
|
116
107
|
:param account: Account identifier as a string.
|
|
117
108
|
:param vo: The VO to act on.
|
|
118
|
-
:param session: The database session in use.
|
|
119
109
|
"""
|
|
120
110
|
|
|
121
|
-
|
|
111
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
112
|
+
dest_rse_id = get_rse_id(rse=dest_rse, vo=vo, session=session)
|
|
122
113
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
114
|
+
kwargs = {'account': account, 'issuer': issuer}
|
|
115
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='cancel_request_did', kwargs=kwargs, session=session)
|
|
116
|
+
if not auth_result.allowed:
|
|
117
|
+
raise exception.AccessDenied(f'{account} cannot cancel {request_type} request for {scope}:{name}. {auth_result.message}')
|
|
127
118
|
|
|
128
|
-
|
|
129
|
-
|
|
119
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
120
|
+
return request.cancel_request_did(internal_scope, name, dest_rse_id, request_type, session=session)
|
|
130
121
|
|
|
131
122
|
|
|
132
|
-
@transactional_session
|
|
133
123
|
def get_next(
|
|
134
124
|
request_type: "RequestType",
|
|
135
125
|
state: "RequestState",
|
|
136
126
|
issuer: str,
|
|
137
127
|
account: str,
|
|
138
128
|
vo: str = 'def',
|
|
139
|
-
*,
|
|
140
|
-
session: "Session"
|
|
141
129
|
) -> list[dict[str, Any]]:
|
|
142
130
|
"""
|
|
143
131
|
Retrieve the next request matching the request type and state.
|
|
@@ -147,28 +135,26 @@ def get_next(
|
|
|
147
135
|
:param issuer: Issuing account as a string.
|
|
148
136
|
:param account: Account identifier as a string.
|
|
149
137
|
:param vo: The VO to act on.
|
|
150
|
-
:param session: The database session in use.
|
|
151
138
|
:returns: Request as a dictionary.
|
|
152
139
|
"""
|
|
153
140
|
|
|
154
141
|
kwargs = {'account': account, 'issuer': issuer, 'request_type': request_type, 'state': state}
|
|
155
|
-
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_next', kwargs=kwargs, session=session)
|
|
156
|
-
if not auth_result.allowed:
|
|
157
|
-
raise exception.AccessDenied(f'{account} cannot get the next request of type {request_type} in state {state}. {auth_result.message}')
|
|
158
142
|
|
|
159
|
-
|
|
160
|
-
|
|
143
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
144
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_next', kwargs=kwargs, session=session)
|
|
145
|
+
if not auth_result.allowed:
|
|
146
|
+
raise exception.AccessDenied(f'{account} cannot get the next request of type {request_type} in state {state}. {auth_result.message}')
|
|
147
|
+
|
|
148
|
+
reqs = request.get_and_mark_next(request_type, state, session=session)
|
|
149
|
+
return [gateway_update_return_dict(r, session=session) for r in reqs]
|
|
161
150
|
|
|
162
151
|
|
|
163
|
-
@read_session
|
|
164
152
|
def get_request_by_did(
|
|
165
153
|
scope: str,
|
|
166
154
|
name: str,
|
|
167
155
|
rse: str,
|
|
168
156
|
issuer: str,
|
|
169
157
|
vo: str = 'def',
|
|
170
|
-
*,
|
|
171
|
-
session: "Session"
|
|
172
158
|
) -> dict[str, Any]:
|
|
173
159
|
"""
|
|
174
160
|
Retrieve a request by its DID for a destination RSE.
|
|
@@ -178,31 +164,28 @@ def get_request_by_did(
|
|
|
178
164
|
:param rse: The destination RSE of the request as a string.
|
|
179
165
|
:param issuer: Issuing account as a string.
|
|
180
166
|
:param vo: The VO to act on.
|
|
181
|
-
:param session: The database session in use.
|
|
182
167
|
:returns: Request as a dictionary.
|
|
183
168
|
"""
|
|
184
|
-
|
|
169
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
170
|
+
rse_id = get_rse_id(rse=rse, vo=vo, session=session)
|
|
185
171
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
172
|
+
kwargs = {'scope': scope, 'name': name, 'rse': rse, 'rse_id': rse_id, 'issuer': issuer}
|
|
173
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_by_did', kwargs=kwargs, session=session)
|
|
174
|
+
if not auth_result.allowed:
|
|
175
|
+
raise exception.AccessDenied(f'{issuer} cannot retrieve the request DID {scope}:{name} to RSE {rse}. {auth_result.message}')
|
|
190
176
|
|
|
191
|
-
|
|
192
|
-
|
|
177
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
178
|
+
req = request.get_request_by_did(internal_scope, name, rse_id, session=session)
|
|
193
179
|
|
|
194
|
-
|
|
180
|
+
return gateway_update_return_dict(req, session=session)
|
|
195
181
|
|
|
196
182
|
|
|
197
|
-
@read_session
|
|
198
183
|
def get_request_history_by_did(
|
|
199
184
|
scope: str,
|
|
200
185
|
name: str,
|
|
201
186
|
rse: str,
|
|
202
187
|
issuer: str,
|
|
203
188
|
vo: str = 'def',
|
|
204
|
-
*,
|
|
205
|
-
session: "Session"
|
|
206
189
|
) -> dict[str, Any]:
|
|
207
190
|
"""
|
|
208
191
|
Retrieve a historical request by its DID for a destination RSE.
|
|
@@ -212,31 +195,28 @@ def get_request_history_by_did(
|
|
|
212
195
|
:param rse: The destination RSE of the request as a string.
|
|
213
196
|
:param issuer: Issuing account as a string.
|
|
214
197
|
:param vo: The VO to act on.
|
|
215
|
-
:param session: The database session in use.
|
|
216
198
|
:returns: Request as a dictionary.
|
|
217
199
|
"""
|
|
218
|
-
|
|
200
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
201
|
+
rse_id = get_rse_id(rse=rse, vo=vo, session=session)
|
|
219
202
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
203
|
+
kwargs = {'scope': scope, 'name': name, 'rse': rse, 'rse_id': rse_id, 'issuer': issuer}
|
|
204
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_history_by_did', kwargs=kwargs, session=session)
|
|
205
|
+
if not auth_result.allowed:
|
|
206
|
+
raise exception.AccessDenied(f'{issuer} cannot retrieve the request DID {scope}:{name} to RSE {rse}. {auth_result.message}')
|
|
224
207
|
|
|
225
|
-
|
|
226
|
-
|
|
208
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
209
|
+
req = request.get_request_history_by_did(internal_scope, name, rse_id, session=session)
|
|
227
210
|
|
|
228
|
-
|
|
211
|
+
return gateway_update_return_dict(req, session=session)
|
|
229
212
|
|
|
230
213
|
|
|
231
|
-
@stream_session
|
|
232
214
|
def list_requests(
|
|
233
215
|
src_rses: "Iterable[str]",
|
|
234
216
|
dst_rses: "Iterable[str]",
|
|
235
217
|
states: "Sequence[RequestState]",
|
|
236
218
|
issuer: str,
|
|
237
219
|
vo: str = 'def',
|
|
238
|
-
*,
|
|
239
|
-
session: "Session"
|
|
240
220
|
) -> "Iterator[dict[str, Any]]":
|
|
241
221
|
"""
|
|
242
222
|
List all requests in a specific state from a source RSE to a destination RSE.
|
|
@@ -245,22 +225,21 @@ def list_requests(
|
|
|
245
225
|
:param dst_rses: destination RSEs.
|
|
246
226
|
:param states: list of request states.
|
|
247
227
|
:param issuer: Issuing account as a string.
|
|
248
|
-
:param session: The database session in use.
|
|
249
228
|
"""
|
|
250
|
-
|
|
251
|
-
|
|
229
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
230
|
+
src_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in src_rses]
|
|
231
|
+
dst_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in dst_rses]
|
|
252
232
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
233
|
+
kwargs = {'src_rse_id': src_rse_ids, 'dst_rse_id': dst_rse_ids, 'issuer': issuer}
|
|
234
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='list_requests', kwargs=kwargs, session=session)
|
|
235
|
+
if not auth_result.allowed:
|
|
236
|
+
raise exception.AccessDenied(f'{issuer} cannot list requests from RSEs {src_rses} to RSEs {dst_rses}. {auth_result.message}')
|
|
257
237
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
238
|
+
for req in request.list_requests(src_rse_ids, dst_rse_ids, states, session=session):
|
|
239
|
+
req = req.to_dict()
|
|
240
|
+
yield gateway_update_return_dict(req, session=session)
|
|
261
241
|
|
|
262
242
|
|
|
263
|
-
@stream_session
|
|
264
243
|
def list_requests_history(
|
|
265
244
|
src_rses: "Iterable[str]",
|
|
266
245
|
dst_rses: "Iterable[str]",
|
|
@@ -269,8 +248,6 @@ def list_requests_history(
|
|
|
269
248
|
vo: str = 'def',
|
|
270
249
|
offset: Optional[int] = None,
|
|
271
250
|
limit: Optional[int] = None,
|
|
272
|
-
*,
|
|
273
|
-
session: "Session"
|
|
274
251
|
) -> "Iterator[dict[str, Any]]":
|
|
275
252
|
"""
|
|
276
253
|
List all historical requests in a specific state from a source RSE to a destination RSE.
|
|
@@ -280,22 +257,21 @@ def list_requests_history(
|
|
|
280
257
|
:param issuer: Issuing account as a string.
|
|
281
258
|
:param offset: offset (for paging).
|
|
282
259
|
:param limit: limit number of results.
|
|
283
|
-
:param session: The database session in use.
|
|
284
260
|
"""
|
|
285
|
-
|
|
286
|
-
|
|
261
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
262
|
+
src_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in src_rses]
|
|
263
|
+
dst_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in dst_rses]
|
|
287
264
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
265
|
+
kwargs = {'src_rse_id': src_rse_ids, 'dst_rse_id': dst_rse_ids, 'issuer': issuer}
|
|
266
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='list_requests_history', kwargs=kwargs, session=session)
|
|
267
|
+
if not auth_result.allowed:
|
|
268
|
+
raise exception.AccessDenied(f'{issuer} cannot list requests from RSEs {src_rses} to RSEs {dst_rses}. {auth_result.message}')
|
|
292
269
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
270
|
+
for req in request.list_requests_history(src_rse_ids, dst_rse_ids, states, offset, limit, session=session):
|
|
271
|
+
req = req.to_dict()
|
|
272
|
+
yield gateway_update_return_dict(req, session=session)
|
|
296
273
|
|
|
297
274
|
|
|
298
|
-
@read_session
|
|
299
275
|
def get_request_metrics(
|
|
300
276
|
src_rse: Optional[str],
|
|
301
277
|
dst_rse: Optional[str],
|
|
@@ -303,8 +279,6 @@ def get_request_metrics(
|
|
|
303
279
|
group_by_rse_attribute: Optional[str],
|
|
304
280
|
issuer: str,
|
|
305
281
|
vo: str = 'def',
|
|
306
|
-
*,
|
|
307
|
-
session: "Session"
|
|
308
282
|
) -> dict[str, Any]:
|
|
309
283
|
"""
|
|
310
284
|
Get statistics of requests in a specific state grouped by source RSE, destination RSE, and activity.
|
|
@@ -314,17 +288,117 @@ def get_request_metrics(
|
|
|
314
288
|
:param activity: activity
|
|
315
289
|
:param group_by_rse_attribute: The parameter to group the RSEs by.
|
|
316
290
|
:param issuer: Issuing account as a string.
|
|
317
|
-
:param session: The database session in use.
|
|
318
291
|
"""
|
|
319
292
|
src_rse_id = None
|
|
320
|
-
if src_rse:
|
|
321
|
-
src_rse_id = get_rse_id(rse=src_rse, vo=vo, session=session)
|
|
322
293
|
dst_rse_id = None
|
|
323
|
-
if dst_rse:
|
|
324
|
-
dst_rse_id = get_rse_id(rse=dst_rse, vo=vo, session=session)
|
|
325
294
|
kwargs = {'issuer': issuer}
|
|
326
|
-
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_metrics', kwargs=kwargs, session=session)
|
|
327
|
-
if not auth_result.allowed:
|
|
328
|
-
raise exception.AccessDenied(f'{issuer} cannot get request statistics. {auth_result.message}')
|
|
329
295
|
|
|
330
|
-
|
|
296
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
297
|
+
if src_rse:
|
|
298
|
+
src_rse_id = get_rse_id(rse=src_rse, vo=vo, session=session)
|
|
299
|
+
|
|
300
|
+
if dst_rse:
|
|
301
|
+
dst_rse_id = get_rse_id(rse=dst_rse, vo=vo, session=session)
|
|
302
|
+
|
|
303
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_metrics', kwargs=kwargs, session=session)
|
|
304
|
+
if not auth_result.allowed:
|
|
305
|
+
raise exception.AccessDenied(f'{issuer} cannot get request statistics. {auth_result.message}')
|
|
306
|
+
|
|
307
|
+
return request.get_request_metrics(dest_rse_id=dst_rse_id, src_rse_id=src_rse_id, activity=activity, group_by_rse_attribute=group_by_rse_attribute, session=session)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def list_transfer_limits(
|
|
311
|
+
issuer: str,
|
|
312
|
+
vo: str = 'def'
|
|
313
|
+
) -> "Iterator[dict[str, Any]]":
|
|
314
|
+
"""
|
|
315
|
+
List all the transfer limits.
|
|
316
|
+
|
|
317
|
+
:param issuer: Issuing account as a string.
|
|
318
|
+
:param session: The database session in use.
|
|
319
|
+
|
|
320
|
+
:returns: The list of transfer limits
|
|
321
|
+
"""
|
|
322
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
323
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='list_transfer_limits', kwargs={}, session=session)
|
|
324
|
+
if not auth_result.allowed:
|
|
325
|
+
raise exception.AccessDenied(f'{issuer} cannot list transfer limits. {auth_result.message}')
|
|
326
|
+
|
|
327
|
+
return request.list_transfer_limits(session=session)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def set_transfer_limit(
|
|
331
|
+
issuer: str,
|
|
332
|
+
rse_expression: str,
|
|
333
|
+
activity: Optional[str] = None,
|
|
334
|
+
direction: TransferLimitDirection = TransferLimitDirection.DESTINATION,
|
|
335
|
+
max_transfers: Optional[int] = None,
|
|
336
|
+
volume: Optional[int] = None,
|
|
337
|
+
deadline: Optional[int] = None,
|
|
338
|
+
strategy: Optional[str] = None,
|
|
339
|
+
transfers: Optional[int] = None,
|
|
340
|
+
waitings: Optional[int] = None,
|
|
341
|
+
vo: str = 'def'
|
|
342
|
+
) -> None:
|
|
343
|
+
"""
|
|
344
|
+
Create or update a transfer limit
|
|
345
|
+
|
|
346
|
+
:param issuer: Issuing account as a string.
|
|
347
|
+
:param vo: The VO to act on.
|
|
348
|
+
:param rse_expression: RSE expression for which the transfer limit applies.
|
|
349
|
+
:param activity: The activity for which the transfer limit applies.
|
|
350
|
+
:param direction: The direction in which this limit applies (source/destination)
|
|
351
|
+
:param max_transfers: Maximum transfers.
|
|
352
|
+
:param volume: Maximum transfer volume in bytes.
|
|
353
|
+
:param deadline: Maximum waiting time in hours until a datasets gets released.
|
|
354
|
+
:param strategy: defines how to handle datasets: `fifo` (each file released separately) or `grouped_fifo` (wait for the entire dataset to fit)
|
|
355
|
+
:param transfers: Current number of active transfers
|
|
356
|
+
:param waitings: Current number of waiting transfers
|
|
357
|
+
:param session: The database session in use.
|
|
358
|
+
|
|
359
|
+
:returns: None
|
|
360
|
+
"""
|
|
361
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
362
|
+
kwargs = {'rse_expression': rse_expression, 'activity': activity, 'max_transfers': max_transfers}
|
|
363
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='set_transfer_limit', kwargs=kwargs, session=session)
|
|
364
|
+
if not auth_result.allowed:
|
|
365
|
+
raise exception.AccessDenied(f'{issuer} cannot set transfer limits. {auth_result.message}')
|
|
366
|
+
|
|
367
|
+
request.set_transfer_limit(rse_expression=rse_expression,
|
|
368
|
+
activity=activity,
|
|
369
|
+
direction=direction,
|
|
370
|
+
max_transfers=max_transfers,
|
|
371
|
+
volume=volume,
|
|
372
|
+
deadline=deadline,
|
|
373
|
+
strategy=strategy,
|
|
374
|
+
transfers=transfers,
|
|
375
|
+
waitings=waitings)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def delete_transfer_limit(
|
|
379
|
+
issuer: str,
|
|
380
|
+
rse_expression: str,
|
|
381
|
+
activity: Optional[str] = None,
|
|
382
|
+
direction: TransferLimitDirection = TransferLimitDirection.DESTINATION,
|
|
383
|
+
vo: str = 'def'
|
|
384
|
+
) -> None:
|
|
385
|
+
"""
|
|
386
|
+
Delete a transfer limit
|
|
387
|
+
|
|
388
|
+
:param issuer: Issuing account as a string.
|
|
389
|
+
:param vo: The VO to act on.
|
|
390
|
+
:param rse_expression: RSE expression for which the transfer limit applies.
|
|
391
|
+
:param activity: The activity for which the transfer limit applies.
|
|
392
|
+
:param direction: The direction in which this limit applies (source/destination)
|
|
393
|
+
:param session: The database session in use.
|
|
394
|
+
"""
|
|
395
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
396
|
+
kwargs = {'rse_expression': rse_expression, 'activity': activity}
|
|
397
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='delete_transfer_limit', kwargs=kwargs, session=session)
|
|
398
|
+
if not auth_result.allowed:
|
|
399
|
+
raise exception.AccessDenied(f'{issuer} cannot delete transfer limits. {auth_result.message}')
|
|
400
|
+
|
|
401
|
+
request.delete_transfer_limit(rse_expression=rse_expression,
|
|
402
|
+
activity=activity,
|
|
403
|
+
direction=direction,
|
|
404
|
+
session=session)
|