Esempio n. 1
0
def _verify_compatibility(response: requests.Response) -> None:
    """Ensure we are compatible with the remote site

    In distributed setups the sync from a newer major version central site to an older central site
    is not allowed. Since 2.1.0 the remote site is performing most of the validations. But in case
    the newer site is the central site and the remote site is the older, e.g. 2.1.0 to 2.0.0, there
    is no validation logic on the remote site. To ensure the validation is also performed in this
    case, we execute the validation logic also in the central site when receiving the answer to the
    remote call before processing it's content.

    Since 2.0.0p13 the remote site answers with x-checkmk-version, x-checkmk-edition headers.
    """
    central_version = cmk_version.__version__
    central_edition_short = cmk_version.edition().short

    remote_version = response.headers.get("x-checkmk-version", "")
    remote_edition_short = response.headers.get("x-checkmk-edition", "")

    if not remote_version or not remote_edition_short:
        return  # No validation

    if not compatible_with_central_site(central_version, central_edition_short,
                                        remote_version, remote_edition_short):
        raise MKGeneralException(
            _("The central (Version: %s, Edition: %s) and remote site "
              "(Version: %s, Edition: %s) are not compatible") % (
                  central_version,
                  central_edition_short,
                  remote_version,
                  remote_edition_short,
              ))
Esempio n. 2
0
def _set_version_headers() -> None:
    """Add the x-checkmk-version, x-checkmk-edition headers to the HTTP response

    Has been added with 2.0.0p13.
    """
    response.headers["x-checkmk-version"] = cmk_version.__version__
    response.headers["x-checkmk-edition"] = cmk_version.edition().short
Esempio n. 3
0
def get_url_raw(url, insecure, auth=None, data=None, files=None, timeout=None):
    response = requests.post(
        url,
        data=data,
        verify=not insecure,
        auth=auth,
        files=files,
        timeout=timeout,
        headers={
            "x-checkmk-version": cmk_version.__version__,
            "x-checkmk-edition": cmk_version.edition().short,
        },
    )

    response.encoding = "utf-8"  # Always decode with utf-8

    if response.status_code == 401:
        raise MKUserError("_passwd",
                          _("Authentication failed. Invalid login/password."))

    if response.status_code == 503 and "Site Not Started" in response.text:
        raise MKUserError(None, _("Site is not running"))

    if response.status_code != 200:
        raise MKUserError(
            None,
            _("HTTP Error - %d: %s") % (response.status_code, response.text))

    _verify_compatibility(response)

    return response
Esempio n. 4
0
def test_is_enterprise_edition(
    monkeypatch,
    omd_version_str: str,
    expected: cmk_version.Edition,
) -> None:
    monkeypatch.setattr(cmk_version, "omd_version", lambda: omd_version_str)
    assert cmk_version.edition() is expected
Esempio n. 5
0
 def _verify_compatibility(self) -> None:
     central_version = request.headers.get("x-checkmk-version", "")
     central_edition_short = request.headers.get("x-checkmk-edition", "")
     if not compatible_with_central_site(
             central_version,
             central_edition_short,
             cmk_version.__version__,
             cmk_version.edition().short,
     ):
         raise MKGeneralException(
             _("Your central site (Version: %s, Edition: %s) is incompatible with this "
               "remote site (Version: %s, Edition: %s)") % (
                   central_version,
                   central_edition_short,
                   cmk_version.__version__,
                   cmk_version.edition().short,
               ))
Esempio n. 6
0
    def page(self):
        if not user.may("wato.automation"):
            raise MKAuthException(
                _("This account has no permission for automation."))

        response.set_content_type("text/plain")
        _set_version_headers()

        # Parameter was added with 1.5.0p10
        if not request.has_var("_version"):
            raise MKGeneralException(
                _("Your central site is incompatible with this remote site"))

        # - _version and _edition_short were added with 1.5.0p10 to the login call only
        # - x-checkmk-version and x-checkmk-edition were added with 2.0.0p1
        # Prefer the headers and fall back to the request variables for now.
        central_version = (request.headers["x-checkmk-version"]
                           if "x-checkmk-version" in request.headers else
                           request.get_ascii_input_mandatory("_version"))
        central_edition_short = (
            request.headers["x-checkmk-edition"]
            if "x-checkmk-edition" in request.headers else
            request.get_ascii_input_mandatory("_edition_short"))

        if not compatible_with_central_site(
                central_version,
                central_edition_short,
                cmk_version.__version__,
                cmk_version.edition().short,
        ):
            raise MKGeneralException(
                _("Your central site (Version: %s, Edition: %s) is incompatible with this "
                  "remote site (Version: %s, Edition: %s)") % (
                      central_version,
                      central_edition_short,
                      cmk_version.__version__,
                      cmk_version.edition().short,
                  ))

        response.set_data(
            repr({
                "version": cmk_version.__version__,
                "edition_short": cmk_version.edition().short,
                "login_secret": _get_login_secret(create_on_demand=True),
            }))
