Error handling for delete commands in identity

Add missing multi deletion error handling for
identity delete commands.
All delete commands in identity support
error handling now.

Change-Id: I05626dcb5e516a423d610906347b02236ba7eeaf
This commit is contained in:
Huanxuan Ao 2016-12-30 13:22:07 +08:00
parent f020a9ffd6
commit 96578cb8ab
16 changed files with 392 additions and 45 deletions

View File

@ -20,6 +20,7 @@ import logging
from keystoneauth1 import exceptions as ks_exc
from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
import six
@ -117,12 +118,25 @@ class DeleteProject(command.Command):
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
errors = 0
for project in parsed_args.projects:
project_obj = utils.find_resource(
identity_client.tenants,
project,
)
identity_client.tenants.delete(project_obj.id)
try:
project_obj = utils.find_resource(
identity_client.tenants,
project,
)
identity_client.tenants.delete(project_obj.id)
except Exception as e:
errors += 1
LOG.error(_("Failed to delete project with "
"name or ID '%(project)s': %(e)s"),
{'project': project, 'e': e})
if errors > 0:
total = len(parsed_args.projects)
msg = (_("%(errors)s of %(total)s projects failed "
"to delete.") % {'errors': errors, 'total': total})
raise exceptions.CommandError(msg)
class ListProject(command.Lister):

View File

@ -124,12 +124,25 @@ class DeleteRole(command.Command):
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
errors = 0
for role in parsed_args.roles:
role_obj = utils.find_resource(
identity_client.roles,
role,
)
identity_client.roles.delete(role_obj.id)
try:
role_obj = utils.find_resource(
identity_client.roles,
role,
)
identity_client.roles.delete(role_obj.id)
except Exception as e:
errors += 1
LOG.error(_("Failed to delete role with "
"name or ID '%(role)s': %(e)s"),
{'role': role, 'e': e})
if errors > 0:
total = len(parsed_args.roles)
msg = (_("%(errors)s of %(total)s roles failed "
"to delete.") % {'errors': errors, 'total': total})
raise exceptions.CommandError(msg)
class ListRole(command.Lister):

View File

@ -19,6 +19,7 @@ import logging
from keystoneauth1 import exceptions as ks_exc
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
import six
@ -145,12 +146,25 @@ class DeleteUser(command.Command):
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
errors = 0
for user in parsed_args.users:
user_obj = utils.find_resource(
identity_client.users,
user,
)
identity_client.users.delete(user_obj.id)
try:
user_obj = utils.find_resource(
identity_client.users,
user,
)
identity_client.users.delete(user_obj.id)
except Exception as e:
errors += 1
LOG.error(_("Failed to delete user with "
"name or ID '%(user)s': %(e)s"),
{'user': user, 'e': e})
if errors > 0:
total = len(parsed_args.users)
msg = (_("%(errors)s of %(total)s users failed "
"to delete.") % {'errors': errors, 'total': total})
raise exceptions.CommandError(msg)
class ListUser(command.Lister):

View File

@ -20,6 +20,7 @@ import sys
from keystoneauth1 import exceptions as ks_exc
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
import six
@ -194,11 +195,24 @@ class DeleteGroup(command.Command):
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
errors = 0
for group in parsed_args.groups:
group_obj = common.find_group(identity_client,
group,
parsed_args.domain)
identity_client.groups.delete(group_obj.id)
try:
group_obj = common.find_group(identity_client,
group,
parsed_args.domain)
identity_client.groups.delete(group_obj.id)
except Exception as e:
errors += 1
LOG.error(_("Failed to delete group with "
"name or ID '%(group)s': %(e)s"),
{'group': group, 'e': e})
if errors > 0:
total = len(parsed_args.groups)
msg = (_("%(errors)s of %(total)s groups failed "
"to delete.") % {'errors': errors, 'total': total})
raise exceptions.CommandError(msg)
class ListGroup(command.Lister):

