Add domain_id param to project operations
A domain admin should be able to make project operations on the domain it manages, but for that it needs to specify the domain id. Change-Id: I3fdc72b7819206cd5effce26bda08cfe1d42d4e0
This commit is contained in:
parent
ed93a168b5
commit
e255657cd5
@ -64,7 +64,7 @@ class UserRemoveFromGroup(task_manager.Task):
|
||||
|
||||
class ProjectList(task_manager.Task):
|
||||
def main(self, client):
|
||||
return client._project_manager.list()
|
||||
return client._project_manager.list(**self.args)
|
||||
|
||||
|
||||
class ProjectCreate(task_manager.Task):
|
||||
|
@ -118,7 +118,7 @@ def _filter_list(data, name_or_id, filters):
|
||||
return filtered
|
||||
|
||||
|
||||
def _get_entity(func, name_or_id, filters):
|
||||
def _get_entity(func, name_or_id, filters, **kwargs):
|
||||
"""Return a single entity from the list returned by a given method.
|
||||
|
||||
:param callable func:
|
||||
@ -136,7 +136,7 @@ def _get_entity(func, name_or_id, filters):
|
||||
# object and just short-circuit return it.
|
||||
if hasattr(name_or_id, 'id'):
|
||||
return name_or_id
|
||||
entities = func(name_or_id, filters)
|
||||
entities = func(name_or_id, filters, **kwargs)
|
||||
if not entities:
|
||||
return None
|
||||
if len(entities) > 1:
|
||||
|
@ -442,53 +442,64 @@ class OpenStackCloud(object):
|
||||
return filtered
|
||||
|
||||
@_utils.cache_on_arguments()
|
||||
def list_projects(self):
|
||||
def list_projects(self, domain_id=None):
|
||||
"""List Keystone Projects.
|
||||
|
||||
:param string domain_id: domain id to scope the listed projects.
|
||||
|
||||
:returns: a list of dicts containing the project description.
|
||||
|
||||
:raises: ``OpenStackCloudException``: if something goes wrong during
|
||||
the openstack API call.
|
||||
"""
|
||||
try:
|
||||
projects = self.manager.submitTask(_tasks.ProjectList())
|
||||
if self.cloud_config.get_api_version('identity') == '3':
|
||||
projects = self.manager.submitTask(
|
||||
_tasks.ProjectList(domain=domain_id))
|
||||
else:
|
||||
projects = self.manager.submitTask(
|
||||
_tasks.ProjectList())
|
||||
except Exception as e:
|
||||
self.log.debug("Failed to list projects", exc_info=True)
|
||||
raise OpenStackCloudException(str(e))
|
||||
return projects
|
||||
|
||||
def search_projects(self, name_or_id=None, filters=None):
|
||||
def search_projects(self, name_or_id=None, filters=None, domain_id=None):
|
||||
"""Seach Keystone projects.
|
||||
|
||||
:param name: project name or id.
|
||||
:param filters: a dict containing additional filters to use.
|
||||
:param domain_id: domain id to scope the searched projects.
|
||||
|
||||
:returns: a list of dict containing the projects
|
||||
|
||||
:raises: ``OpenStackCloudException``: if something goes wrong during
|
||||
the openstack API call.
|
||||
"""
|
||||
projects = self.list_projects()
|
||||
projects = self.list_projects(domain_id=domain_id)
|
||||
return _utils._filter_list(projects, name_or_id, filters)
|
||||
|
||||
def get_project(self, name_or_id, filters=None):
|
||||
def get_project(self, name_or_id, filters=None, domain_id=None):
|
||||
"""Get exactly one Keystone project.
|
||||
|
||||
:param id: project name or id.
|
||||
:param filters: a dict containing additional filters to use.
|
||||
:param domain_id: domain id (keystone v3 only)
|
||||
|
||||
:returns: a list of dicts containing the project description.
|
||||
|
||||
:raises: ``OpenStackCloudException``: if something goes wrong during
|
||||
the openstack API call.
|
||||
"""
|
||||
return _utils._get_entity(self.search_projects, name_or_id, filters)
|
||||
return _utils._get_entity(self.search_projects, name_or_id, filters,
|
||||
domain_id=domain_id)
|
||||
|
||||
def update_project(self, name_or_id, description=None, enabled=True):
|
||||
def update_project(self, name_or_id, description=None, enabled=True,
|
||||
domain_id=None):
|
||||
with _utils.shade_exceptions(
|
||||
"Error in updating project {project}".format(
|
||||
project=name_or_id)):
|
||||
proj = self.get_project(name_or_id)
|
||||
proj = self.get_project(name_or_id, domain_id=domain_id)
|
||||
if not proj:
|
||||
raise OpenStackCloudException(
|
||||
"Project %s not found." % name_or_id)
|
||||
@ -523,10 +534,12 @@ class OpenStackCloud(object):
|
||||
self.list_projects.invalidate(self)
|
||||
return project
|
||||
|
||||
def delete_project(self, name_or_id):
|
||||
def delete_project(self, name_or_id, domain_id=None):
|
||||
"""Delete a project
|
||||
|
||||
:param string name_or_id: Project name or id.
|
||||
:param string domain_id: Domain id containing the project (keystone
|
||||
v3 only).
|
||||
|
||||
:returns: True if delete succeeded, False if the project was not found.
|
||||
|
||||
@ -537,7 +550,7 @@ class OpenStackCloud(object):
|
||||
with _utils.shade_exceptions(
|
||||
"Error in deleting project {project}".format(
|
||||
project=name_or_id)):
|
||||
project = self.get_project(name_or_id)
|
||||
project = self.get_project(name_or_id, domain_id=domain_id)
|
||||
if project is None:
|
||||
self.log.debug(
|
||||
"Project {0} not found for deleting".format(name_or_id))
|
||||
|
@ -63,6 +63,25 @@ class TestProject(base.BaseFunctionalTestCase):
|
||||
self.assertEqual(project_name, project['name'])
|
||||
self.assertEqual('test_create_project', project['description'])
|
||||
|
||||
def test_update_project(self):
|
||||
project_name = self.new_project_name + '_update'
|
||||
|
||||
params = {
|
||||
'name': project_name,
|
||||
'description': 'test_update_project',
|
||||
}
|
||||
if self.identity_version == '3':
|
||||
params['domain_id'] = \
|
||||
self.operator_cloud.get_domain('default')['id']
|
||||
|
||||
project = self.operator_cloud.create_project(**params)
|
||||
updated_project = self.operator_cloud.update_project(project_name,
|
||||
description='new')
|
||||
self.assertIsNotNone(updated_project)
|
||||
self.assertEqual(project['id'], updated_project['id'])
|
||||
self.assertEqual(project['name'], updated_project['name'])
|
||||
self.assertEqual(updated_project['description'], 'new')
|
||||
|
||||
def test_delete_project(self):
|
||||
project_name = self.new_project_name + '_delete'
|
||||
params = {'name': project_name}
|
||||
|
@ -75,7 +75,7 @@ class TestProject(base.TestCase):
|
||||
mock_api_version.return_value = '2'
|
||||
mock_get.return_value = dict(id='123')
|
||||
self.assertTrue(self.cloud.delete_project('123'))
|
||||
mock_get.assert_called_once_with('123')
|
||||
mock_get.assert_called_once_with('123', domain_id=None)
|
||||
mock_keystone.tenants.delete.assert_called_once_with(tenant='123')
|
||||
|
||||
@mock.patch.object(occ.cloud_config.CloudConfig, 'get_api_version')
|
||||
@ -86,7 +86,7 @@ class TestProject(base.TestCase):
|
||||
mock_api_version.return_value = '3'
|
||||
mock_get.return_value = dict(id='123')
|
||||
self.assertTrue(self.cloud.delete_project('123'))
|
||||
mock_get.assert_called_once_with('123')
|
||||
mock_get.assert_called_once_with('123', domain_id=None)
|
||||
mock_keystone.projects.delete.assert_called_once_with(project='123')
|
||||
|
||||
@mock.patch.object(shade.OpenStackCloud, 'get_project')
|
||||
@ -119,3 +119,11 @@ class TestProject(base.TestCase):
|
||||
self.cloud.update_project('123', description='new', enabled=False)
|
||||
mock_keystone.projects.update.assert_called_once_with(
|
||||
description='new', enabled=False, project='123')
|
||||
|
||||
@mock.patch.object(occ.cloud_config.CloudConfig, 'get_api_version')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'keystone_client')
|
||||
def test_list_projects_v3(self, mock_keystone, mock_api_version):
|
||||
mock_api_version.return_value = '3'
|
||||
self.cloud.list_projects('123')
|
||||
mock_keystone.projects.list.assert_called_once_with(
|
||||
domain='123')
|
||||
|
Loading…
x
Reference in New Issue
Block a user