Esempio n. 7
0
def do_site_login(site_id: SiteId, name: UserId, password: str) -> str:
    sites = SiteManagementFactory().factory().load_sites()
    site = sites[site_id]
    if not name:
        raise MKUserError(
            "_name",
            _("Please specify your administrator login on the remote site."))
    if not password:
        raise MKUserError("_passwd", _("Please specify your password."))

    # Trying basic auth AND form based auth to ensure the site login works.
    # Adding _ajaxid makes the web service fail silently with an HTTP code and
    # not output HTML code for an error screen.
    url = site["multisiteurl"] + "login.py"
    post_data = {
        "_login":
        "******",
        "_username":
        name,
        "_password":
        password,
        "_origtarget":
        "automation_login.py?_version=%s&_edition_short=%s" %
        (cmk_version.__version__, cmk_version.edition().short),
        "_plain_error":
        "1",
    }
    response = get_url(url,
                       site.get("insecure", False),
                       auth=(name, password),
                       data=post_data).strip()
    if "<html>" in response.lower():
        message = _("Authentication to web service failed.<br>Message:<br>%s"
                    ) % escaping.strip_tags(escaping.strip_scripts(response))
        if config.debug:
            message += "<br>" + _("Automation URL:") + " <tt>%s</tt><br>" % url
        raise MKAutomationException(message)
    if not response:
        raise MKAutomationException(_("Empty response from web service"))
    try:
        eval_response = ast.literal_eval(response)
    except SyntaxError:
        raise MKAutomationException(response)
    if isinstance(eval_response, dict):
        if cmk_version.is_managed_edition(
        ) and eval_response["edition_short"] != "cme":
            raise MKUserError(
                None,
                _("The Check_MK Managed Services Edition can only "
                  "be connected with other sites using the CME."),
            )
        return eval_response["login_secret"]
    return eval_response
Esempio n. 8
0
def _execute_check(
    parsed_sections_broker: ParsedSectionsBroker,
    host_config: config.HostConfig,
    ipaddress: Optional[HostAddress],
    service: ConfiguredService,
    *,
    dry_run: bool,
    show_perfdata: bool,
    value_store_manager: value_store.ValueStoreManager,
) -> bool:
    plugin = agent_based_register.get_check_plugin(service.check_plugin_name)
    submittable = get_aggregated_result(
        parsed_sections_broker,
        host_config,
        ipaddress,
        service,
        plugin,
        value_store_manager=value_store_manager,
        persist_value_store_changes=not dry_run,
    )
    if submittable.submit:
        _submit_to_core.check_result(
            host_name=host_config.hostname,
            service_name=service.description,
            result=submittable.result,
            cache_info=submittable.cache_info,
            submitter=_submit_to_core.get_submitter(
                check_submission=config.check_submission,
                monitoring_core=config.monitoring_core,
                dry_run=dry_run,
                keepalive=get_keepalive(cmk_version.edition()),
            ),
            show_perfdata=show_perfdata,
            perfdata_format="pnp"
            if config.perfdata_format == "pnp" else "standard",
        )
    else:
        console.verbose(
            f"{service.description:20} PEND - {submittable.result.output}\n")
    return submittable.data_received
Esempio n. 9
0
def search(param):
    """Display some version information"""
    if request.args.get("fail"):
        raise Exception("This is an intentional failure.")
    return constructors.serve_json({
        "site":
        omd_site(),
        "group":
        request.environ.get("mod_wsgi.application_group", "unknown"),
        "rest_api": {
            "revision": "0",
        },
        "versions": {
            "apache": request.environ.get("apache.version", "unknown"),
            "checkmk": cmk_version.omd_version(),
            "python": sys.version,
            "mod_wsgi": request.environ.get("mod_wsgi.version", "unknown"),
            "wsgi": request.environ["wsgi.version"],
        },
        "edition":
        cmk_version.edition().short,
        "demo":
        cmk_version.is_free_edition(),
    })
Esempio n. 10
0
 def execute(self, _unused_request: None) -> Dict[str, str]:
     return {
         "version": cmk_version.__version__,
         "edition": cmk_version.edition().short,
     }