From 98a0016cfa1d39bcc37144f0c7700e9a9d6b2c0b Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 29 Sep 2020 16:30:34 +0100 Subject: [PATCH] Add support for 'keypairs list --user' parameter This has been supported by nova and novaclient since the veritable dark ages. Add it to OSC. Change-Id: Ifc95e7dd6c00807c80e87e10046ab154d0989014 Signed-off-by: Stephen Finucane --- openstackclient/compute/v2/keypair.py | 35 +++++++++- .../tests/unit/compute/v2/test_keypair.py | 66 ++++++++++++++++++- ...keypairs-user-filter-e1ce57a4c09c278b.yaml | 6 ++ 3 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/add-keypairs-user-filter-e1ce57a4c09c278b.yaml diff --git a/openstackclient/compute/v2/keypair.py b/openstackclient/compute/v2/keypair.py index 6affaca302..ae653e76ee 100644 --- a/openstackclient/compute/v2/keypair.py +++ b/openstackclient/compute/v2/keypair.py @@ -26,6 +26,7 @@ from osc_lib import exceptions from osc_lib import utils from openstackclient.i18n import _ +from openstackclient.identity import common as identity_common LOG = logging.getLogger(__name__) @@ -163,13 +164,45 @@ class DeleteKeypair(command.Command): class ListKeypair(command.Lister): _description = _("List key fingerprints") + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument( + '--user', + metavar='', + help=_( + 'Show keypairs for another user (admin only) (name or ID). ' + 'Requires ``--os-compute-api-version`` 2.10 or greater.' + ), + ) + identity_common.add_user_domain_option_to_parser(parser) + return parser + def take_action(self, parsed_args): compute_client = self.app.client_manager.compute + identity_client = self.app.client_manager.identity + + kwargs = {} + + if parsed_args.user: + if compute_client.api_version < api_versions.APIVersion('2.10'): + msg = _( + '--os-compute-api-version 2.10 or greater is required to ' + 'support the --user option' + ) + raise exceptions.CommandError(msg) + + kwargs['user_id'] = identity_common.find_user( + identity_client, + parsed_args.user, + parsed_args.user_domain, + ).id + + data = compute_client.keypairs.list(**kwargs) + columns = ( "Name", "Fingerprint" ) - data = compute_client.keypairs.list() if compute_client.api_version >= api_versions.APIVersion('2.2'): columns += ("Type", ) diff --git a/openstackclient/tests/unit/compute/v2/test_keypair.py b/openstackclient/tests/unit/compute/v2/test_keypair.py index ca3bfe7c8b..5e6a47414f 100644 --- a/openstackclient/tests/unit/compute/v2/test_keypair.py +++ b/openstackclient/tests/unit/compute/v2/test_keypair.py @@ -13,6 +13,7 @@ # under the License. # +import copy from unittest import mock from unittest.mock import call import uuid @@ -23,6 +24,8 @@ from osc_lib import utils from openstackclient.compute.v2 import keypair from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes +from openstackclient.tests.unit import fakes +from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes from openstackclient.tests.unit import utils as tests_utils @@ -307,6 +310,14 @@ class TestKeypairList(TestKeypair): def setUp(self): super(TestKeypairList, self).setUp() + self.users_mock = self.app.client_manager.identity.users + self.users_mock.reset_mock() + self.users_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.USER), + loaded=True, + ) + self.keypairs_mock.list.return_value = self.keypairs # Get the command object to test @@ -334,8 +345,8 @@ class TestKeypairList(TestKeypair): ) def test_keypair_list_v22(self): - self.app.client_manager.compute.api_version = api_versions.APIVersion( - '2.2') + self.app.client_manager.compute.api_version = \ + api_versions.APIVersion('2.2') arglist = [] verifylist = [] @@ -361,6 +372,57 @@ class TestKeypairList(TestKeypair): tuple(data) ) + def test_keypair_list_with_user(self): + + # Filtering by user is support for nova api 2.10 or above + self.app.client_manager.compute.api_version = \ + api_versions.APIVersion('2.10') + + arglist = [ + '--user', identity_fakes.user_name, + ] + verifylist = [ + ('user', identity_fakes.user_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.users_mock.get.assert_called_with(identity_fakes.user_name) + self.keypairs_mock.list.assert_called_with( + user_id=identity_fakes.user_id, + ) + + self.assertEqual(('Name', 'Fingerprint', 'Type'), columns) + self.assertEqual( + (( + self.keypairs[0].name, + self.keypairs[0].fingerprint, + self.keypairs[0].type, + ), ), + tuple(data) + ) + + def test_keypair_list_with_user_pre_v210(self): + + self.app.client_manager.compute.api_version = \ + api_versions.APIVersion('2.9') + + arglist = [ + '--user', identity_fakes.user_name, + ] + verifylist = [ + ('user', identity_fakes.user_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + ex = self.assertRaises( + exceptions.CommandError, + self.cmd.take_action, + parsed_args) + self.assertIn( + '--os-compute-api-version 2.10 or greater is required', str(ex)) + class TestKeypairShow(TestKeypair): diff --git a/releasenotes/notes/add-keypairs-user-filter-e1ce57a4c09c278b.yaml b/releasenotes/notes/add-keypairs-user-filter-e1ce57a4c09c278b.yaml new file mode 100644 index 0000000000..6e82091a0f --- /dev/null +++ b/releasenotes/notes/add-keypairs-user-filter-e1ce57a4c09c278b.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + It is now possible to list the keypairs for a specific user using the + ``--user`` parameter. This is an admin-only action by default and requires + Compute API microversion 2.10 or later.