Ejemplo n.º 1
0
def acknowledge_werks(werks, check_permission=True):
    if check_permission:
        user.need_permission("general.acknowledge_werks")

    ack_ids = load_acknowledgements()
    for werk in werks:
        ack_ids.append(werk["id"])
        werk["compatible"] = "incomp_ack"
    save_acknowledgements(ack_ids)
Ejemplo n.º 2
0
def load_tag_config() -> TagConfig:
    """Load the tag config object based upon the most recently saved tag config file"""
    # This sometimes gets called on import-time where we don't have a request-context yet, so we
    # have to omit on checking the permissions there.
    if user:
        user.need_permission("wato.hosttags")  # see cmk.gui.wato.pages.tags
    tag_config = cmk.utils.tags.TagConfig.from_config(
        TagConfigFile().load_for_modification())
    return tag_config
Ejemplo n.º 3
0
def list_groups(params):
    """Show all service groups"""
    user.need_permission("wato.groups")
    collection = [{
        "id": k,
        "alias": v["alias"]
    } for k, v in load_service_group_information().items()]
    return constructors.serve_json(
        serialize_group_list("service_group_config", collection))
Ejemplo n.º 4
0
def _check_permissions(api_call: APICallDefinitionDict) -> None:
    if not user.get_attribute("automation_secret"):
        raise MKAuthException("The API is only available for automation users")

    if not active_config.wato_enabled:
        raise MKUserError(None, _("Setup is disabled on this site."))

    for permission in ["wato.use", "wato.api_allowed"] + api_call.get(
            "required_permissions", []):
        user.need_permission(permission)
Ejemplo n.º 5
0
def update(params):
    """Update a contact group"""
    user.need_permission("wato.edit")
    name = params["name"]
    group = fetch_group(name, "contact")
    constructors.require_etag(constructors.etag_of_dict(group))
    edit_group(name, "contact",
               updated_group_details(name, "contact", params["body"]))
    group = fetch_group(name, "contact")
    return serve_group(group, serialize_group("contact_group_config"))
Ejemplo n.º 6
0
def show_time_period(params):
    """Show a time period"""
    user.need_permission("wato.timeperiods")
    name = params["name"]
    time_periods = load_timeperiods()
    if name not in time_periods:
        raise ProblemException(404, http.client.responses[404],
                               f"Time period {name} not found")
    time_period = time_periods[name]
    return _serve_time_period(_to_api_format(time_period, name == "24X7"))
Ejemplo n.º 7
0
    def page(self):
        user.need_permission("wato.services")

        job_status_snapshot = self._job.get_status_snapshot()
        if job_status_snapshot.is_active():
            html.show_message(
                _('Bulk discovery currently running in <a href="%s">background</a>.'
                  ) % self._job.detail_url())
            return

        self._show_start_form()
Ejemplo n.º 8
0
def create(params):
    """Create a contact group"""
    user.need_permission("wato.edit")
    body = params["body"]
    name = body["name"]
    group_details = {"alias": body.get("alias")}
    if version.is_managed_edition():
        group_details = update_customer_info(group_details, body["customer"])
    add_group(name, "contact", group_details)
    group = fetch_group(name, "contact")
    return serve_group(group, serialize_group("contact_group_config"))
Ejemplo n.º 9
0
def list_users(params):
    """Show all users"""
    user.need_permission("wato.users")
    users = []
    for user_id, attrs in userdb.load_users(False).items():
        user_attributes = _internal_to_api_format(attrs)
        users.append(
            serialize_user(user_id, complement_customer(user_attributes)))

    return constructors.serve_json(
        constructors.collection_object(domain_type="user_config", value=users))
Ejemplo n.º 10
0
def bulk_update(params):
    """Bulk update folders

    Please be aware that when doing bulk updates, it is not possible to prevent the
    [Updating Values]("lost update problem"), which is normally prevented by the ETag locking
    mechanism. Use at your own risk
    """
    user.need_permission("wato.edit")
    user.need_permission("wato.edit_folders")
    body = params["body"]
    entries = body["entries"]
    folders = []

    faulty_folders = []

    for update_details in entries:
        folder = update_details["folder"]
        current_title = folder.title()
        title = update_details.get("title", current_title)
        replace_attributes = update_details["attributes"]
        update_attributes = update_details["update_attributes"]
        remove_attributes = update_details["remove_attributes"]
        attributes = folder.attributes().copy()

        if replace_attributes:
            attributes = replace_attributes

        if update_attributes:
            attributes.update(update_attributes)

        faulty_attempt = False
        for attribute in remove_attributes:
            try:
                attributes.pop(attribute)
            except KeyError:
                faulty_attempt = True
                break

        if faulty_attempt:
            faulty_folders.append(current_title)
            continue

        folder.edit(title, attributes)
        folders.append(folder)

    if faulty_folders:
        return problem(
            status=400,
            title="Some folders were not updated",
            detail=
            f"The following folders were not updated since some of the provided remove attributes did not exist: {', '.join(faulty_folders)}",
        )

    return constructors.serve_json(_folders_collection(folders, False))
