Return boolean from delete_project

Make delete_project conform to our standard delete APIs and return
True when the delete succeeds, False when the project was not found
for deleting. It would previously raise an exception during the
attempt to delete.

Also, add some missing functional tests for projects.

Change-Id: Ie1773944b573c743a55fec202454968f1d813ec1
This commit is contained in:
David Shrewsbury 2016-04-11 10:15:05 -04:00
parent 0db5e02d57
commit 92dc7a2089
4 changed files with 101 additions and 2 deletions

View File

@ -0,0 +1,5 @@
---
fixes:
- The delete_project() API now conforms to our standard of returning True
when the delete succeeds, or False when the project was not found. It
would previously raise an expection if the project was not found.

View File

@ -519,10 +519,25 @@ class OpenStackCloud(object):
return project
def delete_project(self, name_or_id):
"""Delete a project
:param string name_or_id: Project name or id.
:returns: True if delete succeeded, False if the project was not found.
:raises: ``OpenStackCloudException`` if something goes wrong during
the openstack API call
"""
with _utils.shade_exceptions(
"Error in deleting project {project}".format(
project=name_or_id)):
project = self.get_project(name_or_id)
if project is None:
self.log.debug(
"Project {0} not found for deleting".format(name_or_id))
return False
params = {}
if self.cloud_config.get_api_version('identity') == '3':
params['project'] = project['id']
@ -530,6 +545,8 @@ class OpenStackCloud(object):
params['tenant'] = project['id']
self.manager.submitTask(_tasks.ProjectDelete(**params))
return True
@_utils.cache_on_arguments()
def list_users(self):
"""List Keystone Users.

View File

@ -0,0 +1,77 @@
# Copyright (c) 2016 IBM
#
# 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.
"""
test_project
----------------------------------
Functional tests for `shade` project resource.
"""
from shade.exc import OpenStackCloudException
from shade.tests.functional import base
class TestProject(base.BaseFunctionalTestCase):
def setUp(self):
super(TestProject, self).setUp()
self.new_project_name = self.getUniqueString('project')
self.identity_version = \
self.operator_cloud.cloud_config.get_api_version('identity')
self.addCleanup(self._cleanup_projects)
def _cleanup_projects(self):
exception_list = list()
for p in self.operator_cloud.list_projects():
if p['name'].startswith(self.new_project_name):
try:
self.operator_cloud.delete_project(p['id'])
except Exception as e:
exception_list.append(str(e))
continue
if exception_list:
raise OpenStackCloudException('\n'.join(exception_list))
def test_create_project(self):
project_name = self.new_project_name + '_create'
params = {
'name': project_name,
'description': 'test_create_project',
}
if self.identity_version == '3':
params['domain_id'] = \
self.operator_cloud.get_domain('default')['id']
project = self.operator_cloud.create_project(**params)
self.assertIsNotNone(project)
self.assertEqual(project_name, project['name'])
self.assertEqual('test_create_project', project['description'])
def test_delete_project(self):
project_name = self.new_project_name + '_delete'
params = {'name': project_name}
if self.identity_version == '3':
params['domain_id'] = \
self.operator_cloud.get_domain('default')['id']
project = self.operator_cloud.create_project(**params)
self.assertIsNotNone(project)
self.assertTrue(self.operator_cloud.delete_project(project['id']))
def test_delete_project_not_found(self):
self.assertFalse(self.operator_cloud.delete_project('doesNotExist'))

View File

@ -73,7 +73,7 @@ class TestProject(base.TestCase):
mock_api_version):
mock_api_version.return_value = '2'
mock_get.return_value = dict(id='123')
self.cloud.delete_project('123')
self.assertTrue(self.cloud.delete_project('123'))
mock_get.assert_called_once_with('123')
mock_keystone.tenants.delete.assert_called_once_with(tenant='123')
@ -84,7 +84,7 @@ class TestProject(base.TestCase):
mock_api_version):
mock_api_version.return_value = '3'
mock_get.return_value = dict(id='123')
self.cloud.delete_project('123')
self.assertTrue(self.cloud.delete_project('123'))
mock_get.assert_called_once_with('123')
mock_keystone.projects.delete.assert_called_once_with(project='123')