summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.zuul.yaml2
-rw-r--r--doc/requirements.txt6
-rw-r--r--doc/source/admin/policy-json-file.rst4
-rw-r--r--doc/source/admin/policy-yaml-file.rst4
-rw-r--r--doc/source/conf.py40
-rw-r--r--doc/source/reference/index.rst1
-rw-r--r--doc/source/user/plugins.rst8
-rw-r--r--lower-constraints.txt4
-rw-r--r--oslo_policy/policy.py7
-rw-r--r--oslo_policy/shell.py10
-rw-r--r--oslo_policy/tests/test_checks.py6
-rw-r--r--oslo_policy/tests/test_policy.py64
-rw-r--r--oslo_policy/tests/test_shell.py73
-rw-r--r--oslo_policy/tests/token_fixture.py142
-rw-r--r--releasenotes/source/conf.py13
-rw-r--r--sample_data/auth_v3_token_system_admin.json136
-rw-r--r--tox.ini34
17 files changed, 468 insertions, 86 deletions
diff --git a/.zuul.yaml b/.zuul.yaml
index 18e5056..35eecfd 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -5,7 +5,7 @@
- lib-forward-testing-python3
- openstack-lower-constraints-jobs
- openstack-python-jobs
- - openstack-python3-train-jobs
+ - openstack-python3-ussuri-jobs
- periodic-stable-jobs
- publish-openstack-docs-pti
- release-notes-jobs-python3
diff --git a/doc/requirements.txt b/doc/requirements.txt
index c843563..970dcf6 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -2,9 +2,9 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-openstackdocstheme>=1.18.1 # Apache-2.0
-sphinx!=1.6.6,!=1.6.7,>=1.6.5,<2.0.0;python_version=='2.7' # BSD
-sphinx!=1.6.6,!=1.6.7,>=1.6.5;python_version>='3.4' # BSD
+openstackdocstheme>=1.20.0 # Apache-2.0
+sphinx>=1.8.0,<2.0.0;python_version=='2.7' # BSD
+sphinx>=1.8.0,!=2.1.0;python_version>='3.4' # BSD
sphinxcontrib-apidoc>=0.2.0 # BSD
reno>=2.5.0 # Apache-2.0
diff --git a/doc/source/admin/policy-json-file.rst b/doc/source/admin/policy-json-file.rst
index 8d918d8..b0c3b96 100644
--- a/doc/source/admin/policy-json-file.rst
+++ b/doc/source/admin/policy-json-file.rst
@@ -76,6 +76,10 @@ administrators can create new users in the Identity database:
"identity:create_user" : "role:admin"
+.. note:: ``admin`` is a built-in default role in Keystone. For more
+ details and other roles that may be available, see the
+ `Keystone documentation on default roles. <https://docs.openstack.org/keystone/latest/admin/service-api-protection.html>`_
+
You can limit APIs to any role. For example, the Orchestration service
defines a role named ``heat_stack_user``. Whoever has this role is not
allowed to create stacks:
diff --git a/doc/source/admin/policy-yaml-file.rst b/doc/source/admin/policy-yaml-file.rst
index 0018f8a..1cef8fe 100644
--- a/doc/source/admin/policy-yaml-file.rst
+++ b/doc/source/admin/policy-yaml-file.rst
@@ -71,6 +71,10 @@ administrators can create new users in the Identity database:
"identity:create_user" : "role:admin"
+.. note:: ``admin`` is a built-in default role in Keystone. For more
+ details and other roles that may be available, see the
+ `Keystone documentation on default roles. <https://docs.openstack.org/keystone/latest/admin/service-api-protection.html>`_
+
You can limit APIs to any role. For example, the Orchestration service
defines a role named ``heat_stack_user``. Whoever has this role is not
allowed to create stacks:
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 0a9e203..c2b91e4 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -12,11 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import os
-import sys
-
-sys.path.insert(0, os.path.abspath('../..'))
-# -- General configuration ----------------------------------------------------
+# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
@@ -24,7 +20,6 @@ extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.extlinks',
'sphinxcontrib.apidoc',
- #'sphinx.ext.intersphinx',
'openstackdocstheme',
'oslo_config.sphinxext',
]
@@ -33,7 +28,6 @@ extensions = [
repository_name = 'openstack/oslo.policy'
bug_project = 'oslo.policy'
bug_tag = ''
-html_last_updated_fmt = '%Y-%m-%d %H:%M'
# autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles.
@@ -45,10 +39,6 @@ source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['api/oslo_policy.tests.*', 'api/setup.rst']
-
# General information about the project.
project = u'oslo.policy'
copyright = u'2014, OpenStack Foundation'
@@ -67,36 +57,24 @@ pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
modindex_common_prefix = ['oslo_policy.']
-# -- Options for HTML output --------------------------------------------------
+
+# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
-# html_theme_path = ["."]
-# html_theme = '_theme'
-# html_static_path = ['static']
html_theme = 'openstackdocs'
-# Output file base name for HTML help builder.
-htmlhelp_basename = '%sdoc' % project
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass
-# [howto/manual]).
-latex_documents = [
- ('index',
- '%s.tex' % project,
- u'%s Documentation' % project,
- u'OpenStack Foundation', 'manual'),
-]
-# Shortened external links.
+# -- sphinx.ext.extlinks configuration ---------------------------------------
+
extlinks = {
'example': (source_tree + '/oslo_policy/%s', ''),
}
-# Example configuration for intersphinx: refer to the Python standard library.
-#intersphinx_mapping = {'http://docs.python.org/': None}
-
# -- sphinxcontrib.apidoc configuration --------------------------------------
+
apidoc_module_dir = '../../oslo_policy'
apidoc_output_dir = 'reference/api'
+apidoc_excluded_paths = [
+ 'tests',
+]
diff --git a/doc/source/reference/index.rst b/doc/source/reference/index.rst
index 6284450..512a8b9 100644
--- a/doc/source/reference/index.rst
+++ b/doc/source/reference/index.rst
@@ -5,4 +5,3 @@
.. toctree::
api/modules
-
diff --git a/doc/source/user/plugins.rst b/doc/source/user/plugins.rst
index 54d2dda..9638cd8 100644
--- a/doc/source/user/plugins.rst
+++ b/doc/source/user/plugins.rst
@@ -1,6 +1,6 @@
-==========================
-Writing custom check rules
-==========================
+========================
+Writing HTTP check rules
+========================
oslo.policy has supported the following syntax for a while::
@@ -48,4 +48,4 @@ Example code - HttpCheck
.. literalinclude:: ../../../oslo_policy/_external.py
:language: python
:linenos:
- :lines: 28-64 \ No newline at end of file
+ :lines: 28-64
diff --git a/lower-constraints.txt b/lower-constraints.txt
index 04c5324..7717f7b 100644
--- a/lower-constraints.txt
+++ b/lower-constraints.txt
@@ -25,7 +25,7 @@ mox3==0.20.0
msgpack-python==0.4.0
netaddr==0.7.18
netifaces==0.10.4
-openstackdocstheme==1.18.1
+openstackdocstheme==1.20.0
os-client-config==1.28.0
oslo.config==5.2.0
oslo.context==2.22.0
@@ -51,7 +51,7 @@ six==1.10.0
stestr==2.0.0
smmap==0.9.0
snowballstemmer==1.2.1
-Sphinx==1.6.5
+Sphinx==1.8.0
sphinxcontrib-websupport==1.0.1
stevedore==1.20.0
testrepository==0.0.18
diff --git a/oslo_policy/policy.py b/oslo_policy/policy.py
index 3429ea4..61a3597 100644
--- a/oslo_policy/policy.py
+++ b/oslo_policy/policy.py
@@ -699,10 +699,9 @@ class Enforcer(object):
if (deprecated_rule.check_str != default.check_str
and default.name not in self.file_rules):
- default.check = _parser.parse_rule(
- default.check_str + ' or ' +
- deprecated_rule.check_str
- )
+ default.check = OrCheck([_parser.parse_rule(cs) for cs in
+ [default.check_str,
+ deprecated_rule.check_str]])
if not self.suppress_deprecation_warnings:
warnings.warn(deprecated_msg)
diff --git a/oslo_policy/shell.py b/oslo_policy/shell.py
index 365a514..7ffb5ea 100644
--- a/oslo_policy/shell.py
+++ b/oslo_policy/shell.py
@@ -74,7 +74,11 @@ def tool(policy_file, access_file, apply_rule, is_admin=False,
access_data = jsonutils.loads(access)['token']
access_data['roles'] = [role['name'] for role in access_data['roles']]
- access_data['project_id'] = access_data['project']['id']
+ access_data['user_id'] = access_data['user']['id']
+ if access_data.get('project'):
+ access_data['project_id'] = access_data['project']['id']
+ if access_data.get('system'):
+ access_data['system_scope'] = 'all'
access_data['is_admin'] = is_admin
with open(policy_file, "rb", 0) as p:
@@ -90,7 +94,9 @@ def tool(policy_file, access_file, apply_rule, is_admin=False,
target_data = flatten(jsonutils.loads(target))
else:
- target_data = {"project_id": access_data['project_id']}
+ target_data = {'user_id': access_data['user']['id']}
+ if access_data.get('project_id'):
+ target_data['project_id'] = access_data['project_id']
if apply_rule:
key = apply_rule
diff --git a/oslo_policy/tests/test_checks.py b/oslo_policy/tests/test_checks.py
index 1cd08ec..8c2f143 100644
--- a/oslo_policy/tests/test_checks.py
+++ b/oslo_policy/tests/test_checks.py
@@ -185,19 +185,19 @@ class GenericCheckTestCase(base.PolicyBaseTestCase):
check = _checks.GenericCheck(
'token.catalog.endpoints.id',
token_fixture.REGION_ONE_PUBLIC_KEYSTONE_ENDPOINT_ID)
- credentials = token_fixture.SCOPED_TOKEN_FIXTURE
+ credentials = token_fixture.PROJECT_SCOPED_TOKEN_FIXTURE
self.assertTrue(check({}, credentials, self.enforcer))
def test_generic_role_check_matches(self):
check = _checks.GenericCheck(
'token.roles.name', 'role1')
- credentials = token_fixture.SCOPED_TOKEN_FIXTURE
+ credentials = token_fixture.PROJECT_SCOPED_TOKEN_FIXTURE
self.assertTrue(check({}, credentials, self.enforcer))
def test_generic_missing_role_does_not_matches(self):
check = _checks.GenericCheck(
'token.roles.name', 'missing')
- credentials = token_fixture.SCOPED_TOKEN_FIXTURE
+ credentials = token_fixture.PROJECT_SCOPED_TOKEN_FIXTURE
self.assertFalse(check({}, credentials, self.enforcer))
def test_multiple_nested_lists_accepted(self):
diff --git a/oslo_policy/tests/test_policy.py b/oslo_policy/tests/test_policy.py
index 88d363a..bc41054 100644
--- a/oslo_policy/tests/test_policy.py
+++ b/oslo_policy/tests/test_policy.py
@@ -1190,6 +1190,70 @@ class DocumentedRuleDefaultDeprecationTestCase(base.PolicyBaseTestCase):
enforcer.load_rules()
mock_warn.assert_called_once_with(expected_msg)
+ self.assertTrue(
+ enforcer.enforce('foo:create_bar', {}, {'roles': ['bang']})
+ )
+ self.assertTrue(
+ enforcer.enforce('foo:create_bar', {}, {'roles': ['fizz']})
+ )
+ self.assertFalse(
+ enforcer.enforce('foo:create_bar', {}, {'roles': ['baz']})
+ )
+
+ def test_deprecate_an_empty_policy_check_string(self):
+ deprecated_rule = policy.DeprecatedRule(
+ name='foo:create_bar',
+ check_str=''
+ )
+
+ rule_list = [policy.DocumentedRuleDefault(
+ name='foo:create_bar',
+ check_str='role:bang',
+ description='Create a bar.',
+ operations=[{'path': '/v1/bars', 'method': 'POST'}],
+ deprecated_rule=deprecated_rule,
+ deprecated_reason='because of reasons',
+ deprecated_since='N'
+ )]
+ enforcer = policy.Enforcer(self.conf)
+ enforcer.register_defaults(rule_list)
+
+ with mock.patch('warnings.warn') as mock_warn:
+ enforcer.load_rules()
+ mock_warn.assert_called_once()
+
+ enforcer.enforce('foo:create_bar', {}, {'roles': ['bang']},
+ do_raise=True)
+ enforcer.enforce('foo:create_bar', {}, {'roles': ['fizz']},
+ do_raise=True)
+
+ def test_deprecate_replace_with_empty_policy_check_string(self):
+ deprecated_rule = policy.DeprecatedRule(
+ name='foo:create_bar',
+ check_str='role:fizz'
+ )
+
+ rule_list = [policy.DocumentedRuleDefault(
+ name='foo:create_bar',
+ check_str='',
+ description='Create a bar.',
+ operations=[{'path': '/v1/bars', 'method': 'POST'}],
+ deprecated_rule=deprecated_rule,
+ deprecated_reason='because of reasons',
+ deprecated_since='N'
+ )]
+ enforcer = policy.Enforcer(self.conf)
+ enforcer.register_defaults(rule_list)
+
+ with mock.patch('warnings.warn') as mock_warn:
+ enforcer.load_rules()
+ mock_warn.assert_called_once()
+
+ enforcer.enforce('foo:create_bar', {}, {'roles': ['fizz']},
+ do_raise=True)
+ enforcer.enforce('foo:create_bar', {}, {'roles': ['bang']},
+ do_raise=True)
+
def test_deprecate_a_policy_name(self):
deprecated_rule = policy.DeprecatedRule(
name='foo:bar',
diff --git a/oslo_policy/tests/test_shell.py b/oslo_policy/tests/test_shell.py
index 09a07c7..32dad51 100644
--- a/oslo_policy/tests/test_shell.py
+++ b/oslo_policy/tests/test_shell.py
@@ -36,12 +36,21 @@ class CheckerTestCase(base.PolicyBaseTestCase):
"sampleservice:sample_rule1": ""
'''
+ SAMPLE_POLICY_SCOPED = '''---
+"sampleservice:sample_rule": "role:role1"
+"sampleservice:scoped_rule": "role:role1 and system_scope:all"
+'''
+
+ SAMPLE_POLICY_OWNER = '''---
+"sampleservice:owner_rule": "user_id:%(user_id)s"
+'''
+
def setUp(self):
super(CheckerTestCase, self).setUp()
self.create_config_file("policy.yaml", self.SAMPLE_POLICY)
self.create_config_file(
"access.json",
- jsonutils.dumps(token_fixture.SCOPED_TOKEN_FIXTURE))
+ jsonutils.dumps(token_fixture.PROJECT_SCOPED_TOKEN_FIXTURE))
@mock.patch("oslo_policy._checks.TrueCheck.__call__")
def test_pass_rule_parameters(self, call_mock):
@@ -53,12 +62,14 @@ class CheckerTestCase(base.PolicyBaseTestCase):
stdout = self._capture_stdout()
access_data = copy.deepcopy(
- token_fixture.SCOPED_TOKEN_FIXTURE["token"])
+ token_fixture.PROJECT_SCOPED_TOKEN_FIXTURE["token"])
target = {
- "project_id": access_data['project']['id']
+ 'user_id': access_data['user']['id'],
+ 'project_id': access_data['project']['id']
}
access_data['roles'] = [
role['name'] for role in access_data['roles']]
+ access_data['user_id'] = access_data['user']['id']
access_data['project_id'] = access_data['project']['id']
access_data['is_admin'] = is_admin
@@ -71,6 +82,56 @@ class CheckerTestCase(base.PolicyBaseTestCase):
'''
self.assertEqual(expected, stdout.getvalue())
+ def test_pass_rule_parameters_with_scope(self):
+ self.create_config_file("policy.yaml", self.SAMPLE_POLICY_SCOPED)
+ self.create_config_file(
+ "access.json",
+ jsonutils.dumps(token_fixture.SYSTEM_SCOPED_TOKEN_FIXTURE))
+ policy_file = self.get_config_file_fullname('policy.yaml')
+ access_file = self.get_config_file_fullname('access.json')
+ apply_rule = None
+ is_admin = False
+ stdout = self._capture_stdout()
+
+ access_data = copy.deepcopy(
+ token_fixture.SYSTEM_SCOPED_TOKEN_FIXTURE["token"])
+ access_data['roles'] = [
+ role['name'] for role in access_data['roles']]
+ access_data['user_id'] = access_data['user']['id']
+ access_data['is_admin'] = is_admin
+
+ shell.tool(policy_file, access_file, apply_rule, is_admin)
+
+ expected = '''passed: sampleservice:sample_rule
+passed: sampleservice:scoped_rule
+'''
+ self.assertEqual(expected, stdout.getvalue())
+
+ def test_pass_rule_parameters_with_owner(self):
+ self.create_config_file("policy.yaml", self.SAMPLE_POLICY_OWNER)
+ self.create_config_file(
+ "access.json",
+ jsonutils.dumps(token_fixture.PROJECT_SCOPED_TOKEN_FIXTURE))
+ policy_file = self.get_config_file_fullname('policy.yaml')
+ access_file = self.get_config_file_fullname('access.json')
+ apply_rule = None
+ is_admin = False
+ stdout = self._capture_stdout()
+
+ access_data = copy.deepcopy(
+ token_fixture.PROJECT_SCOPED_TOKEN_FIXTURE["token"])
+ access_data['roles'] = [
+ role['name'] for role in access_data['roles']]
+ access_data['user_id'] = access_data['user']['id']
+ access_data['project_id'] = access_data['project']['id']
+ access_data['is_admin'] = is_admin
+
+ shell.tool(policy_file, access_file, apply_rule, is_admin)
+
+ expected = '''passed: sampleservice:owner_rule
+'''
+ self.assertEqual(expected, stdout.getvalue())
+
def test_pass_rule_parameters_sorted(self):
self.create_config_file("policy.yaml", self.SAMPLE_POLICY_UNSORTED)
@@ -81,9 +142,10 @@ class CheckerTestCase(base.PolicyBaseTestCase):
stdout = self._capture_stdout()
access_data = copy.deepcopy(
- token_fixture.SCOPED_TOKEN_FIXTURE["token"])
+ token_fixture.PROJECT_SCOPED_TOKEN_FIXTURE["token"])
access_data['roles'] = [
role['name'] for role in access_data['roles']]
+ access_data['user_id'] = access_data['user']['id']
access_data['project_id'] = access_data['project']['id']
access_data['is_admin'] = is_admin
@@ -100,9 +162,10 @@ passed: sampleservice:sample_rule2
apply_rule = None
is_admin = False
access_data = copy.deepcopy(
- token_fixture.SCOPED_TOKEN_FIXTURE["token"])
+ token_fixture.PROJECT_SCOPED_TOKEN_FIXTURE["token"])
access_data['roles'] = [
role['name'] for role in access_data['roles']]
+ access_data['user_id'] = access_data['user']['id']
access_data['project_id'] = access_data['project']['id']
access_data['is_admin'] = is_admin
diff --git a/oslo_policy/tests/token_fixture.py b/oslo_policy/tests/token_fixture.py
index 6695efe..683f1b1 100644
--- a/oslo_policy/tests/token_fixture.py
+++ b/oslo_policy/tests/token_fixture.py
@@ -16,7 +16,7 @@
REGION_ONE_PUBLIC_KEYSTONE_ENDPOINT_ID = '8cd4b957090f4ca5842a22e9a74099cd'
-SCOPED_TOKEN_FIXTURE = {
+PROJECT_SCOPED_TOKEN_FIXTURE = {
"token": {
"methods": [
"password"
@@ -162,3 +162,143 @@ SCOPED_TOKEN_FIXTURE = {
}
}
}
+
+SYSTEM_SCOPED_TOKEN_FIXTURE = {
+ "token": {
+ "methods": [
+ "password"
+ ],
+ "expires_at": "2038-01-18T21:14:07Z",
+ "issued_at": "2000-01-18T21:14:07Z",
+ "roles": [
+ {
+ "id": "41b1af9bb39241e8b8b79fae5906abcc",
+ "name": "role1"
+ },
+ {
+ "id": "ac9add6b3c5a46dcaaf21390c4657949",
+ "name": "role2"
+ }
+ ],
+ "system": {
+ "all": True
+ },
+ "catalog": [
+ {
+ "endpoints": [
+ {
+ "id": "3b5e554bcf114f2483e8a1be7a0506d1",
+ "interface": "admin",
+ "url": "http://127.0.0.1:8776/v1/" +
+ "64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ },
+ {
+ "id": "54abd2dc463c4ba4a72915498f8ecad1",
+ "interface": "internal",
+ "url": "http://127.0.0.1:8776/v1/" +
+ "64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ },
+ {
+ "id": "70a7efa4b1b941968357cc43ae1419ee",
+ "interface": "public",
+ "url": "http://127.0.0.1:8776/v1/" +
+ "64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ }
+ ],
+ "id": "5707c3fc0a294703a3c638e9cf6a6c3a",
+ "type": "volume",
+ "name": "volume"
+ },
+ {
+ "endpoints": [
+ {
+ "id": "92217a3b95394492859bc49fd474382f",
+ "interface": "admin",
+ "url": "http://127.0.0.1:9292/v1",
+ "region": "regionOne"
+ },
+ {
+ "id": "f20563bdf66f4efa8a1f11d99b672be1",
+ "interface": "internal",
+ "url": "http://127.0.0.1:9292/v1",
+ "region": "regionOne"
+ },
+ {
+ "id": "375f9ba459a447738fb60fe5fc26e9aa",
+ "interface": "public",
+ "url": "http://127.0.0.1:9292/v1",
+ "region": "regionOne"
+ }
+ ],
+ "id": "15c21aae6b274a8da52e0a068e908aac",
+ "type": "image",
+ "name": "glance"
+ },
+ {
+ "endpoints": [
+ {
+ "id": "edbd9f50f66746ae9ed11dc3b1ae35da",
+ "interface": "admin",
+ "url": "http://127.0.0.1:8774/v1.1/" +
+ "64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ },
+ {
+ "id": "9e03c46c80a34a159cb39f5cb0498b92",
+ "interface": "internal",
+ "url": "http://127.0.0.1:8774/v1.1/" +
+ "64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ },
+ {
+ "id": "1df0b44d92634d59bd0e0d60cf7ce432",
+ "interface": "public",
+ "url":
+ "http://127.0.0.1:8774/v1.1/" +
+ "64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ }
+ ],
+ "id": "2f404fdb89154c589efbc10726b029ec",
+ "type": "compute",
+ "name": "nova"
+ },
+ {
+ "endpoints": [
+ {
+ "id": "a4501e141a4b4e14bf282e7bffd81dc5",
+ "interface": "admin",
+ "url": "http://127.0.0.1:35357/v3",
+ "region": "RegionOne"
+ },
+ {
+ "id": "3d17e3227bfc4483b58de5eaa584e360",
+ "interface": "internal",
+ "url": "http://127.0.0.1:35357/v3",
+ "region": "RegionOne"
+ },
+ {
+ "id": REGION_ONE_PUBLIC_KEYSTONE_ENDPOINT_ID,
+ "interface": "public",
+ "url": "http://127.0.0.1:5000/v3",
+ "region": "RegionOne"
+ }
+ ],
+ "id": "c5d926d566424e4fba4f80c37916cde5",
+ "type": "identity",
+ "name": "keystone"
+ }
+ ],
+ "user": {
+ "domain": {
+ "id": "domain_id1",
+ "name": "domain_name1"
+ },
+ "name": "user_name1",
+ "id": "user_id1"
+ }
+ }
+}
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
index 7f70376..5084a9d 100644
--- a/releasenotes/source/conf.py
+++ b/releasenotes/source/conf.py
@@ -43,7 +43,6 @@ extensions = [
repository_name = 'openstack/oslo.policy'
bug_project = 'oslo.policy'
bug_tag = ''
-html_last_updated_fmt = '%Y-%m-%d %H:%M'
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -58,7 +57,6 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
-project = u'oslo.policy Release Notes'
copyright = u'2016, oslo.policy Developers'
# Release notes do not need a version in the title, they span
@@ -194,17 +192,6 @@ htmlhelp_basename = 'oslo.policyReleaseNotesDoc'
# -- Options for LaTeX output ---------------------------------------------
-latex_elements = {
- # The paper size ('letterpaper' or 'a4paper').
- # 'papersize': 'letterpaper',
-
- # The font size ('10pt', '11pt' or '12pt').
- # 'pointsize': '10pt',
-
- # Additional stuff for the LaTeX preamble.
- # 'preamble': '',
-}
-
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
diff --git a/sample_data/auth_v3_token_system_admin.json b/sample_data/auth_v3_token_system_admin.json
new file mode 100644
index 0000000..bbf963f
--- /dev/null
+++ b/sample_data/auth_v3_token_system_admin.json
@@ -0,0 +1,136 @@
+{
+ "token": {
+ "methods": [
+ "password"
+ ],
+ "expires_at": "2038-01-18T21:14:07Z",
+ "issued_at": "2000-01-18T21:14:07Z",
+ "roles": [
+ {
+ "id":"41b1af9bb39241e8b8b79fae5906abcc",
+ "name": "admin"
+ },
+ {
+ "id": "ac9add6b3c5a46dcaaf21390c4657949",
+ "name": "member"
+ },
+ {
+ "id": "b0cb8117845f4fd489865d498b80bab3",
+ "name": "reader"
+ }
+ ],
+ "system": {
+ "all": true
+ },
+ "catalog": [
+ {
+ "endpoints": [
+ {
+ "id": "f84e070735e54914b41e2b5cfa94dcf7",
+ "interface": "admin",
+ "url": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ },
+ {
+ "id": "8220bba1d2844e0b81b171c6ede1155f",
+ "interface": "internal",
+ "url": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ },
+ {
+ "id": "719b92ea82a04e7a9ff1107c62da10da",
+ "interface": "public",
+ "url": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ }
+ ],
+ "type": "volume",
+ "name": "volume",
+ "id":"547e9195d1914b5eb087bedbc98fccc3"
+ },
+ {
+ "endpoints": [
+ {
+ "id": "44752324c0d44375bc854168ea22f1fc",
+ "interface": "admin",
+ "url": "http://127.0.0.1:9292/v1",
+ "region": "regionOne"
+ },
+ {
+ "id": "a59b3734f57449078f1637c10f96c8e8",
+ "interface": "internal",
+ "url": "http://127.0.0.1:9292/v1",
+ "region": "regionOne"
+ },
+ {
+ "id": "16c3ab1a4df640569812e432c98b2a48",
+ "interface": "public",
+ "url": "http://127.0.0.1:9292/v1",
+ "region": "regionOne"
+ }
+ ],
+ "type": "image",
+ "name": "glance",
+ "id": "22c15d232e55419eb4aeb3ebbd12aac2"
+ },
+ {
+ "endpoints": [
+ {
+ "id": "9c2fdc2d45bb45c5a7f973e235e0f998",
+ "interface": "admin",
+ "url": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ },
+ {
+ "id": "88ccfa8cbb7743998b38b998f4e6a720",
+ "interface": "internal",
+ "url": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ },
+ {
+ "id": "113ee928c6934c92b9a12bd4e456c804",
+ "interface": "public",
+ "url": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a",
+ "region": "regionOne"
+ }
+ ],
+ "type": "compute",
+ "name": "nova",
+ "id": "fbf2afcdeb10473392636df9785d3fb5"
+ },
+ {
+ "endpoints": [
+ {
+ "id": "c10a5cda00784049953296d18464aa38",
+ "interface": "admin",
+ "url": "http://127.0.0.1:35357/v3",
+ "region": "RegionOne"
+ },
+ {
+ "id": "334650263e064428bb2f0b7c3c7a743c",
+ "interface": "internal",
+ "url": "http://127.0.0.1:35357/v3",
+ "region": "RegionOne"
+ },
+ {
+ "id": "52ff54addc38430d9b656c7164e2caf8",
+ "interface": "public",
+ "url": "http://127.0.0.1:5000/v3",
+ "region": "RegionOne"
+ }
+ ],
+ "type": "identity",
+ "name": "keystone",
+ "id": "a0d9913a4bca4d5699e151804e0b5172"
+ }
+ ],
+ "user": {
+ "domain": {
+ "id": "domain_id1",
+ "name": "domain_name1"
+ },
+ "name": "user_name1",
+ "id": "user_id1"
+ }
+ }
+}
diff --git a/tox.ini b/tox.ini
index b05205c..21552b8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,9 +1,10 @@
[tox]
-minversion = 2.0
+minversion = 3.1
envlist = py27,py37,pep8,docs
+ignore_basepython_conflict = True
[testenv]
-install_command = pip install {opts} {packages}
+basepython = python3
deps =
-c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{toxinidir}/test-requirements.txt
@@ -11,11 +12,7 @@ deps =
-r{toxinidir}/doc/requirements.txt
commands = stestr run --slowest {posargs}
-[testenv:py27]
-basepython = python2.7
-
[testenv:pep8]
-basepython = python3
deps =
-r{toxinidir}/test-requirements.txt
commands =
@@ -24,26 +21,28 @@ commands =
bandit -r oslo_policy tests -n5
[testenv:venv]
-basepython = python3
commands = {posargs}
[testenv:docs]
-basepython = python3
whitelist_externals =
rm
deps =
{[testenv]deps}
-r{toxinidir}/doc/requirements.txt
commands =
- rm -rf doc/build
- sphinx-build -W -b html doc/source doc/build/html
+ rm -rf doc/build doc/source/reference/api
+ sphinx-build -W --keep-going -b html doc/source doc/build/html
[testenv:cover]
-basepython = python3
-commands = python setup.py test --coverage --coverage-package-name=oslo_policy --testr-args='{posargs}'
+setenv =
+ PYTHON=coverage run --source oslo_policy --parallel-mode
+commands =
+ stestr run --slowest {posargs}
+ coverage combine
+ coverage html -d cover
+ coverage report
[flake8]
-
show-source = True
ignore =
builtins = _
@@ -53,11 +52,14 @@ exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
import_exceptions = oslo_policy._i18n
[testenv:releasenotes]
-basepython = python3
-commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
+deps = -r{toxinidir}/doc/requirements.txt
+whitelist_externals =
+ rm
+commands =
+ rm -rf releasenotes/build
+ sphinx-build -a -E -W -d releasenotes/build/doctrees --keep-going -b html releasenotes/source releasenotes/build/html
[testenv:lower-constraints]
-basepython = python3
deps =
-c{toxinidir}/lower-constraints.txt
-r{toxinidir}/test-requirements.txt