summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/command-objects/ec2-credentials.rst4
-rw-r--r--doc/source/command-objects/endpoint.rst6
-rw-r--r--doc/source/command-objects/service.rst6
-rw-r--r--functional/tests/identity/v2/test_ec2_credentials.py8
-rw-r--r--functional/tests/identity/v2/test_endpoint.py7
-rw-r--r--functional/tests/identity/v2/test_service.py7
-rw-r--r--openstackclient/identity/v2_0/ec2creds.py27
-rw-r--r--openstackclient/identity/v2_0/endpoint.py30
-rw-r--r--openstackclient/identity/v2_0/service.py26
-rw-r--r--openstackclient/tests/identity/v2_0/test_endpoint.py2
-rw-r--r--openstackclient/tests/identity/v2_0/test_service.py2
-rw-r--r--releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml5
12 files changed, 108 insertions, 22 deletions
diff --git a/doc/source/command-objects/ec2-credentials.rst b/doc/source/command-objects/ec2-credentials.rst
index 6748422e..caf7fd69 100644
--- a/doc/source/command-objects/ec2-credentials.rst
+++ b/doc/source/command-objects/ec2-credentials.rst
@@ -55,7 +55,7 @@ Delete EC2 credentials
os ec2 credentials delete
[--user <user>]
[--user-domain <user-domain>]
- <access-key>
+ <access-key> [<access-key> ...]
.. option:: --user <user>
@@ -71,7 +71,7 @@ Delete EC2 credentials
.. _ec2_credentials_delete-access-key:
.. describe:: access-key
- Credentials access key
+ Credentials access key(s)
The :option:`--user` option is typically only useful for admin users, but
may be allowed for other users depending on the policy of the cloud and
diff --git a/doc/source/command-objects/endpoint.rst b/doc/source/command-objects/endpoint.rst
index 817ad491..c058c844 100644
--- a/doc/source/command-objects/endpoint.rst
+++ b/doc/source/command-objects/endpoint.rst
@@ -81,18 +81,18 @@ Create new endpoint
endpoint delete
---------------
-Delete endpoint
+Delete endpoint(s)
.. program:: endpoint delete
.. code:: bash
os endpoint delete
- <endpoint-id>
+ <endpoint-id> [<endpoint-id> ...]
.. _endpoint_delete-endpoint:
.. describe:: <endpoint-id>
- Endpoint to delete (ID only)
+ Endpoint(s) to delete (ID only)
endpoint list
-------------
diff --git a/doc/source/command-objects/service.rst b/doc/source/command-objects/service.rst
index 421a298b..b5ec2d99 100644
--- a/doc/source/command-objects/service.rst
+++ b/doc/source/command-objects/service.rst
@@ -46,18 +46,18 @@ Create new service
service delete
--------------
-Delete service
+Delete service(s)
.. program:: service delete
.. code-block:: bash
os service delete
- <service>
+ <service> [<service> ...]
.. _service_delete-type:
.. describe:: <service>
- Service to delete (type, name or ID)
+ Service(s) to delete (type, name or ID)
service list
------------
diff --git a/functional/tests/identity/v2/test_ec2_credentials.py b/functional/tests/identity/v2/test_ec2_credentials.py
index 319bd11a..7a8ee35d 100644
--- a/functional/tests/identity/v2/test_ec2_credentials.py
+++ b/functional/tests/identity/v2/test_ec2_credentials.py
@@ -25,6 +25,14 @@ class EC2CredentialsTests(common.IdentityTests):
)
self.assertEqual(0, len(raw_output))
+ def test_ec2_credentials_multi_delete(self):
+ access_key_1 = self._create_dummy_ec2_credentials(add_clean_up=False)
+ access_key_2 = self._create_dummy_ec2_credentials(add_clean_up=False)
+ raw_output = self.openstack(
+ 'ec2 credentials delete ' + access_key_1 + ' ' + access_key_2
+ )
+ self.assertEqual(0, len(raw_output))
+
def test_ec2_credentials_list(self):
self._create_dummy_ec2_credentials()
raw_output = self.openstack('ec2 credentials list')
diff --git a/functional/tests/identity/v2/test_endpoint.py b/functional/tests/identity/v2/test_endpoint.py
index 0682e6b4..34888c0b 100644
--- a/functional/tests/identity/v2/test_endpoint.py
+++ b/functional/tests/identity/v2/test_endpoint.py
@@ -24,6 +24,13 @@ class EndpointTests(common.IdentityTests):
'endpoint delete %s' % endpoint_id)
self.assertEqual(0, len(raw_output))
+ def test_endpoint_multi_delete(self):
+ endpoint_id_1 = self._create_dummy_endpoint(add_clean_up=False)
+ endpoint_id_2 = self._create_dummy_endpoint(add_clean_up=False)
+ raw_output = self.openstack(
+ 'endpoint delete ' + endpoint_id_1 + ' ' + endpoint_id_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/v2/test_service.py b/functional/tests/identity/v2/test_service.py
index 219ed33f..9dcb6bea 100644
--- a/functional/tests/identity/v2/test_service.py
+++ b/functional/tests/identity/v2/test_service.py
@@ -23,6 +23,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_name_1 = self._create_dummy_service(add_clean_up=False)
+ service_name_2 = self._create_dummy_service(add_clean_up=False)
+ raw_output = self.openstack(
+ 'service delete ' + service_name_1 + ' ' + service_name_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/openstackclient/identity/v2_0/ec2creds.py b/openstackclient/identity/v2_0/ec2creds.py
index 78f65824..058b5772 100644
--- a/openstackclient/identity/v2_0/ec2creds.py
+++ b/openstackclient/identity/v2_0/ec2creds.py
@@ -16,13 +16,19 @@
"""Identity v2 EC2 Credentials 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 CreateEC2Creds(command.ShowOne):
"""Create EC2 credentials"""
@@ -85,9 +91,10 @@ class DeleteEC2Creds(command.Command):
def get_parser(self, prog_name):
parser = super(DeleteEC2Creds, self).get_parser(prog_name)
parser.add_argument(
- 'access_key',
+ 'access_keys',
metavar='<access-key>',
- help=_('Credentials access key'),
+ nargs='+',
+ help=_('Credentials access keys'),
)
parser.add_argument(
'--user',
@@ -108,7 +115,21 @@ class DeleteEC2Creds(command.Command):
# Get the user from the current auth
user = self.app.client_manager.auth_ref.user_id
- identity_client.ec2.delete(user, parsed_args.access_key)
+ result = 0
+ for access_key in parsed_args.access_keys:
+ try:
+ identity_client.ec2.delete(user, access_key)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete EC2 keys with "
+ "access key '%(access_key)s': %(e)s")
+ % {'access_key': access_key, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.access_keys)
+ 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/v2_0/endpoint.py b/openstackclient/identity/v2_0/endpoint.py
index ee2bab6f..5a3b3186 100644
--- a/openstackclient/identity/v2_0/endpoint.py
+++ b/openstackclient/identity/v2_0/endpoint.py
@@ -15,7 +15,10 @@
"""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__)
+
+
class CreateEndpoint(command.ShowOne):
"""Create new endpoint"""
@@ -74,20 +80,36 @@ 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',
+ 'endpoints',
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
- identity_client.endpoints.delete(parsed_args.endpoint)
+
+ result = 0
+ for endpoint in parsed_args.endpoints:
+ try:
+ identity_client.endpoints.delete(endpoint)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete endpoint with "
+ "ID '%(endpoint)s': %(e)s")
+ % {'endpoint': endpoint, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.endpoints)
+ 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/v2_0/service.py b/openstackclient/identity/v2_0/service.py
index df332eb6..e318643c 100644
--- a/openstackclient/identity/v2_0/service.py
+++ b/openstackclient/identity/v2_0/service.py
@@ -91,21 +91,37 @@ 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',
+ 'services',
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 service in parsed_args.services:
+ try:
+ service = common.find_service(identity_client, service)
+ identity_client.services.delete(service.id)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete service with "
+ "name or ID '%(service)s': %(e)s")
+ % {'service': service, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.services)
+ 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/tests/identity/v2_0/test_endpoint.py b/openstackclient/tests/identity/v2_0/test_endpoint.py
index e8fb9262..0b539702 100644
--- a/openstackclient/tests/identity/v2_0/test_endpoint.py
+++ b/openstackclient/tests/identity/v2_0/test_endpoint.py
@@ -112,7 +112,7 @@ class TestEndpointDelete(TestEndpoint):
self.fake_endpoint.id,
]
verifylist = [
- ('endpoint', self.fake_endpoint.id),
+ ('endpoints', [self.fake_endpoint.id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/identity/v2_0/test_service.py b/openstackclient/tests/identity/v2_0/test_service.py
index dc0fbcd1..ba976f4c 100644
--- a/openstackclient/tests/identity/v2_0/test_service.py
+++ b/openstackclient/tests/identity/v2_0/test_service.py
@@ -190,7 +190,7 @@ class TestServiceDelete(TestService):
identity_fakes.service_name,
]
verifylist = [
- ('service', identity_fakes.service_name),
+ ('services', [identity_fakes.service_name]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml b/releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml
new file mode 100644
index 00000000..a9b0606f
--- /dev/null
+++ b/releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - Support bulk deletion for ``ec2 credentials delete``, ``endpoint delete``,
+ ``service delete`` in identity V2.0 .
+ [Bug `1592906 <https://bugs.launchpad.net/bugs/1592906>`_]