rucio 37.2.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.

Files changed (127) hide show
  1. rucio/cli/rule.py +1 -1
  2. rucio/client/accountclient.py +205 -60
  3. rucio/client/accountlimitclient.py +84 -25
  4. rucio/client/baseclient.py +85 -48
  5. rucio/client/client.py +49 -41
  6. rucio/client/configclient.py +36 -13
  7. rucio/client/credentialclient.py +16 -6
  8. rucio/client/didclient.py +321 -133
  9. rucio/client/diracclient.py +13 -6
  10. rucio/client/downloadclient.py +435 -165
  11. rucio/client/exportclient.py +8 -2
  12. rucio/client/fileclient.py +10 -3
  13. rucio/client/importclient.py +4 -1
  14. rucio/client/lifetimeclient.py +48 -31
  15. rucio/client/lockclient.py +22 -7
  16. rucio/client/metaconventionsclient.py +59 -21
  17. rucio/client/pingclient.py +3 -1
  18. rucio/client/replicaclient.py +213 -96
  19. rucio/client/requestclient.py +123 -16
  20. rucio/client/rseclient.py +385 -160
  21. rucio/client/ruleclient.py +147 -51
  22. rucio/client/scopeclient.py +35 -10
  23. rucio/client/subscriptionclient.py +60 -27
  24. rucio/client/touchclient.py +16 -7
  25. rucio/common/plugins.py +1 -1
  26. rucio/core/did.py +2 -3
  27. rucio/core/permission/generic.py +37 -1
  28. rucio/core/replica.py +6 -6
  29. rucio/core/rule.py +5 -3
  30. rucio/daemons/judge/evaluator.py +1 -1
  31. rucio/db/sqla/util.py +1 -1
  32. rucio/gateway/authentication.py +58 -88
  33. rucio/gateway/config.py +63 -75
  34. rucio/gateway/did.py +245 -329
  35. rucio/gateway/dirac.py +33 -34
  36. rucio/gateway/exporter.py +27 -30
  37. rucio/gateway/importer.py +12 -14
  38. rucio/gateway/lifetime_exception.py +16 -24
  39. rucio/gateway/lock.py +27 -40
  40. rucio/gateway/replica.py +334 -249
  41. rucio/gateway/request.py +176 -103
  42. rucio/gateway/rse.py +191 -218
  43. rucio/gateway/rule.py +115 -146
  44. rucio/gateway/scope.py +18 -25
  45. rucio/gateway/subscription.py +90 -108
  46. rucio/gateway/trace.py +48 -0
  47. rucio/vcsversion.py +3 -3
  48. rucio/web/rest/flaskapi/v1/accounts.py +2 -2
  49. rucio/web/rest/flaskapi/v1/auth.py +15 -0
  50. rucio/web/rest/flaskapi/v1/common.py +3 -0
  51. rucio/web/rest/flaskapi/v1/config.py +7 -7
  52. rucio/web/rest/flaskapi/v1/dids.py +55 -55
  53. rucio/web/rest/flaskapi/v1/dirac.py +2 -2
  54. rucio/web/rest/flaskapi/v1/export.py +1 -1
  55. rucio/web/rest/flaskapi/v1/import.py +1 -1
  56. rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +5 -5
  57. rucio/web/rest/flaskapi/v1/locks.py +4 -4
  58. rucio/web/rest/flaskapi/v1/main.py +17 -10
  59. rucio/web/rest/flaskapi/v1/redirect.py +1 -1
  60. rucio/web/rest/flaskapi/v1/replicas.py +30 -29
  61. rucio/web/rest/flaskapi/v1/requests.py +211 -20
  62. rucio/web/rest/flaskapi/v1/rses.py +37 -37
  63. rucio/web/rest/flaskapi/v1/rules.py +15 -15
  64. rucio/web/rest/flaskapi/v1/scopes.py +3 -3
  65. rucio/web/rest/flaskapi/v1/subscriptions.py +9 -9
  66. rucio/web/rest/flaskapi/v1/traces.py +75 -77
  67. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/rucio.cfg.template +0 -1
  68. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -1
  69. {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/METADATA +1 -1
  70. {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/RECORD +127 -126
  71. {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/WHEEL +1 -1
  72. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/alembic.ini.template +0 -0
  73. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
  74. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
  75. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
  76. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
  77. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
  78. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
  79. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
  80. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
  81. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
  82. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
  83. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
  84. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/requirements.server.txt +0 -0
  85. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/tools/bootstrap.py +0 -0
  86. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
  87. {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/tools/reset_database.py +0 -0
  88. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio +0 -0
  89. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-abacus-account +0 -0
  90. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-abacus-collection-replica +0 -0
  91. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-abacus-rse +0 -0
  92. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-admin +0 -0
  93. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-atropos +0 -0
  94. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-auditor +0 -0
  95. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-automatix +0 -0
  96. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-bb8 +0 -0
  97. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-cache-client +0 -0
  98. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-cache-consumer +0 -0
  99. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-finisher +0 -0
  100. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-poller +0 -0
  101. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-preparer +0 -0
  102. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-receiver +0 -0
  103. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-stager +0 -0
  104. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-submitter +0 -0
  105. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-throttler +0 -0
  106. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-dark-reaper +0 -0
  107. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-dumper +0 -0
  108. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-follower +0 -0
  109. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-hermes +0 -0
  110. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-judge-cleaner +0 -0
  111. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-judge-evaluator +0 -0
  112. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-judge-injector +0 -0
  113. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-judge-repairer +0 -0
  114. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-kronos +0 -0
  115. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-minos +0 -0
  116. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
  117. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-necromancer +0 -0
  118. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-oauth-manager +0 -0
  119. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-reaper +0 -0
  120. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-replica-recoverer +0 -0
  121. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-rse-decommissioner +0 -0
  122. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-storage-consistency-actions +0 -0
  123. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-transmogrifier +0 -0
  124. {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-undertaker +0 -0
  125. {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/licenses/AUTHORS.rst +0 -0
  126. {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/licenses/LICENSE +0 -0
  127. {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/top_level.txt +0 -0
rucio/gateway/rule.py CHANGED
@@ -20,7 +20,8 @@ from rucio.common.schema import validate_schema
20
20
  from rucio.common.types import InternalAccount, InternalScope
21
21
  from rucio.common.utils import gateway_update_return_dict
22
22
  from rucio.core import rule
23
- from rucio.db.sqla.session import read_session, stream_session, transactional_session
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:
@@ -29,8 +30,7 @@ if TYPE_CHECKING:
29
30
  from sqlalchemy.orm import Session
30
31
 
31
32
 
32
- @read_session
33
- def is_multi_vo(*, session: "Session") -> bool:
33
+ def is_multi_vo(session: "Session") -> bool:
34
34
  """
35
35
  Check whether this instance is configured for multi-VO
36
36
  returns: Boolean True if running in multi-VO
@@ -38,7 +38,6 @@ def is_multi_vo(*, session: "Session") -> bool:
38
38
  return config_get_bool('common', 'multi_vo', raise_exception=False, default=False, session=session)
39
39
 
40
40
 
41
- @transactional_session
42
41
  def add_replication_rule(
43
42
  dids: "Sequence[dict[str, str]]",
44
43
  copies: int,
@@ -63,8 +62,6 @@ def add_replication_rule(
63
62
  meta: Optional[dict[str, Any]],
64
63
  issuer: str,
65
64
  vo: str = 'def',
66
- *,
67
- session: "Session"
68
65
  ) -> list[str]:
69
66
  """
70
67
  Adds a replication rule.
@@ -93,7 +90,6 @@ def add_replication_rule(
93
90
  :param meta: WFMS metadata as a dictionary.
94
91
  :param issuer: The issuing account of this operation.
95
92
  :param vo: The VO to act on.
96
- :param session: The database session in use.
97
93
  :returns: List of created replication rules.
98
94
  """
99
95
  if account is None:
@@ -111,69 +107,65 @@ def add_replication_rule(
111
107
 
112
108
  validate_schema(name='rule', obj=kwargs, vo=vo)
113
109
 
114
- auth_result = has_permission(issuer=issuer, vo=vo, action='add_rule', kwargs=kwargs, session=session)
115
- if not auth_result.allowed:
116
- raise AccessDenied('Account %s can not add replication rule. %s' % (issuer, auth_result.message))
117
-
118
- account_internal = InternalAccount(account, vo=vo)
119
- dids_with_internal_scope = [{'name': d['name'], 'scope': InternalScope(d['scope'], vo=vo)} for d in dids]
120
-
121
- return rule.add_rule(account=account_internal,
122
- dids=dids_with_internal_scope,
123
- copies=copies,
124
- rse_expression=rse_expression,
125
- grouping=grouping,
126
- weight=weight,
127
- lifetime=lifetime,
128
- locked=locked,
129
- subscription_id=subscription_id,
130
- source_replica_expression=source_replica_expression,
131
- activity=activity,
132
- notify=notify,
133
- purge_replicas=purge_replicas,
134
- ignore_availability=ignore_availability,
135
- comment=comment,
136
- ask_approval=ask_approval,
137
- asynchronous=asynchronous,
138
- delay_injection=delay_injection,
139
- priority=priority,
140
- split_container=split_container,
141
- meta=meta,
142
- session=session)
143
-
144
-
145
- @read_session
146
- def get_replication_rule(rule_id: str, issuer: str, vo: str = 'def', *, session: "Session") -> dict[str, Any]:
110
+ with db_session(DatabaseOperationType.WRITE) as session:
111
+ auth_result = has_permission(issuer=issuer, vo=vo, action='add_rule', kwargs=kwargs, session=session)
112
+ if not auth_result.allowed:
113
+ raise AccessDenied('Account %s can not add replication rule. %s' % (issuer, auth_result.message))
114
+
115
+ account_internal = InternalAccount(account, vo=vo)
116
+ dids_with_internal_scope = [{'name': d['name'], 'scope': InternalScope(d['scope'], vo=vo)} for d in dids]
117
+
118
+ return rule.add_rule(account=account_internal,
119
+ dids=dids_with_internal_scope,
120
+ copies=copies,
121
+ rse_expression=rse_expression,
122
+ grouping=grouping,
123
+ weight=weight,
124
+ lifetime=lifetime,
125
+ locked=locked,
126
+ subscription_id=subscription_id,
127
+ source_replica_expression=source_replica_expression,
128
+ activity=activity,
129
+ notify=notify,
130
+ purge_replicas=purge_replicas,
131
+ ignore_availability=ignore_availability,
132
+ comment=comment,
133
+ ask_approval=ask_approval,
134
+ asynchronous=asynchronous,
135
+ delay_injection=delay_injection,
136
+ priority=priority,
137
+ split_container=split_container,
138
+ meta=meta,
139
+ session=session)
140
+
141
+
142
+ def get_replication_rule(rule_id: str, issuer: str, vo: str = 'def') -> dict[str, Any]:
147
143
  """
148
144
  Get replication rule by it's id.
149
145
 
150
146
  :param rule_id: The rule_id to get.
151
147
  :param issuer: The issuing account of this operation.
152
148
  :param vo: The VO of the issuer.
153
- :param session: The database session in use.
154
149
  """
155
150
  kwargs = {'rule_id': rule_id}
156
- if is_multi_vo(session=session):
157
- auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
158
- if not auth_result.allowed:
159
- raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
160
- result = rule.get_rule(rule_id, session=session)
161
- return gateway_update_return_dict(result, session=session)
151
+ with db_session(DatabaseOperationType.READ) as session:
152
+ if is_multi_vo(session=session):
153
+ auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
154
+ if not auth_result.allowed:
155
+ raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
156
+ result = rule.get_rule(rule_id, session=session)
157
+ return gateway_update_return_dict(result, session=session)
162
158
 
163
159
 
164
- @stream_session
165
160
  def list_replication_rules(
166
161
  filters: Optional[dict[str, Any]] = None,
167
162
  vo: str = 'def',
168
- *,
169
- session: "Session"
170
163
  ) -> "Iterator[dict[str, Any]]":
171
164
  """
172
165
  Lists replication rules based on a filter.
173
166
 
174
167
  :param filters: dictionary of attributes by which the results should be filtered.
175
168
  :param vo: The VO to act on.
176
- :param session: The database session in use.
177
169
  """
178
170
  # If filters is empty, create a new dict to avoid overwriting the function's default
179
171
  filters = filters or {}
@@ -190,18 +182,16 @@ def list_replication_rules(
190
182
  account = '*'
191
183
  filters['account'] = InternalAccount(account=account, vo=vo)
192
184
 
193
- rules = rule.list_rules(filters, session=session)
194
- for r in rules:
195
- yield gateway_update_return_dict(r, session=session)
185
+ with db_session(DatabaseOperationType.READ) as session:
186
+ rules = rule.list_rules(filters, session=session)
187
+ for r in rules:
188
+ yield gateway_update_return_dict(r, session=session)
196
189
 
197
190
 
198
- @read_session
199
191
  def list_replication_rule_history(
200
192
  rule_id: str,
201
193
  issuer: str,
202
194
  vo: str = 'def',
203
- *,
204
- session: "Session"
205
195
  ) -> "Iterator[dict[str, Any]]":
206
196
  """
207
197
  Lists replication rule history..
@@ -209,23 +199,20 @@ def list_replication_rule_history(
209
199
  :param rule_id: The rule_id to list.
210
200
  :param issuer: The issuing account of this operation.
211
201
  :param vo: The VO of the issuer.
212
- :param session: The database session in use.
213
202
  """
214
203
  kwargs = {'rule_id': rule_id}
215
- if is_multi_vo(session=session):
216
- auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
217
- if not auth_result.allowed:
218
- raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
219
- return rule.list_rule_history(rule_id, session=session)
204
+ with db_session(DatabaseOperationType.READ) as session:
205
+ if is_multi_vo(session=session):
206
+ auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
207
+ if not auth_result.allowed:
208
+ raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
209
+ return rule.list_rule_history(rule_id, session=session)
220
210
 
221
211
 
222
- @stream_session
223
212
  def list_replication_rule_full_history(
224
213
  scope: str,
225
214
  name: str,
226
215
  vo: str = 'def',
227
- *,
228
- session: "Session"
229
216
  ) -> "Iterator[dict[str, Any]]":
230
217
  """
231
218
  List the rule history of a DID.
@@ -233,21 +220,18 @@ def list_replication_rule_full_history(
233
220
  :param scope: The scope of the DID.
234
221
  :param name: The name of the DID.
235
222
  :param vo: The VO to act on.
236
- :param session: The database session in use.
237
223
  """
238
224
  scope_internal = InternalScope(scope, vo=vo)
239
- rules = rule.list_rule_full_history(scope_internal, name, session=session)
240
- for r in rules:
241
- yield gateway_update_return_dict(r, session=session)
225
+ with db_session(DatabaseOperationType.READ) as session:
226
+ rules = rule.list_rule_full_history(scope_internal, name, session=session)
227
+ for r in rules:
228
+ yield gateway_update_return_dict(r, session=session)
242
229
 
243
230
 
244
- @stream_session
245
231
  def list_associated_replication_rules_for_file(
246
232
  scope: str,
247
233
  name: str,
248
234
  vo: str = 'def',
249
- *,
250
- session: "Session"
251
235
  ) -> "Iterator[dict[str, Any]]":
252
236
  """
253
237
  Lists associated replication rules by file.
@@ -255,22 +239,19 @@ def list_associated_replication_rules_for_file(
255
239
  :param scope: Scope of the file..
256
240
  :param name: Name of the file.
257
241
  :param vo: The VO to act on.
258
- :param session: The database session in use.
259
242
  """
260
243
  scope_internal = InternalScope(scope, vo=vo)
261
- rules = rule.list_associated_rules_for_file(scope=scope_internal, name=name, session=session)
262
- for r in rules:
263
- yield gateway_update_return_dict(r, session=session)
244
+ with db_session(DatabaseOperationType.READ) as session:
245
+ rules = rule.list_associated_rules_for_file(scope=scope_internal, name=name, session=session)
246
+ for r in rules:
247
+ yield gateway_update_return_dict(r, session=session)
264
248
 
265
249
 
266
- @transactional_session
267
250
  def delete_replication_rule(
268
251
  rule_id: str,
269
252
  purge_replicas: Optional[bool],
270
253
  issuer: str,
271
254
  vo: str = 'def',
272
- *,
273
- session: "Session"
274
255
  ) -> None:
275
256
  """
276
257
  Deletes a replication rule and all associated locks.
@@ -279,28 +260,25 @@ def delete_replication_rule(
279
260
  :param purge_replicas: Purge the replicas immediately
280
261
  :param issuer: The issuing account of this operation
281
262
  :param vo: The VO to act on.
282
- :param session: The database session in use.
283
263
  :raises: RuleNotFound, AccessDenied
284
264
  """
285
265
  kwargs = {'rule_id': rule_id, 'purge_replicas': purge_replicas}
286
- if is_multi_vo(session=session):
287
- auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
266
+ with db_session(DatabaseOperationType.WRITE) as session:
267
+ if is_multi_vo(session=session):
268
+ auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
269
+ if not auth_result.allowed:
270
+ raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
271
+ auth_result = has_permission(issuer=issuer, vo=vo, action='del_rule', kwargs=kwargs)
288
272
  if not auth_result.allowed:
289
- raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
290
- auth_result = has_permission(issuer=issuer, vo=vo, action='del_rule', kwargs=kwargs)
291
- if not auth_result.allowed:
292
- raise AccessDenied('Account %s can not remove this replication rule. %s' % (issuer, auth_result.message))
293
- rule.delete_rule(rule_id=rule_id, purge_replicas=purge_replicas, soft=True, session=session)
273
+ raise AccessDenied('Account %s can not remove this replication rule. %s' % (issuer, auth_result.message))
274
+ rule.delete_rule(rule_id=rule_id, purge_replicas=purge_replicas, soft=True, session=session)
294
275
 
295
276
 
296
- @transactional_session
297
277
  def update_replication_rule(
298
278
  rule_id: str,
299
279
  options: dict[str, Any],
300
280
  issuer: str,
301
281
  vo: str = 'def',
302
- *,
303
- session: "Session"
304
282
  ) -> None:
305
283
  """
306
284
  Update lock state of a replication rule.
@@ -309,42 +287,39 @@ def update_replication_rule(
309
287
  :param options: Options dictionary.
310
288
  :param issuer: The issuing account of this operation
311
289
  :param vo: The VO to act on.
312
- :param session: The database session in use.
313
290
  :raises: RuleNotFound if no Rule can be found.
314
291
  """
315
292
  kwargs = {'rule_id': rule_id, 'options': options}
316
- if is_multi_vo(session=session):
317
- auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
318
- if not auth_result.allowed:
319
- raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
320
- if 'approve' in options:
321
- auth_result = has_permission(issuer=issuer, vo=vo, action='approve_rule', kwargs=kwargs, session=session)
322
- if not auth_result.allowed:
323
- raise AccessDenied('Account %s can not approve/deny this replication rule. %s' % (issuer, auth_result.message))
324
-
325
- issuer_ia = InternalAccount(issuer, vo=vo)
326
- if options['approve']:
327
- rule.approve_rule(rule_id=rule_id, approver=issuer_ia, session=session)
293
+ with db_session(DatabaseOperationType.WRITE) as session:
294
+ if is_multi_vo(session=session):
295
+ auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
296
+ if not auth_result.allowed:
297
+ raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
298
+ if 'approve' in options:
299
+ auth_result = has_permission(issuer=issuer, vo=vo, action='approve_rule', kwargs=kwargs, session=session)
300
+ if not auth_result.allowed:
301
+ raise AccessDenied('Account %s can not approve/deny this replication rule. %s' % (issuer, auth_result.message))
302
+
303
+ issuer_ia = InternalAccount(issuer, vo=vo)
304
+ if options['approve']:
305
+ rule.approve_rule(rule_id=rule_id, approver=issuer_ia, session=session)
306
+ else:
307
+ rule.deny_rule(rule_id=rule_id, approver=issuer_ia, reason=options.get('comment', None), session=session)
328
308
  else:
329
- rule.deny_rule(rule_id=rule_id, approver=issuer_ia, reason=options.get('comment', None), session=session)
330
- else:
331
- auth_result = has_permission(issuer=issuer, vo=vo, action='update_rule', kwargs=kwargs, session=session)
332
- if not auth_result.allowed:
333
- raise AccessDenied('Account %s can not update this replication rule. %s' % (issuer, auth_result.message))
334
- if 'account' in options:
335
- options['account'] = InternalAccount(options['account'], vo=vo)
336
- rule.update_rule(rule_id=rule_id, options=options, session=session)
309
+ auth_result = has_permission(issuer=issuer, vo=vo, action='update_rule', kwargs=kwargs, session=session)
310
+ if not auth_result.allowed:
311
+ raise AccessDenied('Account %s can not update this replication rule. %s' % (issuer, auth_result.message))
312
+ if 'account' in options:
313
+ options['account'] = InternalAccount(options['account'], vo=vo)
314
+ rule.update_rule(rule_id=rule_id, options=options, session=session)
337
315
 
338
316
 
339
- @transactional_session
340
317
  def reduce_replication_rule(
341
318
  rule_id: str,
342
319
  copies: int,
343
320
  exclude_expression: Optional[str],
344
321
  issuer: str,
345
322
  vo: str = 'def',
346
- *,
347
- session: "Session"
348
323
  ) -> str:
349
324
  """
350
325
  Reduce the number of copies for a rule by atomically replacing the rule.
@@ -354,28 +329,25 @@ def reduce_replication_rule(
354
329
  :param exclude_expression: RSE Expression of RSEs to exclude.
355
330
  :param issuer: The issuing account of this operation
356
331
  :param vo: The VO to act on.
357
- :param session: The database session in use.
358
332
  :raises: RuleReplaceFailed, RuleNotFound
359
333
  """
360
334
  kwargs = {'rule_id': rule_id, 'copies': copies, 'exclude_expression': exclude_expression}
361
- if is_multi_vo(session=session):
362
- auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
335
+ with db_session(DatabaseOperationType.WRITE) as session:
336
+ if is_multi_vo(session=session):
337
+ auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
338
+ if not auth_result.allowed:
339
+ raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
340
+ auth_result = has_permission(issuer=issuer, vo=vo, action='reduce_rule', kwargs=kwargs, session=session)
363
341
  if not auth_result.allowed:
364
- raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
365
- auth_result = has_permission(issuer=issuer, vo=vo, action='reduce_rule', kwargs=kwargs, session=session)
366
- if not auth_result.allowed:
367
- raise AccessDenied('Account %s can not reduce this replication rule. %s' % (issuer, auth_result.message))
342
+ raise AccessDenied('Account %s can not reduce this replication rule. %s' % (issuer, auth_result.message))
368
343
 
369
- return rule.reduce_rule(rule_id=rule_id, copies=copies, exclude_expression=exclude_expression, session=session)
344
+ return rule.reduce_rule(rule_id=rule_id, copies=copies, exclude_expression=exclude_expression, session=session)
370
345
 
371
346
 
372
- @read_session
373
347
  def examine_replication_rule(
374
348
  rule_id: str,
375
349
  issuer: str,
376
350
  vo: str = 'def',
377
- *,
378
- session: "Session"
379
351
  ) -> dict[str, Any]:
380
352
  """
381
353
  Examine a replication rule.
@@ -383,29 +355,26 @@ def examine_replication_rule(
383
355
  :param rule_id: The rule_id to get.
384
356
  :param issuer: The issuing account of this operation.
385
357
  :param vo: The VO of the issuer.
386
- :param session: The database session in use.
387
358
  """
388
359
  kwargs = {'rule_id': rule_id}
389
- if is_multi_vo(session=session):
390
- auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
391
- if not auth_result.allowed:
392
- raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
393
- result = rule.examine_rule(rule_id, session=session)
394
- result = gateway_update_return_dict(result, session=session)
395
- if 'transfers' in result:
396
- result['transfers'] = [gateway_update_return_dict(t, session=session) for t in result['transfers']]
360
+ with db_session(DatabaseOperationType.READ) as session:
361
+ if is_multi_vo(session=session):
362
+ auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
363
+ if not auth_result.allowed:
364
+ raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
365
+ result = rule.examine_rule(rule_id, session=session)
366
+ result = gateway_update_return_dict(result, session=session)
367
+ if 'transfers' in result:
368
+ result['transfers'] = [gateway_update_return_dict(t, session=session) for t in result['transfers']]
397
369
  return result
398
370
 
399
371
 
400
- @transactional_session
401
372
  def move_replication_rule(
402
373
  rule_id: str,
403
374
  rse_expression: str,
404
375
  override: dict[str, Any],
405
376
  issuer: str,
406
377
  vo: str = 'def',
407
- *,
408
- session: "Session"
409
378
  ) -> str:
410
379
  """
411
380
  Move a replication rule to another RSE and, once done, delete the original one.
@@ -413,7 +382,6 @@ def move_replication_rule(
413
382
  :param rule_id: Rule to be moved.
414
383
  :param rse_expression: RSE expression of the new rule.
415
384
  :param override: Configurations to update for the new rule.
416
- :param session: The DB Session.
417
385
  :param vo: The VO to act on.
418
386
  :raises: RuleNotFound, RuleReplaceFailed, InvalidRSEExpression, AccessDenied
419
387
  """
@@ -426,12 +394,13 @@ def move_replication_rule(
426
394
  'override': override,
427
395
  }
428
396
 
429
- if is_multi_vo(session=session):
430
- auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
397
+ with db_session(DatabaseOperationType.WRITE) as session:
398
+ if is_multi_vo(session=session):
399
+ auth_result = has_permission(issuer=issuer, vo=vo, action='access_rule_vo', kwargs=kwargs, session=session)
400
+ if not auth_result.allowed:
401
+ raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
402
+ auth_result = has_permission(issuer=issuer, vo=vo, action='move_rule', kwargs=kwargs, session=session)
431
403
  if not auth_result.allowed:
432
- raise AccessDenied('Account %s can not access rules at other VOs. %s' % (issuer, auth_result.message))
433
- auth_result = has_permission(issuer=issuer, vo=vo, action='move_rule', kwargs=kwargs, session=session)
434
- if not auth_result.allowed:
435
- raise AccessDenied('Account %s can not move this replication rule. %s' % (issuer, auth_result.message))
404
+ raise AccessDenied('Account %s can not move this replication rule. %s' % (issuer, auth_result.message))
436
405
 
437
- return rule.move_rule(**kwargs, session=session)
406
+ return rule.move_rule(**kwargs, session=session)
rucio/gateway/scope.py CHANGED
@@ -12,27 +12,23 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import TYPE_CHECKING, Any, Optional
15
+ from typing import Any, Optional
16
16
 
17
- import rucio.common.exception
18
17
  import rucio.gateway.permission
18
+ from rucio.common.exception import AccessDenied
19
19
  from rucio.common.schema import validate_schema
20
20
  from rucio.common.types import InternalAccount, InternalScope
21
21
  from rucio.core import scope as core_scope
22
- from rucio.db.sqla.session import read_session, transactional_session
22
+ from rucio.db.sqla.constants import DatabaseOperationType
23
+ from rucio.db.sqla.session import db_session
23
24
 
24
- if TYPE_CHECKING:
25
- from sqlalchemy.orm import Session
26
25
 
27
-
28
- @read_session
29
- def list_scopes(filter_: Optional[dict[str, Any]] = None, vo: str = 'def', *, session: "Session") -> list[str]:
26
+ def list_scopes(filter_: Optional[dict[str, Any]] = None, vo: str = 'def') -> list[str]:
30
27
  """
31
28
  Lists all scopes.
32
29
 
33
30
  :param filter_: Dictionary of attributes by which the input data should be filtered
34
31
  :param vo: The VO to act on.
35
- :param session: The database session in use.
36
32
 
37
33
  :returns: A list containing all scopes.
38
34
  """
@@ -43,17 +39,16 @@ def list_scopes(filter_: Optional[dict[str, Any]] = None, vo: str = 'def', *, se
43
39
  filter_['scope'] = InternalScope(scope=filter_['scope'], vo=vo)
44
40
  else:
45
41
  filter_['scope'] = InternalScope(scope='*', vo=vo)
46
- return [scope.external for scope in core_scope.list_scopes(filter_=filter_, session=session)]
42
+
43
+ with db_session(DatabaseOperationType.READ) as session:
44
+ return [scope.external for scope in core_scope.list_scopes(filter_=filter_, session=session)]
47
45
 
48
46
 
49
- @transactional_session
50
47
  def add_scope(
51
48
  scope: str,
52
49
  account: str,
53
50
  issuer: str,
54
51
  vo: str = 'def',
55
- *,
56
- session: "Session"
57
52
  ) -> None:
58
53
  """
59
54
  Creates a scope for an account.
@@ -62,39 +57,37 @@ def add_scope(
62
57
  :param scope: The scope identifier.
63
58
  :param issuer: The issuer account.
64
59
  :param vo: The VO to act on.
65
- :param session: The database session in use.
66
60
  """
67
61
 
68
62
  validate_schema(name='scope', obj=scope, vo=vo)
69
63
 
70
64
  kwargs = {'scope': scope, 'account': account}
71
- auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='add_scope', kwargs=kwargs, session=session)
72
- if not auth_result.allowed:
73
- raise rucio.common.exception.AccessDenied('Account %s can not add scope. %s' % (issuer, auth_result.message))
74
65
 
75
- internal_scope = InternalScope(scope, vo=vo)
76
- internal_account = InternalAccount(account, vo=vo)
66
+ with db_session(DatabaseOperationType.WRITE) as session:
67
+ auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='add_scope', kwargs=kwargs, session=session)
68
+ if not auth_result.allowed:
69
+ raise AccessDenied('Account %s can not add scope. %s' % (issuer, auth_result.message))
70
+
71
+ internal_scope = InternalScope(scope, vo=vo)
72
+ internal_account = InternalAccount(account, vo=vo)
77
73
 
78
- core_scope.add_scope(internal_scope, internal_account, session=session)
74
+ core_scope.add_scope(internal_scope, internal_account, session=session)
79
75
 
80
76
 
81
- @read_session
82
77
  def get_scopes(
83
78
  account: str,
84
79
  vo: str = 'def',
85
- *,
86
- session: "Session"
87
80
  ) -> list[str]:
88
81
  """
89
82
  Gets a list of all scopes for an account.
90
83
 
91
84
  :param account: The account name.
92
85
  :param vo: The VO to act on.
93
- :param session: The database session in use.
94
86
 
95
87
  :returns: A list containing the names of all scopes for this account.
96
88
  """
97
89
 
98
90
  internal_account = InternalAccount(account, vo=vo)
99
91
 
100
- return [scope.external for scope in core_scope.get_scopes(internal_account, session=session)]
92
+ with db_session(DatabaseOperationType.READ) as session:
93
+ return [scope.external for scope in core_scope.get_scopes(internal_account, session=session)]