rucio 38.1.0__py3-none-any.whl → 38.3.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/bin_legacy/rucio.py +26 -23
- rucio/cli/command.py +36 -26
- rucio/cli/config.py +22 -7
- rucio/cli/did.py +1 -1
- rucio/cli/download.py +1 -1
- rucio/cli/opendata.py +60 -9
- rucio/cli/utils.py +13 -1
- rucio/client/configclient.py +23 -0
- rucio/client/richclient.py +6 -0
- rucio/common/constants.py +5 -0
- rucio/common/exception.py +10 -0
- rucio/common/plugins.py +24 -8
- rucio/common/utils.py +3 -3
- rucio/core/config.py +8 -6
- rucio/core/did_meta_plugins/did_column_meta.py +226 -69
- rucio/core/replica.py +3 -4
- rucio/core/request.py +7 -2
- rucio/core/rule.py +6 -3
- rucio/core/rule_grouping.py +2 -2
- rucio/daemons/abacus/account.py +1 -1
- rucio/daemons/abacus/collection_replica.py +1 -1
- rucio/daemons/abacus/rse.py +1 -1
- rucio/daemons/common.py +1 -1
- rucio/daemons/hermes/hermes.py +14 -13
- rucio/daemons/judge/cleaner.py +2 -2
- rucio/daemons/judge/evaluator.py +2 -2
- rucio/daemons/judge/injector.py +5 -4
- rucio/daemons/judge/repairer.py +2 -2
- rucio/gateway/config.py +2 -37
- rucio/gateway/rule.py +2 -2
- rucio/rse/translation.py +3 -3
- rucio/transfertool/fts3_plugins.py +3 -3
- rucio/vcsversion.py +3 -3
- rucio/web/rest/flaskapi/v1/config.py +52 -14
- {rucio-38.1.0.dist-info → rucio-38.3.0.dist-info}/METADATA +1 -1
- {rucio-38.1.0.dist-info → rucio-38.3.0.dist-info}/RECORD +95 -95
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/alembic.ini.template +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/rucio.cfg.template +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/requirements.server.txt +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/tools/bootstrap.py +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/data/rucio/tools/reset_database.py +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-abacus-account +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-abacus-collection-replica +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-abacus-rse +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-admin +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-atropos +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-auditor +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-automatix +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-bb8 +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-cache-client +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-cache-consumer +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-conveyor-finisher +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-conveyor-poller +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-conveyor-preparer +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-conveyor-receiver +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-conveyor-stager +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-conveyor-submitter +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-conveyor-throttler +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-dark-reaper +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-dumper +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-follower +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-hermes +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-judge-cleaner +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-judge-evaluator +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-judge-injector +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-judge-repairer +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-kronos +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-minos +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-necromancer +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-oauth-manager +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-reaper +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-replica-recoverer +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-rse-decommissioner +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-storage-consistency-actions +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-transmogrifier +0 -0
- {rucio-38.1.0.data → rucio-38.3.0.data}/scripts/rucio-undertaker +0 -0
- {rucio-38.1.0.dist-info → rucio-38.3.0.dist-info}/WHEEL +0 -0
- {rucio-38.1.0.dist-info → rucio-38.3.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {rucio-38.1.0.dist-info → rucio-38.3.0.dist-info}/licenses/LICENSE +0 -0
- {rucio-38.1.0.dist-info → rucio-38.3.0.dist-info}/top_level.txt +0 -0
rucio/daemons/judge/evaluator.py
CHANGED
|
@@ -92,12 +92,12 @@ def run_once(
|
|
|
92
92
|
worker_number=worker_number,
|
|
93
93
|
limit=did_limit,
|
|
94
94
|
blocked_dids=[(InternalScope(key[0], from_external=False), key[1]) for key in paused_dids])
|
|
95
|
-
logger(logging.DEBUG, '
|
|
95
|
+
logger(logging.DEBUG, 'Index query time %f fetch size is %d (%d blocked)', time.time() - start, len(dids),
|
|
96
96
|
len([(InternalScope(key[0], from_external=False), key[1]) for key in paused_dids]))
|
|
97
97
|
|
|
98
98
|
# If the list is empty, sent the worker to sleep
|
|
99
99
|
if not dids:
|
|
100
|
-
logger(logging.DEBUG, '
|
|
100
|
+
logger(logging.DEBUG, 'Did not get any work (paused_dids=%s)', str(len(paused_dids)))
|
|
101
101
|
return
|
|
102
102
|
|
|
103
103
|
done_dids = {}
|
rucio/daemons/judge/injector.py
CHANGED
|
@@ -83,10 +83,10 @@ def run_once(
|
|
|
83
83
|
worker_number=worker_number,
|
|
84
84
|
limit=100,
|
|
85
85
|
blocked_rules=[key for key in paused_rules])
|
|
86
|
-
logger(logging.DEBUG, '
|
|
86
|
+
logger(logging.DEBUG, 'Index query time %f fetch size is %d' % (time.time() - start, len(rules)))
|
|
87
87
|
|
|
88
88
|
if not rules:
|
|
89
|
-
logger(logging.DEBUG, '
|
|
89
|
+
logger(logging.DEBUG, 'Did not get any work (paused_rules=%s)' % str(len(paused_rules)))
|
|
90
90
|
return
|
|
91
91
|
|
|
92
92
|
for rule_id in rules:
|
|
@@ -97,12 +97,13 @@ def run_once(
|
|
|
97
97
|
try:
|
|
98
98
|
start = time.time()
|
|
99
99
|
inject_rule(rule_id=rule_id, logger=logger)
|
|
100
|
-
logger(logging.DEBUG, '
|
|
100
|
+
logger(logging.DEBUG, 'Injection of %s took %f' % (rule_id, time.time() - start))
|
|
101
101
|
except (DatabaseException, DatabaseError) as e:
|
|
102
102
|
if match(ORACLE_RESOURCE_BUSY_REGEX, str(e.args[0])) or match(PSQL_PSYCOPG_LOCK_NOT_AVAILABLE_REGEX, str(e.args[0])) or match(MYSQL_LOCK_NOWAIT_REGEX, str(e.args[0])):
|
|
103
103
|
paused_rules[rule_id] = datetime.utcnow() + timedelta(seconds=randint(60, 600)) # noqa: S311
|
|
104
104
|
METRICS.counter('exceptions.{exception}').labels(exception='LocksDetected').inc()
|
|
105
|
-
logger(logging.WARNING,
|
|
105
|
+
logger(logging.WARNING,
|
|
106
|
+
'Database locks detected for %s. Another instance might be processing this rule at the moment' % rule_id)
|
|
106
107
|
elif match('.*QueuePool.*', str(e.args[0])):
|
|
107
108
|
logger(logging.WARNING, 'DatabaseException', exc_info=True)
|
|
108
109
|
METRICS.counter('exceptions.{exception}').labels(exception=e.__class__.__name__).inc()
|
rucio/daemons/judge/repairer.py
CHANGED
|
@@ -90,10 +90,10 @@ def run_once(
|
|
|
90
90
|
limit=100,
|
|
91
91
|
blocked_rules=[key for key in paused_rules])
|
|
92
92
|
|
|
93
|
-
logger(logging.DEBUG, '
|
|
93
|
+
logger(logging.DEBUG, 'Index query time %f fetch size is %d' % (time.time() - start, len(rules)))
|
|
94
94
|
|
|
95
95
|
if not rules:
|
|
96
|
-
logger(logging.DEBUG, '
|
|
96
|
+
logger(logging.DEBUG, 'Did not get any work (paused_rules=%s)' % (str(len(paused_rules))))
|
|
97
97
|
return
|
|
98
98
|
|
|
99
99
|
for rule_id in rules:
|
rucio/gateway/config.py
CHANGED
|
@@ -47,23 +47,6 @@ def sections(issuer: str, vo: str = DEFAULT_VO) -> list[str]:
|
|
|
47
47
|
return config.sections(session=session)
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
def add_section(section: str, issuer: str, vo: str = DEFAULT_VO) -> None:
|
|
51
|
-
"""
|
|
52
|
-
Add a section to the configuration.
|
|
53
|
-
|
|
54
|
-
:param section: The name of the section.
|
|
55
|
-
:param issuer: The issuer account.
|
|
56
|
-
:param vo: The VO to act on.
|
|
57
|
-
"""
|
|
58
|
-
|
|
59
|
-
kwargs = {'issuer': issuer, 'section': section}
|
|
60
|
-
with db_session(DatabaseOperationType.WRITE) as session:
|
|
61
|
-
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_add_section', kwargs=kwargs, session=session)
|
|
62
|
-
if not auth_result.allowed:
|
|
63
|
-
raise exception.AccessDenied('%s cannot add section %s. %s' % (issuer, section, auth_result.message))
|
|
64
|
-
return config.add_section(section, session=session)
|
|
65
|
-
|
|
66
|
-
|
|
67
50
|
def has_section(section: str, issuer: str, vo: str = DEFAULT_VO) -> bool:
|
|
68
51
|
"""
|
|
69
52
|
Indicates whether the named section is present in the configuration.
|
|
@@ -79,25 +62,7 @@ def has_section(section: str, issuer: str, vo: str = DEFAULT_VO) -> bool:
|
|
|
79
62
|
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_has_section', kwargs=kwargs, session=session)
|
|
80
63
|
if not auth_result.allowed:
|
|
81
64
|
raise exception.AccessDenied('%s cannot check existence of section %s. %s' % (issuer, section, auth_result.message))
|
|
82
|
-
return config.has_section(section, session=session)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def options(section: str, issuer: str, vo: str = DEFAULT_VO) -> list[str]:
|
|
86
|
-
"""
|
|
87
|
-
Returns a list of options available in the specified section.
|
|
88
|
-
|
|
89
|
-
:param section: The name of the section.
|
|
90
|
-
:param issuer: The issuer account.
|
|
91
|
-
:param vo: The VO to act on.
|
|
92
|
-
:returns: ['option', ...]
|
|
93
|
-
"""
|
|
94
|
-
|
|
95
|
-
kwargs = {'issuer': issuer, 'section': section}
|
|
96
|
-
with db_session(DatabaseOperationType.READ) as session:
|
|
97
|
-
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_options', kwargs=kwargs, session=session)
|
|
98
|
-
if auth_result.allowed:
|
|
99
|
-
raise exception.AccessDenied('%s cannot retrieve options from section %s. %s' % (issuer, section, auth_result.message))
|
|
100
|
-
return config.options(section, session=session)
|
|
65
|
+
return config.has_section(section, session=session, use_cache=False)
|
|
101
66
|
|
|
102
67
|
|
|
103
68
|
def has_option(section: str, option: str, issuer: str, vo: str = DEFAULT_VO) -> bool:
|
|
@@ -116,7 +81,7 @@ def has_option(section: str, option: str, issuer: str, vo: str = DEFAULT_VO) ->
|
|
|
116
81
|
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_has_option', kwargs=kwargs, session=session)
|
|
117
82
|
if not auth_result.allowed:
|
|
118
83
|
raise exception.AccessDenied('%s cannot check existence of option %s from section %s. %s' % (issuer, option, section, auth_result.message))
|
|
119
|
-
return config.has_option(section, option, session=session)
|
|
84
|
+
return config.has_option(section, option, session=session, use_cache=False)
|
|
120
85
|
|
|
121
86
|
|
|
122
87
|
def get(section: str, option: str, issuer: str, vo: str = DEFAULT_VO) -> Any:
|
rucio/gateway/rule.py
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from typing import TYPE_CHECKING, Any, Literal, Optional
|
|
16
16
|
|
|
17
17
|
from rucio.common.config import config_get_bool
|
|
18
|
-
from rucio.common.constants import DEFAULT_VO
|
|
18
|
+
from rucio.common.constants import DEFAULT_ACTIVITY, DEFAULT_VO
|
|
19
19
|
from rucio.common.exception import AccessDenied
|
|
20
20
|
from rucio.common.schema import validate_schema
|
|
21
21
|
from rucio.common.types import InternalAccount, InternalScope
|
|
@@ -97,7 +97,7 @@ def add_replication_rule(
|
|
|
97
97
|
account = issuer
|
|
98
98
|
|
|
99
99
|
if activity is None:
|
|
100
|
-
activity =
|
|
100
|
+
activity = DEFAULT_ACTIVITY
|
|
101
101
|
|
|
102
102
|
kwargs = {'dids': dids, 'copies': copies, 'rse_expression': rse_expression, 'weight': weight, 'lifetime': lifetime,
|
|
103
103
|
'grouping': grouping, 'account': account, 'locked': locked, 'subscription_id': subscription_id,
|
rucio/rse/translation.py
CHANGED
|
@@ -18,7 +18,7 @@ from configparser import NoOptionError, NoSectionError
|
|
|
18
18
|
from typing import TYPE_CHECKING, Any, Optional
|
|
19
19
|
|
|
20
20
|
from rucio.common import config
|
|
21
|
-
from rucio.common.constants import DEFAULT_VO, RseAttr
|
|
21
|
+
from rucio.common.constants import DEFAULT_VO, POLICY_ALGORITHM_TYPES_LITERAL, RseAttr
|
|
22
22
|
from rucio.common.exception import ConfigNotFound
|
|
23
23
|
from rucio.common.plugins import PolicyPackageAlgorithms
|
|
24
24
|
|
|
@@ -33,7 +33,7 @@ class RSEDeterministicScopeTranslation(PolicyPackageAlgorithms):
|
|
|
33
33
|
Translates a pfn dictionary into a scope and name
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
|
-
_algorithm_type = "pfn2lfn"
|
|
36
|
+
_algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL = "pfn2lfn"
|
|
37
37
|
|
|
38
38
|
def __init__(self, vo: str = DEFAULT_VO):
|
|
39
39
|
super().__init__()
|
|
@@ -111,7 +111,7 @@ class RSEDeterministicTranslation(PolicyPackageAlgorithms):
|
|
|
111
111
|
"""
|
|
112
112
|
|
|
113
113
|
_DEFAULT_LFN2PFN = "hash"
|
|
114
|
-
_algorithm_type = "lfn2pfn"
|
|
114
|
+
_algorithm_type: POLICY_ALGORITHM_TYPES_LITERAL = "lfn2pfn"
|
|
115
115
|
|
|
116
116
|
def __init__(
|
|
117
117
|
self,
|
|
@@ -17,7 +17,7 @@ import sys
|
|
|
17
17
|
from typing import TYPE_CHECKING, Any, Optional, TypeVar
|
|
18
18
|
|
|
19
19
|
from rucio.common.config import config_get_int
|
|
20
|
-
from rucio.common.constants import DEFAULT_VO
|
|
20
|
+
from rucio.common.constants import DEFAULT_VO, POLICY_ALGORITHM_TYPES_LITERAL
|
|
21
21
|
from rucio.common.exception import InvalidRequest
|
|
22
22
|
from rucio.common.plugins import PolicyPackageAlgorithms
|
|
23
23
|
|
|
@@ -33,8 +33,8 @@ class FTS3TapeMetadataPlugin(PolicyPackageAlgorithms):
|
|
|
33
33
|
Plugins are registered during initialization and called during a transfer with FTS3
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
|
-
ALGORITHM_NAME = "fts3_tape_metadata_plugins"
|
|
37
|
-
_INIT_FUNC_NAME = "fts3_plugins_init"
|
|
36
|
+
ALGORITHM_NAME: POLICY_ALGORITHM_TYPES_LITERAL = "fts3_tape_metadata_plugins"
|
|
37
|
+
_INIT_FUNC_NAME: POLICY_ALGORITHM_TYPES_LITERAL = "fts3_plugins_init"
|
|
38
38
|
DEFAULT = "def"
|
|
39
39
|
|
|
40
40
|
def __init__(self, policy_algorithm: str) -> None:
|
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': '38.
|
|
7
|
+
'version': '38.3.0',
|
|
8
8
|
'branch_nick': 'release-38-LTS',
|
|
9
|
-
'revision_id': '
|
|
10
|
-
'revno':
|
|
9
|
+
'revision_id': '5eebc4e67a544dcb2d689bd45260cb73fb10066a',
|
|
10
|
+
'revno': 14003
|
|
11
11
|
}
|
|
@@ -12,6 +12,8 @@
|
|
|
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
|
|
16
|
+
|
|
15
17
|
from flask import Flask, jsonify
|
|
16
18
|
from flask import request as request
|
|
17
19
|
|
|
@@ -20,12 +22,15 @@ from rucio.gateway import config
|
|
|
20
22
|
from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
|
|
21
23
|
from rucio.web.rest.flaskapi.v1.common import ErrorHandlingMethodView, check_accept_header_wrapper_flask, generate_http_error_flask, json_parameters, response_headers
|
|
22
24
|
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from flask.typing import ResponseReturnValue
|
|
27
|
+
|
|
23
28
|
|
|
24
29
|
class Config(ErrorHandlingMethodView):
|
|
25
30
|
""" REST API for full configuration. """
|
|
26
31
|
|
|
27
32
|
@check_accept_header_wrapper_flask(['application/json'])
|
|
28
|
-
def get(self):
|
|
33
|
+
def get(self) -> 'ResponseReturnValue':
|
|
29
34
|
"""
|
|
30
35
|
---
|
|
31
36
|
summary: List
|
|
@@ -53,7 +58,7 @@ class Config(ErrorHandlingMethodView):
|
|
|
53
58
|
|
|
54
59
|
return jsonify(res), 200
|
|
55
60
|
|
|
56
|
-
def post(self):
|
|
61
|
+
def post(self) -> 'ResponseReturnValue':
|
|
57
62
|
"""
|
|
58
63
|
---
|
|
59
64
|
summary: Create
|
|
@@ -97,7 +102,7 @@ class Section(ErrorHandlingMethodView):
|
|
|
97
102
|
""" REST API for the sections in the configuration. """
|
|
98
103
|
|
|
99
104
|
@check_accept_header_wrapper_flask(['application/json'])
|
|
100
|
-
def get(self, section):
|
|
105
|
+
def get(self, section: str) -> 'ResponseReturnValue':
|
|
101
106
|
"""
|
|
102
107
|
---
|
|
103
108
|
summary: List Sections
|
|
@@ -136,25 +141,55 @@ class Section(ErrorHandlingMethodView):
|
|
|
136
141
|
406:
|
|
137
142
|
description: "Not acceptable"
|
|
138
143
|
"""
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
if config.has_section(section, issuer=request.environ['issuer'], vo=request.environ['vo']):
|
|
145
|
+
res = {}
|
|
146
|
+
for item in config.items(section, issuer=request.environ['issuer'], vo=request.environ['vo']):
|
|
147
|
+
res[item[0]] = item[1]
|
|
148
|
+
return jsonify(res), 200
|
|
142
149
|
|
|
143
|
-
|
|
150
|
+
else:
|
|
144
151
|
return generate_http_error_flask(
|
|
145
152
|
status_code=404,
|
|
146
153
|
exc=ConfigNotFound.__name__,
|
|
147
154
|
exc_msg=f"No configuration found for section '{section}'"
|
|
148
155
|
)
|
|
149
156
|
|
|
150
|
-
|
|
157
|
+
def delete(self, section: str) -> 'ResponseReturnValue':
|
|
158
|
+
"""
|
|
159
|
+
---
|
|
160
|
+
summary: Remove an existing section
|
|
161
|
+
tags:
|
|
162
|
+
- Config
|
|
163
|
+
parameters:
|
|
164
|
+
- name: section
|
|
165
|
+
in: path
|
|
166
|
+
description: "The section."
|
|
167
|
+
responses:
|
|
168
|
+
200:
|
|
169
|
+
description: "OK"
|
|
170
|
+
401:
|
|
171
|
+
description: "Invalid Auth Token"
|
|
172
|
+
404:
|
|
173
|
+
description: "Config not found"
|
|
174
|
+
406:
|
|
175
|
+
description: "Not acceptable"
|
|
176
|
+
"""
|
|
177
|
+
if config.has_section(section, issuer=request.environ['issuer'], vo=request.environ['vo']):
|
|
178
|
+
config.remove_section(section, issuer=request.environ['issuer'], vo=request.environ['vo'])
|
|
179
|
+
return '', 200
|
|
180
|
+
else:
|
|
181
|
+
return generate_http_error_flask(
|
|
182
|
+
status_code=404,
|
|
183
|
+
exc=ConfigNotFound.__name__,
|
|
184
|
+
exc_msg=f"No configuration found for section '{section}'"
|
|
185
|
+
)
|
|
151
186
|
|
|
152
187
|
|
|
153
188
|
class OptionGetDel(ErrorHandlingMethodView):
|
|
154
189
|
""" REST API for reading or deleting the options in the configuration. """
|
|
155
190
|
|
|
156
191
|
@check_accept_header_wrapper_flask(['application/json'])
|
|
157
|
-
def get(self, section, option):
|
|
192
|
+
def get(self, section: str, option: str) -> 'ResponseReturnValue':
|
|
158
193
|
"""
|
|
159
194
|
---
|
|
160
195
|
summary: Get option
|
|
@@ -197,7 +232,7 @@ class OptionGetDel(ErrorHandlingMethodView):
|
|
|
197
232
|
except ConfigNotFound as error:
|
|
198
233
|
return generate_http_error_flask(404, error, f"No configuration found for section '{section}' option '{option}'")
|
|
199
234
|
|
|
200
|
-
def delete(self, section, option):
|
|
235
|
+
def delete(self, section: str, option: str) -> 'ResponseReturnValue':
|
|
201
236
|
"""
|
|
202
237
|
---
|
|
203
238
|
summary: Delete option
|
|
@@ -223,14 +258,17 @@ class OptionGetDel(ErrorHandlingMethodView):
|
|
|
223
258
|
401:
|
|
224
259
|
description: "Invalid Auth Token"
|
|
225
260
|
"""
|
|
226
|
-
config.
|
|
227
|
-
|
|
261
|
+
if config.has_option(section, option, issuer=request.environ['issuer'], vo=request.environ['vo']):
|
|
262
|
+
config.remove_option(section=section, option=option, issuer=request.environ['issuer'], vo=request.environ['vo'])
|
|
263
|
+
return '', 200
|
|
264
|
+
else:
|
|
265
|
+
return generate_http_error_flask(404, ConfigNotFound.__name__, f"No configuration found for section '{section}' option '{option}'")
|
|
228
266
|
|
|
229
267
|
|
|
230
268
|
class OptionSet(ErrorHandlingMethodView):
|
|
231
269
|
""" REST API for setting the options in the configuration. """
|
|
232
270
|
|
|
233
|
-
def put(self, section, option, value):
|
|
271
|
+
def put(self, section: str, option: str, value: str) -> 'ResponseReturnValue':
|
|
234
272
|
"""
|
|
235
273
|
---
|
|
236
274
|
summary: Create value
|
|
@@ -289,7 +327,7 @@ def blueprint() -> AuthenticatedBlueprint:
|
|
|
289
327
|
option_get_del_view = OptionGetDel.as_view('option_get_del')
|
|
290
328
|
bp.add_url_rule('/<section>/<option>', view_func=option_get_del_view, methods=['get', 'delete'])
|
|
291
329
|
section_view = Section.as_view('section')
|
|
292
|
-
bp.add_url_rule('/<section>', view_func=section_view, methods=['get', ])
|
|
330
|
+
bp.add_url_rule('/<section>', view_func=section_view, methods=['get', 'delete'])
|
|
293
331
|
config_view = Config.as_view('config')
|
|
294
332
|
bp.add_url_rule('', view_func=config_view, methods=['get', 'post'])
|
|
295
333
|
|