Merge "identity: Normalise output of application credentials commands"
This commit is contained in:
@ -20,6 +20,7 @@ import json
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
from cliff import columns as cliff_columns
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
@ -27,10 +28,84 @@ from osc_lib import utils
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RolesColumn(cliff_columns.FormattableColumn):
|
||||
"""Generate a formatted string of role names."""
|
||||
|
||||
def human_readable(self):
|
||||
return utils.format_list(r['name'] for r in self._value)
|
||||
|
||||
|
||||
def _format_application_credential(
|
||||
application_credential, *, include_secret=False
|
||||
):
|
||||
column_headers: tuple[str, ...] = (
|
||||
'ID',
|
||||
'Name',
|
||||
'Description',
|
||||
'Project ID',
|
||||
'Roles',
|
||||
'Unrestricted',
|
||||
'Access Rules',
|
||||
'Expires At',
|
||||
)
|
||||
columns: tuple[str, ...] = (
|
||||
'id',
|
||||
'name',
|
||||
'description',
|
||||
'project_id',
|
||||
'roles',
|
||||
'unrestricted',
|
||||
'access_rules',
|
||||
'expires_at',
|
||||
)
|
||||
if include_secret:
|
||||
column_headers += ('Secret',)
|
||||
columns += ('secret',)
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
utils.get_item_properties(
|
||||
application_credential, columns, formatters={'roles': RolesColumn}
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _format_application_credentials(application_credentials):
|
||||
column_headers = (
|
||||
'ID',
|
||||
'Name',
|
||||
'Description',
|
||||
'Project ID',
|
||||
'Roles',
|
||||
'Unrestricted',
|
||||
'Access Rules',
|
||||
'Expires At',
|
||||
)
|
||||
columns = (
|
||||
'id',
|
||||
'name',
|
||||
'description',
|
||||
'project_id',
|
||||
'roles',
|
||||
'unrestricted',
|
||||
'access_rules',
|
||||
'expires_at',
|
||||
)
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
x, columns, formatters={'roles': RolesColumn}
|
||||
)
|
||||
for x in application_credentials
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# TODO(stephenfin): Move this to osc_lib since it's useful elsewhere
|
||||
def is_uuid_like(value) -> bool:
|
||||
"""Returns validation of a value as a UUID.
|
||||
@ -38,9 +113,6 @@ def is_uuid_like(value) -> bool:
|
||||
:param val: Value to verify
|
||||
:type val: string
|
||||
:returns: bool
|
||||
|
||||
.. versionchanged:: 1.1.1
|
||||
Support non-lowercase UUIDs.
|
||||
"""
|
||||
try:
|
||||
formatted_value = (
|
||||
@ -179,31 +251,8 @@ class CreateApplicationCredential(command.ShowOne):
|
||||
access_rules=access_rules,
|
||||
)
|
||||
|
||||
# Format roles into something sensible
|
||||
if application_credential['roles']:
|
||||
roles = application_credential['roles']
|
||||
msg = ' '.join(r['name'] for r in roles)
|
||||
application_credential['roles'] = msg
|
||||
|
||||
columns = (
|
||||
'id',
|
||||
'name',
|
||||
'description',
|
||||
'project_id',
|
||||
'roles',
|
||||
'unrestricted',
|
||||
'access_rules',
|
||||
'expires_at',
|
||||
'secret',
|
||||
)
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_dict_properties(
|
||||
application_credential,
|
||||
columns,
|
||||
)
|
||||
),
|
||||
return _format_application_credential(
|
||||
application_credential, include_secret=True
|
||||
)
|
||||
|
||||
|
||||
@ -252,6 +301,8 @@ class DeleteApplicationCredential(command.Command):
|
||||
) % {'errors': errors, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class ListApplicationCredential(command.Lister):
|
||||
_description = _("List application credentials")
|
||||
@ -276,39 +327,12 @@ class ListApplicationCredential(command.Lister):
|
||||
conn = self.app.client_manager.sdk_connection
|
||||
user_id = conn.config.get_auth().get_user_id(conn.identity)
|
||||
|
||||
data = identity_client.application_credentials(user=user_id)
|
||||
|
||||
data_formatted = []
|
||||
for ac in data:
|
||||
# Format roles into something sensible
|
||||
roles = ac['roles']
|
||||
msg = ' '.join(r['name'] for r in roles)
|
||||
ac['roles'] = msg
|
||||
|
||||
data_formatted.append(ac)
|
||||
|
||||
columns = (
|
||||
'ID',
|
||||
'Name',
|
||||
'Description',
|
||||
'Project ID',
|
||||
'Roles',
|
||||
'Unrestricted',
|
||||
'Access Rules',
|
||||
'Expires At',
|
||||
)
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters={},
|
||||
)
|
||||
for s in data_formatted
|
||||
),
|
||||
application_credentials = identity_client.application_credentials(
|
||||
user=user_id
|
||||
)
|
||||
|
||||
return _format_application_credentials(application_credentials)
|
||||
|
||||
|
||||
class ShowApplicationCredential(command.ShowOne):
|
||||
_description = _("Display application credential details")
|
||||
@ -327,31 +351,8 @@ class ShowApplicationCredential(command.ShowOne):
|
||||
conn = self.app.client_manager.sdk_connection
|
||||
user_id = conn.config.get_auth().get_user_id(conn.identity)
|
||||
|
||||
app_cred = identity_client.find_application_credential(
|
||||
application_credential = identity_client.find_application_credential(
|
||||
user_id, parsed_args.application_credential
|
||||
)
|
||||
|
||||
# Format roles into something sensible
|
||||
roles = app_cred['roles']
|
||||
msg = ' '.join(r['name'] for r in roles)
|
||||
app_cred['roles'] = msg
|
||||
|
||||
columns = (
|
||||
'id',
|
||||
'name',
|
||||
'description',
|
||||
'project_id',
|
||||
'roles',
|
||||
'unrestricted',
|
||||
'access_rules',
|
||||
'expires_at',
|
||||
)
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_dict_properties(
|
||||
app_cred,
|
||||
columns,
|
||||
)
|
||||
),
|
||||
)
|
||||
return _format_application_credential(application_credential)
|
||||
|
@ -62,7 +62,7 @@ class AccessRuleTests(common.IdentityTests):
|
||||
|
||||
items = self.parse_show_as_object(raw_output)
|
||||
self.access_rule_ids = [
|
||||
x['id'] for x in ast.literal_eval(items['access_rules'])
|
||||
x['id'] for x in ast.literal_eval(items['Access Rules'])
|
||||
]
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
|
@ -21,13 +21,13 @@ from openstackclient.tests.functional.identity.v3 import common
|
||||
|
||||
class ApplicationCredentialTests(common.IdentityTests):
|
||||
APPLICATION_CREDENTIAL_FIELDS = [
|
||||
'id',
|
||||
'name',
|
||||
'project_id',
|
||||
'description',
|
||||
'roles',
|
||||
'expires_at',
|
||||
'unrestricted',
|
||||
'ID',
|
||||
'Name',
|
||||
'Project ID',
|
||||
'Description',
|
||||
'Roles',
|
||||
'Expires At',
|
||||
'Unrestricted',
|
||||
]
|
||||
APPLICATION_CREDENTIAL_LIST_HEADERS = [
|
||||
'ID',
|
||||
|
@ -31,18 +31,6 @@ from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
|
||||
|
||||
|
||||
class TestApplicationCredentialCreate(identity_fakes.TestIdentityv3):
|
||||
columns = (
|
||||
'id',
|
||||
'name',
|
||||
'description',
|
||||
'project_id',
|
||||
'roles',
|
||||
'unrestricted',
|
||||
'access_rules',
|
||||
'expires_at',
|
||||
'secret',
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -52,12 +40,25 @@ class TestApplicationCredentialCreate(identity_fakes.TestIdentityv3):
|
||||
roles=[],
|
||||
)
|
||||
|
||||
self.datalist = (
|
||||
self.columns = (
|
||||
'ID',
|
||||
'Name',
|
||||
'Description',
|
||||
'Project ID',
|
||||
'Roles',
|
||||
'Unrestricted',
|
||||
'Access Rules',
|
||||
'Expires At',
|
||||
'Secret',
|
||||
)
|
||||
self.data = (
|
||||
self.application_credential.id,
|
||||
self.application_credential.name,
|
||||
self.application_credential.description,
|
||||
self.application_credential.project_id,
|
||||
self.application_credential.roles,
|
||||
application_credential.RolesColumn(
|
||||
self.application_credential.roles
|
||||
),
|
||||
self.application_credential.unrestricted,
|
||||
self.application_credential.access_rules,
|
||||
self.application_credential.expires_at,
|
||||
@ -101,7 +102,7 @@ class TestApplicationCredentialCreate(identity_fakes.TestIdentityv3):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist, data)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_application_credential_create_with_options(self):
|
||||
name = self.application_credential.name
|
||||
@ -147,7 +148,7 @@ class TestApplicationCredentialCreate(identity_fakes.TestIdentityv3):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist, data)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_application_credential_create_with_access_rules_string(self):
|
||||
name = self.application_credential.name
|
||||
@ -191,7 +192,7 @@ class TestApplicationCredentialCreate(identity_fakes.TestIdentityv3):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist, data)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
@mock.patch('openstackclient.identity.v3.application_credential.json.load')
|
||||
@mock.patch('openstackclient.identity.v3.application_credential.open')
|
||||
@ -231,7 +232,7 @@ class TestApplicationCredentialCreate(identity_fakes.TestIdentityv3):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist, data)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
|
||||
class TestApplicationCredentialDelete(identity_fakes.TestIdentityv3):
|
||||
@ -345,7 +346,9 @@ class TestApplicationCredentialList(identity_fakes.TestIdentityv3):
|
||||
self.application_credential.name,
|
||||
self.application_credential.description,
|
||||
self.application_credential.project_id,
|
||||
'',
|
||||
application_credential.RolesColumn(
|
||||
self.application_credential.roles
|
||||
),
|
||||
self.application_credential.unrestricted,
|
||||
self.application_credential.access_rules,
|
||||
self.application_credential.expires_at,
|
||||
@ -408,6 +411,29 @@ class TestApplicationCredentialShow(identity_fakes.TestIdentityv3):
|
||||
self.application_credential
|
||||
)
|
||||
|
||||
self.columns = (
|
||||
'ID',
|
||||
'Name',
|
||||
'Description',
|
||||
'Project ID',
|
||||
'Roles',
|
||||
'Unrestricted',
|
||||
'Access Rules',
|
||||
'Expires At',
|
||||
)
|
||||
self.data = (
|
||||
self.application_credential.id,
|
||||
self.application_credential.name,
|
||||
self.application_credential.description,
|
||||
self.application_credential.project_id,
|
||||
application_credential.RolesColumn(
|
||||
self.application_credential.roles
|
||||
),
|
||||
self.application_credential.unrestricted,
|
||||
self.application_credential.access_rules,
|
||||
self.application_credential.expires_at,
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = application_credential.ShowApplicationCredential(
|
||||
self.app, None
|
||||
@ -434,25 +460,5 @@ class TestApplicationCredentialShow(identity_fakes.TestIdentityv3):
|
||||
user_id, self.application_credential.id
|
||||
)
|
||||
|
||||
collist = (
|
||||
'id',
|
||||
'name',
|
||||
'description',
|
||||
'project_id',
|
||||
'roles',
|
||||
'unrestricted',
|
||||
'access_rules',
|
||||
'expires_at',
|
||||
)
|
||||
self.assertEqual(collist, columns)
|
||||
datalist = (
|
||||
self.application_credential.id,
|
||||
self.application_credential.name,
|
||||
self.application_credential.description,
|
||||
self.application_credential.project_id,
|
||||
self.application_credential.roles,
|
||||
self.application_credential.unrestricted,
|
||||
self.application_credential.access_rules,
|
||||
self.application_credential.expires_at,
|
||||
)
|
||||
self.assertEqual(datalist, data)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
@ -5,7 +5,7 @@
|
||||
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
|
||||
cryptography>=2.7 # BSD/Apache-2.0
|
||||
cliff>=3.5.0 # Apache-2.0
|
||||
cliff>=4.8.0 # Apache-2.0
|
||||
iso8601>=0.1.11 # MIT
|
||||
openstacksdk>=4.5.0 # Apache-2.0
|
||||
osc-lib>=2.3.0 # Apache-2.0
|
||||
|
Reference in New Issue
Block a user