Ejemplo n.º 11
0
def show_user(params):
    """Show a user"""
    user.need_permission("wato.users")
    username = params["username"]
    try:
        return serve_user(username)
    except KeyError:
        return problem(
            404,
            f"User '{username}' is not known.",
            "The user you asked for is not known. Please check for eventual misspellings.",
        )
Ejemplo n.º 12
0
def delete(params):
    """Delete a time period"""
    user.need_permission("wato.edit")
    user.need_permission("wato.timeperiods")
    name = params["name"]
    time_periods = load_timeperiods()
    if name not in time_periods:
        raise ProblemException(404, http.client.responses[404],
                               f"Time period {name} not found")
    del time_periods[name]
    save_timeperiods(time_periods)
    return Response(status=204)
Ejemplo n.º 13
0
    def page(self):
        user.need_permission("general.see_crash_reports")

        filename = "Checkmk_Crash_%s_%s_%s.tar.gz" % (
            urlencode(self._site_id),
            urlencode(self._crash_id),
            time.strftime("%Y-%m-%d_%H-%M-%S"),
        )

        response.headers["Content-Disposition"] = "Attachment; filename=%s" % filename
        response.headers["Content-Type"] = "application/x-tar"
        response.set_data(_pack_crash_report(self._get_serialized_crash_report()))
Ejemplo n.º 14
0
def get_bi_rule(params):
    """Show a BI rule"""
    user.need_permission("wato.bi_rules")
    bi_packs = get_cached_bi_packs()
    bi_packs.load_config()
    try:
        bi_rule = bi_packs.get_rule_mandatory(params["rule_id"])
    except MKGeneralException:
        _bailout_with_message("Unknown bi_rule: %s" % params["rule_id"])

    data = {"pack_id": bi_rule.pack_id}
    data.update(BIRuleSchema().dump(bi_rule))
    return constructors.serve_json(data)
Ejemplo n.º 15
0
def create_host(params):
    """Create a host"""
    user.need_permission("wato.edit")
    body = params["body"]
    host_name = body["host_name"]
    folder: CREFolder = body["folder"]

    # is_cluster is defined as "cluster_hosts is not None"
    folder.create_hosts([(host_name, body["attributes"], None)],
                        bake_hosts=params[BAKE_AGENT_PARAM_NAME])

    host = Host.load_host(host_name)
    return _serve_host(host, False)
Ejemplo n.º 16
0
def update_tag_config(tag_config: TagConfig):
    """Persist the tag config saving the information to the mk file
    and update the current environment

    Args:
        tag_config:
            The tag config object to persist

    """
    if user:
        user.need_permission("wato.hosttags")
    TagConfigFile().save(tag_config.get_dict_format())
    _update_tag_dependencies()
Ejemplo n.º 17
0
def get_bi_aggregation(params):
    """Get a BI aggregation"""
    user.need_permission("wato.bi_rules")
    bi_packs = get_cached_bi_packs()
    bi_packs.load_config()
    try:
        bi_aggregation = bi_packs.get_aggregation_mandatory(params["aggregation_id"])
    except MKGeneralException:
        _bailout_with_message("Unknown bi_aggregation: %s" % params["aggregation_id"])

    data = {"pack_id": bi_aggregation.pack_id}
    data.update(BIAggregationSchema().dump(bi_aggregation))
    return constructors.serve_json(data)
Ejemplo n.º 18
0
def bulk_update(params):
    """Bulk update service groups

    Please be aware that when doing bulk updates, it is not possible to prevent the
    [Updating Values]("lost update problem"), which is normally prevented by the ETag locking
    mechanism. Use at your own risk.
    """
    user.need_permission("wato.edit")
    body = params["body"]
    entries = body["entries"]
    updated_service_groups = update_groups("service", entries)
    return constructors.serve_json(
        serialize_group_list("service_group_config", updated_service_groups))
Ejemplo n.º 19
0
def check_modify_group_permissions(group_type: GroupType) -> None:
    required_permissions = {
        "contact": ["wato.users"],
        "host": ["wato.groups"],
        "service": ["wato.groups"],
    }

    # Check permissions
    perms = required_permissions.get(group_type)
    if perms is None:
        raise Exception("invalid group type %r" % (group_type, ))
    for permission in perms:
        user.need_permission(permission)
