Merge "Revert "Add JSON driver for access rules config""

This commit is contained in:
Zuul 2019-06-27 07:35:45 +00:00 committed by Gerrit Code Review
commit 8f1e4cf348
14 changed files with 0 additions and 1278 deletions

View File

@ -1,31 +0,0 @@
# Copyright 2019 SUSE Linux GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import abc
import six
@six.add_metaclass(abc.ABCMeta)
class AccessRulesConfigDriverBase(object):
@abc.abstractmethod
def list_access_rules_config(self, service=None):
"""List access rules config."""
raise NotImplementedError() # pragma: no cover
@abc.abstractmethod
def check_access_rule(self, service, request_path, request_method):
"""Check if an access rule exists in config."""
raise NotImplementedError() # pragma: no cover

View File

@ -1,160 +0,0 @@
# Copyright 2019 SUSE Linux GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import re
from oslo_log import log
from oslo_serialization import jsonutils
from keystone.access_rules_config.backends import base
import keystone.conf
from keystone import exception
CONF = keystone.conf.CONF
LOG = log.getLogger(__name__)
class AccessRulesConfig(base.AccessRulesConfigDriverBase):
"""This backend reads the access rules from a JSON file on disk.
The format of the file is a mapping from service type to rules for that
service type. For example::
{
"identity": [
{
"path": "/v3/users",
"method": "GET"
},
{
"path": "/v3/users",
"method": "POST"
},
{
"path": "/v3/users/*",
"method": "GET"
},
{
"path": "/v3/users/*",
"method": "PATCH"
},
{
"path": "/v3/users/*",
"method": "DELETE"
}
...
],
"image": [
{
"path": "/v2/images",
"method": "GET"
},
...
],
...
}
This will be transmuted in memory to a hash map that looks like this::
{
"identity": {
"GET": [
{
"path": "/v3/users"
},
{
"path": "/v3/users/*"
}
...
],
"POST": [ ... ]
},
...
}
The path may include a wildcard like '*' or '**' or a named wildcard like
{server_id}. An application credential access rule validation request for
a path like "/v3/users/uuid" will match with a configured access rule like
"/v3/users/*" or "/v3/users/{user_id}", and a request for a path like
"/v3/users/uuid/application_credentials/uuid" will match with a configured
access rule like "/v3/users/**".
"""
def __init__(self):
super(AccessRulesConfig, self).__init__()
access_rules_file = CONF.access_rules_config.rules_file
self.access_rules = dict()
self.access_rules_json = dict()
try:
with open(access_rules_file, "rb") as f:
self.access_rules_json = jsonutils.load(f)
except IOError:
LOG.warning('No config file found for access rules, application'
' credential access rules will be unavailable.')
return
except ValueError as e:
raise exception.AccessRulesConfigFileError(error=e)
for service, rules in self.access_rules_json.items():
self.access_rules[service] = dict()
for rule in rules:
try:
self.access_rules[service].setdefault(
rule['method'], []).append({
'path': rule['path']
})
except KeyError as e:
raise exception.AccessRulesConfigFileError(error=e)
def _path_matches(self, request_path, path_pattern):
# The fnmatch module doesn't provide the ability to match * versus **,
# so convert to regex.
# replace {tags} with *
pattern = r'{[^}]*}'
replace = r'*'
path_regex = re.sub(pattern, replace, path_pattern)
# temporarily sub out **
pattern = r'([^\*]*)\*\*([^\*]*)'
replace = r'\1%TMP%\2'
path_regex = re.sub(pattern, replace, path_regex)
# replace * with [^\/]* (all except /)
pattern = r'([^\*]?)\*($|[^\*])'
replace = r'\1[^\/]*\2'
path_regex = re.sub(pattern, replace, path_regex)
# replace ** with .* (includes /)
pattern = r'%TMP%'
replace = '.*'
path_regex = re.sub(pattern, replace, path_regex)
path_regex = r'^%s$' % path_regex
regex = re.compile(path_regex)
return regex.match(request_path)
def list_access_rules_config(self, service=None):
"""List access rules config in human readable form."""
if service:
if service not in self.access_rules_json:
raise exception.AccessRulesConfigNotFound(service=service)
return {service: self.access_rules_json[service]}
return self.access_rules_json
def check_access_rule(self, service, request_path, request_method):
"""Check if an access rule exists in config."""
if (service in self.access_rules
and request_method in self.access_rules[service]):
rules = self.access_rules[service][request_method]
for rule in rules:
if self._path_matches(request_path, rule['path']):
return True
return False

