Support multi-delete for commands in identity V2
Commands are "ec2 credentials delete", "service delete", "endpoint delete". Also update their unit tests and functional tests. Partial-Bug: #1592906 Change-Id: I1a0b7160b803a523646d09d030e6f112c81c4c24
This commit is contained in:
parent
5b144334bf
commit
6df09fd377
@ -55,7 +55,7 @@ Delete EC2 credentials
|
|||||||
os ec2 credentials delete
|
os ec2 credentials delete
|
||||||
[--user <user>]
|
[--user <user>]
|
||||||
[--user-domain <user-domain>]
|
[--user-domain <user-domain>]
|
||||||
<access-key>
|
<access-key> [<access-key> ...]
|
||||||
|
|
||||||
.. option:: --user <user>
|
.. option:: --user <user>
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ Delete EC2 credentials
|
|||||||
.. _ec2_credentials_delete-access-key:
|
.. _ec2_credentials_delete-access-key:
|
||||||
.. describe:: access-key
|
.. describe:: access-key
|
||||||
|
|
||||||
Credentials access key
|
Credentials access key(s)
|
||||||
|
|
||||||
The :option:`--user` option is typically only useful for admin users, but
|
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
|
may be allowed for other users depending on the policy of the cloud and
|
||||||
|
@ -81,18 +81,18 @@ Create new endpoint
|
|||||||
endpoint delete
|
endpoint delete
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Delete endpoint
|
Delete endpoint(s)
|
||||||
|
|
||||||
.. program:: endpoint delete
|
.. program:: endpoint delete
|
||||||
.. code:: bash
|
.. code:: bash
|
||||||
|
|
||||||
os endpoint delete
|
os endpoint delete
|
||||||
<endpoint-id>
|
<endpoint-id> [<endpoint-id> ...]
|
||||||
|
|
||||||
.. _endpoint_delete-endpoint:
|
.. _endpoint_delete-endpoint:
|
||||||
.. describe:: <endpoint-id>
|
.. describe:: <endpoint-id>
|
||||||
|
|
||||||
Endpoint to delete (ID only)
|
Endpoint(s) to delete (ID only)
|
||||||
|
|
||||||
endpoint list
|
endpoint list
|
||||||
-------------
|
-------------
|
||||||
|
@ -46,18 +46,18 @@ Create new service
|
|||||||
service delete
|
service delete
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Delete service
|
Delete service(s)
|
||||||
|
|
||||||
.. program:: service delete
|
.. program:: service delete
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
os service delete
|
os service delete
|
||||||
<service>
|
<service> [<service> ...]
|
||||||
|
|
||||||
.. _service_delete-type:
|
.. _service_delete-type:
|
||||||
.. describe:: <service>
|
.. describe:: <service>
|
||||||
|
|
||||||
Service to delete (type, name or ID)
|
Service(s) to delete (type, name or ID)
|
||||||
|
|
||||||
service list
|
service list
|
||||||
------------
|
------------
|
||||||
|
@ -25,6 +25,14 @@ class EC2CredentialsTests(common.IdentityTests):
|
|||||||
)
|
)
|
||||||
self.assertEqual(0, len(raw_output))
|
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):
|
def test_ec2_credentials_list(self):
|
||||||
self._create_dummy_ec2_credentials()
|
self._create_dummy_ec2_credentials()
|
||||||
raw_output = self.openstack('ec2 credentials list')
|
raw_output = self.openstack('ec2 credentials list')
|
||||||
|
@ -24,6 +24,13 @@ class EndpointTests(common.IdentityTests):
|
|||||||
'endpoint delete %s' % endpoint_id)
|
'endpoint delete %s' % endpoint_id)
|
||||||
self.assertEqual(0, len(raw_output))
|
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):
|
def test_endpoint_list(self):
|
||||||
endpoint_id = self._create_dummy_endpoint()
|
endpoint_id = self._create_dummy_endpoint()
|
||||||
raw_output = self.openstack('endpoint list')
|
raw_output = self.openstack('endpoint list')
|
||||||
|
@ -23,6 +23,13 @@ class ServiceTests(common.IdentityTests):
|
|||||||
raw_output = self.openstack('service delete %s' % service_name)
|
raw_output = self.openstack('service delete %s' % service_name)
|
||||||
self.assertEqual(0, len(raw_output))
|
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):
|
def test_service_list(self):
|
||||||
self._create_dummy_service()
|
self._create_dummy_service()
|
||||||
raw_output = self.openstack('service list')
|
raw_output = self.openstack('service list')
|
||||||
|
@ -16,13 +16,19 @@
|
|||||||
|
|
||||||
"""Identity v2 EC2 Credentials action implementations"""
|
"""Identity v2 EC2 Credentials action implementations"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
|
from osc_lib import exceptions
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from openstackclient.i18n import _
|
from openstackclient.i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class CreateEC2Creds(command.ShowOne):
|
class CreateEC2Creds(command.ShowOne):
|
||||||
"""Create EC2 credentials"""
|
"""Create EC2 credentials"""
|
||||||
|
|
||||||
@ -85,9 +91,10 @@ class DeleteEC2Creds(command.Command):
|
|||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(DeleteEC2Creds, self).get_parser(prog_name)
|
parser = super(DeleteEC2Creds, self).get_parser(prog_name)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'access_key',
|
'access_keys',
|
||||||
metavar='<access-key>',
|
metavar='<access-key>',
|
||||||
help=_('Credentials access key'),
|
nargs='+',
|
||||||
|
help=_('Credentials access keys'),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--user',
|
'--user',
|
||||||
@ -108,7 +115,21 @@ class DeleteEC2Creds(command.Command):
|
|||||||
# Get the user from the current auth
|
# Get the user from the current auth
|
||||||
user = self.app.client_manager.auth_ref.user_id
|
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):
|
class ListEC2Creds(command.Lister):
|
||||||
|
@ -15,7 +15,10 @@
|
|||||||
|
|
||||||
"""Endpoint action implementations"""
|
"""Endpoint action implementations"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
|
from osc_lib import exceptions
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
import six
|
import six
|
||||||
|
|
||||||
@ -23,6 +26,9 @@ from openstackclient.i18n import _
|
|||||||
from openstackclient.identity import common
|
from openstackclient.identity import common
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class CreateEndpoint(command.ShowOne):
|
class CreateEndpoint(command.ShowOne):
|
||||||
"""Create new endpoint"""
|
"""Create new endpoint"""
|
||||||
|
|
||||||
@ -74,20 +80,36 @@ class CreateEndpoint(command.ShowOne):
|
|||||||
|
|
||||||
|
|
||||||
class DeleteEndpoint(command.Command):
|
class DeleteEndpoint(command.Command):
|
||||||
"""Delete endpoint"""
|
"""Delete endpoint(s)"""
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(DeleteEndpoint, self).get_parser(prog_name)
|
parser = super(DeleteEndpoint, self).get_parser(prog_name)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'endpoint',
|
'endpoints',
|
||||||
metavar='<endpoint-id>',
|
metavar='<endpoint-id>',
|
||||||
help=_('Endpoint to delete (ID only)'),
|
nargs='+',
|
||||||
|
help=_('Endpoint(s) to delete (ID only)'),
|
||||||
)
|
)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
identity_client = self.app.client_manager.identity
|
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):
|
class ListEndpoint(command.Lister):
|
||||||
|
@ -91,21 +91,37 @@ class CreateService(command.ShowOne):
|
|||||||
|
|
||||||
|
|
||||||
class DeleteService(command.Command):
|
class DeleteService(command.Command):
|
||||||
"""Delete service"""
|
"""Delete service(s)"""
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(DeleteService, self).get_parser(prog_name)
|
parser = super(DeleteService, self).get_parser(prog_name)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'service',
|
'services',
|
||||||
metavar='<service>',
|
metavar='<service>',
|
||||||
help=_('Service to delete (type, name or ID)'),
|
nargs='+',
|
||||||
|
help=_('Service(s) to delete (type, name or ID)'),
|
||||||
)
|
)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
identity_client = self.app.client_manager.identity
|
identity_client = self.app.client_manager.identity
|
||||||
service = common.find_service(identity_client, parsed_args.service)
|
|
||||||
|
result = 0
|
||||||
|
for service in parsed_args.services:
|
||||||
|
try:
|
||||||
|
service = common.find_service(identity_client, service)
|
||||||
identity_client.services.delete(service.id)
|
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):
|
class ListService(command.Lister):
|
||||||
|
@ -112,7 +112,7 @@ class TestEndpointDelete(TestEndpoint):
|
|||||||
self.fake_endpoint.id,
|
self.fake_endpoint.id,
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('endpoint', self.fake_endpoint.id),
|
('endpoints', [self.fake_endpoint.id]),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ class TestServiceDelete(TestService):
|
|||||||
identity_fakes.service_name,
|
identity_fakes.service_name,
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('service', identity_fakes.service_name),
|
('services', [identity_fakes.service_name]),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
5
releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml
Normal file
5
releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml
Normal file
@ -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>`_]
|
Loading…
Reference in New Issue
Block a user