View File

@ -20,6 +20,7 @@ import logging
from keystoneauth1 import exceptions as ks_exc
from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
import six
@ -148,15 +149,28 @@ class DeleteProject(command.Command):
domain = None
if parsed_args.domain:
domain = common.find_domain(identity_client, parsed_args.domain)
errors = 0
for project in parsed_args.projects:
if domain is not None:
project_obj = utils.find_resource(identity_client.projects,
project,
domain_id=domain.id)
else:
project_obj = utils.find_resource(identity_client.projects,
project)
identity_client.projects.delete(project_obj.id)
try:
if domain is not None:
project_obj = utils.find_resource(identity_client.projects,
project,
domain_id=domain.id)
else:
project_obj = utils.find_resource(identity_client.projects,
project)
identity_client.projects.delete(project_obj.id)
except Exception as e:
errors += 1
LOG.error(_("Failed to delete project with "
"name or ID '%(project)s': %(e)s"),
{'project': project, 'e': e})
if errors > 0:
total = len(parsed_args.projects)
msg = (_("%(errors)s of %(total)s projects failed "
"to delete.") % {'errors': errors, 'total': total})
raise exceptions.CommandError(msg)
class ListProject(command.Lister):

View File

@ -20,6 +20,7 @@ import sys
from keystoneauth1 import exceptions as ks_exc
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
import six
@ -223,14 +224,26 @@ class DeleteRole(command.Command):
if parsed_args.domain:
domain_id = common.find_domain(identity_client,
parsed_args.domain).id
errors = 0
for role in parsed_args.roles:
role_obj = utils.find_resource(
identity_client.roles,
role,
domain_id=domain_id
)
identity_client.roles.delete(role_obj.id)
try:
role_obj = utils.find_resource(
identity_client.roles,
role,
domain_id=domain_id
)
identity_client.roles.delete(role_obj.id)
except Exception as e:
errors += 1
LOG.error(_("Failed to delete role with "
"name or ID '%(role)s': %(e)s"),
{'role': role, 'e': e})
if errors > 0:
total = len(parsed_args.roles)
msg = (_("%(errors)s of %(total)s roles failed "
"to delete.") % {'errors': errors, 'total': total})
raise exceptions.CommandError(msg)
class ListRole(command.Lister):

View File

@ -14,8 +14,10 @@
"""Identity v3 Trust action implementations"""
import datetime
import logging
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
import six
@ -23,6 +25,9 @@ from openstackclient.i18n import _
from openstackclient.identity import common
LOG = logging.getLogger(__name__)
class CreateTrust(command.ShowOne):
_description = _("Create new trust")
@ -145,9 +150,24 @@ class DeleteTrust(command.Command):
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
for t in parsed_args.trust:
trust_obj = utils.find_resource(identity_client.trusts, t)
identity_client.trusts.delete(trust_obj.id)
errors = 0
for trust in parsed_args.trust:
try:
trust_obj = utils.find_resource(identity_client.trusts,
trust)
identity_client.trusts.delete(trust_obj.id)
except Exception as e:
errors += 1
LOG.error(_("Failed to delete trust with "
"name or ID '%(trust)s': %(e)s"),
{'trust': trust, 'e': e})
if errors > 0:
total = len(parsed_args.trust)
msg = (_("%(errors)s of %(total)s trusts failed "
"to delete.") % {'errors': errors, 'total': total})
raise exceptions.CommandError(msg)
class ListTrust(command.Lister):

View File

