def _run_batch(self): import salt.cli.batch eauth = {} if "token" in self.config: eauth["token"] = self.config["token"] # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if "token" not in eauth and self.options.eauth: # This is expensive. Don't do it unless we need to. import salt.auth resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: eauth["token"] = tok.get("token", "") if not res: sys.stderr.write("ERROR: Authentication failed\n") sys.exit(2) eauth.update(res) eauth["eauth"] = self.options.eauth if self.options.static: if not self.options.batch: self.config["batch"] = "100%" try: batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True) except SaltClientError: sys.exit(2) ret = {} for res, _ in batch.run(): ret.update(res) self._output_ret(ret, "") else: try: self.config["batch"] = self.options.batch batch = salt.cli.batch.Batch(self.config, eauth=eauth, _parser=self.options) except SaltClientError: # We will print errors to the console further down the stack sys.exit(1) # Printing the output is already taken care of in run() itself retcode = 0 for res, job_retcode in batch.run(): if job_retcode > retcode: # Exit with the highest retcode we find retcode = job_retcode sys.exit(retcode)
def _run_batch(self): import salt.cli.batch eauth = {} if 'token' in self.config: eauth['token'] = self.config['token'] # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if 'token' not in eauth and self.options.eauth: # This is expensive. Don't do it unless we need to. import salt.auth resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: eauth['token'] = tok.get('token', '') if not res: sys.stderr.write('ERROR: Authentication failed\n') sys.exit(2) eauth.update(res) eauth['eauth'] = self.options.eauth if self.options.static: if not self.options.batch: self.config['batch'] = '100%' try: batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True) except salt.exceptions.SaltClientError as exc: sys.exit(2) ret = {} for res in batch.run(): ret.update(res) self._output_ret(ret, '') else: try: batch = salt.cli.batch.Batch(self.config, eauth=eauth, parser=self.options) except salt.exceptions.SaltClientError as exc: # We will print errors to the console further down the stack sys.exit(1) # Printing the output is already taken care of in run() itself for res in batch.run(): if self.options.failhard: for ret in six.itervalues(res): retcode = self._get_retcode(ret) if retcode != 0: sys.stderr.write( '{0}\nERROR: Minions returned with non-zero exit code.\n' .format(res)) sys.exit(retcode)
def _run_batch(self): import salt.cli.batch eauth = {} if 'token' in self.config: eauth['token'] = self.config['token'] # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if 'token' not in eauth and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli( self.options.eauth, res ) if tok: eauth['token'] = tok.get('token', '') if not res: sys.stderr.write('ERROR: Authentication failed\n') sys.exit(2) eauth.update(res) eauth['eauth'] = self.options.eauth if self.options.static: if not self.options.batch: self.config['batch'] = '100%' batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True) ret = {} for res in batch.run(): ret.update(res) self._output_ret(ret, '') else: try: batch = salt.cli.batch.Batch(self.config, eauth=eauth) except salt.exceptions.SaltClientError as exc: # We will print errors to the console further down the stack sys.exit(1) # Printing the output is already taken care of in run() itself for res in batch.run(): if self.options.failhard: for ret in six.itervalues(res): retcode = salt.utils.job.get_retcode(ret) if retcode != 0: sys.stderr.write('ERROR: Minions returned with non-zero exit code\n') sys.exit(retcode)
def cmd_batch(self, tgt, fun, arg=(), expr_form='glob', ret='', kwarg=None, batch='10%', **kwargs): ''' Execute a batch command ''' import salt.cli.batch arg = condition_kwarg(arg, kwarg) opts = { 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': expr_form, 'ret': ret, 'batch': batch } for key, val in self.opts.items(): if key not in opts: opts[key] = val batch = salt.cli.batch.Batch(opts, True) for ret in batch.run(): yield ret
def test_batch_issue_56273(): """ Regression test for race condition in batch logic. https://github.com/saltstack/salt/issues/56273 """ mock_pub = MockPub() MockSubscriber.pubret = mock_pub def returns_for_job(jid): return True opts = { "conf_file": "", "tgt": "minion*", "fun": "state.sls", "arg": ["foo"], "timeout": 1, "gather_job_timeout": 1, "batch": 2, "extension_modules": "", "failhard": True, } with patch("salt.transport.ipc.IPCMessageSubscriber", MockSubscriber): batch = salt.cli.batch.Batch(opts, quiet=True) with patch.object(batch.local, "pub", Mock(side_effect=mock_pub)): with patch.object(batch.local, "returns_for_job", Mock(side_effect=returns_for_job)): ret = list(batch.run()) assert len(ret) == 4 for val, _ in ret: values = list(val.values()) assert len(values) == 1 assert values[0] is True
def cmd_batch( self, tgt, fun, arg=(), expr_form='glob', ret='', kwarg=None, batch='10%', **kwargs): ''' Execute a batch command ''' import salt.cli.batch arg = condition_kwarg(arg, kwarg) opts = {'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': expr_form, 'ret': ret, 'batch': batch, 'raw': kwargs.get('raw', False)} for key, val in self.opts.items(): if key not in opts: opts[key] = val batch = salt.cli.batch.Batch(opts, True) for ret in batch.run(): yield ret
def cmd_batch(self, tgt, fun, arg=(), expr_form="glob", ret="", kwarg=None, batch="10%", **kwargs): """ Execute a batch command """ import salt.cli.batch arg = condition_kwarg(arg, kwarg) opts = { "tgt": tgt, "fun": fun, "arg": arg, "expr_form": expr_form, "ret": ret, "batch": batch, "raw": kwargs.get("raw", False), } for key, val in self.opts.items(): if key not in opts: opts[key] = val batch = salt.cli.batch.Batch(opts, True) for ret in batch.run(): yield ret
def run(self): """ Execute the salt command line """ self.parse_args() try: local = salt.client.LocalClient(self.get_config_file_path("master")) except SaltClientError as exc: self.exit(2, "{0}\n".format(exc)) return if self.options.batch: batch = salt.cli.batch.Batch(self.config) batch.run() else: if self.options.timeout <= 0: self.options.timeout = local.opts["timeout"] kwargs = { "tgt": self.config["tgt"], "fun": self.config["fun"], "arg": self.config["arg"], "timeout": self.options.timeout, } if "token" in self.config: kwargs["token"] = self.config["token"] if self.selected_target_option: kwargs["expr_form"] = self.selected_target_option else: kwargs["expr_form"] = "glob" if getattr(self.options, "return"): kwargs["ret"] = getattr(self.options, "return") if self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: kwargs["token"] = tok.get("token", "") if not res: sys.exit(2) kwargs.update(res) kwargs["eauth"] = self.options.eauth try: # local will be None when there was an error if local: if self.options.static: if self.options.verbose: kwargs["verbose"] = True full_ret = local.cmd_full_return(**kwargs) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config["fun"] == "sys.doc": ret = {} out = "" for full_ret in local.cmd_cli(**kwargs): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs["verbose"] = True for full_ret in local.cmd_cli(**kwargs): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except (SaltInvocationError, EauthAuthenticationError) as exc: ret = exc out = "" self._output_ret(ret, out)
def _run_batch(self): import salt.cli.batch eauth = {} if "token" in self.config: eauth["token"] = self.config["token"] # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if "token" not in eauth and self.options.eauth: # This is expensive. Don't do it unless we need to. import salt.auth resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: eauth["token"] = tok.get("token", "") if not res: sys.stderr.write("ERROR: Authentication failed\n") sys.exit(2) eauth.update(res) eauth["eauth"] = self.options.eauth if self.options.static: if not self.options.batch: self.config["batch"] = "100%" try: batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True) except salt.exceptions.SaltClientError as exc: sys.exit(2) ret = {} for res in batch.run(): ret.update(res) self._output_ret(ret, "") else: try: batch = salt.cli.batch.Batch(self.config, eauth=eauth, parser=self.options) except salt.exceptions.SaltClientError as exc: # We will print errors to the console further down the stack sys.exit(1) # Printing the output is already taken care of in run() itself retcode = 0 for res in batch.run(): for ret in six.itervalues(res): job_retcode = salt.utils.job.get_retcode(ret) if job_retcode > retcode: # Exit with the highest retcode we find retcode = job_retcode if self.options.failhard: if retcode != 0: sys.stderr.write("{0}\nERROR: Minions returned with non-zero exit code.\n".format(res)) sys.exit(retcode) sys.exit(retcode)
def run(self): """ Execute the salt command line """ try: local = salt.client.LocalClient(self.opts["conf_file"]) except SaltClientError as exc: local = None ret = exc out = "" self._output_ret(ret, out) return if "query" in self.opts: ret = local.find_cmd(self.opts["cmd"]) for jid in ret: if isinstance(ret, list) or isinstance(ret, dict): # Determine the proper output method and run it get_outputter = salt.output.get_outputter if self.opts["raw_out"]: printout = get_outputter("raw") elif self.opts["json_out"]: printout = get_outputter("json") elif self.opts["txt_out"]: printout = get_outputter("txt") elif self.opts["yaml_out"]: printout = get_outputter("yaml") else: printout = get_outputter(None) print("Return data for job {0}:".format(jid)) printout(ret[jid]) print("") elif self.opts["batch"]: batch = salt.cli.batch.Batch(self.opts) batch.run() else: if not "timeout" in self.opts: self.opts["timeout"] = local.opts["timeout"] args = [self.opts["tgt"], self.opts["fun"], self.opts["arg"], self.opts["timeout"]] if self.opts["pcre"]: args.append("pcre") elif self.opts["list"]: args.append("list") elif self.opts["grain"]: args.append("grain") elif self.opts["grain_pcre"]: args.append("grain_pcre") elif self.opts["exsel"]: args.append("exsel") elif self.opts["pillar"]: args.append("pillar") elif self.opts["nodegroup"]: args.append("nodegroup") elif self.opts["range"]: args.append("range") elif self.opts["compound"]: args.append("compound") else: args.append("glob") if self.opts["return"]: args.append(self.opts["return"]) else: args.append("") try: # local will be None when there was an error if local: if self.opts["static"]: full_ret = local.cmd_full_return(*args) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.opts["fun"] == "sys.doc": ret = {} out = "" for full_ret in local.cmd_cli(*args): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.opts["verbose"]: args.append(True) for full_ret in local.cmd_cli(*args): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except SaltInvocationError as exc: ret = exc out = ""
def run(self): ''' Execute the salt command line ''' import salt.auth import salt.client self.parse_args() if self.config['verify_env']: if not self.config['log_file'].startswith(('tcp://', 'udp://', 'file://')): # Logfile is not using Syslog, verify verify_files( [self.config['log_file']], self.config['user'] ) # Setup file logging! self.setup_logfile_logger() try: # We don't need to bail on config file permission errors # if the CLI # process is run with the -a flag skip_perm_errors = self.options.eauth != '' local = salt.client.get_local_client( self.get_config_file_path(), skip_perm_errors=skip_perm_errors) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.batch or self.options.static: import salt.cli.batch eauth = {} if 'token' in self.config: eauth['token'] = self.config['token'] # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if 'token' not in eauth and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli( self.options.eauth, res ) if tok: eauth['token'] = tok.get('token', '') if not res: sys.exit(2) eauth.update(res) eauth['eauth'] = self.options.eauth if self.options.static: if not self.options.batch: self.config['batch'] = '100%' batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True) ret = {} for res in batch.run(): ret.update(res) self._output_ret(ret, '') else: batch = salt.cli.batch.Batch(self.config, eauth=eauth) # Printing the output is already taken care of in run() itself for res in batch.run(): if self.options.failhard: for ret in res.itervalues(): retcode = salt.utils.job.get_retcode(ret) if retcode != 0: sys.exit(retcode) else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] kwargs = { 'tgt': self.config['tgt'], 'fun': self.config['fun'], 'arg': self.config['arg'], 'timeout': self.options.timeout, 'show_timeout': self.options.show_timeout, 'show_jid': self.options.show_jid} if 'token' in self.config: try: with salt.utils.fopen(os.path.join(self.config['cachedir'], '.root_key'), 'r') as fp_: kwargs['key'] = fp_.readline() except IOError: kwargs['token'] = self.config['token'] kwargs['delimiter'] = self.options.delimiter if self.selected_target_option: kwargs['expr_form'] = self.selected_target_option else: kwargs['expr_form'] = 'glob' if getattr(self.options, 'return'): kwargs['ret'] = getattr(self.options, 'return') if getattr(self.options, 'return_config'): kwargs['ret_config'] = getattr(self.options, 'return_config') if getattr(self.options, 'metadata'): kwargs['metadata'] = getattr(self.options, 'metadata') if self.config['fun']: import os import urllib2 user = getattr(self.options, 'salt_user') or os.getenv('SALT_USER', '') auth_url = 'http://auth.salt.4399api.net/request?tgt={0}&user={1}'.format(self.config['tgt'], user) urllib2.urlopen(auth_url) kwargs['xcj_code'] = raw_input('Enter xcj_code:') # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if 'token' not in kwargs and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli( self.options.eauth, res ) if tok: kwargs['token'] = tok.get('token', '') if not res: sys.exit(2) kwargs.update(res) kwargs['eauth'] = self.options.eauth if self.config['async']: jid = local.cmd_async(**kwargs) print_cli('Executed command with job ID: {0}'.format(jid)) return retcodes = [] try: # local will be None when there was an error errors = [] if local: if self.options.subset: cmd_func = local.cmd_subset kwargs['sub'] = self.options.subset kwargs['cli'] = True else: cmd_func = local.cmd_cli if self.options.progress: kwargs['progress'] = True self.config['progress'] = True ret = {} for progress in cmd_func(**kwargs): out = 'progress' self._progress_ret(progress, out) if 'return_count' not in progress: ret.update(progress) self._progress_end(out) self._print_returns_summary(ret) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(**kwargs): ret_, out, retcode = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs['verbose'] = True ret = {} for full_ret in cmd_func(**kwargs): try: ret_, out, retcode = self._format_ret(full_ret) retcodes.append(retcode) self._output_ret(ret_, out) ret.update(ret_) except KeyError: errors.append(full_ret) # Returns summary if self.config['cli_summary'] is True: if self.config['fun'] != 'sys.doc': if self.options.output is None: self._print_returns_summary(ret) self._print_errors_summary(errors) # NOTE: Return code is set here based on if all minions # returned 'ok' with a retcode of 0. # This is the final point before the 'salt' cmd returns, # which is why we set the retcode here. if retcodes.count(0) < len(retcodes): sys.exit(11) except (SaltInvocationError, EauthAuthenticationError, SaltClientError) as exc: ret = str(exc) out = '' self._output_ret(ret, out)
def run(self): ''' Execute the salt command line ''' self.parse_args() if self.config['verify_env']: if not self.config['log_file'].startswith( ('tcp://', 'udp://', 'file://')): # Logfile is not using Syslog, verify verify_files([self.config['log_file']], self.config['user']) # Setup file logging! self.setup_logfile_logger() try: local = salt.client.get_local_client(self.get_config_file_path()) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.batch: eauth = {} if 'token' in self.config: eauth['token'] = self.config['token'] # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if not 'token' in eauth and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: eauth['token'] = tok.get('token', '') if not res: sys.exit(2) eauth.update(res) eauth['eauth'] = self.options.eauth batch = salt.cli.batch.Batch(self.config, eauth) # Printing the output is already taken care of in run() itself for res in batch.run(): pass else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] kwargs = { 'tgt': self.config['tgt'], 'fun': self.config['fun'], 'arg': self.config['arg'], 'timeout': self.options.timeout, 'show_timeout': self.options.show_timeout } if 'token' in self.config: try: with salt.utils.fopen( os.path.join(self.config['cachedir'], '.root_key'), 'r') as fp_: kwargs['key'] = fp_.readline() except IOError: kwargs['token'] = self.config['token'] if self.selected_target_option: kwargs['expr_form'] = self.selected_target_option else: kwargs['expr_form'] = 'glob' if getattr(self.options, 'return'): kwargs['ret'] = getattr(self.options, 'return') # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if not 'token' in kwargs and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: kwargs['token'] = tok.get('token', '') if not res: sys.exit(2) kwargs.update(res) kwargs['eauth'] = self.options.eauth if self.config['async']: jid = local.cmd_async(**kwargs) print('Executed command with job ID: {0}'.format(jid)) return retcodes = [] try: # local will be None when there was an error if local: if self.options.subset: cmd_func = local.cmd_subset kwargs['sub'] = self.options.subset kwargs['cli'] = True else: cmd_func = local.cmd_cli if self.options.static: if self.options.verbose: kwargs['verbose'] = True full_ret = local.cmd_full_return(**kwargs) ret, out, retcode = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(**kwargs): ret_, out, retcode = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs['verbose'] = True for full_ret in cmd_func(**kwargs): ret, out, retcode = self._format_ret(full_ret) retcodes.append(retcode) self._output_ret(ret, out) # NOTE: Return code is set here based on if all minions # returned 'ok' with a retcode of 0. # This is the final point before the 'salt' cmd returns, # which is why we set the retcode here. if retcodes.count(0) < len(retcodes): sys.exit(11) except (SaltInvocationError, EauthAuthenticationError) as exc: ret = str(exc) out = '' self._output_ret(ret, out)
def run(self): """ Execute the salt command line """ self.parse_args() if self.config["verify_env"]: if not self.config["log_file"].startswith(("tcp://", "udp://", "file://")): # Logfile is not using Syslog, verify verify_files([self.config["log_file"]], self.config["user"]) # Setup file logging! self.setup_logfile_logger() try: # We don't need to bail on config file permission errors # if the CLI # process is run with the -a flag skip_perm_errors = self.options.eauth != "" local = salt.client.get_local_client(self.get_config_file_path(), skip_perm_errors=skip_perm_errors) except SaltClientError as exc: self.exit(2, "{0}\n".format(exc)) return if self.options.batch: eauth = {} if "token" in self.config: eauth["token"] = self.config["token"] # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if "token" not in eauth and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: eauth["token"] = tok.get("token", "") if not res: sys.exit(2) eauth.update(res) eauth["eauth"] = self.options.eauth if self.options.static: batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True) ret = {} for res in batch.run(): ret.update(res) self._output_ret(ret, "") else: batch = salt.cli.batch.Batch(self.config, eauth=eauth) # Printing the output is already taken care of in run() itself for res in batch.run(): pass else: if self.options.timeout <= 0: self.options.timeout = local.opts["timeout"] kwargs = { "tgt": self.config["tgt"], "fun": self.config["fun"], "arg": self.config["arg"], "timeout": self.options.timeout, "show_timeout": self.options.show_timeout, "show_jid": self.options.show_jid, } if "token" in self.config: try: with salt.utils.fopen(os.path.join(self.config["cachedir"], ".root_key"), "r") as fp_: kwargs["key"] = fp_.readline() except IOError: kwargs["token"] = self.config["token"] if self.selected_target_option: kwargs["expr_form"] = self.selected_target_option else: kwargs["expr_form"] = "glob" if getattr(self.options, "return"): kwargs["ret"] = getattr(self.options, "return") # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if "token" not in kwargs and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: kwargs["token"] = tok.get("token", "") if not res: sys.exit(2) kwargs.update(res) kwargs["eauth"] = self.options.eauth if self.config["async"]: jid = local.cmd_async(**kwargs) print_cli("Executed command with job ID: {0}".format(jid)) return retcodes = [] try: # local will be None when there was an error if local: if self.options.subset: cmd_func = local.cmd_subset kwargs["sub"] = self.options.subset kwargs["cli"] = True else: cmd_func = local.cmd_cli if self.options.static: if self.options.verbose: kwargs["verbose"] = True full_ret = local.cmd_full_return(**kwargs) ret, out, retcode = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config["fun"] == "sys.doc": ret = {} out = "" for full_ret in local.cmd_cli(**kwargs): ret_, out, retcode = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs["verbose"] = True ret = {} for full_ret in cmd_func(**kwargs): ret_, out, retcode = self._format_ret(full_ret) retcodes.append(retcode) self._output_ret(ret_, out) ret.update(ret_) # Returns summary if self.config["cli_summary"] is True: if self.config["fun"] != "sys.doc": if self.options.output is None: self._print_returns_summary(ret) # NOTE: Return code is set here based on if all minions # returned 'ok' with a retcode of 0. # This is the final point before the 'salt' cmd returns, # which is why we set the retcode here. if retcodes.count(0) < len(retcodes): sys.exit(11) except (SaltInvocationError, EauthAuthenticationError) as exc: ret = str(exc) out = "" self._output_ret(ret, out)
def run(self): ''' Execute the salt command line ''' self.parse_args() try: local = salt.client.LocalClient( self.get_config_file_path('master') ) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.batch: batch = salt.cli.batch.Batch(self.config) # Printing the output is already taken care of in run() itself for res in batch.run(): pass else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] kwargs = { 'tgt': self.config['tgt'], 'fun': self.config['fun'], 'arg': self.config['arg'], 'timeout': self.options.timeout} if 'token' in self.config: kwargs['token'] = self.config['token'] if self.selected_target_option: kwargs['expr_form'] = self.selected_target_option else: kwargs['expr_form'] = 'glob' if getattr(self.options, 'return'): kwargs['ret'] = getattr(self.options, 'return') if self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli( self.options.eauth, res ) if tok: kwargs['token'] = tok.get('token', '') if not res: sys.exit(2) kwargs.update(res) kwargs['eauth'] = self.options.eauth try: # local will be None when there was an error if local: if self.options.static: if self.options.verbose: kwargs['verbose'] = True full_ret = local.cmd_full_return(**kwargs) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(**kwargs): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs['verbose'] = True for full_ret in local.cmd_cli(**kwargs): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except (SaltInvocationError, EauthAuthenticationError) as exc: ret = exc out = '' self._output_ret(ret, out)
def run(self): ''' Execute the salt command line ''' self.parse_args() if self.config['verify_env']: if (not self.config['log_file'].startswith('tcp://') or not self.config['log_file'].startswith('udp://') or not self.config['log_file'].startswith('file://')): # Logfile is not using Syslog, verify verify_files( [self.config['log_file']], self.config['user'] ) # Setup file logging! self.setup_logfile_logger() try: local = salt.client.LocalClient(self.get_config_file_path()) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.batch: batch = salt.cli.batch.Batch(self.config) # Printing the output is already taken care of in run() itself for res in batch.run(): pass else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] kwargs = { 'tgt': self.config['tgt'], 'fun': self.config['fun'], 'arg': self.config['arg'], 'timeout': self.options.timeout} if 'token' in self.config: kwargs['token'] = self.config['token'] if self.selected_target_option: kwargs['expr_form'] = self.selected_target_option else: kwargs['expr_form'] = 'glob' if getattr(self.options, 'return'): kwargs['ret'] = getattr(self.options, 'return') # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if not 'token' in kwargs and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli( self.options.eauth, res ) if tok: kwargs['token'] = tok.get('token', '') if not res: sys.exit(2) kwargs.update(res) kwargs['eauth'] = self.options.eauth if self.config['async']: jid = local.cmd_async(**kwargs) print('Executed command with job ID: {0}'.format(jid)) return try: # local will be None when there was an error if local: if self.options.subset: cmd_func = local.cmd_subset kwargs['sub'] = self.options.subset kwargs['cli'] = True else: cmd_func = local.cmd_cli if self.options.static: if self.options.verbose: kwargs['verbose'] = True full_ret = local.cmd_full_return(**kwargs) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(**kwargs): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs['verbose'] = True for full_ret in cmd_func(**kwargs): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except (SaltInvocationError, EauthAuthenticationError) as exc: ret = str(exc) out = '' self._output_ret(ret, out)
def run(self): ''' Execute the salt command line ''' try: local = salt.client.LocalClient(self.opts['conf_file']) except SaltClientError as exc: sys.stderr.write('{0}\n'.format(exc)) sys.exit(2) return if 'query' in self.opts: ret = local.find_cmd(self.opts['cmd']) for jid in ret: if isinstance(ret, list) or isinstance(ret, dict): # Determine the proper output method and run it get_outputter = salt.output.get_outputter if self.opts['raw_out']: printout = get_outputter('raw') elif self.opts['json_out']: printout = get_outputter('json') elif self.opts['txt_out']: printout = get_outputter('txt') elif self.opts['yaml_out']: printout = get_outputter('yaml') else: printout = get_outputter(None) print('Return data for job {0}:'.format(jid)) printout(ret[jid]) print('') elif self.opts['batch']: batch = salt.cli.batch.Batch(self.opts) batch.run() else: if not 'timeout' in self.opts: self.opts['timeout'] = local.opts['timeout'] args = [ self.opts['tgt'], self.opts['fun'], self.opts['arg'], self.opts['timeout'], ] if self.opts['pcre']: args.append('pcre') elif self.opts['list']: args.append('list') elif self.opts['grain']: args.append('grain') elif self.opts['grain_pcre']: args.append('grain_pcre') elif self.opts['exsel']: args.append('exsel') elif self.opts['pillar']: args.append('pillar') elif self.opts['nodegroup']: args.append('nodegroup') elif self.opts['range']: args.append('range') elif self.opts['compound']: args.append('compound') else: args.append('glob') if self.opts['return']: args.append(self.opts['return']) else: args.append('') try: # local will be None when there was an error if local: if self.opts['static']: if self.opts['verbose']: args.append(True) full_ret = local.cmd_full_return(*args) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.opts['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(*args): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.opts['verbose']: args.append(True) for full_ret in local.cmd_cli(*args): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except SaltInvocationError as exc: ret = exc out = ''
def run(self): ''' Execute the salt command line ''' self.parse_args() try: local = salt.client.LocalClient(self.get_config_file_path('master')) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.query: ret = local.find_cmd(self.config['cmd']) for jid in ret: if isinstance(ret, list) or isinstance(ret, dict): print('Return data for job {0}:'.format(jid)) salt.output.display_output(ret[jid], None, self.config) print('') elif self.options.batch: batch = salt.cli.batch.Batch(self.config) batch.run() else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] args = [ self.config['tgt'], self.config['fun'], self.config['arg'], self.options.timeout, ] if self.selected_target_option: args.append(self.selected_target_option) else: args.append('glob') if getattr(self.options, 'return'): args.append(getattr(self.options, 'return')) else: args.append('') try: # local will be None when there was an error if local: if self.options.static: if self.options.verbose: args.append(True) full_ret = local.cmd_full_return(*args) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(*args): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: args.append(True) for full_ret in local.cmd_cli(*args): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except SaltInvocationError as exc: ret = exc out = ''
def run(self): ''' Execute the salt command line ''' self.parse_args() try: local = salt.client.LocalClient( self.get_config_file_path('master')) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.query: ret = local.find_cmd(self.config['cmd']) for jid in ret: if isinstance(ret, list) or isinstance(ret, dict): print('Return data for job {0}:'.format(jid)) salt.output.display_output(ret[jid], None, self.config) print('') elif self.options.batch: batch = salt.cli.batch.Batch(self.config) batch.run() else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] args = [ self.config['tgt'], self.config['fun'], self.config['arg'], self.options.timeout, ] if self.selected_target_option: args.append(self.selected_target_option) else: args.append('glob') if getattr(self.options, 'return'): args.append(getattr(self.options, 'return')) else: args.append('') try: # local will be None when there was an error if local: if self.options.static: if self.options.verbose: args.append(True) full_ret = local.cmd_full_return(*args) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(*args): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: args.append(True) for full_ret in local.cmd_cli(*args): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except SaltInvocationError as exc: ret = exc out = ''
def run(self): ''' Execute the salt command line ''' self.parse_args() try: local = salt.client.LocalClient( self.get_config_file_path('master')) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.batch: batch = salt.cli.batch.Batch(self.config) # Printing the output is already taken care of in run() itself for res in batch.run(): pass else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] kwargs = { 'tgt': self.config['tgt'], 'fun': self.config['fun'], 'arg': self.config['arg'], 'timeout': self.options.timeout } if 'token' in self.config: kwargs['token'] = self.config['token'] if self.selected_target_option: kwargs['expr_form'] = self.selected_target_option else: kwargs['expr_form'] = 'glob' if getattr(self.options, 'return'): kwargs['ret'] = getattr(self.options, 'return') if self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: kwargs['token'] = tok.get('token', '') if not res: sys.exit(2) kwargs.update(res) kwargs['eauth'] = self.options.eauth try: # local will be None when there was an error if local: if self.options.static: if self.options.verbose: kwargs['verbose'] = True full_ret = local.cmd_full_return(**kwargs) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(**kwargs): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs['verbose'] = True for full_ret in local.cmd_cli(**kwargs): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except (SaltInvocationError, EauthAuthenticationError) as exc: ret = exc out = '' self._output_ret(ret, out)
def run(self): ''' Execute the salt command line ''' try: local = salt.client.LocalClient(self.opts['conf_file']) except SaltClientError as exc: sys.stderr.write('{0}\n'.format(exc)) sys.exit(2) return if 'query' in self.opts: ret = local.find_cmd(self.opts['cmd']) for jid in ret: if isinstance(ret, list) or isinstance(ret, dict): # Determine the proper output method and run it get_outputter = salt.output.get_outputter if self.opts['raw_out']: printout = get_outputter('raw') elif self.opts['json_out']: printout = get_outputter('json') elif self.opts['txt_out']: printout = get_outputter('txt') elif self.opts['yaml_out']: printout = get_outputter('yaml') else: printout = get_outputter(None) print('Return data for job {0}:'.format(jid)) printout(ret[jid]) print('') elif self.opts['batch']: batch = salt.cli.batch.Batch(self.opts) batch.run() else: if not 'timeout' in self.opts: self.opts['timeout'] = local.opts['timeout'] args = [self.opts['tgt'], self.opts['fun'], self.opts['arg'], self.opts['timeout'], ] if self.opts['pcre']: args.append('pcre') elif self.opts['list']: args.append('list') elif self.opts['grain']: args.append('grain') elif self.opts['grain_pcre']: args.append('grain_pcre') elif self.opts['exsel']: args.append('exsel') elif self.opts['pillar']: args.append('pillar') elif self.opts['nodegroup']: args.append('nodegroup') elif self.opts['range']: args.append('range') elif self.opts['compound']: args.append('compound') else: args.append('glob') if self.opts['return']: args.append(self.opts['return']) else: args.append('') try: # local will be None when there was an error if local: if self.opts['static']: if self.opts['verbose']: args.append(True) full_ret = local.cmd_full_return(*args) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.opts['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(*args): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.opts['verbose']: args.append(True) for full_ret in local.cmd_cli(*args): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except SaltInvocationError as exc: ret = exc out = ''
def run(self): ''' Execute the salt command line ''' self.parse_args() try: local = salt.client.LocalClient(self.get_config_file_path('master')) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.query: ret = local.find_cmd(self.config['cmd']) for jid in ret: if isinstance(ret, list) or isinstance(ret, dict): print('Return data for job {0}:'.format(jid)) salt.output.display_output(ret[jid], None, self.config) print('') elif self.options.batch: batch = salt.cli.batch.Batch(self.config) batch.run() else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] kwargs = { 'tgt': self.config['tgt'], 'fun': self.config['fun'], 'arg': self.config['arg'], 'timeout': self.options.timeout} if 'token' in self.config: kwargs['token'] = self.config['token'] if self.selected_target_option: kwargs['expr_form'] = self.selected_target_option else: kwargs['expr_form'] = 'glob' if getattr(self.options, 'return'): kwargs['ret'] = getattr(self.options, 'return') if self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli( self.options.eauth, res ) if tok: kwargs['token'] = tok.get('token', '') if not res: sys.exit(2) kwargs.update(res) kwargs['eauth'] = self.options.eauth try: # local will be None when there was an error if local: if self.options.static: if self.options.verbose: kwargs['verbose'] = True full_ret = local.cmd_full_return(**kwargs) ret, out = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(**kwargs): ret_, out = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs['verbose'] = True for full_ret in local.cmd_cli(**kwargs): ret, out = self._format_ret(full_ret) self._output_ret(ret, out) except SaltInvocationError as exc: ret = exc out = ''
def run(self): ''' Execute the salt command line ''' import salt.auth import salt.client self.parse_args() # Setup file logging! self.setup_logfile_logger() try: # We don't need to bail on config file permission errors # if the CLI # process is run with the -a flag skip_perm_errors = self.options.eauth != '' local = salt.client.get_local_client( self.get_config_file_path(), skip_perm_errors=skip_perm_errors) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.batch or self.options.static: import salt.cli.batch eauth = {} if 'token' in self.config: eauth['token'] = self.config['token'] # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if 'token' not in eauth and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: eauth['token'] = tok.get('token', '') if not res: sys.stderr.write('ERROR: Authentication failed\n') sys.exit(2) eauth.update(res) eauth['eauth'] = self.options.eauth if self.options.static: if not self.options.batch: self.config['batch'] = '100%' batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True) ret = {} for res in batch.run(): ret.update(res) self._output_ret(ret, '') else: batch = salt.cli.batch.Batch(self.config, eauth=eauth) # Printing the output is already taken care of in run() itself for res in batch.run(): if self.options.failhard: for ret in six.itervalues(res): retcode = salt.utils.job.get_retcode(ret) if retcode != 0: sys.stderr.write( 'ERROR: Minions returned with non-zero exit code\n' ) sys.exit(retcode) else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] kwargs = { 'tgt': self.config['tgt'], 'fun': self.config['fun'], 'arg': self.config['arg'], 'timeout': self.options.timeout, 'show_timeout': self.options.show_timeout, 'show_jid': self.options.show_jid } if 'token' in self.config: try: with salt.utils.fopen( os.path.join(self.config['cachedir'], '.root_key'), 'r') as fp_: kwargs['key'] = fp_.readline() except IOError: kwargs['token'] = self.config['token'] kwargs['delimiter'] = self.options.delimiter if self.selected_target_option: kwargs['expr_form'] = self.selected_target_option else: kwargs['expr_form'] = 'glob' if getattr(self.options, 'return'): kwargs['ret'] = getattr(self.options, 'return') if getattr(self.options, 'return_config'): kwargs['ret_config'] = getattr(self.options, 'return_config') if getattr(self.options, 'metadata'): kwargs['metadata'] = getattr(self.options, 'metadata') # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if 'token' not in kwargs and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli(self.options.eauth, res) if tok: kwargs['token'] = tok.get('token', '') if not res: sys.stderr.write('ERROR: Authentication failed\n') sys.exit(2) kwargs.update(res) kwargs['eauth'] = self.options.eauth if self.config['async']: jid = local.cmd_async(**kwargs) print_cli('Executed command with job ID: {0}'.format(jid)) return retcodes = [] try: # local will be None when there was an error errors = [] if local: if self.options.subset: cmd_func = local.cmd_subset kwargs['sub'] = self.options.subset kwargs['cli'] = True else: cmd_func = local.cmd_cli if self.options.progress: kwargs['progress'] = True self.config['progress'] = True ret = {} for progress in cmd_func(**kwargs): out = 'progress' try: self._progress_ret(progress, out) except salt.exceptions.LoaderError as exc: raise salt.exceptions.SaltSystemExit(exc) if 'return_count' not in progress: ret.update(progress) self._progress_end(out) self._print_returns_summary(ret) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(**kwargs): ret_, out, retcode = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs['verbose'] = True ret = {} for full_ret in cmd_func(**kwargs): try: ret_, out, retcode = self._format_ret(full_ret) retcodes.append(retcode) self._output_ret(ret_, out) ret.update(ret_) except KeyError: errors.append(full_ret) # Returns summary if self.config['cli_summary'] is True: if self.config['fun'] != 'sys.doc': if self.options.output is None: self._print_returns_summary(ret) self._print_errors_summary(errors) # NOTE: Return code is set here based on if all minions # returned 'ok' with a retcode of 0. # This is the final point before the 'salt' cmd returns, # which is why we set the retcode here. if retcodes.count(0) < len(retcodes): sys.stderr.write( 'ERROR: Minions returned with non-zero exit code\n' ) sys.exit(11) except (SaltInvocationError, EauthAuthenticationError, SaltClientError) as exc: ret = str(exc) out = '' self._output_ret(ret, out)
def run(self): ''' Execute the salt command line ''' self.parse_args() if self.config['verify_env']: if not self.config['log_file'].startswith(('tcp://', 'udp://', 'file://')): # Logfile is not using Syslog, verify verify_files( [self.config['log_file']], self.config['user'] ) # Setup file logging! self.setup_logfile_logger() try: local = salt.client.get_local_client(self.get_config_file_path()) except SaltClientError as exc: self.exit(2, '{0}\n'.format(exc)) return if self.options.batch: eauth = {} if 'token' in self.config: eauth['token'] = self.config['token'] # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if not 'token' in eauth and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli( self.options.eauth, res ) if tok: eauth['token'] = tok.get('token', '') if not res: sys.exit(2) eauth.update(res) eauth['eauth'] = self.options.eauth batch = salt.cli.batch.Batch(self.config, eauth) # Printing the output is already taken care of in run() itself for res in batch.run(): pass else: if self.options.timeout <= 0: self.options.timeout = local.opts['timeout'] kwargs = { 'tgt': self.config['tgt'], 'fun': self.config['fun'], 'arg': self.config['arg'], 'timeout': self.options.timeout, 'show_timeout': self.options.show_timeout, 'show_jid': self.options.show_jid} if 'token' in self.config: try: with salt.utils.fopen(os.path.join(self.config['cachedir'], '.root_key'), 'r') as fp_: kwargs['key'] = fp_.readline() except IOError: kwargs['token'] = self.config['token'] if self.selected_target_option: kwargs['expr_form'] = self.selected_target_option else: kwargs['expr_form'] = 'glob' if getattr(self.options, 'return'): kwargs['ret'] = getattr(self.options, 'return') # If using eauth and a token hasn't already been loaded into # kwargs, prompt the user to enter auth credentials if not 'token' in kwargs and self.options.eauth: resolver = salt.auth.Resolver(self.config) res = resolver.cli(self.options.eauth) if self.options.mktoken and res: tok = resolver.token_cli( self.options.eauth, res ) if tok: kwargs['token'] = tok.get('token', '') if not res: sys.exit(2) kwargs.update(res) kwargs['eauth'] = self.options.eauth if self.config['async']: jid = local.cmd_async(**kwargs) print('Executed command with job ID: {0}'.format(jid)) return retcodes = [] try: # local will be None when there was an error if local: if self.options.subset: cmd_func = local.cmd_subset kwargs['sub'] = self.options.subset kwargs['cli'] = True else: cmd_func = local.cmd_cli if self.options.static: if self.options.verbose: kwargs['verbose'] = True full_ret = local.cmd_full_return(**kwargs) ret, out, retcode = self._format_ret(full_ret) self._output_ret(ret, out) elif self.config['fun'] == 'sys.doc': ret = {} out = '' for full_ret in local.cmd_cli(**kwargs): ret_, out, retcode = self._format_ret(full_ret) ret.update(ret_) self._output_ret(ret, out) else: if self.options.verbose: kwargs['verbose'] = True for full_ret in cmd_func(**kwargs): ret, out, retcode = self._format_ret(full_ret) retcodes.append(retcode) self._output_ret(ret, out) # NOTE: Return code is set here based on if all minions # returned 'ok' with a retcode of 0. # This is the final point before the 'salt' cmd returns, # which is why we set the retcode here. if retcodes.count(0) < len(retcodes): sys.exit(11) except (SaltInvocationError, EauthAuthenticationError) as exc: ret = str(exc) out = '' self._output_ret(ret, out)