View File

@ -20,7 +20,6 @@ import oslo_messaging
from oslo_middleware import cors
from osprofiler import opts as profiler
from keystone.conf import access_rules_config
from keystone.conf import application_credential
from keystone.conf import assignment
from keystone.conf import auth
@ -59,7 +58,6 @@ CONF = cfg.CONF
conf_modules = [
access_rules_config,
application_credential,
assignment,
auth,

View File

@ -1,68 +0,0 @@
# Copyright 2019 SUSE Linux GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from keystone.conf import utils
driver = cfg.StrOpt(
'driver',
default='json',
help=utils.fmt("""
Entry point for the access rules config backend driver in the
`keystone.access_rules_config` namespace. Keystone only provides a `json`
driver, so there is no reason to change this unless you are providing a custom
entry point.
"""))
caching = cfg.BoolOpt(
'caching',
default=True,
help=utils.fmt("""
Toggle for access rules caching. This has no effect unless global caching is
enabled.
"""))
cache_time = cfg.IntOpt(
'cache_time',
help=utils.fmt("""
Time to cache access rule data in seconds. This has no effect unless global
caching is enabled.
"""))
rules_file = cfg.StrOpt(
'rules_file',
default='/etc/keystone/access_rules.json',
help=utils.fmt("""
Path to access rules configuration. If not present, no access rule
configuration will be loaded and application credential access rules will be
unavailable.
"""))
GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [
driver,
caching,
cache_time,
rules_file,
]
def register_opts(conf):
conf.register_opts(ALL_OPTS, group=GROUP_NAME)
def list_opts():
return {GROUP_NAME: ALL_OPTS}

View File

@ -549,11 +549,6 @@ class ApplicationCredentialNotFound(NotFound):
"%(application_credential_id)s.")
class AccessRulesConfigNotFound(NotFound):
message_format = _(
"Could not find access rules config for service %(service)s.")
class Conflict(Error):
message_format = _("Conflict occurred attempting to store %(type)s -"
" %(details)s.")
@ -714,8 +709,3 @@ class CacheDeserializationError(Exception):
'obj': obj, 'data': data
}
)
class AccessRulesConfigFileError(UnexpectedError):
debug_message_format = _(
'Could not parse access rules config file: %(error)s')

View File

