Skip to content

Commit 17f641e

Browse files
soulxuHuihuihh
authored andcommitted
Compute: Add user id support for keypair
This patch adds functionality of specific the user id when create, delete, show and list keypairs. Change-Id: Ib826f1f4f5a73d1875ba0f02e124b3222c4d05ed Co-Authored-By: tianhui <tianhui@awcloud.com>
1 parent 7fdbc6b commit 17f641e

3 files changed

Lines changed: 250 additions & 13 deletions

File tree

openstackclient/compute/v2/keypair.py

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,20 @@ def get_parser(self, prog_name):
6464
"(Supported by API versions '2.2' - '2.latest')"
6565
),
6666
)
67+
parser.add_argument(
68+
'--user',
69+
metavar='<user>',
70+
help=_(
71+
'The owner of the keypair. (admin only) (name or ID). '
72+
'Requires ``--os-compute-api-version`` 2.10 or greater.'
73+
),
74+
)
75+
identity_common.add_user_domain_option_to_parser(parser)
6776
return parser
6877

6978
def take_action(self, parsed_args):
7079
compute_client = self.app.client_manager.compute
80+
identity_client = self.app.client_manager.identity
7181

7282
public_key = parsed_args.public_key
7383
if public_key:
@@ -89,12 +99,26 @@ def take_action(self, parsed_args):
8999
if compute_client.api_version < api_versions.APIVersion('2.2'):
90100
msg = _(
91101
'--os-compute-api-version 2.2 or greater is required to '
92-
'support the --type option.'
102+
'support the --type option'
93103
)
94104
raise exceptions.CommandError(msg)
95105

96106
kwargs['key_type'] = parsed_args.type
97107

108+
if parsed_args.user:
109+
if compute_client.api_version < api_versions.APIVersion('2.10'):
110+
msg = _(
111+
'--os-compute-api-version 2.10 or greater is required to '
112+
'support the --user option'
113+
)
114+
raise exceptions.CommandError(msg)
115+
116+
kwargs['user_id'] = identity_common.find_user(
117+
identity_client,
118+
parsed_args.user,
119+
parsed_args.user_domain,
120+
).id
121+
98122
keypair = compute_client.keypairs.create(**kwargs)
99123

100124
private_key = parsed_args.private_key
@@ -139,16 +163,43 @@ def get_parser(self, prog_name):
139163
nargs='+',
140164
help=_("Name of key(s) to delete (name only)")
141165
)
166+
parser.add_argument(
167+
'--user',
168+
metavar='<user>',
169+
help=_(
170+
'The owner of the keypair. (admin only) (name or ID). '
171+
'Requires ``--os-compute-api-version`` 2.10 or greater.'
172+
),
173+
)
174+
identity_common.add_user_domain_option_to_parser(parser)
142175
return parser
143176