Ejemplo n.º 20
0
    def page(self):
        check_csrf_token()
        user.need_permission("wato.activate")

        api_request = self.webapi_request()
        # ? type of activate_until is unclear
        activate_until = api_request.get("activate_until")
        if not activate_until:
            raise MKUserError("activate_until",
                              _('Missing parameter "%s".') % "activate_until")

        manager = activate_changes.ActivateChangesManager()
        manager.load()
        # ? type of api_request is unclear
        affected_sites_request = ensure_str(  # pylint: disable= six-ensure-str-bin-call
            api_request.get("sites", "").strip())
        if not affected_sites_request:
            affected_sites = manager.dirty_and_active_activation_sites()
        else:
            affected_sites = [
                SiteId(s) for s in affected_sites_request.split(",")
            ]

        comment: Optional[str] = api_request.get("comment", "").strip()

        activate_foreign = api_request.get("activate_foreign", "0") == "1"

        valuespec = _vs_activation("", manager.has_foreign_changes())
        if valuespec:
            valuespec.validate_value(
                {
                    "comment": comment,
                    "foreign": activate_foreign,
                },
                "activate",
            )

        if comment == "":
            comment = None

        activation_id = manager.start(
            sites=affected_sites,
            activate_until=ensure_str(activate_until),  # pylint: disable= six-ensure-str-bin-call
            comment=comment,
            activate_foreign=activate_foreign,
        )

        return {
            "activation_id": activation_id,
        }
Ejemplo n.º 21
0
def create_timeperiod(params):
    """Create a time period"""
    user.need_permission("wato.edit")
    user.need_permission("wato.timeperiods")
    body = params["body"]
    name = body["name"]
    exceptions = _format_exceptions(body.get("exceptions", []))
    periods = _daily_time_ranges(body["active_time_ranges"])
    time_period = _to_checkmk_format(alias=body["alias"],
                                     periods=periods,
                                     exceptions=exceptions,
                                     exclude=body.get("exclude", []))
    save_timeperiod(name, time_period)
    return _serve_time_period(_to_api_format(load_timeperiod(name)))
Ejemplo n.º 22
0
def delete_password(params):
    """Delete a password"""
    user.need_permission("wato.edit")
    user.need_permission("wato.passwords")
    ident = params["name"]
    if ident not in load_passwords():
        return problem(
            status=404,
            title='Password "{ident}" is not known.',
            detail=
            "The password you asked for is not known. Please check for eventual misspellings.",
        )
    remove_password(ident)
    return Response(status=204)
Ejemplo n.º 23
0
def bulk_delete(params):
    """Bulk delete service groups"""
    user.need_permission("wato.edit")
    body = params["body"]
    entries = body["entries"]
    for group_name in entries:
        _group = fetch_group(group_name,
                             "service",
                             status=400,
                             message="service group %s was not found" %
                             group_name)
    for group_name in entries:
        groups.delete_group(group_name, group_type="service")
    return Response(status=204)
Ejemplo n.º 24
0
def show_password(params):
    """Show a password"""
    user.need_permission("wato.passwords")
    ident = params["name"]
    passwords = load_passwords()
    if ident not in passwords:
        return problem(
            status=404,
            title=f'Password "{ident}" is not known.',
            detail=
            "The password you asked for is not known. Please check for eventual misspellings.",
        )
    password_details = passwords[ident]
    return _serve_password(ident, password_details)
Ejemplo n.º 25
0
    def action(self) -> ActionResult:
        folder = Folder.current()
        if not transactions.check_transaction():
            return redirect(mode_url("folder", folder=folder.path()))

        if request.var("_update_dns_cache") and self._should_use_dns_cache():
            user.need_permission("wato.update_dns_cache")
            update_dns_cache_result = update_dns_cache(self._host.site_id())
            infotext = (_("Successfully updated IP addresses of %d hosts.") %
                        update_dns_cache_result.n_updated)
            if update_dns_cache_result.failed_hosts:
                infotext += "<br><br><b>Hostnames failed to lookup:</b> " + ", ".join(
                    [
                        "<tt>%s</tt>" % h
                        for h in update_dns_cache_result.failed_hosts
                    ])
            flash(infotext)
            return None

        if request.var("delete"):  # Delete this host
            folder.delete_hosts([self._host.name()], automation=delete_hosts)
            return redirect(mode_url("folder", folder=folder.path()))

        if request.var("_remove_tls_registration"):
            remove_tls_registration(
                {self._host.site_id(): [self._host.name()]})
            return None

        attributes = collect_attributes(
            "host" if not self._is_cluster() else "cluster", new=False)
        host = Host.host(self._host.name())
        if host is None:
            flash(f"Host {self._host.name()} could not be found.")
            return None

        host.edit(attributes, self._get_cluster_nodes())
        self._host = folder.load_host(self._host.name())

        if request.var("_save"):
            return redirect(
                mode_url("inventory",
                         folder=folder.path(),
                         host=self._host.name()))
        if request.var("diag_host"):
            return redirect(
                mode_url("diag_host",
                         folder=folder.path(),
                         host=self._host.name(),
                         _start_on_load="1"))
        return redirect(mode_url("folder", folder=folder.path()))