@ -1,84 +0,0 @@
# Copyright 2019 SUSE Linux GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import uuid
from keystone.access_rules_config.backends import json as json_driver
from keystone import exception
from keystone.tests import unit
from keystone.tests.unit.ksfixtures import access_rules_config
from keystone.tests.unit.ksfixtures import temporaryfile
class JSONDriverTestCase(unit.TestCase):
"""Tests for validating the access rules config driver."""
def setUp(self):
super(JSONDriverTestCase, self).setUp()
rules_file = '%s/access_rules.json' % unit.TESTCONF
self.useFixture(access_rules_config.AccessRulesConfig(
self.config_fixture, rules_file=rules_file))
self.driver = json_driver.AccessRulesConfig()
def test_invalid_json_raises_error(self):
tmpfile = self.useFixture(temporaryfile.SecureTempFile())
invalid_access_rules = tmpfile.file_name
with open(invalid_access_rules, 'w') as f:
f.write("This is an invalid data")
self.useFixture(access_rules_config.AccessRulesConfig(
self.config_fixture, rules_file=invalid_access_rules))
self.assertRaises(exception.AccessRulesConfigFileError,
json_driver.AccessRulesConfig)
def test_list_access_rules_config(self):
rules = self.driver.list_access_rules_config()
self.assertIn('identity', rules)
self.assertIn('image', rules)
def test_list_access_rules_config_for_service(self):
rules = self.driver.list_access_rules_config(service='image')
self.assertNotIn('identity', rules)
self.assertIn('image', rules)
def test_check_access_rule(self):
result = self.driver.check_access_rule('identity', '/v3/users', 'GET')
self.assertTrue(result)
userid = uuid.uuid4().hex
check_path = '/v3/users/%(userid)s' % {'userid': userid}
result = self.driver.check_access_rule('identity', check_path, 'GET')
self.assertTrue(result)
img = uuid.uuid4().hex
memb = uuid.uuid4().hex
check_path = '/v2/images/%(img)s/members/%(memb)s' % {'img': img,
'memb': memb}
result = self.driver.check_access_rule('image', check_path, 'PUT')
self.assertTrue(result)
result = self.driver.check_access_rule('image', '/servers', 'GET')
self.assertFalse(result)
result = self.driver.check_access_rule('glance', '/v2/images', 'GET')
self.assertFalse(result)
result = self.driver.check_access_rule('image', 'images', 'POST')
self.assertFalse(result)
projectid = uuid.uuid4().hex
check_path = '/v3/%(projectid)s/volumes' % {'projectid': projectid}
result = self.driver.check_access_rule('block-storage', check_path,
'GET')
self.assertTrue(result)
check_path = '/v2/%(projectid)s/volumes' % {'projectid': projectid}
result = self.driver.check_access_rule('block-storage', check_path,
'GET')
self.assertFalse(result)
result = self.driver.check_access_rule('compute', '/v2.1/servers',
'GET')
self.assertTrue(result)

View File