@ -20,6 +20,7 @@ import logging
from keystoneauth1 import exceptions as ks_exc
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
import six
@ -161,15 +162,28 @@ class DeleteUser(command.Command):
domain = None
if parsed_args.domain:
domain = common.find_domain(identity_client, parsed_args.domain)
errors = 0
for user in parsed_args.users:
if domain is not None:
user_obj = utils.find_resource(identity_client.users,
user,
domain_id=domain.id)
else:
user_obj = utils.find_resource(identity_client.users,
user)
identity_client.users.delete(user_obj.id)
try:
if domain is not None:
user_obj = utils.find_resource(identity_client.users,
user,
domain_id=domain.id)
else:
user_obj = utils.find_resource(identity_client.users,
user)
identity_client.users.delete(user_obj.id)
except Exception as e:
errors += 1
LOG.error(_("Failed to delete user with "
"name or ID '%(user)s': %(e)s"),
{'user': user, 'e': e})
if errors > 0:
total = len(parsed_args.users)
msg = (_("%(errors)s of %(total)s users failed "
"to delete.") % {'errors': errors, 'total': total})
raise exceptions.CommandError(msg)
class ListUser(command.Lister):

View File

@ -13,8 +13,11 @@
# under the License.
#
import mock
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.identity.v2_0 import project
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
@ -302,6 +305,32 @@ class TestProjectDelete(TestProject):
)
self.assertIsNone(result)
@mock.patch.object(utils, 'find_resource')
def test_delete_multi_projects_with_exception(self, find_mock):
find_mock.side_effect = [self.fake_project,
exceptions.CommandError]
arglist = [
self.fake_project.id,
'unexist_project',
]
verifylist = [
('projects', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 projects failed to delete.',
str(e))
find_mock.assert_any_call(self.projects_mock, self.fake_project.id)
find_mock.assert_any_call(self.projects_mock, 'unexist_project')
self.assertEqual(2, find_mock.call_count)
self.projects_mock.delete.assert_called_once_with(self.fake_project.id)
class TestProjectList(TestProject):

View File

@ -17,6 +17,7 @@ import mock
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.identity.v2_0 import role
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
@ -240,6 +241,32 @@ class TestRoleDelete(TestRole):
)
self.assertIsNone(result)
@mock.patch.object(utils, 'find_resource')
def test_delete_multi_roles_with_exception(self, find_mock):
find_mock.side_effect = [self.fake_role,
exceptions.CommandError]
arglist = [
self.fake_role.id,
'unexist_role',
]
verifylist = [
('roles', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 roles failed to delete.',
str(e))
find_mock.assert_any_call(self.roles_mock, self.fake_role.id)
find_mock.assert_any_call(self.roles_mock, 'unexist_role')
self.assertEqual(2, find_mock.call_count)
self.roles_mock.delete.assert_called_once_with(self.fake_role.id)
class TestRoleList(TestRole):

View File

@ -17,6 +17,7 @@ import mock
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.identity.v2_0 import user
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
@ -411,6 +412,32 @@ class TestUserDelete(TestUser):
)
self.assertIsNone(result)
@mock.patch.object(utils, 'find_resource')
def test_delete_multi_users_with_exception(self, find_mock):
find_mock.side_effect = [self.fake_user,
exceptions.CommandError]
arglist = [
self.fake_user.id,
'unexist_user',
]
verifylist = [
('users', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 users failed to delete.',
str(e))
find_mock.assert_any_call(self.users_mock, self.fake_user.id)
find_mock.assert_any_call(self.users_mock, 'unexist_user')
self.assertEqual(2, find_mock.call_count)
self.users_mock.delete.assert_called_once_with(self.fake_user.id)
class TestUserList(TestUser):

View File

@ -16,6 +16,7 @@ from mock import call
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.identity.v3 import group
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
@ -257,6 +258,32 @@ class TestGroupDelete(TestGroup):
self.groups_mock.delete.assert_called_once_with(self.groups[0].id)
self.assertIsNone(result)
@mock.patch.object(utils, 'find_resource')
def test_delete_multi_groups_with_exception(self, find_mock):
find_mock.side_effect = [self.groups[0],
exceptions.CommandError]
arglist = [
self.groups[0].id,
'unexist_group',
]
verifylist = [
('groups', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 groups failed to delete.',
str(e))
find_mock.assert_any_call(self.groups_mock, self.groups[0].id)
find_mock.assert_any_call(self.groups_mock, 'unexist_group')
self.assertEqual(2, find_mock.call_count)
self.groups_mock.delete.assert_called_once_with(self.groups[0].id)
class TestGroupList(TestGroup):

View File

@ -16,6 +16,7 @@
import mock
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.identity.v3 import project
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
@ -445,6 +446,32 @@ class TestProjectDelete(TestProject):
)
self.assertIsNone(result)
@mock.patch.object(utils, 'find_resource')
def test_delete_multi_projects_with_exception(self, find_mock):
find_mock.side_effect = [self.project,
exceptions.CommandError]
arglist = [
self.project.id,
'unexist_project',
]
verifylist = [
('projects', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 projects failed to delete.',
str(e))
find_mock.assert_any_call(self.projects_mock, self.project.id)
find_mock.assert_any_call(self.projects_mock, 'unexist_project')
self.assertEqual(2, find_mock.call_count)
self.projects_mock.delete.assert_called_once_with(self.project.id)
class TestProjectList(TestProject):

View File

@ -14,6 +14,10 @@
#
import copy
import mock
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.identity.v3 import role
from openstackclient.tests.unit import fakes
@ -428,6 +432,36 @@ class TestRoleDelete(TestRole):
)
self.assertIsNone(result)
@mock.patch.object(utils, 'find_resource')
def test_delete_multi_roles_with_exception(self, find_mock):
find_mock.side_effect = [self.roles_mock.get.return_value,
exceptions.CommandError]
arglist = [
identity_fakes.role_name,
'unexist_role',
]
verifylist = [
('roles', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 roles failed to delete.',
str(e))
find_mock.assert_any_call(self.roles_mock,
identity_fakes.role_name,
domain_id=None)
find_mock.assert_any_call(self.roles_mock,
'unexist_role',
domain_id=None)
self.assertEqual(2, find_mock.call_count)
self.roles_mock.delete.assert_called_once_with(identity_fakes.role_id)
class TestRoleList(TestRole):

View File

@ -12,6 +12,10 @@
#
import copy
import mock
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.identity.v3 import trust
from openstackclient.tests.unit import fakes
@ -148,6 +152,33 @@ class TestTrustDelete(TestTrust):
)
self.assertIsNone(result)
@mock.patch.object(utils, 'find_resource')
def test_delete_multi_trusts_with_exception(self, find_mock):
find_mock.side_effect = [self.trusts_mock.get.return_value,
exceptions.CommandError]
arglist = [
identity_fakes.trust_id,
'unexist_trust',
]
verifylist = [
('trust', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 trusts failed to delete.',
str(e))
find_mock.assert_any_call(self.trusts_mock, identity_fakes.trust_id)
find_mock.assert_any_call(self.trusts_mock, 'unexist_trust')
self.assertEqual(2, find_mock.call_count)
self.trusts_mock.delete.assert_called_once_with(
identity_fakes.trust_id)
class TestTrustList(TestTrust):

View File

@ -16,6 +16,9 @@
import contextlib
import mock
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.identity.v3 import user
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
@ -465,6 +468,32 @@ class TestUserDelete(TestUser):
)
self.assertIsNone(result)
@mock.patch.object(utils, 'find_resource')
def test_delete_multi_users_with_exception(self, find_mock):
find_mock.side_effect = [self.user,
exceptions.CommandError]
arglist = [
self.user.id,
'unexist_user',
]
verifylist = [
('users', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 users failed to delete.',
str(e))
find_mock.assert_any_call(self.users_mock, self.user.id)
find_mock.assert_any_call(self.users_mock, 'unexist_user')
self.assertEqual(2, find_mock.call_count)
self.users_mock.delete.assert_called_once_with(self.user.id)
class TestUserList(TestUser):