Beispiel #1
0
def add_deploy(state, deploy_func, *args, **kwargs):
    """
    Prepare & add an deploy to pyinfra.state by executing it on all hosts.

    Args:
        state (``pyinfra.api.State`` obj): the deploy state to add the operation
        deploy_func (function): the operation function from one of the modules,
        ie ``server.user``
        args/kwargs: passed to the operation function
    """

    if pyinfra.is_cli:
        raise PyinfraError(
            (
                "`add_deploy` should not be called when pyinfra is executing in CLI mode! ({0})"
            ).format(get_call_location()),
        )

    hosts = kwargs.pop("host", state.inventory.iter_active_hosts())
    if isinstance(hosts, Host):
        hosts = [hosts]

    with ctx_state.use(state):
        for deploy_host in hosts:
            with ctx_host.use(deploy_host):
                deploy_func(*args, **kwargs)
Beispiel #2
0
def add_op(state, op_func, *args, **kwargs):
    """
    Prepare & add an operation to ``pyinfra.state`` by executing it on all hosts.

    Args:
        state (``pyinfra.api.State`` obj): the deploy state to add the operation
        to op_func (function): the operation function from one of the modules,
        ie ``server.user``
        args/kwargs: passed to the operation function
    """

    allow_cli_mode = kwargs.pop("_allow_cli_mode", False)
    after_host_callback = kwargs.pop("_after_host_callback", lambda host: None)

    if pyinfra.is_cli and not allow_cli_mode:
        raise PyinfraError((
            "`add_op` should not be called when pyinfra is executing in CLI mode! ({0})"
        ).format(get_call_location(), ), )

    hosts = kwargs.pop("host", state.inventory.iter_active_hosts())
    if isinstance(hosts, Host):
        hosts = [hosts]

    with ctx_state.use(state):
        results = {}
        for op_host in hosts:
            with ctx_host.use(op_host):
                results[op_host] = op_func(*args, **kwargs)
            after_host_callback(op_host)

    return results
Beispiel #3
0
 def load_file(local_host):
     with ctx_config.use(state.config.copy()):
         with ctx_host.use(local_host):
             exec_file(filename)
             logger.info(
                 "{0}{1} {2}".format(
                     local_host.print_prefix,
                     click.style("Ready:", "green"),
                     click.style(filename, bold=True),
                 ),
             )
Beispiel #4
0
 def get_fact_with_context(state, host, *args, **kwargs):
     with ctx_state.use(state):
         with ctx_host.use(host):
             return get_fact(state, host, *args, **kwargs)
Beispiel #5
0
def _run_host_op_with_context(state, host, op_hash):
    with ctx_host.use(host):
        return run_host_op(state, host, op_hash)
Beispiel #6
0
        def jsontest_function(self, test_name, test_data):
            if ("require_platform" in test_data
                    and PLATFORM_NAME not in test_data["require_platform"]):
                return

            op_test_name = "{0}/{1}.json".format(arg, test_name)

            # Create a host with this tests facts and attach to context host
            host = create_host(facts=test_data.get("facts", {}))

            allowed_exception = test_data.get("exception")

            args = parse_value(test_data.get("args", []))
            kwargs = parse_value(test_data.get("kwargs", {}))

            with ctx_state.use(self.state):
                with ctx_host.use(host):
                    with patch_files(test_data.get("local_files", {})):
                        try:
                            output_commands = list(
                                op._pyinfra_op(*args, **kwargs))
                        except Exception as e:
                            if allowed_exception:
                                allowed_exception_names = allowed_exception.get(
                                    "names")
                                if not allowed_exception_names:
                                    allowed_exception_names = [
                                        allowed_exception["name"]
                                    ]

                                if e.__class__.__name__ not in allowed_exception_names:
                                    print("Wrong execption raised!")
                                    raise

                                assert e.args[0] == allowed_exception[
                                    "message"]
                                return

                            raise

                        op_is_idempotent = getattr(op._pyinfra_op,
                                                   "is_idempotent", True)
                        second_output_commands = []
                        test_second_output_commands = "second_output_commands" in test_data

                        if op_is_idempotent or test_second_output_commands:
                            second_output_commands = list(
                                op._pyinfra_op(*args, **kwargs))

            if op_is_idempotent:
                if test_data.get("idempotent", True):
                    if second_output_commands:
                        raise Exception(
                            "Operation not idempotent, second output commands: {0}"
                            .format(second_output_commands, ), )
                else:
                    if not second_output_commands:
                        raise Exception(
                            ("Operation tests as idempotent but test "
                             "says it is not: {0}").format(op_test_name), )
                    if not test_data.get("disable_idempotent_warning_reason"):
                        warnings.warn((
                            "This operation should be idempotent, but the test has "
                            "disabled this check without reason: {0}"
                        ).format(op_test_name), )

            if op_is_idempotent is False:
                if "disable_idempotent_warning_reason" in test_data:
                    warnings.warn((
                        "This operation is not idempotent and so the test does not need "
                        "`disable_idempotent_warning_reason` set: {0}"
                    ).format(op_test_name), )

            commands = parse_commands(output_commands)
            assert_commands(commands, test_data["commands"])

            if test_second_output_commands:
                assert_commands(
                    parse_commands(second_output_commands),
                    test_data["second_output_commands"],
                )

            noop_description = test_data.get("noop_description")
            if len(commands) == 0 or noop_description:
                if noop_description is not None:
                    assert host.noop_description == noop_description
                else:
                    assert host.noop_description is not None, "no noop description was set"
                    warnings.warn(
                        'No noop_description set for test: {0} (got "{1}")'.
                        format(
                            op_test_name,
                            host.noop_description,
                        ), )