@ -1,890 +0,0 @@
{
"identity": [
{
"path": "/v3/users/*/application_credentials",
"method": "POST"
},
{
"path": "/v3/users/*/application_credentials",
"method": "GET"
},
{
"path": "/v3/users/*/application_credentials/*",
"method": "GET"
},
{
"path": "/v3/users/*/application_credentials/*",
"method": "DELETE"
},
{
"path": "/v3/auth/catalog",
"method": "GET"
},
{
"path": "/v3/auth/projects",
"method": "GET"
},
{
"path": "/v3/auth/domains",
"method": "GET"
},
{
"path": "/v3/auth/system",
"method": "GET"
},
{
"path": "/v3/credentials",
"method": "POST"
},
{
"path": "/v3/credentials",
"method": "GET"
},
{
"path": "/v3/credentials/*",
"method": "GET"
},
{
"path": "/v3/credentials/*",
"method": "PATCH"
},
{
"path": "/v3/credentials/*",
"method": "DELETE"
},
{
"path": "/v3/domains/config/default",
"method": "GET"
},
{
"path": "/v3/domains/config/*/default",
"method": "GET"
},
{
"path": "/v3/domains/config/*/*/default",
"method": "GET"
},
{
"path": "/v3/domains/*/config/*/*",
"method": "GET"
},
{
"path": "/v3/domains/*/config/*/*",
"method": "PATCH"
},
{
"path": "/v3/domains/*/config/*/*",
"method": "DELETE"
},
{
"path": "/v3/domains/*/config/*",
"method": "GET"
},
{
"path": "/v3/domains/*/config/*",
"method": "PATCH"
},
{
"path": "/v3/domains/*/config/*",
"method": "DELETE"
},
{
"path": "/v3/domains/*/config",
"method": "PUT"
},
{
"path": "/v3/domains/*/config",
"method": "GET"
},
{
"path": "/v3/domains/*/config",
"method": "PATCH"
},
{
"path": "/v3/domains/*/config",
"method": "DELETE"
},
{
"path": "/v3/domains",
"method": "GET"
},
{
"path": "/v3/domains",
"method": "POST"
},
{
"path": "/v3/domains/*",
"method": "GET"
},
{
"path": "/v3/domains/*",
"method": "PATCH"
},
{
"path": "/v3/domains/*",
"method": "DELETE"
},
{
"path": "/v3/groups",
"method": "GET"
},
{
"path": "/v3/groups",
"method": "POST"
},
{
"path": "/v3/groups/*",
"method": "GET"
},
{
"path": "/v3/groups/*",
"method": "PATCH"
},
{
"path": "/v3/groups/*",
"method": "DELETE"
},
{
"path": "/v3/groups/*/users",
"method": "GET"
},
{
"path": "/v3/groups/*/users/*",
"method": "PUT"
},
{
"path": "/v3/groups/*/users/*",
"method": "HEAD"
},
{
"path": "/v3/groups/*/users/*",
"method": "DELETE"
},
{
"path": "/v3/OS-INHERIT/domains/*/users/*/roles/*/inherited_to_projects",
"method": "PUT"
},
{
"path": "/v3/OS-INHERIT/domains/*/groups/*/roles/*/inherited_to_projects",
"method": "PUT"
},
{
"path": "/v3/OS-INHERIT/domains/*/users/*/roles/inherited_to_projects",
"method": "GET"
},
{
"path": "/v3/OS-INHERIT/domains/*/groups/*/roles/inherited_to_projects",
"method": "GET"
},
{
"path": "/v3/OS-INHERIT/domains/*/users/*/roles/*/inherited_to_projects",
"method": "HEAD"
},
{
"path": "/v3/OS-INHERIT/domains/*/groups/*/roles/*/inherited_to_projects",
"method": "HEAD"
},
{
"path": "/v3/OS-INHERIT/domains/*/users/*/roles/*/inherited_to_projects",
"method": "DELETE"
},
{
"path": "/v3/OS-INHERIT/domains/*/groups/*/roles/*/inherited_to_projects",
"method": "DELETE"
},
{
"path": "/v3/OS-INHERIT/projects/*/users/*/roles/*/inherited_to_projects",
"method": "PUT"
},
{
"path": "/v3/OS-INHERIT/projects/*/groups/*/roles/*/inherited_to_projects",
"method": "PUT"
},
{
"path": "/v3/OS-INHERIT/projects/*/users/*/roles/*/inherited_to_projects",
"method": "HEAD"
},
{
"path": "/v3/OS-INHERIT/projects/*/groups/*/roles/*/inherited_to_projects",
"method": "HEAD"
},
{
"path": "/v3/OS-INHERIT/projects/*/users/*/roles/*/inherited_to_projects",
"method": "DELETE"
},
{
"path": "/v3/OS-INHERIT/projects/*/groups/*/roles/*/inherited_to_projects",
"method": "DELETE"
},
{
"path": "/v3/role_assignments",
"method": "GET"
},
{
"path": "/v3/auth/tokens/OS-PKI/revoked",
"method": "GET"
},
{
"path": "/v3/policies",
"method": "POST"
},
{
"path": "/v3/policies",
"method": "GET"
},
{
"path": "/v3/policies/*",
"method": "GET"
},
{
"path": "/v3/policies/*",
"method": "PATCH"
},
{
"path": "/v3/policies/*",
"method": "DELETE"
},
{
"path": "/v3/projects/*/tags",
"method": "GET"
},
{
"path": "/v3/projects/*/tags",
"method": "PUT"
},
{
"path": "/v3/projects/*/tags",
"method": "DELETE"
},
{
"path": "/v3/projects/*/tags/*",
"method": "GET"
},
{
"path": "/v3/projects/*/tags/*",
"method": "PUT"
},
{
"path": "/v3/projects/*/tags/*",
"method": "DELETE"
},
{
"path": "/v3/projects",
"method": "GET"
},
{
"path": "/v3/projects",
"method": "POST"
},
{
"path": "/v3/projects/*",
"method": "GET"
},
{
"path": "/v3/projects/*",
"method": "PATCH"
},
{
"path": "/v3/projects/*",
"method": "DELETE"
},
{
"path": "/v3/regions/*",
"method": "GET"
},
{
"path": "/v3/regions/*",
"method": "PATCH"
},
{
"path": "/v3/regions/*",
"method": "DELETE"
},
{
"path": "/v3/regions",
"method": "GET"
},
{
"path": "/v3/regions",
"method": "POST"
},
{
"path": "/v3/roles",
"method": "GET"
},
{
"path": "/v3/roles",
"method": "POST"
},
{
"path": "/v3/roles/*",
"method": "GET"
},
{
"path": "/v3/roles/*",
"method": "PATCH"
},
{
"path": "/v3/roles/*",
"method": "DELETE"
},
{
"path": "/v3/domains/*/groups/*/roles",
"method": "GET"
},
{
"path": "/v3/domains/*/groups/*/roles/*",
"method": "PUT"
},
{
"path": "/v3/domains/*/groups/*/roles/*",
"method": "HEAD"
},
{
"path": "/v3/domains/*/groups/*/roles/*",
"method": "DELETE"
},
{
"path": "/v3/domains/*/users/*/roles",
"method": "GET"
},
{
"path": "/v3/domains/*/users/*/roles/*",
"method": "PUT"
},
{
"path": "/v3/domains/*/users/*/roles/*",
"method": "HEAD"
},
{
"path": "/v3/domains/*/users/*/roles/*",
"method": "DELETE"
},
{
"path": "/v3/projects/*/groups/*/roles",
"method": "GET"
},
{
"path": "/v3/projects/*/groups/*/roles/*",
"method": "PUT"
},
{
"path": "/v3/projects/*/groups/*/roles/*",
"method": "HEAD"
},
{
"path": "/v3/projects/*/groups/*/roles/*",
"method": "DELETE"
},
{
"path": "/v3/projects/*/users/*/roles",
"method": "GET"
},
{
"path": "/v3/projects/*/users/*/roles/*",
"method": "PUT"
},
{
"path": "/v3/projects/*/users/*/roles/*",
"method": "HEAD"
},
{
"path": "/v3/projects/*/users/*/roles/*",
"method": "DELETE"
},
{
"path": "/v3/roles/*/implies",
"method": "GET"
},
{
"path": "/v3/roles/*/implies/*",
"method": "PUT"
},
{
"path": "/v3/roles/*/implies/*",
"method": "GET"
},
{
"path": "/v3/roles/*/implies/*",
"method": "HEAD"
},
{
"path": "/v3/roles/*/implies/*",
"method": "DELETE"
},
{
"path": "/v3/role_assignments",
"method": "GET"
},
{
"path": "/v3/role_inferences",
"method": "GET"
},
{
"path": "/v3/services",
"method": "GET"
},
{
"path": "/v3/services",
"method": "POST"
},
{
"path": "/v3/services/*",
"method": "GET"
},
{
"path": "/v3/services/*",
"method": "PATCH"
},
{
"path": "/v3/services/*",
"method": "DELETE"
},
{
"path": "/v3/endpoints",
"method": "GET"
},
{
"path": "/v3/endpoints",
"method": "POST"
},
{
"path": "/v3/endpoints/*",
"method": "GET"
},
{
"path": "/v3/endpoints/*",
"method": "PATCH"
},
{
"path": "/v3/endpoints/*",
"method": "DELETE"
},
{
"path": "/v3/system/users/*/roles",
"method": "GET"
},
{
"path": "/v3/system/users/*/roles/*",
"method": "PUT"
},
{
"path": "/v3/system/users/*/roles/*",
"method": "HEAD"
},
{
"path": "/v3/system/users/*/roles/*",
"method": "GET"
},
{
"path": "/v3/system/users/*/roles/*",
"method": "DELETE"
},
{
"path": "/v3/system/groups/*/roles",
"method": "GET"
},
{
"path": "/v3/system/groups/*/roles/*",
"method": "PUT"
},
{
"path": "/v3/system/groups/*/roles/*",
"method": "HEAD"
},
{
"path": "/v3/system/groups/*/roles/*",
"method": "GET"
},
{
"path": "/v3/system/groups/*/roles/*",
"method": "DELETE"
},
{
"path": "/v3/registered_limits",
"method": "GET"
},
{
"path": "/v3/registered_limits",
"method": "POST"
},
{
"path": "/v3/registered_limits/*",
"method": "PATCH"
},
{
"path": "/v3/registered_limits/*",
"method": "GET"
},
{
"path": "/v3/registered_limits/*",
"method": "DELETE"
},
{
"path": "/v3/limits/model",
"method": "GET"
},
{
"path": "/v3/limits",
"method": "GET"
},
{
"path": "/v3/limits",
"method": "POST"
},
{
"path": "/v3/limits/*",
"method": "PATCH"
},
{
"path": "/v3/limits/*",
"method": "GET"
},
{
"path": "/v3/limits/*",
"method": "DELETE"
},
{
"path": "/v3/users",
"method": "GET"
},
{
"path": "/v3/users",
"method": "POST"
},
{
"path": "/v3/users/*",
"method": "GET"
},
{
"path": "/v3/users/*",
"method": "PATCH"
},
{
"path": "/v3/users/*",
"method": "DELETE"
},
{
"path": "/v3/users/*/groups",
"method": "GET"
},
{
"path": "/v3/users/*/projects",
"method": "GET"
},
{
"path": "/v3/users/*/password",
"method": "POST"
}
],
"image": [
{
"path": "/v1/images",
"method": "POST"
},
{
"path": "/v1/images",
"method": "GET"
},
{
"path": "/v1/images/detail",
"method": "GET"
},
{
"path": "/v1/images/*",
"method": "PUT"
},
{
"path": "/v1/images/*",
"method": "GET"
},
{
"path": "/v1/images/*",
"method": "HEAD"
},
{
"path": "/v1/images/*",
"method": "DELETE"
},
{
"path": "/v1/images/*/members/*",
"method": "PUT"
},
{
"path": "/v1/images/*/members",
"method": "PUT"
},
{
"path": "/v1/images/*/members/*",
"method": "DELETE"
},
{
"path": "/v1/shared-images/*",
"method": "GET"
},
{
"path": "/v2/images/*/file",
"method": "PUT"
},
{
"path": "/v2/images/*/file",
"method": "GET"
},
{
"path": "/v2/images",
"method": "POST"
},
{
"path": "/v2/images/*",
"method": "GET"
},
{
"path": "/v2/images",
"method": "GET"
},
{
"path": "/v2/images/*",
"method": "PATCH"
},
{
"path": "/v2/images/*",
"method": "DELETE"
},
{
"path": "/v2/images/*/actions/deactivate",
"method": "POST"
},
{
"path": "/v2/images/*/actions/reactivate",
"method": "POST"
},
{
"path": "/v2/schemas/images",
"method": "GET"
},
{
"path": "/v2/schemas/image",
"method": "GET"
},
{
"path": "/v2/schemas/members",
"method": "GET"
},
{
"path": "/v2/schemas/member",
"method": "GET"
},
{
"path": "/v2/images/*/members",
"method": "POST"
},
{
"path": "/v2/images/*/members/*",
"method": "GET"
},
{
"path": "/v2/images/*/members",
"method": "GET"
},
{
"path": "/v2/images/*/members/*",
"method": "PUT"
},
{
"path": "/v2/images/*/members/*",
"method": "DELETE"
},
{
"path": "/v2/images/*/tags/*",
"method": "PUT"
},
{
"path": "/v2/images/*/tags/*",
"method": "DELETE"
},
{
"path": "/v2/metadefs/namespaces/*/objects",
"method": "POST"
},
{
"path": "/v2/metadefs/namespaces/*/objects",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*/objects/*",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*/objects/*",
"method": "PUT"
},
{
"path": "/v2/metadefs/namespaces/*/objects/*",
"method": "DELETE"
},
{
"path": "/v2/metadefs/namespaces/*/properties",
"method": "POST"
},
{
"path": "/v2/metadefs/namespaces/*/properties",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*/properties/*",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*/properties/*",
"method": "PUT"
},
{
"path": "/v2/metadefs/namespaces/*/properties/*",
"method": "DELETE"
},
{
"path": "/v2/metadefs/namespaces/*/tags/*",
"method": "POST"
},
{
"path": "/v2/metadefs/namespaces/*/tags/*",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*/tags/*",
"method": "PUT"
},
{
"path": "/v2/metadefs/namespaces/*/tags/*",
"method": "DELETE"
},
{
"path": "/v2/metadefs/namespaces/*/tags",
"method": "POST"
},
{
"path": "/v2/metadefs/namespaces/*/tags",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*/tags",
"method": "DELETE"
},
{
"path": "/v2/metadefs/namespaces",
"method": "POST"
},
{
"path": "/v2/metadefs/namespaces",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*",
"method": "PUT"
},
{
"path": "/v2/metadefs/namespaces/*",
"method": "DELETE"
},
{
"path": "/v2/metadefs/resource_types",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*/resource_types",
"method": "POST"
},
{
"path": "/v2/metadefs/namespaces/*/resource_types",
"method": "GET"
},
{
"path": "/v2/metadefs/namespaces/*/resource_types/*",
"method": "DELETE"
},
{
"path": "/v2/schemas/metadefs/namespace",
"method": "GET"
},
{
"path": "/v2/schemas/metadefs/namespaces",
"method": "GET"
},
{
"path": "/v2/schemas/metadefs/resource_type",
"method": "GET"
},
{
"path": "/v2/schemas/metadefs/resource_types",
"method": "GET"
},
{
"path": "/v2/schemas/metadefs/object",
"method": "GET"
},
{
"path": "/v2/schemas/metadefs/objects",
"method": "GET"
},
{
"path": "/v2/schemas/metadefs/property",
"method": "GET"
},
{
"path": "/v2/schemas/metadefs/properties",
"method": "GET"
},
{
"path": "/v2/schemas/metadefs/tag",
"method": "GET"
},
{
"path": "/v2/schemas/metadefs/tags",
"method": "GET"
},
{
"path": "/v2/schemas/tasks",
"method": "GET"
},
{
"path": "/v2/schemas/task",
"method": "GET"
},
{
"path": "/v2/tasks",
"method": "POST"
},
{
"path": "/v2/tasks",
"method": "GET"
},
{
"path": "/v2/tasks/*",
"method": "GET"
},
{
"path": "/versions",
"method": "GET"
},
{
"path": "/",
"method": "GET"
}
],
"block-storage": [
{
"path": "/v3/**",
"method": "GET"
}
],
"compute": [
{
"path": "**",
"method": "GET"
}
]
}

View File

@ -11,7 +11,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from keystone.tests.unit.ksfixtures.access_rules_config import AccessRulesConfig # noqa
from keystone.tests.unit.ksfixtures.auth_plugins import ConfigAuthPlugins # noqa
from keystone.tests.unit.ksfixtures.backendloader import BackendLoader # noqa
from keystone.tests.unit.ksfixtures.cache import Cache # noqa

View File

@ -1,29 +0,0 @@
# Copyright 2019 SUSE Linux GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import fixtures
class AccessRulesConfig(fixtures.Fixture):
"""A fixture for working with JSON access rules config."""
def __init__(self, config_fixture, rules_file=None):
self._config_fixture = config_fixture
self._rules_file = rules_file
def setUp(self):
super(AccessRulesConfig, self).setUp()
self._config_fixture.config(group='access_rules_config',
rules_file=self._rules_file)

View File

@ -178,9 +178,6 @@ keystone.unified_limit.model =
flat = keystone.limit.models.flat:FlatModel
strict_two_level = keystone.limit.models.strict_two_level:StrictTwoLevelModel
keystone.access_rules_config =
json = keystone.access_rules_config.backends.json:AccessRulesConfig
oslo.config.opts =
keystone = keystone.conf.opts:list_opts