1616# Azure SDK imports
1717from azure .identity import DefaultAzureCredential
1818from azure .mgmt .authorization import AuthorizationManagementClient
19+ import colorama
20+ from colorama import Fore , Style
1921
20-
21- # ANSI color codes for terminal output
22- class Colors :
23- RED = "\033 [91m"
24- GREEN = "\033 [92m"
25- YELLOW = "\033 [93m"
26- BLUE = "\033 [94m"
27- CYAN = "\033 [96m"
28- RESET = "\033 [0m"
22+ # Initialize colorama for cross-platform color support
23+ colorama .init (autoreset = True )
2924
3025
3126def colored (text : str , color : str ) -> str :
3227 """Add color to terminal output."""
33- return f"{ color } { text } { Colors . RESET } "
28+ return f"{ color } { text } { Style . RESET_ALL } "
3429
3530
3631# Get script directory and config
@@ -77,9 +72,9 @@ async def get_az_cli_logged_in_info(print_info: bool = True) -> AzCliLoggedInInf
7772 )
7873
7974 if print_info :
80- print (f"Logged in as { colored (info .user , Colors .CYAN )} " )
75+ print (f"Logged in as { colored (info .user , Fore .CYAN )} " )
8176 print (
82- f"Subscription: { colored (info .subscription_name , Colors .CYAN )} ({ colored (info .subscription_id , Colors .CYAN )} )"
77+ f"Subscription: { colored (info .subscription_name , Fore .CYAN )} ({ colored (info .subscription_id , Fore .CYAN )} )"
8378 )
8479
8580 return info
@@ -142,7 +137,7 @@ async def elevate(self, options: Dict):
142137 }
143138
144139 print (
145- f"Elevating { colored (principal_id , Colors .CYAN )} to { colored (options ['roleName' ], Colors .CYAN )} for { colored (options ['expirationDuration' ], Colors .CYAN )} "
140+ f"Elevating { colored (principal_id , Fore .CYAN )} to { colored (options ['roleName' ], Fore .CYAN )} for { colored (options ['expirationDuration' ], Fore .CYAN )} "
146141 )
147142
148143 try :
@@ -155,15 +150,13 @@ async def elevate(self, options: Dict):
155150 print (result )
156151 print (
157152 colored (
158- f"ELEVATION SUCCESSFUL for role { options ['roleName' ]} " , Colors .GREEN
153+ f"ELEVATION SUCCESSFUL for role { options ['roleName' ]} " , Fore .GREEN
159154 )
160155 )
161156 except Exception as e :
162157 print (e )
163158 print (
164- colored (
165- f"Unable to elevate for role { options ['roleName' ]} ." , Colors .RED
166- )
159+ colored (f"Unable to elevate for role { options ['roleName' ]} ." , Fore .RED )
167160 )
168161
169162 async def get_role_definition_id (
@@ -196,14 +189,14 @@ async def get_role_definition_id(
196189 role_id = role .expanded_properties .role_definition .id
197190 if role_id :
198191 print (
199- f"Found Role Definition { colored (role_name , Colors .CYAN )} with id { colored (role_id , Colors .CYAN )} "
192+ f"Found Role Definition { colored (role_name , Fore .CYAN )} with id { colored (role_id , Fore .CYAN )} "
200193 )
201194 return role_id
202195
203196 print (
204197 colored (
205198 f"ERROR: Unable to find the requested role '{ role_name } '. Are you certain you are logged into the correct subscription?" ,
206- Colors .RED ,
199+ Fore .RED ,
207200 )
208201 )
209202 raise Exception (f"Unable to find the role '{ role_name } '." )
@@ -225,7 +218,7 @@ async def get_principal_id(self, continue_on_failure: bool = False) -> str:
225218 print (
226219 colored (
227220 "ERROR: Unable to get principal id of the current user." ,
228- Colors .RED ,
221+ Fore .RED ,
229222 )
230223 )
231224 sys .exit (12 )
@@ -247,21 +240,21 @@ async def create():
247240 check = True ,
248241 )
249242 account = json .loads (result .stdout )
250- print (f"Logged in as { colored (account ['user' ]['name' ], Colors .CYAN )} " )
243+ print (f"Logged in as { colored (account ['user' ]['name' ], Fore .CYAN )} " )
251244 return AzCliKeyVaultClient ()
252245 except subprocess .CalledProcessError :
253246 print (
254247 colored (
255248 "ERROR: User not logged in to Azure CLI. Run 'az login'." ,
256- Colors .RED ,
249+ Fore .RED ,
257250 )
258251 )
259252 sys .exit (1 )
260253 except FileNotFoundError :
261254 print (
262255 colored (
263256 "ERROR: Azure CLI is not installed. Install it and run 'az login' before running this tool." ,
264- Colors .RED ,
257+ Fore .RED ,
265258 )
266259 )
267260 sys .exit (1 )
@@ -332,7 +325,7 @@ async def get_secret_list_with_elevation(
332325
333326 # Try to elevate to Key Vault Administrator
334327 try :
335- print (colored ("Elevating to get secrets..." , Colors .YELLOW ))
328+ print (colored ("Elevating to get secrets..." , Fore .YELLOW ))
336329 pim_client = await AzPIMClient .create ()
337330 await pim_client .elevate (
338331 {
@@ -344,22 +337,22 @@ async def get_secret_list_with_elevation(
344337 }
345338 )
346339
347- print (colored ("Elevation successful." , Colors .GREEN ))
348- print (colored ("Waiting 5 seconds..." , Colors .YELLOW ))
340+ print (colored ("Elevation successful." , Fore .GREEN ))
341+ print (colored ("Waiting 5 seconds..." , Fore .YELLOW ))
349342 await asyncio .sleep (5 )
350343
351344 return client .get_secrets (vault_name )
352345 except Exception :
353346 print (
354347 colored (
355348 "Elevation to key vault admin failed...attempting to get secrets as key vault reader." ,
356- Colors .YELLOW ,
349+ Fore .YELLOW ,
357350 )
358351 )
359352
360353 # Try to elevate to Key Vault Secrets User
361354 try :
362- print (colored ("Elevating to get secrets..." , Colors .YELLOW ))
355+ print (colored ("Elevating to get secrets..." , Fore .YELLOW ))
363356 pim_client = await AzPIMClient .create ()
364357 await pim_client .elevate (
365358 {
@@ -371,14 +364,14 @@ async def get_secret_list_with_elevation(
371364 }
372365 )
373366
374- print (colored ("Elevation successful." , Colors .GREEN ))
375- print (colored ("Waiting 5 seconds..." , Colors .YELLOW ))
367+ print (colored ("Elevation successful." , Fore .GREEN ))
368+ print (colored ("Waiting 5 seconds..." , Fore .YELLOW ))
376369 await asyncio .sleep (5 )
377370 except Exception :
378371 print (
379372 colored (
380373 "Elevation failed...attempting to get secrets without elevation." ,
381- Colors .YELLOW ,
374+ Fore .YELLOW ,
382375 )
383376 )
384377
@@ -390,7 +383,7 @@ async def get_secrets(
390383) -> List [Tuple [str , str ]]:
391384 """Get all enabled secrets from a vault."""
392385 print (
393- f"Getting existing { 'shared' if shared else 'private' } secrets from { colored (vault_name , Colors .CYAN )} key vault."
386+ f"Getting existing { 'shared' if shared else 'private' } secrets from { colored (vault_name , Fore .CYAN )} key vault."
394387 )
395388
396389 secret_list = await get_secret_list_with_elevation (client , vault_name )
@@ -401,13 +394,13 @@ async def fetch_secret(secret):
401394 secret_name = secret ["id" ].split ("/" )[- 1 ]
402395 try :
403396 response = client .read_secret (vault_name , secret_name )
404- print (colored (f" Found secret: { secret_name [:3 ]} ***" , Colors .GREEN ))
397+ print (colored (f" Found secret: { secret_name [:3 ]} ***" , Fore .GREEN ))
405398 return (secret_name , response ["value" ])
406399 except Exception as e :
407400 print (
408401 colored (
409402 f"Failed to read secret { secret_name [:3 ]} ***: { e } " ,
410- Colors .YELLOW ,
403+ Fore .YELLOW ,
411404 )
412405 )
413406 return None
@@ -574,8 +567,8 @@ async def pull_secrets_from_vault(
574567 if not secrets :
575568 print (
576569 colored (
577- f"WARNING: No secrets found in key vault { colored (vault_name , Colors .CYAN )} ." ,
578- Colors .YELLOW ,
570+ f"WARNING: No secrets found in key vault { colored (vault_name , Fore .CYAN )} ." ,
571+ Fore .YELLOW ,
579572 )
580573 )
581574 return None
@@ -599,7 +592,7 @@ async def pull_secrets():
599592 client = await AzCliKeyVaultClient .create ()
600593 vault_names = get_vault_names (dotenv )
601594
602- print (f"Pulling secrets to { colored (str (DOTENV_PATH ), Colors .CYAN )} " )
595+ print (f"Pulling secrets to { colored (str (DOTENV_PATH ), Fore .CYAN )} " )
603596
604597 shared_vault = vault_names ["shared" ]
605598 assert shared_vault is not None , "Shared vault name is required"
@@ -638,11 +631,11 @@ async def pull_secrets():
638631 updated += 1
639632
640633 if updated == 0 :
641- print (f"\n All values up to date in { colored (str (DOTENV_PATH ), Colors .CYAN )} " )
634+ print (f"\n All values up to date in { colored (str (DOTENV_PATH ), Fore .CYAN )} " )
642635 return
643636
644637 print (
645- f"\n { updated } values updated.\n Writing '{ colored (str (DOTENV_PATH ), Colors .CYAN )} '."
638+ f"\n { updated } values updated.\n Writing '{ colored (str (DOTENV_PATH ), Fore .CYAN )} '."
646639 )
647640
648641 # Write back to .env file
@@ -708,12 +701,12 @@ async def main():
708701 print (
709702 colored (
710703 "ERROR: Azure CLI is not installed. Install it and run 'az login' before running this tool." ,
711- Colors .RED ,
704+ Fore .RED ,
712705 )
713706 )
714707 sys .exit (0 )
715708
716- print (colored (f"FATAL ERROR: { e } " , Colors .RED ))
709+ print (colored (f"FATAL ERROR: { e } " , Fore .RED ))
717710 import traceback
718711
719712 traceback .print_exc ()
0 commit comments