Skip to content

Commit e383672

Browse files
jamesp-epccbari12
authored andcommitted
Policies: standardise permission policy check logic rucio#7206
1 parent b7a7eb7 commit e383672

File tree

8 files changed

+31
-35
lines changed

8 files changed

+31
-35
lines changed

lib/rucio/common/policy.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,37 @@
1313
# limitations under the License.
1414

1515
import json
16+
import logging
1617
import os
1718
from configparser import NoOptionError, NoSectionError
1819
from functools import wraps
19-
from typing import Any
20+
from typing import TYPE_CHECKING, Any
2021

2122
from dogpile.cache import make_region
2223
from dogpile.cache.api import NoValue
2324

2425
from rucio.common.config import config_get
2526
from rucio.common.exception import UndefinedPolicy
2627

28+
if TYPE_CHECKING:
29+
from rucio.common.types import LoggerFunction
30+
2731
REGION = make_region().configure('dogpile.cache.memory',
2832
expiration_time=900)
2933

3034

31-
def get_policy() -> str:
35+
def get_policy(logger: 'LoggerFunction' = logging.log) -> str:
3236
policy = REGION.get('policy')
3337
if isinstance(policy, NoValue):
3438
try:
3539
policy = config_get('policy', 'permission')
3640
except (NoOptionError, NoSectionError):
37-
policy = 'atlas'
41+
try:
42+
policy = config_get('permission', 'policy')
43+
except (NoOptionError, NoSectionError):
44+
policy = 'def'
45+
logger(logging.WARNING, "Policy not specified, falling back to 'def'")
46+
policy = os.environ.get('POLICY', policy)
3847
REGION.set('policy', policy)
3948
return policy
4049

lib/rucio/core/permission/__init__.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import rucio.core.permission.generic
2222
from rucio.common import config, exception
2323
from rucio.common.plugins import check_policy_package_version
24+
from rucio.common.policy import get_policy
2425

2526
if TYPE_CHECKING:
2627
from typing import Optional
@@ -43,17 +44,8 @@
4344
if not multivo:
4445
generic_fallback = 'generic'
4546

46-
if config.config_has_section('permission'):
47-
try:
48-
fallback_policy = config.config_get('permission', 'policy')
49-
except (NoOptionError, NoSectionError):
50-
fallback_policy = generic_fallback
51-
elif config.config_has_section('policy'):
52-
try:
53-
fallback_policy = config.config_get('policy', 'permission')
54-
except (NoOptionError, NoSectionError):
55-
fallback_policy = generic_fallback
56-
else:
47+
fallback_policy = get_policy()
48+
if fallback_policy == 'def':
5749
fallback_policy = generic_fallback
5850

5951
if config.config_has_section('policy'):

