rucio 37.3.0__py3-none-any.whl → 37.4.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 +123 -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/core/permission/generic.py +37 -1
- rucio/core/replica.py +5 -5
- rucio/core/rule.py +5 -3
- rucio/daemons/judge/evaluator.py +1 -1
- rucio/gateway/replica.py +129 -41
- rucio/gateway/request.py +176 -103
- rucio/gateway/subscription.py +90 -108
- rucio/vcsversion.py +3 -3
- rucio/web/rest/flaskapi/v1/redirect.py +1 -1
- rucio/web/rest/flaskapi/v1/replicas.py +1 -1
- rucio/web/rest/flaskapi/v1/requests.py +211 -20
- rucio/web/rest/flaskapi/v1/subscriptions.py +9 -9
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/rucio.cfg.template +0 -1
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -1
- {rucio-37.3.0.dist-info → rucio-37.4.0.dist-info}/METADATA +1 -1
- {rucio-37.3.0.dist-info → rucio-37.4.0.dist-info}/RECORD +97 -97
- {rucio-37.3.0.dist-info → rucio-37.4.0.dist-info}/WHEEL +1 -1
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/alembic.ini.template +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/requirements.server.txt +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/tools/bootstrap.py +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/data/rucio/tools/reset_database.py +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-abacus-account +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-abacus-collection-replica +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-abacus-rse +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-admin +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-atropos +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-auditor +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-automatix +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-bb8 +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-cache-client +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-cache-consumer +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-finisher +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-poller +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-preparer +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-receiver +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-stager +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-submitter +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-throttler +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-dark-reaper +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-dumper +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-follower +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-hermes +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-judge-cleaner +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-judge-evaluator +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-judge-injector +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-judge-repairer +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-kronos +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-minos +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-necromancer +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-oauth-manager +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-reaper +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-replica-recoverer +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-rse-decommissioner +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-storage-consistency-actions +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-transmogrifier +0 -0
- {rucio-37.3.0.data → rucio-37.4.0.data}/scripts/rucio-undertaker +0 -0
- {rucio-37.3.0.dist-info → rucio-37.4.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {rucio-37.3.0.dist-info → rucio-37.4.0.dist-info}/licenses/LICENSE +0 -0
- {rucio-37.3.0.dist-info → rucio-37.4.0.dist-info}/top_level.txt +0 -0
rucio/gateway/subscription.py
CHANGED
|
@@ -20,19 +20,17 @@ from rucio.common.exception import AccessDenied, InvalidObject
|
|
|
20
20
|
from rucio.common.schema import validate_schema
|
|
21
21
|
from rucio.common.types import InternalAccount, InternalScope
|
|
22
22
|
from rucio.core import subscription
|
|
23
|
-
from rucio.db.sqla.
|
|
23
|
+
from rucio.db.sqla.constants import DatabaseOperationType
|
|
24
|
+
from rucio.db.sqla.session import db_session
|
|
24
25
|
from rucio.gateway.permission import has_permission
|
|
25
26
|
|
|
26
27
|
if TYPE_CHECKING:
|
|
27
28
|
from collections.abc import Iterator
|
|
28
29
|
|
|
29
|
-
from sqlalchemy.orm import Session
|
|
30
|
-
|
|
31
30
|
|
|
32
31
|
SubscriptionRuleState = namedtuple('SubscriptionRuleState', ['account', 'name', 'state', 'count'])
|
|
33
32
|
|
|
34
33
|
|
|
35
|
-
@transactional_session
|
|
36
34
|
def add_subscription(
|
|
37
35
|
name: str,
|
|
38
36
|
account: str,
|
|
@@ -42,11 +40,9 @@ def add_subscription(
|
|
|
42
40
|
lifetime: Union[int, Literal[False]],
|
|
43
41
|
retroactive: bool,
|
|
44
42
|
dry_run: bool,
|
|
43
|
+
issuer: str,
|
|
45
44
|
priority: Optional[int] = None,
|
|
46
|
-
issuer: Optional[str] = None,
|
|
47
45
|
vo: str = 'def',
|
|
48
|
-
*,
|
|
49
|
-
session: "Session"
|
|
50
46
|
) -> str:
|
|
51
47
|
"""
|
|
52
48
|
Adds a new subscription which will be verified against every new added file and dataset
|
|
@@ -63,53 +59,50 @@ def add_subscription(
|
|
|
63
59
|
:param priority: The priority of the subscription
|
|
64
60
|
:param issuer: The account issuing this operation.
|
|
65
61
|
:param vo: The VO to act on.
|
|
66
|
-
:param session: The database session in use.
|
|
67
62
|
:returns: subscription_id
|
|
68
63
|
"""
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
raise InvalidObject('You must specify a rule')
|
|
85
|
-
except ValueError as error:
|
|
86
|
-
raise TypeError(error)
|
|
87
|
-
|
|
88
|
-
internal_account = InternalAccount(account, vo=vo)
|
|
89
|
-
|
|
90
|
-
keys = ['scope', 'account']
|
|
91
|
-
types = [InternalScope, InternalAccount]
|
|
92
|
-
for _key, _type in zip(keys, types):
|
|
93
|
-
if _key in filter_:
|
|
94
|
-
if isinstance(filter_[_key], list):
|
|
95
|
-
filter_[_key] = [_type(val, vo=vo).internal for val in filter_[_key]]
|
|
64
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
65
|
+
auth_result = has_permission(issuer=issuer, vo=vo, action='add_subscription', kwargs={'account': account}, session=session)
|
|
66
|
+
if not auth_result.allowed:
|
|
67
|
+
raise AccessDenied('Account %s can not add subscription. %s' % (issuer, auth_result.message))
|
|
68
|
+
try:
|
|
69
|
+
if filter_:
|
|
70
|
+
if not isinstance(filter_, dict):
|
|
71
|
+
raise TypeError('filter should be a dict')
|
|
72
|
+
validate_schema(name='subscription_filter', obj=filter_, vo=vo)
|
|
73
|
+
if replication_rules:
|
|
74
|
+
if not isinstance(replication_rules, list):
|
|
75
|
+
raise TypeError('replication_rules should be a list')
|
|
76
|
+
else:
|
|
77
|
+
for rule in replication_rules:
|
|
78
|
+
validate_schema(name='activity', obj=rule.get('activity', 'default'), vo=vo)
|
|
96
79
|
else:
|
|
97
|
-
|
|
80
|
+
raise InvalidObject('You must specify a rule')
|
|
81
|
+
except ValueError as error:
|
|
82
|
+
raise TypeError(error)
|
|
83
|
+
|
|
84
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
85
|
+
|
|
86
|
+
keys = ['scope', 'account']
|
|
87
|
+
types = [InternalScope, InternalAccount]
|
|
88
|
+
for _key, _type in zip(keys, types):
|
|
89
|
+
if _key in filter_:
|
|
90
|
+
if isinstance(filter_[_key], list):
|
|
91
|
+
filter_[_key] = [_type(val, vo=vo).internal for val in filter_[_key]]
|
|
92
|
+
else:
|
|
93
|
+
filter_[_key] = _type(filter_[_key], vo=vo).internal
|
|
98
94
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
95
|
+
return subscription.add_subscription(name=name, account=internal_account, filter_=dumps(filter_), replication_rules=dumps(replication_rules),
|
|
96
|
+
comments=comments, lifetime=lifetime, retroactive=retroactive, dry_run=dry_run, priority=priority,
|
|
97
|
+
session=session)
|
|
102
98
|
|
|
103
99
|
|
|
104
|
-
@transactional_session
|
|
105
100
|
def update_subscription(
|
|
106
101
|
name: str,
|
|
107
102
|
account: str,
|
|
103
|
+
issuer: str,
|
|
108
104
|
metadata: Optional[dict[str, Any]] = None,
|
|
109
|
-
issuer: Optional[str] = None,
|
|
110
105
|
vo: str = 'def',
|
|
111
|
-
*,
|
|
112
|
-
session: "Session"
|
|
113
106
|
) -> None:
|
|
114
107
|
"""
|
|
115
108
|
Updates a subscription
|
|
@@ -119,53 +112,50 @@ def update_subscription(
|
|
|
119
112
|
:param metadata: Dictionary of metadata to update. Supported keys : filter, replication_rules, comments, lifetime, retroactive, dry_run, priority, last_processed
|
|
120
113
|
:param issuer: The account issuing this operation.
|
|
121
114
|
:param vo: The VO to act on.
|
|
122
|
-
:param session: The database session in use.
|
|
123
115
|
:raises: SubscriptionNotFound if subscription is not found
|
|
124
116
|
"""
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
117
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
118
|
+
auth_result = has_permission(issuer=issuer, vo=vo, action='update_subscription', kwargs={'account': account}, session=session)
|
|
119
|
+
if not auth_result.allowed:
|
|
120
|
+
raise AccessDenied('Account %s can not update subscription. %s' % (issuer, auth_result.message))
|
|
121
|
+
try:
|
|
122
|
+
if not isinstance(metadata, dict):
|
|
123
|
+
raise TypeError('metadata should be a dict')
|
|
124
|
+
if 'filter' in metadata and metadata['filter']:
|
|
125
|
+
if not isinstance(metadata['filter'], dict):
|
|
126
|
+
raise TypeError('filter should be a dict')
|
|
127
|
+
validate_schema(name='subscription_filter', obj=metadata['filter'], vo=vo)
|
|
128
|
+
if 'replication_rules' in metadata and metadata['replication_rules']:
|
|
129
|
+
if not isinstance(metadata['replication_rules'], list):
|
|
130
|
+
raise TypeError('replication_rules should be a list')
|
|
131
|
+
else:
|
|
132
|
+
for rule in metadata['replication_rules']:
|
|
133
|
+
validate_schema(name='activity', obj=rule.get('activity', 'default'), vo=vo)
|
|
134
|
+
except ValueError as error:
|
|
135
|
+
raise TypeError(error)
|
|
143
136
|
|
|
144
|
-
|
|
137
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
145
138
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
139
|
+
if 'filter' in metadata and metadata['filter'] is not None:
|
|
140
|
+
filter_ = metadata['filter']
|
|
141
|
+
keys = ['scope', 'account']
|
|
142
|
+
types = [InternalScope, InternalAccount]
|
|
150
143
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
144
|
+
for _key, _type in zip(keys, types):
|
|
145
|
+
if _key in filter_ and filter_[_key] is not None:
|
|
146
|
+
if isinstance(filter_[_key], list):
|
|
147
|
+
filter_[_key] = [_type(val, vo=vo).internal for val in filter_[_key]]
|
|
148
|
+
else:
|
|
149
|
+
filter_[_key] = _type(filter_[_key], vo=vo).internal
|
|
157
150
|
|
|
158
|
-
|
|
151
|
+
return subscription.update_subscription(name=name, account=internal_account, metadata=metadata, session=session)
|
|
159
152
|
|
|
160
153
|
|
|
161
|
-
@stream_session
|
|
162
154
|
def list_subscriptions(
|
|
163
155
|
name: Optional[str] = None,
|
|
164
156
|
account: Optional[str] = None,
|
|
165
157
|
state: Optional[str] = None,
|
|
166
158
|
vo: str = 'def',
|
|
167
|
-
*,
|
|
168
|
-
session: "Session"
|
|
169
159
|
) -> 'Iterator[dict[str, Any]]':
|
|
170
160
|
"""
|
|
171
161
|
Returns a dictionary with the subscription information :
|
|
@@ -175,7 +165,6 @@ def list_subscriptions(
|
|
|
175
165
|
:param account: Account identifier
|
|
176
166
|
:param state: Filter for subscription state
|
|
177
167
|
:param vo: The VO to act on.
|
|
178
|
-
:param session: The database session in use.
|
|
179
168
|
:returns: Dictionary containing subscription parameter
|
|
180
169
|
:raises: exception.NotFound if subscription is not found
|
|
181
170
|
"""
|
|
@@ -185,85 +174,78 @@ def list_subscriptions(
|
|
|
185
174
|
else:
|
|
186
175
|
internal_account = InternalAccount('*', vo=vo)
|
|
187
176
|
|
|
188
|
-
|
|
177
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
178
|
+
subs = subscription.list_subscriptions(name, internal_account, state, session=session)
|
|
189
179
|
|
|
190
|
-
|
|
191
|
-
|
|
180
|
+
for sub in subs:
|
|
181
|
+
sub['account'] = sub['account'].external
|
|
192
182
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
183
|
+
if 'filter' in sub:
|
|
184
|
+
fil = loads(sub['filter'])
|
|
185
|
+
if 'account' in fil:
|
|
186
|
+
fil['account'] = [InternalAccount(acc, from_external=False).external for acc in fil['account']]
|
|
187
|
+
if 'scope' in fil:
|
|
188
|
+
fil['scope'] = [InternalScope(sco, from_external=False).external for sco in fil['scope']]
|
|
189
|
+
sub['filter'] = dumps(fil)
|
|
200
190
|
|
|
201
|
-
|
|
191
|
+
yield sub
|
|
202
192
|
|
|
203
193
|
|
|
204
|
-
@stream_session
|
|
205
194
|
def list_subscription_rule_states(
|
|
206
195
|
name: Optional[str] = None,
|
|
207
196
|
account: Optional[str] = None,
|
|
208
197
|
vo: str = 'def',
|
|
209
|
-
*,
|
|
210
|
-
session: "Session"
|
|
211
198
|
) -> 'Iterator[SubscriptionRuleState]':
|
|
212
199
|
"""Returns a list of with the number of rules per state for a subscription.
|
|
213
200
|
|
|
214
201
|
:param name: Name of the subscription
|
|
215
202
|
:param account: Account identifier
|
|
216
203
|
:param vo: The VO to act on.
|
|
217
|
-
:param session: The database session in use.
|
|
218
204
|
:returns: Sequence with SubscriptionRuleState named tuples (account, name, state, count)
|
|
219
205
|
"""
|
|
220
206
|
if account is not None:
|
|
221
207
|
internal_account = InternalAccount(account, vo=vo)
|
|
222
208
|
else:
|
|
223
209
|
internal_account = InternalAccount('*', vo=vo)
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
210
|
+
|
|
211
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
212
|
+
subs = subscription.list_subscription_rule_states(name, internal_account, session=session)
|
|
213
|
+
|
|
214
|
+
for sub in subs:
|
|
215
|
+
# sub is an immutable Row so return new named tuple with edited entries
|
|
216
|
+
d = sub._asdict()
|
|
217
|
+
d['account'] = d['account'].external
|
|
218
|
+
yield SubscriptionRuleState(**d)
|
|
230
219
|
|
|
231
220
|
|
|
232
|
-
@transactional_session
|
|
233
221
|
def delete_subscription(
|
|
234
222
|
subscription_id: str,
|
|
235
223
|
vo: str = 'def',
|
|
236
|
-
*,
|
|
237
|
-
session: "Session"
|
|
238
224
|
) -> None:
|
|
239
225
|
"""
|
|
240
226
|
Deletes a subscription
|
|
241
227
|
|
|
242
228
|
:param subscription_id: Subscription identifier
|
|
243
229
|
:param vo: The VO of the user issuing command
|
|
244
|
-
:param session: The database session in use.
|
|
245
230
|
"""
|
|
246
231
|
|
|
247
232
|
raise NotImplementedError
|
|
248
233
|
|
|
249
234
|
|
|
250
|
-
@read_session
|
|
251
235
|
def get_subscription_by_id(
|
|
252
236
|
subscription_id: str,
|
|
253
237
|
vo: str = 'def',
|
|
254
|
-
*,
|
|
255
|
-
session: "Session"
|
|
256
238
|
) -> dict[str, Any]:
|
|
257
239
|
"""
|
|
258
240
|
Get a specific subscription by id.
|
|
259
241
|
|
|
260
242
|
:param subscription_id: The subscription_id to select.
|
|
261
243
|
:param vo: The VO of the user issuing command.
|
|
262
|
-
:param session: The database session in use.
|
|
263
244
|
|
|
264
245
|
:raises: SubscriptionNotFound if no Subscription can be found.
|
|
265
246
|
"""
|
|
266
|
-
|
|
247
|
+
with db_session(DatabaseOperationType.READ) as session:
|
|
248
|
+
sub = subscription.get_subscription_by_id(subscription_id, session=session)
|
|
267
249
|
if sub['account'].vo != vo:
|
|
268
250
|
raise AccessDenied('Unable to get subscription')
|
|
269
251
|
|
rucio/vcsversion.py
CHANGED
|
@@ -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': '37.
|
|
7
|
+
'version': '37.4.0',
|
|
8
8
|
'branch_nick': 'release-37',
|
|
9
|
-
'revision_id': '
|
|
10
|
-
'revno':
|
|
9
|
+
'revision_id': '20eed71b1dd6d1d8e550966b7d40ea730a16c7d8',
|
|
10
|
+
'revno': 13754
|
|
11
11
|
}
|
|
@@ -296,7 +296,7 @@ class HeaderRedirector(ErrorHandlingMethodView):
|
|
|
296
296
|
vo = extract_vo(request.headers)
|
|
297
297
|
|
|
298
298
|
replicas = list(
|
|
299
|
-
list_replicas(
|
|
299
|
+
list_replicas(
|
|
300
300
|
dids=[{'scope': scope, 'name': name, 'type': 'FILE'}],
|
|
301
301
|
schemes=schemes,
|
|
302
302
|
client_location=client_location,
|
|
@@ -252,7 +252,7 @@ class Replicas(ErrorHandlingMethodView):
|
|
|
252
252
|
def _list_and_sort_replicas(vo):
|
|
253
253
|
# we need to call list_replicas before starting to reply
|
|
254
254
|
# otherwise the exceptions won't be propagated correctly
|
|
255
|
-
for rfile in list_replicas(dids=dids, schemes=schemes, vo=vo):
|
|
255
|
+
for rfile in list_replicas(dids=dids, schemes=schemes, vo=vo): # type: ignore (pending https://github.com/rucio/rucio/issues/7739)
|
|
256
256
|
replicas = []
|
|
257
257
|
dictreplica = {}
|
|
258
258
|
for rse in rfile['rses']:
|