diff options
-rw-r--r-- | doc/source/conf.py | 19 | ||||
-rw-r--r-- | keystoneclient/tests/functional/v3/test_projects.py | 24 | ||||
-rw-r--r-- | keystoneclient/tests/unit/test_session.py | 2 | ||||
-rw-r--r-- | keystoneclient/tests/unit/v3/test_projects.py | 15 | ||||
-rw-r--r-- | keystoneclient/tests/unit/v3/test_role_assignments.py | 2 | ||||
-rw-r--r-- | keystoneclient/v3/projects.py | 6 | ||||
-rw-r--r-- | releasenotes/notes/list_projects_filtered_by_the_parent_project-a873974f197c1e37.yaml | 5 | ||||
-rw-r--r-- | tox.ini | 12 |
8 files changed, 75 insertions, 10 deletions
diff --git a/doc/source/conf.py b/doc/source/conf.py index c5b98f9..8fb3dba 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -180,10 +180,9 @@ htmlhelp_basename = 'python-keystoneclientdoc' # (source start file, target name, title, author, documentclass [howto/manual]) # . latex_documents = [ - ('index', 'python-keystoneclient.tex', - 'python-keystoneclient Documentation', - 'Nebula Inc, based on work by Rackspace and Jacob Kaplan-Moss', - 'manual'), + ('index', 'doc-python-keystoneclient.tex', + u'python-keystoneclient Documentation', + u'OpenStack', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -203,6 +202,18 @@ latex_documents = [ # If false, no module index is generated. #latex_use_modindex = True +# Disable usage of xindy https://bugzilla.redhat.com/show_bug.cgi?id=1643664 +latex_use_xindy = False + +latex_domain_indices = False + +latex_elements = { + 'makeindex': '', + 'printindex': '', + 'preamble': r'\setcounter{tocdepth}{3}', + 'maxlistdepth': 10, +} + keystoneauth_url = 'https://docs.openstack.org/keystoneauth/latest/' intersphinx_mapping = { 'python': ('https://docs.python.org/', None), diff --git a/keystoneclient/tests/functional/v3/test_projects.py b/keystoneclient/tests/functional/v3/test_projects.py index c40da50..eec2745 100644 --- a/keystoneclient/tests/functional/v3/test_projects.py +++ b/keystoneclient/tests/functional/v3/test_projects.py @@ -157,6 +157,30 @@ class ProjectsTestCase(base.V3ClientTestCase, ProjectsTestMixin): self.assertIn(project_one.entity, projects) self.assertIn(project_two.entity, projects) + def test_list_subprojects(self): + parent_project = fixtures.Project(self.client, self.test_domain.id) + self.useFixture(parent_project) + + child_project_one = fixtures.Project(self.client, self.test_domain.id, + parent=parent_project.id) + self.useFixture(child_project_one) + + child_project_two = fixtures.Project(self.client, self.test_domain.id, + parent=parent_project.id) + self.useFixture(child_project_two) + + projects = self.client.projects.list(parent=parent_project.id) + + # All projects are valid + for project in projects: + self.check_project(project) + + self.assertIn(child_project_one.entity, projects) + self.assertIn(child_project_two.entity, projects) + + # Parent project should not be included in the result + self.assertNotIn(parent_project.entity, projects) + def test_update_project(self): project = fixtures.Project(self.client, self.test_domain.id) self.useFixture(project) diff --git a/keystoneclient/tests/unit/test_session.py b/keystoneclient/tests/unit/test_session.py index e0d9b28..bf10aa3 100644 --- a/keystoneclient/tests/unit/test_session.py +++ b/keystoneclient/tests/unit/test_session.py @@ -828,7 +828,6 @@ class SessionAuthTests(utils.TestCase): self.assertIn(list(response.keys())[0], output) self.assertIn(list(response.values())[0], output) - self.assertNotIn(self.TEST_URL, self.logger.output) self.assertNotIn(list(response.keys())[0], self.logger.output) self.assertNotIn(list(response.values())[0], self.logger.output) @@ -1026,7 +1025,6 @@ class AdapterTest(utils.TestCase): self.assertIn(list(response.keys())[0], output) self.assertIn(list(response.values())[0], output) - self.assertNotIn(self.TEST_URL, self.logger.output) self.assertNotIn(list(response.keys())[0], self.logger.output) self.assertNotIn(list(response.values())[0], self.logger.output) diff --git a/keystoneclient/tests/unit/v3/test_projects.py b/keystoneclient/tests/unit/v3/test_projects.py index 2df8f05..99186f1 100644 --- a/keystoneclient/tests/unit/v3/test_projects.py +++ b/keystoneclient/tests/unit/v3/test_projects.py @@ -55,8 +55,7 @@ class ProjectTests(utils.ClientTestCase, utils.CrudTests): ref_list = [self.new_ref(), self.new_ref()] domain_id = uuid.uuid4().hex - self.stub_entity('GET', [self.collection_key], - entity=ref_list) + self.stub_entity('GET', [self.collection_key], entity=ref_list) returned_list = self.manager.list(domain=domain_id) self.assertEqual(len(ref_list), len(returned_list)) @@ -64,6 +63,18 @@ class ProjectTests(utils.ClientTestCase, utils.CrudTests): self.assertQueryStringIs('domain_id=%s' % domain_id) + def test_list_projects_for_parent(self): + ref_list = [self.new_ref(), self.new_ref()] + parent_id = uuid.uuid4().hex + + self.stub_entity('GET', [self.collection_key], entity=ref_list) + + returned_list = self.manager.list(parent=parent_id) + self.assertEqual(len(ref_list), len(returned_list)) + [self.assertIsInstance(r, self.model) for r in returned_list] + + self.assertQueryStringIs('parent_id=%s' % parent_id) + def test_create_with_parent(self): parent_ref = self.new_ref() parent_ref['parent_id'] = uuid.uuid4().hex diff --git a/keystoneclient/tests/unit/v3/test_role_assignments.py b/keystoneclient/tests/unit/v3/test_role_assignments.py index 45dd13d..39b4b23 100644 --- a/keystoneclient/tests/unit/v3/test_role_assignments.py +++ b/keystoneclient/tests/unit/v3/test_role_assignments.py @@ -265,7 +265,7 @@ class RoleAssignmentsTests(utils.ClientTestCase, utils.CrudTests): ref_list = self.TEST_ALL_RESPONSE_LIST self.stub_entity('GET', [self.collection_key, - '?include_names'], + '?include_names=True'], entity=ref_list) returned_list = self.manager.list(include_names=True) diff --git a/keystoneclient/v3/projects.py b/keystoneclient/v3/projects.py index 5975bda..edaf982 100644 --- a/keystoneclient/v3/projects.py +++ b/keystoneclient/v3/projects.py @@ -112,7 +112,7 @@ class ProjectManager(base.CrudManager): enabled=enabled, **kwargs) - def list(self, domain=None, user=None, **kwargs): + def list(self, domain=None, user=None, parent=None, **kwargs): """List projects. :param domain: the domain of the projects to be filtered on. @@ -120,6 +120,9 @@ class ProjectManager(base.CrudManager): :param user: filter in projects the specified user has role assignments on. :type user: str or :class:`keystoneclient.v3.users.User` + :param parent: filter in projects the specified project is a parent + for + :type parent: str or :class:`keystoneclient.v3.projects.Project` :param kwargs: any other attribute provided will filter projects on. Project tags filter keyword: ``tags``, ``tags_any``, ``not_tags``, and ``not_tags_any``. tag attribute type @@ -134,6 +137,7 @@ class ProjectManager(base.CrudManager): projects = super(ProjectManager, self).list( base_url=base_url, domain_id=base.getid(domain), + parent_id=base.getid(parent), fallback_to_auth=True, **kwargs) diff --git a/releasenotes/notes/list_projects_filtered_by_the_parent_project-a873974f197c1e37.yaml b/releasenotes/notes/list_projects_filtered_by_the_parent_project-a873974f197c1e37.yaml new file mode 100644 index 0000000..988dca5 --- /dev/null +++ b/releasenotes/notes/list_projects_filtered_by_the_parent_project-a873974f197c1e37.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Now keystone client supports to list projects which belongs to the given + parent project. @@ -71,6 +71,18 @@ basepython = python3 commands = python setup.py build_sphinx deps = -r{toxinidir}/doc/requirements.txt +[testenv:pdf-docs] +basepython = python3 +envdir = {toxworkdir}/docs +deps = {[testenv:docs]deps} +whitelist_externals = + make + rm +commands = + rm -rf doc/build/pdf + sphinx-build -W -b latex doc/source doc/build/pdf + make -C doc/build/pdf + [testenv:releasenotes] basepython = python3 commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html |