Exemple #1
0
def _do_check_mk_remote_automation_in_background_job_serialized(
        site_id: SiteId,
        automation_request: CheckmkAutomationRequest) -> SerializedResult:
    """Execute the automation in a background job on the remote site

    It starts the background job using one call. It then polls the remote site, waiting for
    completion of the job."""
    site_config = get_site_config(site_id)

    job_id = _start_remote_automation_job(site_config, automation_request)

    auto_logger.info("Waiting for job completion")
    result = None
    while True:
        raw_response = do_remote_automation(
            site_config,
            "checkmk-remote-automation-get-status",
            [
                ("request", repr(job_id)),
            ],
        )
        response = CheckmkAutomationGetStatusResponse(*raw_response)
        auto_logger.debug("Job status: %r", response)

        if not response.job_status["is_active"]:
            result = response.result
            auto_logger.debug(
                "Job is not active anymore. Return the result: %s", result)
            break

    assert isinstance(result, str)

    return SerializedResult(result)
Exemple #2
0
def check_mk_remote_automation_serialized(
    *,
    site_id: SiteId,
    command: str,
    args: Optional[Sequence[str]],
    indata: Any,
    stdin_data: Optional[str] = None,
    timeout: Optional[int] = None,
    sync: bool = True,
    non_blocking_http: bool = False,
) -> SerializedResult:
    site = get_site_config(site_id)
    if "secret" not in site:
        raise MKGeneralException(
            _('Cannot connect to site "%s": The site is not logged in') %
            site.get("alias", site_id))

    if not site.get("replication"):
        raise MKGeneralException(
            _('Cannot connect to site "%s": The replication is disabled') %
            site.get("alias", site_id))

    if sync:
        sync_changes_before_remote_automation(site_id)

    if non_blocking_http:
        # This will start a background job process on the remote site to execute the automation
        # asynchronously. It then polls the remote site, waiting for completion of the job.
        return _do_check_mk_remote_automation_in_background_job_serialized(
            site_id,
            CheckmkAutomationRequest(command, args, indata, stdin_data,
                                     timeout))

    # Synchronous execution of the actual remote command in a single blocking HTTP request
    return SerializedResult(
        _do_remote_automation_serialized(
            site=get_site_config(site_id),
            command="checkmk-automation",
            vars_=[
                ("automation", command),  # The Checkmk automation command
                ("arguments", mk_repr(args)),  # The arguments for the command
                ("indata", mk_repr(indata)),  # The input data
                ("stdin_data",
                 mk_repr(stdin_data)),  # The input data for stdin
                ("timeout", mk_repr(timeout)),  # The timeout
            ],
        ))
Exemple #3
0
 def _execute_cmk_automation(self):
     cmk_command = request.get_str_input_mandatory("automation")
     args = watolib.mk_eval(request.get_str_input_mandatory("arguments"))
     indata = watolib.mk_eval(request.get_str_input_mandatory("indata"))
     stdin_data = watolib.mk_eval(
         request.get_str_input_mandatory("stdin_data"))
     timeout = watolib.mk_eval(request.get_str_input_mandatory("timeout"))
     cmdline_cmd, serialized_result = watolib.check_mk_local_automation_serialized(
         command=cmk_command,
         args=args,
         indata=indata,
         stdin_data=stdin_data,
         timeout=timeout,
     )
     # Don't use write_text() here (not needed, because no HTML document is rendered)
     response.set_data(
         self._format_cmk_automation_result(
             serialized_result=SerializedResult(serialized_result),
             cmk_command=cmk_command,
             cmdline_cmd=cmdline_cmd,
         ))
Exemple #4
0
def check_mk_local_automation_serialized(
    *,
    command: str,
    args: Optional[Sequence[str]] = None,
    indata: Any = "",
    stdin_data: Optional[str] = None,
    timeout: Optional[int] = None,
) -> Tuple[Sequence[str], SerializedResult]:
    if args is None:
        args = []
    new_args = list(args)

    if stdin_data is None:
        stdin_data = repr(indata)

    if timeout:
        new_args = ["--timeout", "%d" % timeout] + new_args

    cmd = ["check_mk"]

    if auto_logger.isEnabledFor(logging.DEBUG):
        cmd.append("-vv")
    elif auto_logger.isEnabledFor(VERBOSE):
        cmd.append("-v")

    cmd += ["--automation", command] + new_args

    if command in ["restart", "reload"]:
        call_hook_pre_activate_changes()

    # This debug output makes problems when doing bulk inventory, because
    # it garbles the non-HTML response output
    # if config.debug:
    #     html.write_text("<div class=message>Running <tt>%s</tt></div>\n" % subprocess.list2cmdline(cmd))
    auto_logger.info("RUN: %s" % subprocess.list2cmdline(cmd))
    auto_logger.info("STDIN: %r" % stdin_data)

    try:
        completed_process = subprocess.run(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            close_fds=True,
            encoding="utf-8",
            input=stdin_data,
            check=False,
        )
    except Exception as e:
        raise local_automation_failure(command=command, cmdline=cmd, exc=e)

    auto_logger.info("FINISHED: %d" % completed_process.returncode)
    auto_logger.debug("OUTPUT: %r" % completed_process.stdout)

    if completed_process.stderr:
        auto_logger.warning("'%s' returned '%s'" % (
            " ".join(cmd),
            completed_process.stderr,
        ))
    if completed_process.returncode:
        auto_logger.error("Error running %r (exit code %d)" % (
            subprocess.list2cmdline(cmd),
            completed_process.returncode,
        ))
        raise local_automation_failure(
            command=command,
            cmdline=cmd,
            code=completed_process.returncode,
            out=completed_process.stdout,
            err=completed_process.stderr,
        )

    # On successful "restart" command execute the activate changes hook
    if command in ["restart", "reload"]:
        call_hook_activate_changes()

    return cmd, SerializedResult(completed_process.stdout)