@@ -196,6 +196,12 @@ def add_authopts(self):
196196 dest = 'password' , help = textwrap .dedent ("""\
197197 Optional, but will be prompted unless --non-interactive""" ))
198198
199+ optgroup .add_option ('--token-expire' ,
200+ dest = 'token_expire' , help = textwrap .dedent ("""\
201+ Set eauth token expiry in seconds. Must be allowed per
202+ user. See the `token_expire_user_override` Master setting
203+ for more info.""" ))
204+
199205 optgroup .add_option ('--non-interactive' ,
200206 action = 'store_false' , dest = 'interactive' , help = textwrap .dedent ("""\
201207 Optional, fail rather than waiting for input""" ), default = True )
@@ -207,6 +213,13 @@ def add_authopts(self):
207213 generated and made available for the period defined in the Salt
208214 Master.""" ))
209215
216+ optgroup .add_option ('-r' , '--run-uri' , default = False ,
217+ dest = 'userun' , action = 'store_true' ,
218+ help = textwrap .dedent ("""\
219+ Use an eauth token from /token and send commands through the
220+ /run URL instead of the traditional session token
221+ approach.""" ))
222+
210223 optgroup .add_option ('-x' , dest = 'cache' ,
211224 default = os .environ .get ('PEPPERCACHE' ,
212225 os .path .join (os .path .expanduser ('~' ), '.peppercache' )),
@@ -253,6 +266,8 @@ def get_login_details(self):
253266
254267 if self .options .eauth :
255268 results ['SALTAPI_EAUTH' ] = self .options .eauth
269+ if self .options .token_expire :
270+ results ['SALTAPI_TOKEN_EXPIRE' ] = self .options .token_expire
256271 if self .options .username is None and results ['SALTAPI_USER' ] is None :
257272 if self .options .interactive :
258273 results ['SALTAPI_USER' ] = input ('Username: ' )
@@ -308,11 +323,17 @@ def parse_login(self):
308323 login_details = self .get_login_details ()
309324
310325 # Auth values placeholder; grab interactively at CLI or from config
311- user = login_details ['SALTAPI_USER' ]
312- passwd = login_details ['SALTAPI_PASS' ]
326+ username = login_details ['SALTAPI_USER' ]
327+ password = login_details ['SALTAPI_PASS' ]
313328 eauth = login_details ['SALTAPI_EAUTH' ]
314329
315- return user , passwd , eauth
330+ ret = dict (username = username , password = password , eauth = eauth )
331+
332+ token_expire = login_details .get ('SALTAPI_TOKEN_EXPIRE' , None )
333+ if token_expire :
334+ ret ['token_expire' ] = int (token_expire )
335+
336+ return ret
316337
317338 def parse_cmd (self ):
318339 '''
@@ -396,7 +417,7 @@ def poll_for_returns(self, api, load):
396417 cache for returns for the job.
397418 '''
398419 load [0 ]['client' ] = 'local_async'
399- async_ret = api .low (load )
420+ async_ret = self .low (api , load )
400421 jid = async_ret ['return' ][0 ]['jid' ]
401422 nodes = async_ret ['return' ][0 ]['minions' ]
402423 ret_nodes = []
@@ -413,7 +434,14 @@ def poll_for_returns(self, api, load):
413434 exit_code = 1
414435 break
415436
416- jid_ret = api .lookup_jid (jid )
437+ jid_ret = self .low (api , [{
438+ 'client' : 'runner' ,
439+ 'fun' : 'jobs.lookup_jid' ,
440+ 'kwarg' : {
441+ 'jid' : jid ,
442+ },
443+ }])
444+
417445 responded = set (jid_ret ['return' ][0 ].keys ()) ^ set (ret_nodes )
418446 for node in responded :
419447 yield None , "{{{}: {}}}" .format (
@@ -431,51 +459,71 @@ def poll_for_returns(self, api, load):
431459 yield exit_code , "{{Failed: {}}}" .format (
432460 list (set (ret_nodes ) ^ set (nodes )))
433461
434- def run (self ):
435- '''
436- Parse all arguments and call salt-api
437- '''
438- self .parse ()
439-
440- # move logger instantiation to method?
441- logger .addHandler (logging .StreamHandler ())
442- logger .setLevel (max (logging .ERROR - (self .options .verbose * 10 ), 1 ))
443-
444- load = self .parse_cmd ()
462+ def login (self , api ):
463+ login = api .token if self .options .userun else api .login
445464
446- api = pepper .Pepper (
447- self .parse_url (),
448- debug_http = self .options .debug_http ,
449- ignore_ssl_errors = self .options .ignore_ssl_certificate_errors )
450465 if self .options .mktoken :
451466 token_file = self .options .cache
452467 try :
453468 with open (token_file , 'rt' ) as f :
454- api . auth = json .load (f )
455- if api . auth ['expire' ] < time .time ()+ 30 :
469+ auth = json .load (f )
470+ if auth ['expire' ] < time .time ()+ 30 :
456471 logger .error ('Login token expired' )
457472 raise Exception ('Login token expired' )
458- api .req ('/stats' )
459473 except Exception as e :
460474 if e .args [0 ] is not 2 :
461- logger .error ('Unable to load login token from {0} {1}' .format (token_file , str (e )))
462- auth = api .login (* self .parse_login ())
475+ logger .error ('Unable to load login token from {0} {1}'
476+ .format (token_file , str (e )))
477+ auth = login (** self .parse_login ())
463478 try :
464479 oldumask = os .umask (0 )
465480 fdsc = os .open (token_file , os .O_WRONLY | os .O_CREAT , 0o600 )
466481 with os .fdopen (fdsc , 'wt' ) as f :
467482 json .dump (auth , f )
468483 except Exception as e :
469- logger .error ('Unable to save token to {0} {1}' .format (token_file , str (e )))
484+ logger .error ('Unable to save token to {0} {1}'
485+ .format (token_file , str (e )))
470486 finally :
471487 os .umask (oldumask )
472488 else :
473- auth = api .login (* self .parse_login ())
489+ auth = login (** self .parse_login ())
490+
491+ api .auth = auth
492+ self .auth = auth
493+ return auth
494+
495+ def low (self , api , load ):
496+ path = '/run' if self .options .userun else '/'
497+
498+ if self .options .userun :
499+ for i in load :
500+ i ['token' ] = self .auth ['token' ]
501+
502+ return api .low (load , path = path )
503+
504+ def run (self ):
505+ '''
506+ Parse all arguments and call salt-api
507+ '''
508+ self .parse ()
509+
510+ # move logger instantiation to method?
511+ logger .addHandler (logging .StreamHandler ())
512+ logger .setLevel (max (logging .ERROR - (self .options .verbose * 10 ), 1 ))
513+
514+ load = self .parse_cmd ()
515+
516+ api = pepper .Pepper (
517+ self .parse_url (),
518+ debug_http = self .options .debug_http ,
519+ ignore_ssl_errors = self .options .ignore_ssl_certificate_errors )
520+
521+ self .login (api )
474522
475523 if self .options .fail_if_minions_dont_respond :
476524 for exit_code , ret in self .poll_for_returns (api , load ):
477525 yield exit_code , json .dumps (ret , sort_keys = True , indent = 4 )
478526 else :
479- ret = api .low (load )
527+ ret = self .low (api , load )
480528 exit_code = 0
481529 yield exit_code , json .dumps (ret , sort_keys = True , indent = 4 )
0 commit comments