144177
def take_action(self, parsed_args):
145178
compute_client = self.app.client_manager.compute
179+
identity_client = self.app.client_manager.identity
180+
181+
kwargs = {}
146182
result = 0
183+
184+
if parsed_args.user:
185+
if compute_client.api_version < api_versions.APIVersion('2.10'):
186+
msg = _(
187+
'--os-compute-api-version 2.10 or greater is required to '
188+
'support the --user option'
189+
)
190+
raise exceptions.CommandError(msg)
191+
192+
kwargs['user_id'] = identity_common.find_user(
193+
identity_client,
194+
parsed_args.user,
195+
parsed_args.user_domain,
196+
).id
197+
147198
for n in parsed_args.name:
148199
try:
149200
data = utils.find_resource(
150201
compute_client.keypairs, n)
151-
compute_client.keypairs.delete(data.name)
202+
compute_client.keypairs.delete(data.name, **kwargs)
152203
except Exception as e:
153204
result += 1
154205
LOG.error(_("Failed to delete key with name "
@@ -229,12 +280,39 @@ def get_parser(self, prog_name):
229280
default=False,
230281
help=_("Show only bare public key paired with the generated key")
231282
)
283+
parser.add_argument(
284+
'--user',
285+
metavar='<user>',
286+
help=_(
287+
'The owner of the keypair. (admin only) (name or ID). '
288+
'Requires ``--os-compute-api-version`` 2.10 or greater.'
289+
),
290+
)
291+
identity_common.add_user_domain_option_to_parser(parser)
232292
return parser
233293

234294
def take_action(self, parsed_args):
235295
compute_client = self.app.client_manager.compute
236-
keypair = utils.find_resource(compute_client.keypairs,
237-
parsed_args.name)
296+
identity_client = self.app.client_manager.identity
297+
298+
kwargs = {}
299+
300+
if parsed_args.user:
301+
if compute_client.api_version < api_versions.APIVersion('2.10'):
302+
msg = _(
303+
'--os-compute-api-version 2.10 or greater is required to '
304+
'support the --user option'
305+
)
306+
raise exceptions.CommandError(msg)
307+
308+
kwargs['user_id'] = identity_common.find_user(
309+
identity_client,
310+
parsed_args.user,
311+
parsed_args.user_domain,
312+
).id
313+
314+
keypair = utils.find_resource(
315+
compute_client.keypairs, parsed_args.name, **kwargs)
238316

239317
info = {}
240318
info.update(keypair._info)

openstackclient/tests/unit/compute/v2/test_keypair.py

Lines changed: 162 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ def setUp(self):
3838
self.keypairs_mock = self.app.client_manager.compute.keypairs
3939
self.keypairs_mock.reset_mock()
4040

41+
# Initialize the user mock
42+
self.users_mock = self.app.client_manager.identity.users
43+
self.users_mock.reset_mock()
44+
self.users_mock.get.return_value = fakes.FakeResource(
45+
None,
46+
copy.deepcopy(identity_fakes.USER),
47+
loaded=True,
48+
)
49+
4150

4251
class TestKeypairCreate(TestKeypair):
4352

@@ -226,6 +235,54 @@ def test_keypair_create_with_key_type_pre_v22(self):
226235
'--os-compute-api-version 2.2 or greater is required',
227236
str(ex))
228237

238+
def test_key_pair_create_with_user(self):
239+
240+
self.app.client_manager.compute.api_version = \
241+
api_versions.APIVersion('2.10')
242+
243+
arglist = [
244+
'--user', identity_fakes.user_name,
245+
self.keypair.name,
246+
]
247+
verifylist = [
248+
('user', identity_fakes.user_name),
249+
('name', self.keypair.name),
250+
]
251+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
252+
253+
columns, data = self.cmd.take_action(parsed_args)
254+
255+
self.keypairs_mock.create.assert_called_with(
256+
name=self.keypair.name,
257+
public_key=None,
258+
user_id=identity_fakes.user_id,
259+
)
260+
261+
self.assertEqual({}, columns)
262+
self.assertEqual({}, data)
263+
264+
def test_key_pair_create_with_user_pre_v210(self):
265+
266+
self.app.client_manager.compute.api_version = \
267+
api_versions.APIVersion('2.9')
268+
269+
arglist = [
270+
'--user', identity_fakes.user_name,
271+
self.keypair.name,
272+
]
273+
verifylist = [
274+
('user', identity_fakes.user_name),
275+
('name', self.keypair.name),
276+
]
277+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
278+
279+
ex = self.assertRaises(
280+
exceptions.CommandError,
281+
self.cmd.take_action,
282+
parsed_args)
283+
self.assertIn(
284+
'--os-compute-api-version 2.10 or greater is required', str(ex))
285+
229286

230287
class TestKeypairDelete(TestKeypair):
231288

@@ -301,6 +358,51 @@ def test_delete_multiple_keypairs_with_exception(self):
301358
self.keypairs[0].name
302359
)
303360

