diff --git a/etc/trove/trove.conf.test b/etc/trove/trove.conf.test index 349b7388e0..ed6741824e 100644 --- a/etc/trove/trove.conf.test +++ b/etc/trove/trove.conf.test @@ -73,9 +73,6 @@ http_delete_rate = 500 # default datastore default_datastore = a00000a0-00a0-0a00-00a0-000a000000aa -# Auth -admin_roles = admin - # Users to ignore for user create/list/delete operations ignore_users = os_admin, root ignore_dbs = lost+found, mysql, information_schema diff --git a/releasenotes/notes/deprecate-admin-roles-4c42d4be4e8ee950.yaml b/releasenotes/notes/deprecate-admin-roles-4c42d4be4e8ee950.yaml new file mode 100644 index 0000000000..66aa3e3a7a --- /dev/null +++ b/releasenotes/notes/deprecate-admin-roles-4c42d4be4e8ee950.yaml @@ -0,0 +1,5 @@ +--- +deprecations: + - | + The ``[DEFAULT] admin_roles`` option has been deprecated in favor of + the new ``context_is_admin`` policy rule. diff --git a/trove/common/cfg.py b/trove/common/cfg.py index 1ce864067a..9198f52d2c 100644 --- a/trove/common/cfg.py +++ b/trove/common/cfg.py @@ -70,7 +70,9 @@ common_opts = [ help='Whether to provision a Cinder volume for rootdisk.'), cfg.IntOpt('volume_rootdisk_size', default=10, help='Size of volume rootdisk for Database instance'), - cfg.ListOpt('admin_roles', default=['admin'], + cfg.ListOpt('admin_roles', default=[], + deprecated_for_removal=True, + deprecated_reason=_('Use the context_is_admin policy rule'), help='Roles to add to an admin user.'), cfg.BoolOpt('update_status_on_fail', default=True, help='Set the service and instance task statuses to ERROR ' diff --git a/trove/common/policies/base.py b/trove/common/policies/base.py index 35c9cb7e8f..389a43a009 100644 --- a/trove/common/policies/base.py +++ b/trove/common/policies/base.py @@ -12,6 +12,8 @@ from oslo_policy import policy +ADMIN_CTX_POLICY = 'context_is_admin' + PATH_BASE = '/v1.0/{account_id}' PATH_INSTANCES = PATH_BASE + '/instances' @@ -51,6 +53,10 @@ PATH_MODULES = PATH_BASE + '/modules' PATH_MODULE = PATH_MODULES + '/{module}' rules = [ + policy.RuleDefault( + ADMIN_CTX_POLICY, + 'role:admin', + description='Rule for cloud admin access'), policy.RuleDefault( 'admin', 'role:admin or is_admin:True', diff --git a/trove/common/policy.py b/trove/common/policy.py index 12d8e9a511..1c9d795511 100644 --- a/trove/common/policy.py +++ b/trove/common/policy.py @@ -20,6 +20,7 @@ from oslo_policy import policy from trove.common import exception as trove_exceptions from trove.common import policies +from trove.common.policies import base CONF = cfg.CONF _ENFORCER = None @@ -51,6 +52,13 @@ def authorize_on_target(context, rule, target): "BUG: Target must not evaluate to False.") +def check_is_admin(context): + try: + return authorize_on_tenant(context, base.ADMIN_CTX_POLICY) + except trove_exceptions.PolicyNotAuthorized: + return False + + def __authorize(context, rule, target=None): """Checks authorization of a rule against the target in this context. diff --git a/trove/common/wsgi.py b/trove/common/wsgi.py index 1e126385b3..f7a007bf0f 100644 --- a/trove/common/wsgi.py +++ b/trove/common/wsgi.py @@ -37,6 +37,7 @@ from trove.common import context as rd_context from trove.common import exception from trove.common.i18n import _ from trove.common import pastedeploy +from trove.common import policy from trove.common import utils CONTEXT_KEY = 'trove.context' @@ -541,10 +542,6 @@ class ContextMiddleware(base_wsgi.Middleware): user_id = request.headers.get('X-User-ID', None) roles = request.headers.get('X-Role', '').split(',') is_admin = False - for role in roles: - if role.lower() in self.admin_roles: - is_admin = True - break limits = self._extract_limits(request.params) context = rd_context.TroveContext(auth_token=auth_token, project_id=tenant_id, @@ -554,6 +551,13 @@ class ContextMiddleware(base_wsgi.Middleware): marker=limits.get('marker'), service_catalog=service_catalog, roles=roles) + if self.admin_roles: + for role in roles: + if role.lower() in self.admin_roles: + context.is_admin = True + break + else: + context.is_admin = policy.check_is_admin(context) request.environ[CONTEXT_KEY] = context @classmethod