1818import datetime
1919import json
2020import logging
21+ import uuid
2122
2223from osc_lib .command import command
2324from osc_lib import exceptions
3031LOG = logging .getLogger (__name__ )
3132
3233
34+ # TODO(stephenfin): Move this to osc_lib since it's useful elsewhere
35+ def is_uuid_like (value ) -> bool :
36+ """Returns validation of a value as a UUID.
37+
38+ :param val: Value to verify
39+ :type val: string
40+ :returns: bool
41+
42+ .. versionchanged:: 1.1.1
43+ Support non-lowercase UUIDs.
44+ """
45+ try :
46+ formatted_value = (
47+ value .replace ('urn:' , '' )
48+ .replace ('uuid:' , '' )
49+ .strip ('{}' )
50+ .replace ('-' , '' )
51+ .lower ()
52+ )
53+ return str (uuid .UUID (value )).replace ('-' , '' ) == formatted_value
54+ except (TypeError , ValueError , AttributeError ):
55+ return False
56+
57+
3358class CreateApplicationCredential (command .ShowOne ):
3459 _description = _ ("Create new application credential" )
3560
@@ -105,19 +130,16 @@ def get_parser(self, prog_name):
105130 return parser
106131
107132 def take_action (self , parsed_args ):
108- identity_client = self .app .client_manager .identity
133+ identity_client = self .app .client_manager .sdk_connection .identity
134+ conn = self .app .client_manager .sdk_connection
135+ user_id = conn .config .get_auth ().get_user_id (conn .identity )
109136
110137 role_ids = []
111138 for role in parsed_args .role :
112- # A user can only create an application credential for themself,
113- # not for another user even as an admin, and only on the project to
114- # which they are currently scoped with a subset of the role
115- # assignments they have on that project. Don't bother trying to
116- # look up roles via keystone, just introspect the token.
117- role_id = common ._get_token_resource (
118- identity_client , "roles" , role
119- )
120- role_ids .append (role_id )
139+ if is_uuid_like (role ):
140+ role_ids .append ({'id' : role })
141+ else :
142+ role_ids .append ({'name' : role })
121143
122144 expires_at = None
123145 if parsed_args .expiration :
@@ -144,10 +166,10 @@ def take_action(self, parsed_args):
144166 )
145167 raise exceptions .CommandError (msg )
146168 else :
147- access_rules = None
169+ access_rules = []
148170
149- app_cred_manager = identity_client .application_credentials
150- application_credential = app_cred_manager . create (
171+ application_credential = identity_client .create_application_credential (
172+ user_id ,
151173 parsed_args .name ,
152174 roles = role_ids ,
153175 expires_at = expires_at ,
@@ -157,14 +179,32 @@ def take_action(self, parsed_args):
157179 access_rules = access_rules ,
158180 )
159181
160- application_credential ._info .pop ('links' , None )
161-
162182 # Format roles into something sensible
163- roles = application_credential ._info .pop ('roles' )
164- msg = ' ' .join (r ['name' ] for r in roles )
165- application_credential ._info ['roles' ] = msg
166-
167- return zip (* sorted (application_credential ._info .items ()))
183+ if application_credential ['roles' ]:
184+ roles = application_credential ['roles' ]
185+ msg = ' ' .join (r ['name' ] for r in roles )
186+ application_credential ['roles' ] = msg
187+
188+ columns = (
189+ 'ID' ,
190+ 'Name' ,
191+ 'Description' ,
192+ 'Project ID' ,
193+ 'Roles' ,
194+ 'Unrestricted' ,
195+ 'Access Rules' ,
196+ 'Expires At' ,
197+ 'Secret' ,
198+ )
199+ return (
200+ columns ,
201+ (
202+ utils .get_dict_properties (
203+ application_credential ,
204+ columns ,
205+ )
206+ ),
207+ )
168208
169209
170210class DeleteApplicationCredential (command .Command ):
@@ -181,15 +221,19 @@ def get_parser(self, prog_name):
181221 return parser
182222
183223 def take_action (self , parsed_args ):
184- identity_client = self .app .client_manager .identity
224+ identity_client = self .app .client_manager .sdk_connection .identity
225+ conn = self .app .client_manager .sdk_connection
226+ user_id = conn .config .get_auth ().get_user_id (conn .identity )
185227
186228 errors = 0
187229 for ac in parsed_args .application_credential :
188230 try :
189- app_cred = utils .find_resource (
190- identity_client .application_credentials , ac
231+ app_cred = identity_client .find_application_credential (
232+ user_id , ac
233+ )
234+ identity_client .delete_application_credential (
235+ user_id , app_cred .id
191236 )
192- identity_client .application_credentials .delete (app_cred .id )
193237 except Exception as e :
194238 errors += 1
195239 LOG .error (
@@ -223,16 +267,36 @@ def get_parser(self, prog_name):
223267 return parser
224268
225269 def take_action (self , parsed_args ):
226- identity_client = self .app .client_manager .identity
270+ identity_client = self .app .client_manager .sdk_connection . identity
227271 if parsed_args .user :
228272 user_id = common .find_user (
229273 identity_client , parsed_args .user , parsed_args .user_domain
230274 ).id
231275 else :
232- user_id = None
233-
234- columns = ('ID' , 'Name' , 'Project ID' , 'Description' , 'Expires At' )
235- data = identity_client .application_credentials .list (user = user_id )
276+ conn = self .app .client_manager .sdk_connection
277+ user_id = conn .config .get_auth ().get_user_id (conn .identity )
278+
279+ data = identity_client .application_credentials (user = user_id )
280+
281+ data_formatted = []
282+ for ac in data :
283+ # Format roles into something sensible
284+ roles = ac ['roles' ]
285+ msg = ' ' .join (r ['name' ] for r in roles )
286+ ac ['roles' ] = msg
287+
288+ data_formatted .append (ac )
289+
290+ columns = (
291+ 'ID' ,
292+ 'Name' ,
293+ 'Description' ,
294+ 'Project ID' ,
295+ 'Roles' ,
296+ 'Unrestricted' ,
297+ 'Access Rules' ,
298+ 'Expires At' ,
299+ )
236300 return (
237301 columns ,
238302 (
@@ -241,7 +305,7 @@ def take_action(self, parsed_args):
241305 columns ,
242306 formatters = {},
243307 )
244- for s in data
308+ for s in data_formatted
245309 ),
246310 )
247311
@@ -259,17 +323,35 @@ def get_parser(self, prog_name):
259323 return parser
260324
261325 def take_action (self , parsed_args ):
262- identity_client = self .app .client_manager .identity
263- app_cred = utils .find_resource (
264- identity_client .application_credentials ,
265- parsed_args .application_credential ,
266- )
326+ identity_client = self .app .client_manager .sdk_connection .identity
327+ conn = self .app .client_manager .sdk_connection
328+ user_id = conn .config .get_auth ().get_user_id (conn .identity )
267329
268- app_cred ._info .pop ('links' , None )
330+ app_cred = identity_client .find_application_credential (
331+ user_id , parsed_args .application_credential
332+ )
269333
270334 # Format roles into something sensible
271- roles = app_cred . _info . pop ( 'roles' )
335+ roles = app_cred [ 'roles' ]
272336 msg = ' ' .join (r ['name' ] for r in roles )
273- app_cred ._info ['roles' ] = msg
274-
275- return zip (* sorted (app_cred ._info .items ()))
337+ app_cred ['roles' ] = msg
338+
339+ columns = (
340+ 'ID' ,
341+ 'Name' ,
342+ 'Description' ,
343+ 'Project ID' ,
344+ 'Roles' ,
345+ 'Unrestricted' ,
346+ 'Access Rules' ,
347+ 'Expires At' ,
348+ )
349+ return (
350+ columns ,
351+ (
352+ utils .get_dict_properties (
353+ app_cred ,
354+ columns ,
355+ )
356+ ),
357+ )
0 commit comments