Ejemplo n.º 26
0
def add_service_comment(
    connection,
    host_name: str,
    service_description: str,
    comment: str,
    persistent: bool = False,
    user: str = "",
):
    """Add service comment

    Args:
        connection:
            A livestatus connection object

        host_name:
            The host-name where the service is located

        service_description:
            The service description for which the comment is for

        comment:
            The comment which will be stored for the service

        persistent:
            If set, the comment will persist across program restarts until it is deleted manually.
            If not set, the comment will be deleted the next time the Core is restarted.

        user:

    Examples:
        >>> from cmk.gui.livestatus_utils.testing import simple_expect
        >>> from cmk.gui.utils.script_helpers import application_and_request_context
        >>> from cmk.gui.logged_in import SuperUserContext
        >>> from cmk.gui.config import load_config

        >>> cmd = "COMMAND [...] ADD_SVC_COMMENT;example.com;CPU Load;0;;test"
        >>> expect = simple_expect(cmd, match_type="ellipsis")
        >>> with expect as live, application_and_request_context(), SuperUserContext():
        ...     load_config()
        ...     add_service_comment(live, 'example.com', 'CPU Load', 'test')


    """
    _user.need_permission("action.addcomment")

    return send_command(
        connection,
        "ADD_SVC_COMMENT",
        [host_name, service_description, int(persistent), user, comment],
    )
Ejemplo n.º 27
0
    def page(self):
        user.need_permission("wato.activate")

        api_request = self.webapi_request()

        activation_id = api_request.get("activation_id")
        if not activation_id:
            raise MKUserError("activation_id", _('Missing parameter "%s".') % "activation_id")

        manager = watolib.ActivateChangesManager()
        manager.load()
        manager.load_activation(activation_id)

        return manager.get_state()
Ejemplo n.º 28
0
def _schedule_downtime(
    sites,
    command: LivestatusCommand,
    site_id,
    host_or_group: str,
    service_description: Optional[str],
    start_time: dt.datetime,
    end_time: dt.datetime,
    recur: RecurMode = "fixed",
    trigger_id: int = 0,
    duration: int = 0,
    user_id: str = "",
    comment: str = "",
):
    """Unified low level function

    See:
     * schedule_host_downtime
     * schedule_service_downtime
    """
    # TODO: provide reference documents for recurring magic numbers
    _user.need_permission("action.downtimes")

    recur_mode = _recur_mode(recur, duration)

    if command == "SCHEDULE_HOST_DOWNTIME":
        params = [host_or_group]
    elif command == "SCHEDULE_SVC_DOWNTIME":
        if not service_description:
            raise ValueError("Service description necessary.")
        params = [host_or_group, service_description]
    else:
        raise ValueError(f"Unsupported command: {command}")

    return send_command(
        sites,
        command,
        [
            *params,
            to_timestamp(start_time),
            to_timestamp(end_time),
            recur_mode,
            trigger_id,
            duration,
            user_id,
            comment.replace("\n", ""),
        ],
        site_id,
    )
Ejemplo n.º 29
0
def create_cluster_host(params):
    """Create a cluster host

    A cluster host groups many hosts (called nodes in this context) into a conceptual cluster.
    All the services of the individual nodes will be collated on the cluster host."""
    user.need_permission("wato.edit")
    body = params["body"]
    host_name = body["host_name"]
    folder: CREFolder = body["folder"]

    folder.create_hosts([(host_name, body["attributes"], body["nodes"])],
                        bake_hosts=params[BAKE_AGENT_PARAM_NAME])

    host = Host.load_host(host_name)
    return _serve_host(host, effective_attributes=False)
Ejemplo n.º 30
0
def bulk_create(params):
    """Bulk create host groups"""
    user.need_permission("wato.edit")
    body = params["body"]
    entries = body["entries"]
    contact_group_details = prepare_groups("contact", entries)

    contact_group_names = []
    for group_name, group_details in contact_group_details.items():
        add_group(group_name, "contact", group_details)
        contact_group_names.append(group_name)

    contact_groups = fetch_specific_groups(contact_group_names, "contact")
    return constructors.serve_json(
        serialize_group_list("contact_group_config", contact_groups))