summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorStephen Finucane <sfinucan@redhat.com>2020-09-29 16:51:12 +0100
committerStephen Finucane <sfinucan@redhat.com>2020-10-14 10:27:05 +0100
commit5645fad7622a18e4f3c550ee7d409bf1b685a1a5 (patch)
treedb5d8c3f422be47a185be9ceffcf5df8a65769e1 /openstackclient
parent98a0016cfa1d39bcc37144f0c7700e9a9d6b2c0b (diff)
downloadpython-openstackclient-5645fad7622a18e4f3c550ee7d409bf1b685a1a5.tar.gz
Add support for 'keypairs list --project' parameter
It would be lovely to do this server side but doing so requires a new microversion, a blueprint and a spec. This is less performant but should do the trick for the odd time users want to do this. Change-Id: I26e7d38966304dd67be5da8ed0bb24f87191b82f Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/compute/v2/keypair.py44
-rw-r--r--openstackclient/tests/unit/compute/v2/test_keypair.py95
2 files changed, 124 insertions, 15 deletions
diff --git a/openstackclient/compute/v2/keypair.py b/openstackclient/compute/v2/keypair.py
index ae653e76..8c365cf0 100644
--- a/openstackclient/compute/v2/keypair.py
+++ b/openstackclient/compute/v2/keypair.py
@@ -166,7 +166,8 @@ class ListKeypair(command.Lister):
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
- parser.add_argument(
+ user_group = parser.add_mutually_exclusive_group()
+ user_group.add_argument(
'--user',
metavar='<user>',
help=_(
@@ -175,15 +176,44 @@ class ListKeypair(command.Lister):
),
)
identity_common.add_user_domain_option_to_parser(parser)
+ user_group.add_argument(
+ '--project',
+ metavar='<project>',
+ help=_(
+ 'Show keypairs for all users associated with project '
+ '(admin only) (name or ID). '
+ 'Requires ``--os-compute-api-version`` 2.10 or greater.'
+ ),
+ )
+ identity_common.add_project_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.project:
+ if compute_client.api_version < api_versions.APIVersion('2.10'):
+ msg = _(
+ '--os-compute-api-version 2.10 or greater is required to '
+ 'support the --project option'
+ )
+ raise exceptions.CommandError(msg)
- if parsed_args.user:
+ # NOTE(stephenfin): This is done client side because nova doesn't
+ # currently support doing so server-side. If this is slow, we can
+ # think about spinning up a threadpool or similar.
+ project = identity_common.find_project(
+ identity_client,
+ parsed_args.project,
+ parsed_args.project_domain,
+ ).id
+ users = identity_client.users.list(tenant_id=project)
+
+ data = []
+ for user in users:
+ data.extend(compute_client.keypairs.list(user_id=user.id))
+ elif 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 '
@@ -191,13 +221,15 @@ class ListKeypair(command.Lister):
)
raise exceptions.CommandError(msg)
- kwargs['user_id'] = identity_common.find_user(
+ user = identity_common.find_user(
identity_client,
parsed_args.user,
parsed_args.user_domain,
- ).id
+ )
- data = compute_client.keypairs.list(**kwargs)
+ data = compute_client.keypairs.list(user_id=user.id)
+ else:
+ data = compute_client.keypairs.list()
columns = (
"Name",
diff --git a/openstackclient/tests/unit/compute/v2/test_keypair.py b/openstackclient/tests/unit/compute/v2/test_keypair.py
index 5e6a4741..286cbb09 100644
--- a/openstackclient/tests/unit/compute/v2/test_keypair.py
+++ b/openstackclient/tests/unit/compute/v2/test_keypair.py
@@ -310,14 +310,6 @@ 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
@@ -378,6 +370,14 @@ class TestKeypairList(TestKeypair):
self.app.client_manager.compute.api_version = \
api_versions.APIVersion('2.10')
+ users_mock = self.app.client_manager.identity.users
+ users_mock.reset_mock()
+ users_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.USER),
+ loaded=True,
+ )
+
arglist = [
'--user', identity_fakes.user_name,
]
@@ -388,7 +388,7 @@ class TestKeypairList(TestKeypair):
columns, data = self.cmd.take_action(parsed_args)
- self.users_mock.get.assert_called_with(identity_fakes.user_name)
+ users_mock.get.assert_called_with(identity_fakes.user_name)
self.keypairs_mock.list.assert_called_with(
user_id=identity_fakes.user_id,
)
@@ -423,6 +423,83 @@ class TestKeypairList(TestKeypair):
self.assertIn(
'--os-compute-api-version 2.10 or greater is required', str(ex))
+ def test_keypair_list_with_project(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')
+
+ projects_mock = self.app.client_manager.identity.tenants
+ projects_mock.reset_mock()
+ projects_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.PROJECT),
+ loaded=True,
+ )
+
+ users_mock = self.app.client_manager.identity.users
+ users_mock.reset_mock()
+ users_mock.list.return_value = [
+ fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.USER),
+ loaded=True,
+ ),
+ ]
+
+ arglist = ['--project', identity_fakes.project_name]
+ verifylist = [('project', identity_fakes.project_name)]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ projects_mock.get.assert_called_with(identity_fakes.project_name)
+ users_mock.list.assert_called_with(tenant_id=identity_fakes.project_id)
+ 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_project_pre_v210(self):
+
+ self.app.client_manager.compute.api_version = \
+ api_versions.APIVersion('2.9')
+
+ arglist = ['--project', identity_fakes.project_name]
+ verifylist = [('project', identity_fakes.project_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))
+
+ def test_keypair_list_conflicting_user_options(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,
+ '--project', identity_fakes.project_name,
+ ]
+
+ self.assertRaises(
+ tests_utils.ParserException,
+ self.check_parser, self.cmd, arglist, None)
+
class TestKeypairShow(TestKeypair):