def test_get_from_config(self): config = Config(SUDO="config-value") inventory = Inventory((("somehost", ), {})) state = State(config=config, inventory=inventory) kwargs, keys = pop_global_arguments( {}, state=state, host=inventory.get_host("somehost")) assert kwargs["sudo"] == "config-value"
def _get_executor_defaults(state, host): global_argument_defaults, _ = pop_global_arguments({}, state=state, host=host) return { key: value for key, value in global_argument_defaults.items() if key in get_executor_kwarg_keys() }
def test_get_from_state_deploy_kwargs(self): config = Config(SUDO="config-value") inventory = Inventory(([("somehost", {"sudo": "host-value"})], {})) somehost = inventory.get_host("somehost") state = State(config=config, inventory=inventory) somehost.current_deploy_kwargs = {"sudo": "deploy-kwarg-value"} kwargs, keys = pop_global_arguments({}, state=state, host=somehost) assert kwargs["sudo"] == "deploy-kwarg-value"
def _get_fact( state, host, cls, args=None, kwargs=None, ensure_hosts=None, apply_failed_hosts=True, fact_hash=None, ): fact = cls() name = fact.name args = args or () kwargs = kwargs or {} # Get the defaults *and* overrides by popping from kwargs, executor kwargs passed # into get_fact override everything else (applied below). override_kwargs, override_kwarg_keys = pop_global_arguments( kwargs, state=state, host=host, keys_to_check=get_executor_kwarg_keys(), ) executor_kwargs = _get_executor_kwargs( state, host, override_kwargs=override_kwargs, override_kwarg_keys=override_kwarg_keys, ) if args or kwargs: # Merges args & kwargs into a single kwargs dictionary kwargs = getcallargs(fact.command, *args, **kwargs) kwargs_str = get_kwargs_str(kwargs) logger.debug( "Getting fact: %s (%s) (ensure_hosts: %r)", name, kwargs_str, ensure_hosts, ) if not host.connected: host.connect( reason=f"to load fact: {name} ({kwargs_str})", raise_exceptions=True, ) ignore_errors = (host.current_op_global_kwargs or {}).get( "ignore_errors", state.config.IGNORE_ERRORS, ) # Facts can override the shell (winrm powershell vs cmd support) if fact.shell_executable: executor_kwargs["shell_executable"] = fact.shell_executable command = _make_command(fact.command, kwargs) requires_command = _make_command(fact.requires_command, kwargs) if requires_command: command = StringCommand( # Command doesn't exist, return 0 *or* run & return fact command "!", "command", "-v", requires_command, ">/dev/null", "||", command, ) status = False stdout = [] combined_output_lines = [] try: status, combined_output_lines = host.run_shell_command( command, print_output=state.print_fact_output, print_input=state.print_fact_input, return_combined_output=True, **executor_kwargs, ) except (timeout_error, socket_error, SSHException) as e: log_host_command_error( host, e, timeout=executor_kwargs["timeout"], ) stdout, stderr = split_combined_output(combined_output_lines) data = fact.default() if status: if stdout: data = fact.process(stdout) elif stderr: # If we have error output and that error is sudo or su stating the user # does not exist, do not fail but instead return the default fact value. # This allows for users that don't currently but may be created during # other operations. first_line = stderr[0] if executor_kwargs["sudo_user"] and re.match(SUDO_REGEX, first_line): status = True if executor_kwargs["su_user"] and any( re.match(regex, first_line) for regex in SU_REGEXES): status = True if status: log_message = "{0}{1}".format( host.print_prefix, "Loaded fact {0}{1}".format( click.style(name, bold=True), f" ({get_kwargs_str(kwargs)})" if kwargs else "", ), ) if state.print_fact_info: logger.info(log_message) else: logger.debug(log_message) else: if not state.print_fact_output: print_host_combined_output(host, combined_output_lines) log_error_or_warning( host, ignore_errors, description=("could not load fact: {0} {1}").format( name, get_kwargs_str(kwargs)), ) # Check we've not failed if not status and not ignore_errors and apply_failed_hosts: state.fail_hosts({host}) if fact_hash: host.facts[fact_hash] = data return data