Beispiel #1
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),
                }
            )
        )
Beispiel #2
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))

    return response
Beispiel #3
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()
Beispiel #4
0
def _get_generic_crash_info(type_name, details):
    # type: (Text, Dict) -> Dict
    """Produces the crash info data structure.

    The top level keys of the crash info dict are standardized and need
    to be set for all crash reports."""
    exc_type, exc_value, exc_traceback = sys.exc_info()

    tb_list = traceback.extract_tb(exc_traceback)

    # TODO: This ma be cleaned up by using reraising with python 3
    # MKParseFunctionError() are re raised exceptions originating from the
    # parse functions of checks. They have the original traceback object saved.
    # The formated stack of these tracebacks is somehow relative to the calling
    # function. To get the full stack trace instead of this relative one we need
    # to concatenate the traceback of the MKParseFunctionError() and the original
    # exception.
    # Re-raising exceptions will be much easier with Python 3.x.
    if exc_type and exc_value and exc_type.__name__ == "MKParseFunctionError":
        tb_list += traceback.extract_tb(exc_value.exc_info()[2])  # type: ignore[attr-defined]

    # Unify different string types from exception messages to a unicode string
    # HACK: copy-n-paste from cmk.utils.exception.MKException.__str__ below.
    # Remove this after migration...
    if exc_value is None or not exc_value.args:
        exc_txt = six.text_type("")
    elif len(exc_value.args) == 1 and isinstance(exc_value.args[0], six.binary_type):
        try:
            exc_txt = exc_value.args[0].decode("utf-8")
        except UnicodeDecodeError:
            exc_txt = u"b%s" % repr(exc_value.args[0])
    elif len(exc_value.args) == 1:
        exc_txt = six.text_type(exc_value.args[0])
    else:
        exc_txt = six.text_type(exc_value.args)

    return {
        "id": str(uuid.uuid1()),
        "crash_type": type_name,
        "time": time.time(),
        "os": _get_os_info(),
        "version": cmk_version.__version__,
        "edition": cmk_version.edition_short(),
        "core": _current_monitoring_core(),
        "python_version": sys.version,
        "python_paths": sys.path,
        "exc_type": exc_type.__name__ if exc_type else None,
        "exc_value": exc_txt,
        # Py3: Make traceback.FrameSummary serializable
        "exc_traceback": [tuple(e) for e in tb_list],
        "local_vars": _get_local_vars_of_last_exception(),
        "details": details,
    }
Beispiel #5
0
def do_site_login(site_id, name, password):
    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)
    elif not response:
        raise MKAutomationException(_("Empty response from web service"))
    else:
        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
Beispiel #6
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(),
             )
         )
Beispiel #7
0
def search(param):
    if request.args.get('fail'):
        raise Exception("This is an intentional failure.")
    return {
        "site": cmk_version.omd_site(),
        "group": request.environ.get('mod_wsgi.application_group', 'unknown'),
        "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_demo(),
    }
Beispiel #8
0
    def page(self):
        if not config.user.may("wato.automation"):
            raise MKAuthException(_("This account has no permission for automation."))

        html.set_output_format("python")

        if not html.request.has_var("_version"):
            # Be compatible to calls from sites using versions before 1.5.0p10.
            # Deprecate with 1.7 by throwing an exception in this situation.
            response = _get_login_secret(create_on_demand=True)
        else:
            response = {
                "version": cmk_version.__version__,
                "edition_short": cmk_version.edition_short(),
                "login_secret": _get_login_secret(create_on_demand=True),
            }
        html.write_html(repr(response))
Beispiel #9
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")

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

        response.set_data(
            repr({
                "version": cmk_version.__version__,
                "edition_short": cmk_version.edition_short(),
                "login_secret": _get_login_secret(create_on_demand=True),
            }))
Beispiel #10
0
    def page(self):
        if not config.user.may("wato.automation"):
            raise MKAuthException(_("This account has no permission for automation."))

        response.set_content_type("text/plain")

        if not request.has_var("_version"):
            # Be compatible to calls from sites using versions before 1.5.0p10.
            # Deprecate with 1.7 by throwing an exception in this situation.
            resp = _get_login_secret(create_on_demand=True)
        else:
            resp = {
                "version": cmk_version.__version__,
                "edition_short": cmk_version.edition_short(),
                "login_secret": _get_login_secret(create_on_demand=True),
            }

        response.set_data(repr(resp))
Beispiel #11
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": cmk_version.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(),
    })
Beispiel #12
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(),
    })
Beispiel #13
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,
            )
        )
Beispiel #14
0
 def execute(self, _unused_request: None) -> Dict[str, str]:
     return {
         "version": cmk_version.__version__,
         "edition": cmk_version.edition_short(),
     }
Beispiel #15
0
 def execute(self, _unused_request):
     # type: (None) -> Dict[str, Union[str, Text]]
     return {
         "version": cmk_version.__version__,
         "edition": cmk_version.edition_short(),
     }
Beispiel #16
0
 def execute(self, _unused_request):
     return {
         "version": cmk_version.__version__,
         "edition": cmk_version.edition_short(),
     }