@@ -92,6 +92,8 @@ def __init__(
9292 Path to the secret in Vault
9393 vault_token : str
9494 Token for authenticating with Vault
95+ keyring_service : str
96+ keyring service name to load Mist API settings from system keyring
9597 console_log_level : int, default: 20
9698 Log level for the console output. Values are:
9799 50 -> CRITICAL
@@ -332,6 +334,9 @@ def _load_env(self, env_file=None) -> None:
332334 if os .getenv ("MIST_VAULT_TOKEN" ) and not self .vault_token :
333335 self .vault_token = os .getenv ("MIST_VAULT_TOKEN" )
334336
337+ if os .getenv ("MIST_KEYRING_SERVICE" ):
338+ self .keyring_service = os .getenv ("MIST_KEYRING_SERVICE" )
339+
335340 if os .getenv ("HTTPS_PROXY" ):
336341 self ._proxies ["https" ] = os .getenv ("HTTPS_PROXY" )
337342
@@ -477,14 +482,19 @@ def set_api_token(self, apitoken: str) -> None:
477482 if token and token not in apitokens_out :
478483 apitokens_out .append (token )
479484 LOGGER .info ("apisession:set_api_token:found %s API Tokens" , len (apitokens_out ))
480- if self ._check_api_tokens (apitokens_out ):
481- self ._apitoken = apitokens_out
485+
486+ valid_api_tokens = self ._check_api_tokens (apitokens_out )
487+ if valid_api_tokens :
488+ self ._apitoken = valid_api_tokens
482489 self ._apitoken_index = 0
483490 self ._session .headers .update (
484491 {"Authorization" : "Token " + self ._apitoken [self ._apitoken_index ]}
485492 )
486493 LOGGER .info ("apisession:set_api_token:API Token configured" )
487494 CONSOLE .debug ("API Token configured" )
495+ else :
496+ LOGGER .error ("apisession:set_api_token:No valid API Token provided" )
497+ CONSOLE .error ("No valid API Token provided" )
488498
489499 def _get_api_token_data (self , apitoken ) -> tuple [str | None , list | None ]:
490500 token_privileges = []
@@ -568,30 +578,48 @@ def _get_api_token_data(self, apitoken) -> tuple[str | None, list | None]:
568578 )
569579 return (token_type , token_privileges )
570580
571- def _check_api_tokens (self , apitokens ) -> bool :
581+ def _check_api_tokens (self , apitokens ) -> list [ str ] :
572582 """
573583 Function used when multiple API tokens are provided, to validate they
574584 have same privileges
575585 """
576586 LOGGER .debug ("apisession:_check_api_tokens" )
587+ valid_api_tokens : list [str ] = []
577588 if len (apitokens ) == 0 :
578589 LOGGER .error ("apisession:_check_api_tokens:there is not API token to check" )
579- elif (len (apitokens )) == 1 :
580- LOGGER .info (
581- "apisession:_check_api_tokens:there is only 1 API token. No check required"
582- )
583590 else :
584591 primary_token_privileges : list [str ] = []
585592 primary_token_type : str | None = ""
586593 primary_token_value : str = ""
587594 for token in apitokens :
588595 token_value = f"{ token [:4 ]} ...{ token [- 4 :]} "
596+ if token in valid_api_tokens :
597+ LOGGER .info (
598+ "apisession:_check_api_tokens:API Token %s is already valid" ,
599+ token_value ,
600+ )
601+ continue
589602 (token_type , token_privileges ) = self ._get_api_token_data (token )
590- if len (primary_token_privileges ) == 0 and token_privileges :
603+ if token_type is None or token_privileges is None :
604+ LOGGER .error (
605+ "apisession:_check_api_tokens:API Token %s is not valid" ,
606+ token_value ,
607+ )
608+ LOGGER .error (
609+ "API Token %s is not valid and will not be used" , token_value
610+ )
611+ elif len (primary_token_privileges ) == 0 and token_privileges :
591612 primary_token_privileges = token_privileges
592613 primary_token_type = token_type
593614 primary_token_value = token_value
615+ valid_api_tokens .append (token )
616+ LOGGER .info (
617+ "apisession:_check_api_tokens:"
618+ "API Token %s set as primary for comparison" ,
619+ token_value ,
620+ )
594621 elif primary_token_privileges == token_privileges :
622+ valid_api_tokens .append (token )
595623 LOGGER .info (
596624 "apisession:_check_api_tokens:"
597625 "%s API Token %s has same privileges as "
@@ -602,7 +630,7 @@ def _check_api_tokens(self, apitokens) -> bool:
602630 primary_token_value ,
603631 )
604632 else :
605- LOGGER .critical (
633+ LOGGER .error (
606634 "apisession:_check_api_tokens:"
607635 "%s API Token %s has different privileges "
608636 "than the %s API Token %s" ,
@@ -611,14 +639,11 @@ def _check_api_tokens(self, apitokens) -> bool:
611639 primary_token_type ,
612640 primary_token_value ,
613641 )
614- LOGGER .critical (" /!\\ API TOKEN CRITICAL ERROR /!\\ " )
615- LOGGER .critical (
616- " When using multiple API Tokens, be sure they are all linked"
617- " to the same Org/User, and all have the same privileges"
642+ LOGGER .error (
643+ "API Token %s has different privileges and will not be used" ,
644+ token_value ,
618645 )
619- LOGGER .critical (" Exiting..." )
620- sys .exit (255 )
621- return True
646+ return valid_api_tokens
622647
623648 def _process_login (self , retry : bool = True ) -> str | None :
624649 """
@@ -643,26 +668,42 @@ def _process_login(self, retry: bool = True) -> str | None:
643668 if not self ._password :
644669 self .set_password ()
645670
646- LOGGER .debug ("apisession:_process_login:email/password configured" )
647- uri = "/api/v1/login"
648- body = {"email" : self .email , "password" : self ._password }
649- resp = self ._session .post (self ._url (uri ), json = body )
650- if resp .status_code == 200 :
651- LOGGER .info ("apisession:_process_login:authentication successful!" )
652- CONSOLE .info ("Authentication successful!" )
653- self ._set_authenticated (True )
654- else :
655- error = resp .json ().get ("detail" )
656- LOGGER .error ("apisession:_process_login:authentication failed:%s" , error )
657- CONSOLE .error (f"Authentication failed: { error } \r \n " )
658- self .email = None
659- self ._password = None
660- LOGGER .info (
661- "apisession:_process_login:"
662- "email/password cleaned up. Restarting authentication function"
671+ try :
672+ LOGGER .debug ("apisession:_process_login:email/password configured" )
673+ uri = "/api/v1/login"
674+ body = {"email" : self .email , "password" : self ._password }
675+ resp = self ._session .post (self ._url (uri ), json = body )
676+ if resp .status_code == 200 :
677+ LOGGER .info ("apisession:_process_login:authentication successful!" )
678+ CONSOLE .info ("Authentication successful!" )
679+ self ._set_authenticated (True )
680+ else :
681+ error = resp .json ().get ("detail" )
682+ LOGGER .error (
683+ "apisession:_process_login:authentication failed:%s" , error
684+ )
685+ CONSOLE .error (f"Authentication failed: { error } \r \n " )
686+ self .email = None
687+ self ._password = None
688+ LOGGER .info (
689+ "apisession:_process_login:"
690+ "email/password cleaned up. Restarting authentication function"
691+ )
692+ if retry :
693+ return self ._process_login (retry )
694+ except requests .exceptions .ProxyError :
695+ LOGGER .critical ("apisession:_process_login:proxy not valid..." )
696+ CONSOLE .critical ("Proxy not valid...\r \n " )
697+ sys .exit (0 )
698+ except requests .exceptions .ConnectionError as connexion_error :
699+ LOGGER .critical (
700+ "apirequest:mist_post:Connection Error: %s" , connexion_error
663701 )
664- if retry :
665- return self ._process_login (retry )
702+ CONSOLE .critical ("Connexion error...\r \n " )
703+ sys .exit (0 )
704+ except Exception :
705+ LOGGER .error ("apisession:_process_login:Exception occurred" , exc_info = True )
706+ error = "Exception occurred during authentication"
666707
667708 return error
668709
0 commit comments