summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuanxuan Ao <huanxuan.ao@easystack.cn>2016-07-12 12:44:55 +0800
committerHuanxuan Ao <huanxuan.ao@easystack.cn>2016-07-19 09:49:36 +0800
commit60639d76a742852e18f9e2889c480be95596c268 (patch)
treecad7069ec7b4175f9ceea7e14113b9477698f1e8
parent55c1c575d63f4e9e6fc3f4dbb6c572e841b513d9 (diff)
downloadpython-openstackclient-60639d76a742852e18f9e2889c480be95596c268.tar.gz
Support bulk deletion for delete commands in identityv3
Support bulk deletion for delete commands in the list below identity/v3/consumer identity/v3/credential identity/v3/domain identity/v3/ec2creds identity/v3/endpoint identity/v3/federation_protocol identity/v3/identity_provider identity/v3/mapping identity/v3/policy identity/v3/region identity/v3/service_provider identity/v3/service The unit test in identityv3 need to be refactored, so I add some functional tests instead. I will add all unit tests at one time after the refactor completed. Change-Id: I82367570f59817b47c87b6c7bfeae95ccfe5c50e Closes-Bug: #1592906
-rw-r--r--doc/source/command-objects/consumer.rst6
-rw-r--r--doc/source/command-objects/domain.rst6
-rw-r--r--doc/source/command-objects/federation-protocol.rst6
-rw-r--r--doc/source/command-objects/identity-provider.rst6
-rw-r--r--doc/source/command-objects/mapping.rst6
-rw-r--r--doc/source/command-objects/policy.rst6
-rw-r--r--doc/source/command-objects/region.rst6
-rw-r--r--doc/source/command-objects/service-provider.rst6
-rw-r--r--functional/tests/identity/v3/test_domain.py12
-rw-r--r--functional/tests/identity/v3/test_endpoint.py7
-rw-r--r--functional/tests/identity/v3/test_idp.py7
-rw-r--r--functional/tests/identity/v3/test_region.py7
-rw-r--r--functional/tests/identity/v3/test_service.py7
-rw-r--r--functional/tests/identity/v3/test_service_provider.py7
-rw-r--r--openstackclient/identity/v3/consumer.py31
-rw-r--r--openstackclient/identity/v3/credential.py27
-rwxr-xr-xopenstackclient/identity/v3/domain.py25
-rw-r--r--openstackclient/identity/v3/ec2creds.py25
-rw-r--r--openstackclient/identity/v3/endpoint.py31
-rw-r--r--openstackclient/identity/v3/federation_protocol.py24
-rw-r--r--openstackclient/identity/v3/identity_provider.py23
-rw-r--r--openstackclient/identity/v3/mapping.py22
-rw-r--r--openstackclient/identity/v3/policy.py27
-rw-r--r--openstackclient/identity/v3/region.py28
-rw-r--r--openstackclient/identity/v3/service.py31
-rw-r--r--openstackclient/identity/v3/service_provider.py28
-rw-r--r--openstackclient/tests/identity/v3/test_consumer.py2
-rw-r--r--openstackclient/tests/identity/v3/test_domain.py2
-rw-r--r--openstackclient/tests/identity/v3/test_endpoint.py2
-rw-r--r--openstackclient/tests/identity/v3/test_identity_provider.py2
-rw-r--r--openstackclient/tests/identity/v3/test_mappings.py2
-rw-r--r--openstackclient/tests/identity/v3/test_protocol.py2
-rw-r--r--openstackclient/tests/identity/v3/test_region.py2
-rw-r--r--openstackclient/tests/identity/v3/test_service.py2
-rw-r--r--openstackclient/tests/identity/v3/test_service_provider.py2
-rw-r--r--releasenotes/notes/bug-1592906-ad67ce8736f3cd48.yaml8
36 files changed, 361 insertions, 82 deletions
diff --git a/doc/source/command-objects/consumer.rst b/doc/source/command-objects/consumer.rst
index 91294fa2..335eaea3 100644
--- a/doc/source/command-objects/consumer.rst
+++ b/doc/source/command-objects/consumer.rst
@@ -24,17 +24,17 @@ Create new consumer
consumer delete
---------------
-Delete consumer
+Delete consumer(s)
.. program:: consumer delete
.. code:: bash
os consumer delete
- <consumer>
+ <consumer> [<consumer> ...]
.. describe:: <consumer>
- Consumer to delete
+ Consumer(s) to delete
consumer list
-------------
diff --git a/doc/source/command-objects/domain.rst b/doc/source/command-objects/domain.rst
index 94473570..573a78cb 100644
--- a/doc/source/command-objects/domain.rst
+++ b/doc/source/command-objects/domain.rst
@@ -43,17 +43,17 @@ Create new domain
domain delete
-------------
-Delete domain
+Delete domain(s)
.. program:: domain delete
.. code:: bash
os domain delete
- <domain>
+ <domain> [<domain> ...]
.. describe:: <domain>
- Domain to delete (name or ID)
+ Domain(s) to delete (name or ID)
domain list
-----------
diff --git a/doc/source/command-objects/federation-protocol.rst b/doc/source/command-objects/federation-protocol.rst
index 5b4ea48a..911d4e99 100644
--- a/doc/source/command-objects/federation-protocol.rst
+++ b/doc/source/command-objects/federation-protocol.rst
@@ -34,14 +34,14 @@ Create new federation protocol
federation protocol delete
--------------------------
-Delete federation protocol
+Delete federation protocol(s)
.. program:: federation protocol delete
.. code:: bash
os federation protocol delete
--identity-provider <identity-provider>
- <federation-protocol>
+ <federation-protocol> [<federation-protocol> ...]
.. option:: --identity-provider <identity-provider>
@@ -49,7 +49,7 @@ Delete federation protocol
.. describe:: <federation-protocol>
- Federation protocol to delete (name or ID)
+ Federation protocol(s) to delete (name or ID)
federation protocol list
------------------------
diff --git a/doc/source/command-objects/identity-provider.rst b/doc/source/command-objects/identity-provider.rst
index ca773d81..f772511d 100644
--- a/doc/source/command-objects/identity-provider.rst
+++ b/doc/source/command-objects/identity-provider.rst
@@ -49,17 +49,17 @@ Create new identity provider
identity provider delete
------------------------
-Delete identity provider
+Delete identity provider(s)
.. program:: identity provider delete
.. code:: bash
os identity provider delete
- <identity-provider>
+ <identity-provider> [<identity-provider> ...]
.. describe:: <identity-provider>
- Identity provider to delete
+ Identity provider(s) to delete
identity provider list
----------------------
diff --git a/doc/source/command-objects/mapping.rst b/doc/source/command-objects/mapping.rst
index 25af4740..7f61366e 100644
--- a/doc/source/command-objects/mapping.rst
+++ b/doc/source/command-objects/mapping.rst
@@ -30,18 +30,18 @@ Create new mapping
mapping delete
--------------
-Delete mapping
+Delete mapping(s)
.. program:: mapping delete
.. code:: bash
os mapping delete
- <mapping>
+ <mapping> [<mapping> ...]
.. _mapping_delete-mapping:
.. describe:: <mapping>
- Mapping to delete
+ Mapping(s) to delete
mapping list
------------
diff --git a/doc/source/command-objects/policy.rst b/doc/source/command-objects/policy.rst
index 195a89f2..757b1c53 100644
--- a/doc/source/command-objects/policy.rst
+++ b/doc/source/command-objects/policy.rst
@@ -27,17 +27,17 @@ Create new policy
policy delete
-------------
-Delete policy
+Delete policy(s)
.. program:: policy delete
.. code:: bash
os policy delete
- <policy>
+ <policy> [<policy> ...]
.. describe:: <policy>
- Policy to delete
+ Policy(s) to delete
policy list
-----------
diff --git a/doc/source/command-objects/region.rst b/doc/source/command-objects/region.rst
index 1892fc24..b74821a9 100644
--- a/doc/source/command-objects/region.rst
+++ b/doc/source/command-objects/region.rst
@@ -33,18 +33,18 @@ Create new region
region delete
-------------
-Delete region
+Delete region(s)
.. program:: region delete
.. code:: bash
os region delete
- <region-id>
+ <region-id> [<region-id> ...]
.. _region_delete-region-id:
.. describe:: <region-id>
- Region ID to delete
+ Region ID(s) to delete
region list
-----------
diff --git a/doc/source/command-objects/service-provider.rst b/doc/source/command-objects/service-provider.rst
index 963493b4..e0fbba2f 100644
--- a/doc/source/command-objects/service-provider.rst
+++ b/doc/source/command-objects/service-provider.rst
@@ -48,17 +48,17 @@ Create new service provider
service provider delete
-----------------------
-Delete service provider
+Delete service provider(s)
.. program:: service provider delete
.. code:: bash
os service provider delete
- <service-provider>
+ <service-provider> [<service-provider> ...]
.. describe:: <service-provider>
- Service provider to delete
+ Service provider(s) to delete
service provider list
---------------------
diff --git a/functional/tests/identity/v3/test_domain.py b/functional/tests/identity/v3/test_domain.py
index 305ed58d..3f514b58 100644
--- a/functional/tests/identity/v3/test_domain.py
+++ b/functional/tests/identity/v3/test_domain.py
@@ -43,6 +43,18 @@ class DomainTests(common.IdentityTests):
raw_output = self.openstack('domain delete %s' % domain_name)
self.assertEqual(0, len(raw_output))
+ def test_domain_multi_delete(self):
+ domain_1 = self._create_dummy_domain(add_clean_up=False)
+ domain_2 = self._create_dummy_domain(add_clean_up=False)
+ # cannot delete enabled domain, disable it first
+ raw_output = self.openstack('domain set --disable %s' % domain_1)
+ self.assertEqual(0, len(raw_output))
+ raw_output = self.openstack('domain set --disable %s' % domain_2)
+ self.assertEqual(0, len(raw_output))
+ raw_output = self.openstack(
+ 'domain delete %s %s' % (domain_1, domain_2))
+ self.assertEqual(0, len(raw_output))
+
def test_domain_delete_failure(self):
domain_name = self._create_dummy_domain()
# cannot delete enabled domain
diff --git a/functional/tests/identity/v3/test_endpoint.py b/functional/tests/identity/v3/test_endpoint.py
index 162c9e58..e0afab23 100644
--- a/functional/tests/identity/v3/test_endpoint.py
+++ b/functional/tests/identity/v3/test_endpoint.py
@@ -28,6 +28,13 @@ class EndpointTests(common.IdentityTests):
'endpoint delete %s' % endpoint_id)
self.assertEqual(0, len(raw_output))
+ def test_endpoint_multi_delete(self):
+ endpoint_1 = self._create_dummy_endpoint(add_clean_up=False)
+ endpoint_2 = self._create_dummy_endpoint(add_clean_up=False)
+ raw_output = self.openstack(
+ 'endpoint delete %s %s' % (endpoint_1, endpoint_2))
+ self.assertEqual(0, len(raw_output))
+
def test_endpoint_list(self):
endpoint_id = self._create_dummy_endpoint()
raw_output = self.openstack('endpoint list')
diff --git a/functional/tests/identity/v3/test_idp.py b/functional/tests/identity/v3/test_idp.py
index 8d864712..bc9690f7 100644
--- a/functional/tests/identity/v3/test_idp.py
+++ b/functional/tests/identity/v3/test_idp.py
@@ -26,6 +26,13 @@ class IdentityProviderTests(common.IdentityTests):
% identity_provider)
self.assertEqual(0, len(raw_output))
+ def test_idp_multi_delete(self):
+ idp_1 = self._create_dummy_idp(add_clean_up=False)
+ idp_2 = self._create_dummy_idp(add_clean_up=False)
+ raw_output = self.openstack(
+ 'identity provider delete %s %s' % (idp_1, idp_2))
+ self.assertEqual(0, len(raw_output))
+
def test_idp_show(self):
identity_provider = self._create_dummy_idp(add_clean_up=True)
raw_output = self.openstack('identity provider show %s'
diff --git a/functional/tests/identity/v3/test_region.py b/functional/tests/identity/v3/test_region.py
index 5ba0c231..2ebc0e59 100644
--- a/functional/tests/identity/v3/test_region.py
+++ b/functional/tests/identity/v3/test_region.py
@@ -27,6 +27,13 @@ class RegionTests(common.IdentityTests):
raw_output = self.openstack('region delete %s' % region_id)
self.assertEqual(0, len(raw_output))
+ def test_region_multi_delete(self):
+ region_1 = self._create_dummy_region(add_clean_up=False)
+ region_2 = self._create_dummy_region(add_clean_up=False)
+ raw_output = self.openstack(
+ 'region delete %s %s' % (region_1, region_2))
+ self.assertEqual(0, len(raw_output))
+
def test_region_list(self):
raw_output = self.openstack('region list')
items = self.parse_listing(raw_output)
diff --git a/functional/tests/identity/v3/test_service.py b/functional/tests/identity/v3/test_service.py
index c757d914..79a63dc8 100644
--- a/functional/tests/identity/v3/test_service.py
+++ b/functional/tests/identity/v3/test_service.py
@@ -25,6 +25,13 @@ class ServiceTests(common.IdentityTests):
raw_output = self.openstack('service delete %s' % service_name)
self.assertEqual(0, len(raw_output))
+ def test_service_multi_delete(self):
+ service_1 = self._create_dummy_service(add_clean_up=False)
+ service_2 = self._create_dummy_service(add_clean_up=False)
+ raw_output = self.openstack(
+ 'service delete %s %s' % (service_1, service_2))
+ self.assertEqual(0, len(raw_output))
+
def test_service_list(self):
self._create_dummy_service()
raw_output = self.openstack('service list')
diff --git a/functional/tests/identity/v3/test_service_provider.py b/functional/tests/identity/v3/test_service_provider.py
index 6cfa7e56..458c2ae6 100644
--- a/functional/tests/identity/v3/test_service_provider.py
+++ b/functional/tests/identity/v3/test_service_provider.py
@@ -26,6 +26,13 @@ class ServiceProviderTests(common.IdentityTests):
% service_provider)
self.assertEqual(0, len(raw_output))
+ def test_sp_multi_delete(self):
+ sp1 = self._create_dummy_sp(add_clean_up=False)
+ sp2 = self._create_dummy_sp(add_clean_up=False)
+ raw_output = self.openstack(
+ 'service provider delete %s %s' % (sp1, sp2))
+ self.assertEqual(0, len(raw_output))
+
def test_sp_show(self):
service_provider = self._create_dummy_sp(add_clean_up=True)
raw_output = self.openstack('service provider show %s'
diff --git a/openstackclient/identity/v3/consumer.py b/openstackclient/identity/v3/consumer.py
index 65bf657f..b41a37ca 100644
--- a/openstackclient/identity/v3/consumer.py
+++ b/openstackclient/identity/v3/consumer.py
@@ -15,13 +15,19 @@
"""Identity v3 Consumer action implementations"""
+import logging
+
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
from openstackclient.i18n import _
+LOG = logging.getLogger(__name__)
+
+
class CreateConsumer(command.ShowOne):
"""Create new consumer"""
@@ -44,22 +50,37 @@ class CreateConsumer(command.ShowOne):
class DeleteConsumer(command.Command):
- """Delete consumer"""
+ """Delete consumer(s)"""
def get_parser(self, prog_name):
parser = super(DeleteConsumer, self).get_parser(prog_name)
parser.add_argument(
'consumer',
metavar='<consumer>',
- help=_('Consumer to delete'),
+ nargs='+',
+ help=_('Consumer(s) to delete'),
)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- consumer = utils.find_resource(
- identity_client.oauth1.consumers, parsed_args.consumer)
- identity_client.oauth1.consumers.delete(consumer.id)
+ result = 0
+ for i in parsed_args.consumer:
+ try:
+ consumer = utils.find_resource(
+ identity_client.oauth1.consumers, i)
+ identity_client.oauth1.consumers.delete(consumer.id)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete consumer with name or "
+ "ID '%(consumer)s': %(e)s")
+ % {'consumer': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.consumer)
+ msg = (_("%(result)s of %(total)s consumers failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListConsumer(command.Lister):
diff --git a/openstackclient/identity/v3/credential.py b/openstackclient/identity/v3/credential.py
index eeeddfa5..0ea29aba 100644
--- a/openstackclient/identity/v3/credential.py
+++ b/openstackclient/identity/v3/credential.py
@@ -15,13 +15,19 @@
"""Identity v3 Credential action implementations"""
+import logging
+
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
from openstackclient.i18n import _
+LOG = logging.getLogger(__name__)
+
+
class CreateCredential(command.ShowOne):
"""Create credential command"""
@@ -72,20 +78,35 @@ class CreateCredential(command.ShowOne):
class DeleteCredential(command.Command):
- """Delete credential command"""
+ """Delete credential(s)"""
def get_parser(self, prog_name):
parser = super(DeleteCredential, self).get_parser(prog_name)
parser.add_argument(
'credential',
metavar='<credential-id>',
- help=_('ID of credential to delete'),
+ nargs='+',
+ help=_('ID of credential(s) to delete'),
)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- identity_client.credentials.delete(parsed_args.credential)
+ result = 0
+ for i in parsed_args.credential:
+ try:
+ identity_client.credentials.delete(i)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete credentials with "
+ "ID '%(credential)s': %(e)s")
+ % {'credential': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.credential)
+ msg = (_("%(result)s of %(total)s credential failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListCredential(command.Lister):
diff --git a/openstackclient/identity/v3/domain.py b/openstackclient/identity/v3/domain.py
index 3e9bcf63..76e47d32 100755
--- a/openstackclient/identity/v3/domain.py
+++ b/openstackclient/identity/v3/domain.py
@@ -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
@@ -88,22 +89,36 @@ class CreateDomain(command.ShowOne):
class DeleteDomain(command.Command):
- """Delete domain"""
+ """Delete domain(s)"""
def get_parser(self, prog_name):
parser = super(DeleteDomain, self).get_parser(prog_name)
parser.add_argument(
'domain',
metavar='<domain>',
- help=_('Domain to delete (name or ID)'),
+ nargs='+',
+ help=_('Domain(s) to delete (name or ID)'),
)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- domain = utils.find_resource(identity_client.domains,
- parsed_args.domain)
- identity_client.domains.delete(domain.id)
+ result = 0
+ for i in parsed_args.domain:
+ try:
+ domain = utils.find_resource(identity_client.domains, i)
+ identity_client.domains.delete(domain.id)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete domain with name or "
+ "ID '%(domain)s': %(e)s")
+ % {'domain': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.domain)
+ msg = (_("%(result)s of %(total)s domains failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListDomain(command.Lister):
diff --git a/openstackclient/identity/v3/ec2creds.py b/openstackclient/identity/v3/ec2creds.py
index 835fe96f..7ad01719 100644
--- a/openstackclient/identity/v3/ec2creds.py
+++ b/openstackclient/identity/v3/ec2creds.py
@@ -12,7 +12,10 @@
"""Identity v3 EC2 Credentials action implementations"""
+import logging
+
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
@@ -20,6 +23,9 @@ from openstackclient.i18n import _
from openstackclient.identity import common
+LOG = logging.getLogger(__name__)
+
+
def _determine_ec2_user(parsed_args, client_manager):
"""Determine a user several different ways.
@@ -113,7 +119,8 @@ class DeleteEC2Creds(command.Command):
parser.add_argument(
'access_key',
metavar='<access-key>',
- help=_('Credentials access key'),
+ nargs='+',
+ help=_('Credentials access key(s)'),
)
parser.add_argument(
'--user',
@@ -126,7 +133,21 @@ class DeleteEC2Creds(command.Command):
def take_action(self, parsed_args):
client_manager = self.app.client_manager
user = _determine_ec2_user(parsed_args, client_manager)
- client_manager.identity.ec2.delete(user, parsed_args.access_key)
+ result = 0
+ for i in parsed_args.access_key:
+ try:
+ client_manager.identity.ec2.delete(user, i)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete EC2 credentials with "
+ "access key '%(access_key)s': %(e)s")
+ % {'access_key': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.access_key)
+ msg = (_("%(result)s of %(total)s EC2 keys failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListEC2Creds(command.Lister):
diff --git a/openstackclient/identity/v3/endpoint.py b/openstackclient/identity/v3/endpoint.py
index bd2df361..73b37a43 100644
--- a/openstackclient/identity/v3/endpoint.py
+++ b/openstackclient/identity/v3/endpoint.py
@@ -15,7 +15,10 @@
"""Identity v3 Endpoint action implementations"""
+import logging
+
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
@@ -23,6 +26,9 @@ from openstackclient.i18n import _
from openstackclient.identity import common
+LOG = logging.getLogger(__name__)
+
+
def get_service_name(service):
if hasattr(service, 'name'):
return service.name
@@ -93,22 +99,37 @@ class CreateEndpoint(command.ShowOne):
class DeleteEndpoint(command.Command):
- """Delete endpoint"""
+ """Delete endpoint(s)"""
def get_parser(self, prog_name):
parser = super(DeleteEndpoint, self).get_parser(prog_name)
parser.add_argument(
'endpoint',
metavar='<endpoint-id>',
- help=_('Endpoint to delete (ID only)'),
+ nargs='+',
+ help=_('Endpoint(s) to delete (ID only)'),
)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- endpoint_id = utils.find_resource(identity_client.endpoints,
- parsed_args.endpoint).id
- identity_client.endpoints.delete(endpoint_id)
+ result = 0
+ for i in parsed_args.endpoint:
+ try:
+ endpoint_id = utils.find_resource(
+ identity_client.endpoints, i).id
+ identity_client.endpoints.delete(endpoint_id)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete endpoint with "
+ "ID '%(endpoint)s': %(e)s")
+ % {'endpoint': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.endpoint)
+ msg = (_("%(result)s of %(total)s endpoints failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListEndpoint(command.Lister):
diff --git a/openstackclient/identity/v3/federation_protocol.py b/openstackclient/identity/v3/federation_protocol.py
index 0369bc3d..3fde9027 100644
--- a/openstackclient/identity/v3/federation_protocol.py
+++ b/openstackclient/identity/v3/federation_protocol.py
@@ -17,6 +17,7 @@
import logging
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
@@ -71,14 +72,15 @@ class CreateProtocol(command.ShowOne):
class DeleteProtocol(command.Command):
- """Delete federation protocol"""
+ """Delete federation protocol(s)"""
def get_parser(self, prog_name):
parser = super(DeleteProtocol, self).get_parser(prog_name)
parser.add_argument(
'federation_protocol',
metavar='<federation-protocol>',
- help=_('Federation protocol to delete (name or ID)'),
+ nargs='+',
+ help=_('Federation protocol(s) to delete (name or ID)'),
)
parser.add_argument(
'--identity-provider',
@@ -92,8 +94,22 @@ class DeleteProtocol(command.Command):
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- identity_client.federation.protocols.delete(
- parsed_args.identity_provider, parsed_args.federation_protocol)
+ result = 0
+ for i in parsed_args.federation_protocol:
+ try:
+ identity_client.federation.protocols.delete(
+ parsed_args.identity_provider, i)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete federation protocol "
+ "with name or ID '%(protocol)s': %(e)s")
+ % {'protocol': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.federation_protocol)
+ msg = (_("%(result)s of %(total)s federation protocols failed"
+ " to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListProtocols(command.Lister):
diff --git a/openstackclient/identity/v3/identity_provider.py b/openstackclient/identity/v3/identity_provider.py
index 6fc9b13c..0453e888 100644
--- a/openstackclient/identity/v3/identity_provider.py
+++ b/openstackclient/identity/v3/identity_provider.py
@@ -16,6 +16,7 @@
import logging
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
@@ -93,21 +94,35 @@ class CreateIdentityProvider(command.ShowOne):
class DeleteIdentityProvider(command.Command):
- """Delete identity provider"""
+ """Delete identity provider(s)"""
def get_parser(self, prog_name):
parser = super(DeleteIdentityProvider, self).get_parser(prog_name)
parser.add_argument(
'identity_provider',
metavar='<identity-provider>',
- help=_('Identity provider to delete'),
+ nargs='+',
+ help=_('Identity provider(s) to delete'),
)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- identity_client.federation.identity_providers.delete(
- parsed_args.identity_provider)
+ result = 0
+ for i in parsed_args.identity_provider:
+ try:
+ identity_client.federation.identity_providers.delete(i)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete identity providers with "
+ "name or ID '%(provider)s': %(e)s")
+ % {'provider': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.identity_provider)
+ msg = (_("%(result)s of %(total)s identity providers failed"
+ " to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListIdentityProvider(command.Lister):
diff --git a/openstackclient/identity/v3/mapping.py b/openstackclient/identity/v3/mapping.py
index 69c141b1..09181a0b 100644
--- a/openstackclient/identity/v3/mapping.py
+++ b/openstackclient/identity/v3/mapping.py
@@ -111,21 +111,35 @@ class CreateMapping(command.ShowOne, _RulesReader):
class DeleteMapping(command.Command):
- """Delete mapping"""
+ """Delete mapping(s)"""
def get_parser(self, prog_name):
parser = super(DeleteMapping, self).get_parser(prog_name)
parser.add_argument(
'mapping',
metavar='<mapping>',
- help=_('Mapping to delete'),
+ nargs='+',
+ help=_('Mapping(s) to delete'),
)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
-
- identity_client.federation.mappings.delete(parsed_args.mapping)
+ result = 0
+ for i in parsed_args.mapping:
+ try:
+ identity_client.federation.mappings.delete(i)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete mapping with name or "
+ "ID '%(mapping)s': %(e)s")
+ % {'mapping': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.mapping)
+ msg = (_("%(result)s of %(total)s mappings failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListMapping(command.Lister):
diff --git a/openstackclient/identity/v3/policy.py b/openstackclient/identity/v3/policy.py
index 79215cab..596eae01 100644
--- a/openstackclient/identity/v3/policy.py
+++ b/openstackclient/identity/v3/policy.py
@@ -15,13 +15,19 @@
"""Identity v3 Policy action implementations"""
+import logging
+
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
from openstackclient.i18n import _
+LOG = logging.getLogger(__name__)
+
+
class CreatePolicy(command.ShowOne):
"""Create new policy"""
@@ -55,20 +61,35 @@ class CreatePolicy(command.ShowOne):
class DeletePolicy(command.Command):
- """Delete policy"""
+ """Delete policy(s)"""
def get_parser(self, prog_name):
parser = super(DeletePolicy, self).get_parser(prog_name)
parser.add_argument(
'policy',
metavar='<policy>',
- help=_('Policy to delete'),
+ nargs='+',
+ help=_('Policy(s) to delete'),
)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- identity_client.policies.delete(parsed_args.policy)
+ result = 0
+ for i in parsed_args.policy:
+ try:
+ identity_client.policies.delete(i)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete policy with name or "
+ "ID '%(policy)s': %(e)s")
+ % {'policy': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.policy)
+ msg = (_("%(result)s of %(total)s policys failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListPolicy(command.Lister):
diff --git a/openstackclient/identity/v3/region.py b/openstackclient/identity/v3/region.py
index d714cd05..b7c51f93 100644
--- a/openstackclient/identity/v3/region.py
+++ b/openstackclient/identity/v3/region.py
@@ -13,13 +13,19 @@
"""Identity v3 Region action implementations"""
+import logging
+
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
from openstackclient.i18n import _
+LOG = logging.getLogger(__name__)
+
+
class CreateRegion(command.ShowOne):
"""Create new region"""
@@ -60,21 +66,35 @@ class CreateRegion(command.ShowOne):
class DeleteRegion(command.Command):
- """Delete region"""
+ """Delete region(s)"""
def get_parser(self, prog_name):
parser = super(DeleteRegion, self).get_parser(prog_name)
parser.add_argument(
'region',
metavar='<region-id>',
- help=_('Region ID to delete'),
+ nargs='+',
+ help=_('Region ID(s) to delete'),
)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
-
- identity_client.regions.delete(parsed_args.region)
+ result = 0
+ for i in parsed_args.region:
+ try:
+ identity_client.regions.delete(i)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete region with "
+ "ID '%(region)s': %(e)s")
+ % {'region': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.region)
+ msg = (_("%(result)s of %(total)s regions failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListRegion(command.Lister):
diff --git a/openstackclient/identity/v3/service.py b/openstackclient/identity/v3/service.py
index 7b23ae29..97e64dc6 100644
--- a/openstackclient/identity/v3/service.py
+++ b/openstackclient/identity/v3/service.py
@@ -15,7 +15,10 @@
"""Identity v3 Service action implementations"""
+import logging
+
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
@@ -23,6 +26,9 @@ from openstackclient.i18n import _
from openstackclient.identity import common
+LOG = logging.getLogger(__name__)
+
+
class CreateService(command.ShowOne):
"""Create new service"""
@@ -75,23 +81,36 @@ class CreateService(command.ShowOne):
class DeleteService(command.Command):
- """Delete service"""
+ """Delete service(s)"""
def get_parser(self, prog_name):
parser = super(DeleteService, self).get_parser(prog_name)
parser.add_argument(
'service',
metavar='<service>',
- help=_('Service to delete (type, name or ID)'),
+ nargs='+',
+ help=_('Service(s) to delete (type, name or ID)'),
)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
-
- service = common.find_service(identity_client, parsed_args.service)
-
- identity_client.services.delete(service.id)
+ result = 0
+ for i in parsed_args.service:
+ try:
+ service = common.find_service(identity_client, i)
+ identity_client.services.delete(service.id)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete consumer with type, "
+ "name or ID '%(service)s': %(e)s")
+ % {'service': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.service)
+ msg = (_("%(result)s of %(total)s services failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListService(command.Lister):
diff --git a/openstackclient/identity/v3/service_provider.py b/openstackclient/identity/v3/service_provider.py
index 1f95def8..440eba40 100644
--- a/openstackclient/identity/v3/service_provider.py
+++ b/openstackclient/identity/v3/service_provider.py
@@ -13,13 +13,19 @@
"""Service Provider action implementations"""
+import logging
+
from osc_lib.command import command
+from osc_lib import exceptions
from osc_lib import utils
import six
from openstackclient.i18n import _
+LOG = logging.getLogger(__name__)
+
+
class CreateServiceProvider(command.ShowOne):
"""Create new service provider"""
@@ -81,21 +87,35 @@ class CreateServiceProvider(command.ShowOne):
class DeleteServiceProvider(command.Command):
- """Delete service provider"""
+ """Delete service provider(s)"""
def get_parser(self, prog_name):
parser = super(DeleteServiceProvider, self).get_parser(prog_name)
parser.add_argument(
'service_provider',
metavar='<service-provider>',
- help=_('Service provider to delete'),
+ nargs='+',
+ help=_('Service provider(s) to delete'),
)
return parser
def take_action(self, parsed_args):
service_client = self.app.client_manager.identity
- service_client.federation.service_providers.delete(
- parsed_args.service_provider)
+ result = 0
+ for i in parsed_args.service_provider:
+ try:
+ service_client.federation.service_providers.delete(i)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete service provider with "
+ "name or ID '%(provider)s': %(e)s")
+ % {'provider': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.service_provider)
+ msg = (_("%(result)s of %(total)s service providers failed"
+ " to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListServiceProvider(command.Lister):
diff --git a/openstackclient/tests/identity/v3/test_consumer.py b/openstackclient/tests/identity/v3/test_consumer.py
index 4a8cf087..d90c7347 100644
--- a/openstackclient/tests/identity/v3/test_consumer.py
+++ b/openstackclient/tests/identity/v3/test_consumer.py
@@ -83,7 +83,7 @@ class TestConsumerDelete(TestOAuth1):
identity_fakes.consumer_id,
]
verifylist = [
- ('consumer', identity_fakes.consumer_id),
+ ('consumer', [identity_fakes.consumer_id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/identity/v3/test_domain.py b/openstackclient/tests/identity/v3/test_domain.py
index 17bcee06..5e094021 100644
--- a/openstackclient/tests/identity/v3/test_domain.py
+++ b/openstackclient/tests/identity/v3/test_domain.py
@@ -182,7 +182,7 @@ class TestDomainDelete(TestDomain):
self.domain.id,
]
verifylist = [
- ('domain', self.domain.id),
+ ('domain', [self.domain.id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/identity/v3/test_endpoint.py b/openstackclient/tests/identity/v3/test_endpoint.py
index 184e14a4..04276319 100644
--- a/openstackclient/tests/identity/v3/test_endpoint.py
+++ b/openstackclient/tests/identity/v3/test_endpoint.py
@@ -273,7 +273,7 @@ class TestEndpointDelete(TestEndpoint):
identity_fakes.endpoint_id,
]
verifylist = [
- ('endpoint', identity_fakes.endpoint_id),
+ ('endpoint', [identity_fakes.endpoint_id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/identity/v3/test_identity_provider.py b/openstackclient/tests/identity/v3/test_identity_provider.py
index 8561fab9..1ec61052 100644
--- a/openstackclient/tests/identity/v3/test_identity_provider.py
+++ b/openstackclient/tests/identity/v3/test_identity_provider.py
@@ -255,7 +255,7 @@ class TestIdentityProviderDelete(TestIdentityProvider):
identity_fakes.idp_id,
]
verifylist = [
- ('identity_provider', identity_fakes.idp_id),
+ ('identity_provider', [identity_fakes.idp_id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/identity/v3/test_mappings.py b/openstackclient/tests/identity/v3/test_mappings.py
index af7b135d..6aa1a6e5 100644
--- a/openstackclient/tests/identity/v3/test_mappings.py
+++ b/openstackclient/tests/identity/v3/test_mappings.py
@@ -91,7 +91,7 @@ class TestMappingDelete(TestMapping):
identity_fakes.mapping_id
]
verifylist = [
- ('mapping', identity_fakes.mapping_id)
+ ('mapping', [identity_fakes.mapping_id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/identity/v3/test_protocol.py b/openstackclient/tests/identity/v3/test_protocol.py
index 238b0ff8..f718b27b 100644
--- a/openstackclient/tests/identity/v3/test_protocol.py
+++ b/openstackclient/tests/identity/v3/test_protocol.py
@@ -88,7 +88,7 @@ class TestProtocolDelete(TestProtocol):
identity_fakes.protocol_id
]
verifylist = [
- ('federation_protocol', identity_fakes.protocol_id),
+ ('federation_protocol', [identity_fakes.protocol_id]),
('identity_provider', identity_fakes.idp_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/identity/v3/test_region.py b/openstackclient/tests/identity/v3/test_region.py
index 44e4814b..41ee5ce9 100644
--- a/openstackclient/tests/identity/v3/test_region.py
+++ b/openstackclient/tests/identity/v3/test_region.py
@@ -153,7 +153,7 @@ class TestRegionDelete(TestRegion):
identity_fakes.region_id,
]
verifylist = [
- ('region', identity_fakes.region_id),
+ ('region', [identity_fakes.region_id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/identity/v3/test_service.py b/openstackclient/tests/identity/v3/test_service.py
index 1e70383f..a1f85adc 100644
--- a/openstackclient/tests/identity/v3/test_service.py
+++ b/openstackclient/tests/identity/v3/test_service.py
@@ -200,7 +200,7 @@ class TestServiceDelete(TestService):
identity_fakes.service_name,
]
verifylist = [
- ('service', identity_fakes.service_name),
+ ('service', [identity_fakes.service_name]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/identity/v3/test_service_provider.py b/openstackclient/tests/identity/v3/test_service_provider.py
index 42805794..f5270d83 100644
--- a/openstackclient/tests/identity/v3/test_service_provider.py
+++ b/openstackclient/tests/identity/v3/test_service_provider.py
@@ -185,7 +185,7 @@ class TestServiceProviderDelete(TestServiceProvider):
service_fakes.sp_id,
]
verifylist = [
- ('service_provider', service_fakes.sp_id),
+ ('service_provider', [service_fakes.sp_id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/releasenotes/notes/bug-1592906-ad67ce8736f3cd48.yaml b/releasenotes/notes/bug-1592906-ad67ce8736f3cd48.yaml
new file mode 100644
index 00000000..e674a209
--- /dev/null
+++ b/releasenotes/notes/bug-1592906-ad67ce8736f3cd48.yaml
@@ -0,0 +1,8 @@
+---
+features:
+ - |
+ Support bulk deletion for identity v3 commands: ``consumer``,
+ ``credential``, ``domain``, ``ec2creds``, ``endpoint``,
+ ``federation_protocol``, ``identity_provider``, ``mapping``,
+ ``policy``, ``region``, ``service_provider`` and ``service``.
+ [Bug `1592906 <https://bugs.launchpad.net/bugs/1592906>`_]