Revert "Add JSON driver for access rules config"

This reverts commit f028ca4edd.

In the Train PTG[1] we agreed to defer this feature until we had some
kind of traceability or discoverability for APIs and that this wasn't
feasible or useful until then.

This change was merged to master but never released, so I submit that
it is safe to revert.

[1] https://etherpad.openstack.org/p/keystone-train-ptg-application-credentials

Change-Id: I8fc5fcb2b35431882f0d64866765d6b0cd31356f
This commit is contained in:
Colleen Murphy 2019-05-28 08:36:57 -07:00
parent 78d30c9331
commit 7c42f1a7a8
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