361+
def test_keypair_delete_with_user(self):
362+
363+
self.app.client_manager.compute.api_version = \
364+
api_versions.APIVersion('2.10')
365+
366+
arglist = [
367+
'--user', identity_fakes.user_name,
368+
self.keypairs[0].name
369+
]
370+
verifylist = [
371+
('user', identity_fakes.user_name),
372+
('name', [self.keypairs[0].name]),
373+
]
374+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
375+
376+
ret = self.cmd.take_action(parsed_args)
377+
378+
self.assertIsNone(ret)
379+
self.keypairs_mock.delete.assert_called_with(
380+
self.keypairs[0].name,
381+
user_id=identity_fakes.user_id,
382+
)
383+
384+
def test_keypair_delete_with_user_pre_v210(self):
385+
386+
self.app.client_manager.compute.api_version = \
387+
api_versions.APIVersion('2.9')
388+
389+
arglist = [
390+
'--user', identity_fakes.user_name,
391+
self.keypairs[0].name
392+
]
393+
verifylist = [
394+
('user', identity_fakes.user_name),
395+
('name', [self.keypairs[0].name]),
396+
]
397+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
398+
399+
ex = self.assertRaises(
400+
exceptions.CommandError,
401+
self.cmd.take_action,
402+
parsed_args)
403+
self.assertIn(
404+
'--os-compute-api-version 2.10 or greater is required', str(ex))
405+
304406

305407
class TestKeypairList(TestKeypair):
306408

@@ -310,14 +412,6 @@ class TestKeypairList(TestKeypair):
310412
def setUp(self):
311413
super(TestKeypairList, self).setUp()
312414

313-
self.users_mock = self.app.client_manager.identity.users
314-
self.users_mock.reset_mock()
315-
self.users_mock.get.return_value = fakes.FakeResource(
316-
None,
317-
copy.deepcopy(identity_fakes.USER),
318-
loaded=True,
319-
)
320-
321415
self.keypairs_mock.list.return_value = self.keypairs
322416

323417
# Get the command object to test
@@ -477,11 +571,14 @@ def test_keypair_show(self):
477571
verifylist = [
478572
('name', self.keypair.name)
479573
]
480-
481574
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
482575

483576
columns, data = self.cmd.take_action(parsed_args)
484577

578+
self.keypairs_mock.get.assert_called_with(
579+
self.keypair.name,
580+
)
581+
485582
self.assertEqual(self.columns, columns)
486583
self.assertEqual(self.data, data)
487584

@@ -502,3 +599,59 @@ def test_keypair_show_public(self):
502599

503600
self.assertEqual({}, columns)
504601
self.assertEqual({}, data)
602+
603+
def test_keypair_show_with_user(self):
604+
605+
# overwrite the setup one because we want to omit private_key
606+
self.keypair = compute_fakes.FakeKeypair.create_one_keypair(
607+
no_pri=True)
608+
self.keypairs_mock.get.return_value = self.keypair
609+
610+
self.data = (
611+
self.keypair.fingerprint,
612+
self.keypair.name,
613+
self.keypair.type,
614+
self.keypair.user_id
615+
)
616+
617+
self.app.client_manager.compute.api_version = \
618+
api_versions.APIVersion('2.10')
619+
620+
arglist = [
621+
'--user', identity_fakes.user_name,
622+
self.keypair.name,
623+
]
624+
verifylist = [
625+
('user', identity_fakes.user_name),
626+
('name', self.keypair.name)
627+
]
628+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
629+
630+
columns, data = self.cmd.take_action(parsed_args)
631+
632+
self.users_mock.get.assert_called_with(identity_fakes.user_name)
633+
self.keypairs_mock.get.assert_called_with(
634+
self.keypair.name,
635+
)
636+
637+
self.assertEqual(self.columns, columns)
638+
self.assertEqual(self.data, data)
639+
640+
def test_keypair_show_with_user_pre_v210(self):
641+
642+
arglist = [
643+
'--user', identity_fakes.user_name,
644+
self.keypair.name,
645+
]
646+
verifylist = [
647+
('user', identity_fakes.user_name),
648+
('name', self.keypair.name)
649+
]
650+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
651+
652+
ex = self.assertRaises(
653+
exceptions.CommandError,
654+
self.cmd.take_action,
655+
parsed_args)
656+
self.assertIn(
657+
'--os-compute-api-version 2.10 or greater is required', str(ex))
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
Add ``--user`` option to the ``keypair create``, ``keypair delete``, and
5+
``keypair show`` commands. Only available starting with
6+
``--os-compute-api-version 2.10``.

0 commit comments

Comments
 (0)