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:
parent
78d30c9331
commit
7c42f1a7a8
@ -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
|
@ -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
|
@ -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,
|
||||
|
@ -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}
|
@ -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')
|
||||
|
@ -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)
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user