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/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/rse/rsemanager.py
CHANGED
|
@@ -24,7 +24,7 @@ from rucio.common.checksum import GLOBALLY_SUPPORTED_CHECKSUMS
|
|
|
24
24
|
from rucio.common.config import config_get_int
|
|
25
25
|
from rucio.common.constraints import STRING_TYPES
|
|
26
26
|
from rucio.common.logging import formatted_logger
|
|
27
|
-
from rucio.common.utils import make_valid_did
|
|
27
|
+
from rucio.common.utils import get_transfer_schemas, make_valid_did
|
|
28
28
|
|
|
29
29
|
if TYPE_CHECKING:
|
|
30
30
|
from collections.abc import Callable
|
|
@@ -875,7 +875,7 @@ def __check_compatible_scheme(
|
|
|
875
875
|
|
|
876
876
|
if dest_scheme == src_scheme:
|
|
877
877
|
return True
|
|
878
|
-
if src_scheme in
|
|
878
|
+
if src_scheme in get_transfer_schemas().get(dest_scheme, []):
|
|
879
879
|
return True
|
|
880
880
|
|
|
881
881
|
return False
|
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.5.0',
|
|
8
8
|
'branch_nick': 'release-37',
|
|
9
|
-
'revision_id': '
|
|
10
|
-
'revno':
|
|
9
|
+
'revision_id': '092cfe864848019a987a3a167120cf5cf7df2f61',
|
|
10
|
+
'revno': 13761
|
|
11
11
|
}
|
|
@@ -35,13 +35,13 @@ class LocalAccountLimit(ErrorHandlingMethodView):
|
|
|
35
35
|
parameters:
|
|
36
36
|
- name: account
|
|
37
37
|
in: path
|
|
38
|
-
description: The account for the accountlimit.
|
|
38
|
+
description: "The account for the accountlimit."
|
|
39
39
|
schema:
|
|
40
40
|
type: string
|
|
41
41
|
style: simple
|
|
42
42
|
- name: rse
|
|
43
43
|
in: path
|
|
44
|
-
description: The rse for the accountlimit.
|
|
44
|
+
description: "The rse for the accountlimit."
|
|
45
45
|
schema:
|
|
46
46
|
type: string
|
|
47
47
|
style: simple
|
|
@@ -54,20 +54,20 @@ class LocalAccountLimit(ErrorHandlingMethodView):
|
|
|
54
54
|
- bytes
|
|
55
55
|
properties:
|
|
56
56
|
bytes:
|
|
57
|
-
description: The new limit in bytes.
|
|
57
|
+
description: "The new limit in bytes."
|
|
58
58
|
type: integer
|
|
59
59
|
responses:
|
|
60
60
|
201:
|
|
61
|
-
description: OK
|
|
61
|
+
description: "OK"
|
|
62
62
|
content:
|
|
63
63
|
application/json:
|
|
64
64
|
schema:
|
|
65
65
|
type: string
|
|
66
66
|
enum: ['Created']
|
|
67
67
|
401:
|
|
68
|
-
description: Invalid Auth Token
|
|
68
|
+
description: "Invalid Auth Token"
|
|
69
69
|
404:
|
|
70
|
-
description: No RSE or account found for the given id.
|
|
70
|
+
description: "No RSE or account found for the given id."
|
|
71
71
|
"""
|
|
72
72
|
parameters = json_parameters()
|
|
73
73
|
bytes_param = param_get(parameters, 'bytes')
|
|
@@ -89,23 +89,23 @@ class LocalAccountLimit(ErrorHandlingMethodView):
|
|
|
89
89
|
parameters:
|
|
90
90
|
- name: account
|
|
91
91
|
in: path
|
|
92
|
-
description: The account for the accountlimit.
|
|
92
|
+
description: "The account for the accountlimit."
|
|
93
93
|
schema:
|
|
94
94
|
type: string
|
|
95
95
|
style: simple
|
|
96
96
|
- name: rse
|
|
97
97
|
in: path
|
|
98
|
-
description: The rse for the accountlimit.
|
|
98
|
+
description: "The rse for the accountlimit."
|
|
99
99
|
schema:
|
|
100
100
|
type: string
|
|
101
101
|
style: simple
|
|
102
102
|
responses:
|
|
103
103
|
200:
|
|
104
|
-
description: OK
|
|
104
|
+
description: "OK"
|
|
105
105
|
401:
|
|
106
|
-
description: Invalid Auth Token
|
|
106
|
+
description: "Invalid Auth Token"
|
|
107
107
|
404:
|
|
108
|
-
description: No RSE or account found for the given id.
|
|
108
|
+
description: "No RSE or account found for the given id."
|
|
109
109
|
"""
|
|
110
110
|
try:
|
|
111
111
|
delete_local_account_limit(account=account, rse=rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
@@ -127,13 +127,13 @@ class GlobalAccountLimit(ErrorHandlingMethodView):
|
|
|
127
127
|
parameters:
|
|
128
128
|
- name: account
|
|
129
129
|
in: path
|
|
130
|
-
description: The account for the accountlimit.
|
|
130
|
+
description: "The account for the accountlimit."
|
|
131
131
|
schema:
|
|
132
132
|
type: string
|
|
133
133
|
style: simple
|
|
134
134
|
- name: rse_expression
|
|
135
135
|
in: path
|
|
136
|
-
description: The rse expression for the accountlimit.
|
|
136
|
+
description: "The rse expression for the accountlimit."
|
|
137
137
|
schema:
|
|
138
138
|
type: string
|
|
139
139
|
style: simple
|
|
@@ -146,20 +146,20 @@ class GlobalAccountLimit(ErrorHandlingMethodView):
|
|
|
146
146
|
- bytes
|
|
147
147
|
properties:
|
|
148
148
|
bytes:
|
|
149
|
-
description: The new limit in bytes.
|
|
149
|
+
description: "The new limit in bytes."
|
|
150
150
|
type: integer
|
|
151
151
|
responses:
|
|
152
152
|
201:
|
|
153
|
-
description: OK
|
|
153
|
+
description: "OK"
|
|
154
154
|
content:
|
|
155
155
|
application/json:
|
|
156
156
|
schema:
|
|
157
157
|
type: string
|
|
158
158
|
enum: ['Created']
|
|
159
159
|
401:
|
|
160
|
-
description: Invalid Auth Token
|
|
160
|
+
description: "Invalid Auth Token"
|
|
161
161
|
404:
|
|
162
|
-
description: No RSE or account found for the given id.
|
|
162
|
+
description: "No RSE or account found for the given id."
|
|
163
163
|
"""
|
|
164
164
|
parameters = json_parameters()
|
|
165
165
|
bytes_param = param_get(parameters, 'bytes')
|
|
@@ -187,23 +187,23 @@ class GlobalAccountLimit(ErrorHandlingMethodView):
|
|
|
187
187
|
parameters:
|
|
188
188
|
- name: account
|
|
189
189
|
in: path
|
|
190
|
-
description: The account for the accountlimit.
|
|
190
|
+
description: "The account for the accountlimit."
|
|
191
191
|
schema:
|
|
192
192
|
type: string
|
|
193
193
|
style: simple
|
|
194
194
|
- name: rse_expression
|
|
195
195
|
in: path
|
|
196
|
-
description: The rse expression for the accountlimit.
|
|
196
|
+
description: "The rse expression for the accountlimit."
|
|
197
197
|
schema:
|
|
198
198
|
type: string
|
|
199
199
|
style: simple
|
|
200
200
|
responses:
|
|
201
201
|
200:
|
|
202
|
-
description: OK
|
|
202
|
+
description: "OK"
|
|
203
203
|
401:
|
|
204
|
-
description: Invalid Auth Token
|
|
204
|
+
description: "Invalid Auth Token"
|
|
205
205
|
404:
|
|
206
|
-
description: No RSE or account found for the given id.
|
|
206
|
+
description: "No RSE or account found for the given id."
|
|
207
207
|
"""
|
|
208
208
|
try:
|
|
209
209
|
delete_global_account_limit(account=account, rse_expression=rse_expression, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|