lib/rucio/transfertool/fts3.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from rucio.common.config import config_get, config_get_bool, config_get_int, config_get_list
3434
from rucio.common.constants import FTS_COMPLETE_STATE, FTS_JOB_TYPE, FTS_STATE, RseAttr
3535
from rucio.common.exception import DuplicateFileTransferSubmission, TransferToolTimeout, TransferToolWrongAnswer
36+
from rucio.common.policy import get_policy
3637
from rucio.common.stopwatch import Stopwatch
3738
from rucio.common.utils import APIEncoder, chunks, deep_merge_dict
3839
from rucio.core.monitor import MetricManager
@@ -1369,10 +1370,7 @@ def set_se_config(
13691370

13701371
params_dict = {storage_element: {'operations': {}, 'se_info': {}}}
13711372
if staging is not None:
1372-
try:
1373-
policy = config_get('policy', 'permission')
1374-
except Exception:
1375-
self.logger(logging.WARNING, 'Could not get policy from config')
1373+
policy = get_policy()
13761374
params_dict[storage_element]['operations'] = {policy: {'staging': staging}}
13771375
# A lot of try-excepts to avoid dictionary overwrite's,
13781376
# see https://stackoverflow.com/questions/27118687/updating-nested-dictionaries-when-data-has-existing-key/27118776

lib/rucio/web/ui/flask/bp.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515

1616
from flask import Blueprint, make_response, render_template, request
1717

18-
from rucio.common.config import config_get, config_get_bool
18+
from rucio.common.config import config_get_bool
19+
from rucio.common.policy import get_policy
1920
from rucio.gateway.authentication import get_auth_token_x509
2021
from rucio.web.rest.flaskapi.v1.common import generate_http_error_flask
2122
from rucio.web.ui.flask.common.utils import AUTH_ISSUERS, SAML_SUPPORT, USERPASS_SUPPORT, authenticate, finalize_auth, get_token, oidc_auth, saml_auth, userpass_auth, x509token_auth
2223

2324
MULTI_VO = config_get_bool('common', 'multi_vo', raise_exception=False, default=False)
24-
POLICY = config_get('policy', 'permission')
25+
POLICY = get_policy()
2526
ATLAS_URLS = ()
2627
OTHER_URLS = ()
2728

lib/rucio/web/ui/flask/common/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from rucio.common.config import config_get, config_get_bool
2727
from rucio.common.exception import CannotAuthenticate
2828
from rucio.common.extra import import_extras
29+
from rucio.common.policy import get_policy
2930
from rucio.core import identity as identity_core
3031
from rucio.core import vo as vo_core
3132
from rucio.db.sqla.constants import AccountType, IdentityType
@@ -236,7 +237,7 @@ def access_granted(valid_token_dict, template, title):
236237
:param template: the template name that should be rendered
237238
:returns: rendered base temmplate with template content
238239
"""
239-
policy = config_get('policy', 'permission')
240+
policy = get_policy()
240241
return render_template(template, token=valid_token_dict['token'], account=valid_token_dict['account'], vo=valid_token_dict['vo'], policy=policy, title=title)
241242

242243

tests/test_lifetime.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
@pytest.mark.noparallel(reason='Race conditions with the other tests in test_lifetime.py, they all modify and use the config.')
3535
@skip_multivo(reason='only valid for ATLAS')
36+
@pytest.mark.skipif(os.environ.get('POLICY') != 'atlas', reason='ATLAS-specific test')
3637
def test_lifetime_creation_core(root_account, rse_factory, mock_scope, did_factory):
3738
"""
3839
Test the creation of a lifetime exception on the core side
@@ -101,6 +102,7 @@ def test_lifetime_creation_core(root_account, rse_factory, mock_scope, did_facto
101102

102103
@pytest.mark.noparallel(reason='Race conditions with the other tests in test_lifetime.py, they all modify and use the config.')
103104
@skip_multivo(reason='only valid for ATLAS')
105+
@pytest.mark.skipif(os.environ.get('POLICY') != 'atlas', reason='ATLAS-specific test')
104106
def test_lifetime_truncate_expiration(root_account, rse_factory, mock_scope, did_factory, rucio_client):
105107
"""
106108
Test the duration of a lifetime exception is truncated if max_extension is defined
@@ -134,6 +136,7 @@ def test_lifetime_truncate_expiration(root_account, rse_factory, mock_scope, did
134136

135137
@pytest.mark.noparallel(reason='Race conditions with the other tests in test_lifetime.py, they all modify and use the config.')
136138
@skip_multivo(reason='only valid for ATLAS')
139+
@pytest.mark.skipif(os.environ.get('POLICY') != 'atlas', reason='ATLAS-specific test')
137140
def test_lifetime_creation_client(root_account, rse_factory, mock_scope, did_factory, rucio_client):
138141
"""
139142
Test the creation of a lifetime exception on the client side and that the exception can be listed with the client
@@ -210,6 +213,7 @@ def test_lifetime_creation_client(root_account, rse_factory, mock_scope, did_fac
210213
@skip_multivo(reason='only valid for ATLAS')
211214
@pytest.mark.dirty
212215
@pytest.mark.noparallel(reason='Uses daemons. Write a configuration file')
216+
@pytest.mark.skipif(os.environ.get('POLICY') != 'atlas', reason='ATLAS-specific test')
213217
def test_atropos(root_account, rse_factory, mock_scope, did_factory, rucio_client):
214218
"""
215219
Test the behaviour of atropos

tests/test_rule.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import json
16+
import os
1617
import random
1718
import string
1819
from collections import namedtuple
@@ -41,7 +42,6 @@
4142
RuleReplaceFailed,
4243
UnsupportedOperation,
4344
)
44-
from rucio.common.policy import get_policy
4545
from rucio.common.schema import get_schema_value
4646
from rucio.common.types import InternalAccount, InternalScope
4747
from rucio.common.utils import generate_uuid as uuid
@@ -928,12 +928,9 @@ def test_add_rule_with_ignore_availability(self, vo, mock_scope, did_factory, jd
928928
for filtered_lock in [lock for lock in get_replica_locks(scope=file['scope'], name=file['name'])]:
929929
assert (filtered_lock['state'] == LockState.STUCK)
930930

931+
@pytest.mark.skipif(os.environ.get('POLICY') != 'atlas', reason='ATLAS-specific test')
931932
def test_delete_rule_country_admin(self, vo, mock_scope, did_factory, jdoe_account):
932933
""" REPLICATION RULE (CORE): Delete a rule with a country admin account"""
933-
if get_policy() != 'atlas':
934-
LOG.info("Skipping atlas-specific test")
935-
return
936-
937934
rse = rse_name_generator()
938935
rse_id = add_rse(rse, vo=vo)
939936
add_rse_attribute(rse_id, RseAttr.COUNTRY, 'test')
@@ -1024,12 +1021,9 @@ def test_move_rule_with_arguments(self, mock_scope, did_factory, jdoe_account):
10241021
pytest.raises(RuleReplaceFailed, move_rule, rule_id, self.rse3)
10251022
pytest.raises(RucioException, move_rule, 'foo', self.rse3)
10261023

1024+
@pytest.mark.skipif(os.environ.get('POLICY') != 'atlas', reason='ATLAS-specific test')
10271025
def test_add_rule_with_scratchdisk(self, vo, mock_scope, did_factory, jdoe_account):
10281026
""" REPLICATION RULE (CORE): Add a replication rule for scratchdisk"""
1029-
if get_policy() != 'atlas':
1030-
LOG.info("Skipping atlas-specific test")
1031-
return
1032-
10331027
rse = rse_name_generator()
10341028
rse_id = add_rse(rse, vo=vo)
10351029
add_rse_attribute(rse_id, RseAttr.TYPE, 'SCRATCHDISK')

tests/test_undertaker.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import os
1516
from datetime import datetime, timedelta
1617
from logging import getLogger
1718

1819
import pytest
1920

20-
from rucio.common.policy import get_policy
2121
from rucio.common.types import InternalScope
2222
from rucio.core.account_limit import set_local_account_limit
2323
from rucio.core.did import add_dids, attach_dids, get_did, list_expired_dids, set_metadata
@@ -100,12 +100,9 @@ def test_list_expired_dids_with_locked_rules(self, rse_factory, vo, mock_scope,
100100
for did in list_expired_dids(limit=1000):
101101
assert (did['scope'], did['name']) != (dsn['scope'], dsn['name'])
102102

103+
@pytest.mark.skipif(os.environ.get('POLICY') != 'atlas', reason='ATLAS-specific test')
103104
def test_atlas_archival_policy(self, vo, mock_scope, root_account, jdoe_account):
104105
""" UNDERTAKER (CORE): Test the atlas archival policy. """
105-
if get_policy() != 'atlas':
106-
LOG.info("Skipping atlas-specific test")
107-
return
108-
109106
nbdatasets = 5
110107
nbfiles = 5
111108

0 commit comments

Comments
 (0)