Exemple #1
0
    def action(self) -> ActionResult:
        varname = html.request.var("_varname")
        if not varname:
            return None

        action = html.request.var("_action")

        config_variable = config_variable_registry[varname]()
        def_value = self._default_values[varname]

        if not html.check_transaction():
            return None

        if varname in self._current_settings:
            self._current_settings[
                varname] = not self._current_settings[varname]
        else:
            self._current_settings[varname] = not def_value
        msg = _("Changed Configuration variable %s to %s.") % (
            varname, "on" if self._current_settings[varname] else "off")
        watolib.save_global_settings(self._current_settings)

        watolib.add_change("edit-configvar",
                           msg,
                           domains=[config_variable.domain()],
                           need_restart=config_variable.need_restart())

        if action == "_reset":
            flash(msg)
        return redirect(mode_url("globalvars"))
Exemple #2
0
    def action(self):
        delname = html.request.var("_delete")
        if delname and html.transaction_valid():
            if delname in watolib.timeperiods.builtin_timeperiods():
                raise MKUserError("_delete",
                                  _("Builtin timeperiods can not be modified"))

            usages = self._find_usages_of_timeperiod(delname)
            if usages:
                message = "<b>%s</b><br>%s:<ul>" % \
                            (_("You cannot delete this timeperiod."),
                             _("It is still in use by"))
                for title, link in usages:
                    message += '<li><a href="%s">%s</a></li>\n' % (link, title)
                message += "</ul>"
                raise MKUserError(None, message)

            c = wato_confirm(
                _("Confirm deletion of time period %s") % delname,
                _("Do you really want to delete the time period '%s'? I've checked it: "
                  "it is not being used by any rule or user profile right now."
                  ) % delname)
            if c:
                del self._timeperiods[delname]
                watolib.timeperiods.save_timeperiods(self._timeperiods)
                watolib.add_change("edit-timeperiods",
                                   _("Deleted timeperiod %s") % delname)
            elif c is False:
                return ""
Exemple #3
0
    def action(self) -> ActionResult:
        if not html.check_transaction():
            return redirect(self.mode_url())

        if html.request.var("_delete"):
            delid = html.request.get_ascii_input_mandatory("_delete")

            if delid not in self._roles:
                raise MKUserError(None, _("This role does not exist."))

            if html.transaction_valid() and self._roles[delid].get('builtin'):
                raise MKUserError(None,
                                  _("You cannot delete the builtin roles!"))

            users = userdb.load_users()
            for user in users.values():
                if delid in user["roles"]:
                    raise MKUserError(
                        None,
                        _("You cannot delete roles, that are still in use (%s)!"
                          % delid))

            self._rename_user_role(delid, None)  # Remove from existing users
            del self._roles[delid]
            self._save_roles()
            watolib.add_change("edit-roles",
                               _("Deleted role '%s'") % delid,
                               sites=config.get_login_sites())

        elif html.request.var("_clone"):
            cloneid = html.request.get_ascii_input_mandatory("_clone")

            try:
                cloned_role = self._roles[cloneid]
            except KeyError:
                raise MKUserError(None, _("This role does not exist."))

            newid = cloneid
            while newid in self._roles:
                newid += "x"

            new_role = {}
            new_role.update(cloned_role)

            new_alias = new_role["alias"]
            while not watolib.is_alias_used("roles", newid, new_alias)[0]:
                new_alias += _(" (copy)")
            new_role["alias"] = new_alias

            if cloned_role.get("builtin"):
                new_role["builtin"] = False
                new_role["basedon"] = cloneid

            self._roles[newid] = new_role
            self._save_roles()
            watolib.add_change("edit-roles",
                               _("Created new role '%s'") % newid,
                               sites=config.get_login_sites())

        return redirect(self.mode_url())
Exemple #4
0
    def action(self) -> ActionResult:
        if html.request.var("_reset"):
            if not html.check_transaction():
                return None

            try:
                del self._current_settings[self._varname]
            except KeyError:
                pass

            msg: Union[
                HTML,
                str] = _("Resetted configuration variable %s to its default."
                         ) % self._varname
        else:
            new_value = self._valuespec.from_html_vars("ve")
            self._valuespec.validate_value(new_value, "ve")
            self._current_settings[self._varname] = new_value
            msg = _("Changed global configuration variable %s to %s.") \
                  % (self._varname, self._valuespec.value_to_text(new_value))
            # FIXME: THIS HTML(...) is needed because we do not know what we get from value_to_text!!
            msg = HTML(msg)

        self._save()
        watolib.add_change("edit-configvar",
                           msg,
                           sites=self._affected_sites(),
                           domains=[self._config_variable.domain()],
                           need_restart=self._config_variable.need_restart())

        return redirect(self._back_url())
Exemple #5
0
    def action(self) -> ActionResult:
        delname = request.var("_delete")
        if not delname:
            return redirect(mode_url("timeperiods"))

        if not transactions.check_transaction():
            return redirect(mode_url("timeperiods"))

        if delname in watolib.timeperiods.builtin_timeperiods():
            raise MKUserError("_delete",
                              _("Builtin timeperiods can not be modified"))

        usages = self._find_usages_of_timeperiod(delname)
        if usages:
            message = "<b>%s</b><br>%s:<ul>" % \
                        (_("You cannot delete this timeperiod."),
                         _("It is still in use by"))
            for title, link in usages:
                message += '<li><a href="%s">%s</a></li>\n' % (link, title)
            message += "</ul>"
            raise MKUserError(None, message)

        del self._timeperiods[delname]
        watolib.timeperiods.save_timeperiods(self._timeperiods)
        watolib.add_change("edit-timeperiods",
                           _("Deleted timeperiod %s") % delname)
        return redirect(mode_url("timeperiods"))
Exemple #6
0
    def action(self) -> ActionResult:
        if request.var("_reset"):
            if not transactions.check_transaction():
                return None

            try:
                del self._current_settings[self._varname]
            except KeyError:
                pass

            msg = escape_html_permissive(
                _("Resetted configuration variable %s to its default.") %
                self._varname)
        else:
            new_value = self._valuespec.from_html_vars("ve")
            self._valuespec.validate_value(new_value, "ve")
            self._current_settings[self._varname] = new_value
            msg = HTML(
                _("Changed global configuration variable %s to %s.") % (
                    escaping.escape_attribute(self._varname),
                    self._valuespec.value_to_html(new_value),
                ))

        self._save()
        watolib.add_change(
            "edit-configvar",
            msg,
            sites=self._affected_sites(),
            domains=[self._config_variable.domain()],
            need_restart=self._config_variable.need_restart(),
        )

        return redirect(self._back_url())
Exemple #7
0
 def _add_change(self, action, entry, text):
     # type: (str, Dict, Text) -> None
     """Add a WATO change entry for this object type modifications"""
     watolib.add_change("%s-%s" % (action, self._mode_type.type_name()),
                        text,
                        domains=self._mode_type.affected_config_domains(),
                        sites=self._mode_type.affected_sites(entry))
Exemple #8
0
def create_rule(param):
    """Create rule"""
    body = param["body"]
    folder = body["folder"]
    value = body["value_raw"]
    rulesets = watolib.FolderRulesets(folder)
    rulesets.load()
    try:
        ruleset = rulesets.get(body["ruleset"])
    except KeyError:
        return problem(
            status=400,
            detail=f"Ruleset {body['ruleset']!r} could not be found.",
        )

    try:
        ruleset.valuespec().validate_value(value, "")
    except exceptions.MKUserError as exc:
        if exc.varname is None:
            title = "A field has a problem"
        else:
            field_name = exc.varname.replace("_p_", "")
            title = f"Problem in (sub-)field {field_name!r}"

        return problem(
            status=400,
            detail=strip_tags(exc.message),
            title=title,
        )

    rule = watolib.Rule(
        gen_id(),
        folder,
        ruleset,
        RuleConditions(
            host_folder=folder,
            host_tags=body["conditions"].get("host_tag"),
            host_labels=body["conditions"].get("host_label"),
            host_name=body["conditions"].get("host_name"),
            service_description=body["conditions"].get("service_description"),
            service_labels=body["conditions"].get("service_label"),
        ),
        RuleOptions.from_config(body["properties"]),
        value,
    )
    index = ruleset.append_rule(folder, rule)
    rulesets.save()
    # TODO Duplicated code is in pages/rulesets.py:2670-
    # TODO Move to watolib
    add_change(
        "new-rule",
        _l('Created new rule #%d in ruleset "%s" in folder "%s"')
        % (index, ruleset.title(), folder.alias_path()),
        sites=folder.all_site_ids(),
        diff_text=make_diff_text({}, rule.to_log()),
        object_ref=rule.object_ref(),
    )
    return serve_json(_serialize_rule(folder, index, rule))
Exemple #9
0
    def action(self) -> ActionResult:
        if html.form_submitted("search"):
            return None

        alias = html.request.get_unicode_input("alias")

        unique, info = watolib.is_alias_used("roles", self._role_id, alias)
        if not unique:
            raise MKUserError("alias", info)

        new_id = html.request.get_ascii_input_mandatory("id")
        if not new_id:
            raise MKUserError("id", "You have to provide a ID.")
        if not re.match("^[-a-z0-9A-Z_]*$", new_id):
            raise MKUserError(
                "id", _("Invalid role ID. Only the characters a-z, A-Z, 0-9, _ and - are allowed."))
        if new_id != self._role_id:
            if new_id in self._roles:
                raise MKUserError("id", _("The ID is already used by another role"))

        self._role["alias"] = alias

        # based on
        if not self._role.get("builtin"):
            basedon = html.request.get_ascii_input_mandatory("basedon")
            if basedon not in config.builtin_role_ids:
                raise MKUserError("basedon",
                                  _("Invalid valid for based on. Must be id of builtin rule."))
            self._role["basedon"] = basedon

        # Permissions
        permissions = self._role["permissions"]
        for var_name, value in html.request.itervars(prefix="perm_"):
            try:
                perm = permission_registry[var_name[5:]]
            except KeyError:
                continue

            if value == "yes":
                permissions[perm.name] = True
            elif value == "no":
                permissions[perm.name] = False
            elif value == "default":
                try:
                    del permissions[perm.name]
                except KeyError:
                    pass  # Already at defaults

        if self._role_id != new_id:
            self._roles[new_id] = self._role
            del self._roles[self._role_id]
            self._rename_user_role(self._role_id, new_id)

        self._save_roles()
        watolib.add_change("edit-roles",
                           _("Modified user role '%s'") % new_id,
                           sites=config.get_login_sites())
        return redirect(mode_url("roles"))
Exemple #10
0
    def _move_tag_group(self):
        move_nr = html.get_integer_input("_move")
        move_to = html.get_integer_input("_index")

        moved = self._tag_config.tag_groups.pop(move_nr)
        self._tag_config.tag_groups.insert(move_to, moved)

        self._tag_config.validate_config()
        self._tag_config_file.save(self._tag_config.get_dict_format())
        watolib.add_change("edit-tags", _("Changed order of tag groups"))
Exemple #11
0
    def action(self):
        if html.request.var("_delete"):
            delid = html.request.var("_delete")

            if delid not in self._roles:
                raise MKUserError(None, _("This role does not exist."))

            if html.transaction_valid() and self._roles[delid].get('builtin'):
                raise MKUserError(None,
                                  _("You cannot delete the builtin roles!"))

            c = wato_confirm(
                _("Confirm deletion of role %s") % delid,
                _("Do you really want to delete the role %s?") % delid)
            if c:
                self._rename_user_role(delid,
                                       None)  # Remove from existing users
                del self._roles[delid]
                self._save_roles()
                watolib.add_change("edit-roles",
                                   _("Deleted role '%s'") % delid,
                                   sites=config.get_login_sites())
            elif c is False:
                return ""

        elif html.request.var("_clone"):
            if html.check_transaction():
                cloneid = html.request.var("_clone")

                try:
                    cloned_role = self._roles[cloneid]
                except KeyError:
                    raise MKUserError(None, _("This role does not exist."))

                newid = cloneid
                while newid in self._roles:
                    newid += "x"

                new_role = {}
                new_role.update(cloned_role)

                new_alias = new_role["alias"]
                while not watolib.is_alias_used("roles", newid, new_alias)[0]:
                    new_alias += _(" (copy)")
                new_role["alias"] = new_alias

                if cloned_role.get("builtin"):
                    new_role["builtin"] = False
                    new_role["basedon"] = cloneid

                self._roles[newid] = new_role
                self._save_roles()
                watolib.add_change("edit-roles",
                                   _("Created new role '%s'") % newid,
                                   sites=config.get_login_sites())
    def action(self) -> ActionResult:
        if request.var("_action") != "discard":
            return None

        if not transactions.check_transaction():
            return None

        if not self._may_discard_changes():
            return None

        if not self.has_changes():
            return None

        # Now remove all currently pending changes by simply restoring the last automatically
        # taken snapshot. Then activate the configuration. This should revert all pending changes.
        file_to_restore = self._get_last_wato_snapshot_file()

        if not file_to_restore:
            raise MKUserError(None,
                              _("There is no WATO snapshot to be restored."))

        msg = _("Discarded pending changes (Restored %s)") % file_to_restore

        # All sites and domains can be affected by a restore: Better restart everything.
        watolib.add_change(
            "changes-discarded",
            msg,
            domains=watolib.ABCConfigDomain.enabled_domains(),
            need_restart=True,
        )

        self._extract_snapshot(file_to_restore)
        activate_changes.execute_activate_changes([
            d.get_domain_request([])
            for d in watolib.ABCConfigDomain.enabled_domains()
        ])

        for site_id in activation_sites():
            self.confirm_site_changes(site_id)

        build_index_background()

        html.header(
            self.title(),
            breadcrumb=self.breadcrumb(),
            show_body_start=display_options.enabled(display_options.H),
            show_top_heading=display_options.enabled(display_options.T),
        )
        html.open_div(class_="wato")

        html.show_message(_("Successfully discarded all pending changes."))
        html.javascript("hide_changes_buttons();")
        html.footer()
        return FinalizeRequest(code=200)
Exemple #13
0
 def _add_change(
     self,
     *,
     action: str,
     text: str,
     affected_sites: Optional[List[SiteId]],
 ) -> None:
     """Add a WATO change entry for this object type modifications"""
     watolib.add_change(
         "%s-%s" % (action, self._mode_type.type_name()),
         text,
         domains=self._mode_type.affected_config_domains(),
         sites=affected_sites,
     )
Exemple #14
0
    def _move_tag_group(self):
        move_nr = html.request.get_integer_input_mandatory("_move")
        move_to = html.request.get_integer_input_mandatory("_index")

        moved = self._tag_config.tag_groups.pop(move_nr)
        self._tag_config.tag_groups.insert(move_to, moved)

        try:
            self._tag_config.validate_config()
        except MKGeneralException as e:
            raise MKUserError(None, "%s" % e)
        self._tag_config_file.save(self._tag_config.get_dict_format())
        self._load_effective_config()
        watolib.add_change("edit-tags", _("Changed order of tag groups"))
    def action(self):
        if html.request.var("_action") != "discard":
            return

        if not html.check_transaction():
            return

        if not self._may_discard_changes():
            return

        # TODO: Remove once new changes mechanism has been implemented
        # Now remove all currently pending changes by simply restoring the last automatically
        # taken snapshot. Then activate the configuration. This should revert all pending changes.
        file_to_restore = self._get_last_wato_snapshot_file()

        if not file_to_restore:
            raise MKUserError(None,
                              _('There is no WATO snapshot to be restored.'))

        msg = _("Discarded pending changes (Restored %s)") % file_to_restore

        # All sites and domains can be affected by a restore: Better restart everything.
        watolib.add_change("changes-discarded",
                           msg,
                           domains=watolib.ABCConfigDomain.enabled_domains(),
                           need_restart=True)

        self._extract_snapshot(file_to_restore)
        cmk.gui.watolib.activate_changes.execute_activate_changes(
            [d.ident for d in watolib.ABCConfigDomain.enabled_domains()])

        for site_id in cmk.gui.watolib.changes.activation_sites():
            self.confirm_site_changes(site_id)

        html.header(self.title(),
                    show_body_start=display_options.enabled(display_options.H),
                    show_top_heading=display_options.enabled(
                        display_options.T))
        html.open_div(class_="wato")

        html.begin_context_buttons()
        home_button()
        html.end_context_buttons()

        html.show_message(_("Successfully discarded all pending changes."))
        html.javascript("hide_changes_buttons();")
        html.footer()

        return False
Exemple #16
0
    def action(self):
        if not html.check_transaction():
            return

        vs = self._valuespec()
        vs_spec = vs.from_html_vars("timeperiod")
        vs.validate_value(vs_spec, "timeperiod")
        self._timeperiod = self._from_valuespec(vs_spec)

        if self._name is None:
            self._name = vs_spec["name"]
            watolib.add_change("edit-timeperiods", _("Created new time period %s") % self._name)
        else:
            watolib.add_change("edit-timeperiods", _("Modified time period %s") % self._name)

        self._timeperiods[self._name] = self._timeperiod
        watolib.timeperiods.save_timeperiods(self._timeperiods)
        return "timeperiods"
Exemple #17
0
    def _set(self, request):
        tag_config_file = TagConfigFile()
        hosttags_config = cmk.utils.tags.TagConfig()
        hosttags_config.parse_config(tag_config_file.load_for_modification())

        hosttags_dict = hosttags_config.get_dict_format()
        if "configuration_hash" in request:
            validate_config_hash(request["configuration_hash"], hosttags_dict)
            del request["configuration_hash"]

        changed_hosttags_config = cmk.utils.tags.TagConfig()
        changed_hosttags_config.parse_config(request)
        changed_hosttags_config.validate_config()

        self._verify_no_used_tags_missing(changed_hosttags_config)

        tag_config_file.save(changed_hosttags_config.get_dict_format())
        watolib.add_change("edit-hosttags", _("Updated host tags through Web-API"))
Exemple #18
0
    def action(self) -> ActionResult:
        if not html.check_transaction():
            return None

        vs = self._valuespec()  # returns a Dictionary object
        vs_spec = vs.from_html_vars("timeperiod")
        vs.validate_value(vs_spec, "timeperiod")
        self._timeperiod = self._from_valuespec(vs_spec)

        if self._new:
            self._name = vs_spec["name"]
            watolib.add_change("edit-timeperiods", _("Created new time period %s") % self._name)
        else:
            watolib.add_change("edit-timeperiods", _("Modified time period %s") % self._name)

        assert self._name is not None
        self._timeperiods[self._name] = self._timeperiod
        watolib.timeperiods.save_timeperiods(self._timeperiods)
        return redirect(mode_url("timeperiods"))
Exemple #19
0
    def action(self):
        varname = html.request.var("_varname")
        if not varname:
            return

        action = html.request.var("_action")

        config_variable = config_variable_registry[varname]()
        def_value = self._default_values[varname]

        if action == "reset" and not is_a_checkbox(
                config_variable.valuespec()):
            c = wato_confirm(
                _("Resetting configuration variable"),
                _("Do you really want to reset the configuration variable <b>%s</b> "
                  "back to the default value of <b><tt>%s</tt></b>?") %
                (varname,
                 config_variable.valuespec().value_to_text(def_value)))
        else:
            if not html.check_transaction():
                return
            c = True  # no confirmation for direct toggle

        if c:
            if varname in self._current_settings:
                self._current_settings[
                    varname] = not self._current_settings[varname]
            else:
                self._current_settings[varname] = not def_value
            msg = _("Changed Configuration variable %s to %s.") % (
                varname, "on" if self._current_settings[varname] else "off")
            watolib.save_global_settings(self._current_settings)

            watolib.add_change("edit-configvar",
                               msg,
                               domains=[config_variable.domain()],
                               need_restart=config_variable.need_restart())

            if action == "_reset":
                return "globalvars", msg
            return "globalvars"
        elif c is False:
            return ""
    def action(self):
        if html.request.var("_reset"):
            if not is_a_checkbox(self._valuespec):
                c = wato_confirm(
                    _("Resetting configuration variable"),
                    _("Do you really want to reset this configuration variable "
                      "back to its default value?"))
                if c is False:
                    return ""
                if c is None:
                    return None
            elif not html.check_transaction():
                return

            try:
                del self._current_settings[self._varname]
            except KeyError:
                pass

            msg: Union[
                HTML,
                str] = _("Resetted configuration variable %s to its default."
                         ) % self._varname
        else:
            new_value = self._valuespec.from_html_vars("ve")
            self._valuespec.validate_value(new_value, "ve")
            self._current_settings[self._varname] = new_value
            msg = _("Changed global configuration variable %s to %s.") \
                  % (self._varname, self._valuespec.value_to_text(new_value))
            # FIXME: THIS HTML(...) is needed because we do not know what we get from value_to_text!!
            msg = HTML(msg)

        self._save()
        watolib.add_change("edit-configvar",
                           msg,
                           sites=self._affected_sites(),
                           domains=[self._config_variable.domain()],
                           need_restart=self._config_variable.need_restart())

        page_menu = self.parent_mode()
        assert page_menu is not None
        return page_menu.name()
Exemple #21
0
    def _set(self, request):
        tag_config_file = TagConfigFile()
        hosttags_config = cmk.utils.tags.TagConfig()
        hosttags_config.parse_config(tag_config_file.load_for_modification())

        hosttags_dict = hosttags_config.get_dict_format()
        if "configuration_hash" in request:
            validate_config_hash(request["configuration_hash"], hosttags_dict)
            del request["configuration_hash"]

        # Check for conflicts with existing configuration
        # Tags may be either specified grouped in a host/folder configuration, e.g agent/cmk-agent,
        # or specified as the plain id in rules. We need to check both variants..
        used_tags = self._get_used_grouped_tags()
        used_tags.update(self._get_used_rule_tags())

        changed_hosttags_config = cmk.utils.tags.TagConfig()
        changed_hosttags_config.parse_config(request)
        changed_hosttags_config.validate_config()

        new_tags = changed_hosttags_config.get_tag_ids()
        new_tags.update(
            changed_hosttags_config.get_tag_ids_with_group_prefix())

        # Remove the builtin hoststags from the list of used_tags
        builtin_config = cmk.utils.tags.BuiltinTagConfig()
        used_tags.discard(builtin_config.get_tag_ids_with_group_prefix())

        missing_tags = used_tags - new_tags
        if missing_tags:
            raise MKUserError(
                None,
                _("Unable to apply new hosttag configuration. The following tags "
                  "are still in use, but not mentioned in the updated "
                  "configuration: %s") % ", ".join(missing_tags))

        tag_config_file.save(changed_hosttags_config.get_dict_format())
        watolib.add_change("edit-hosttags",
                           _("Updated host tags through Web-API"))
Exemple #22
0
    def _set(self, request):
        # Py2: This encoding here should be kept Otherwise and unicode encoded text will be written
        # into the configuration file with unknown side effects
        ruleset_name = ensure_str(request["ruleset_name"])

        # Future validation, currently the rule API actions are admin only, so the check is pointless
        # may_edit_ruleset(ruleset_name)

        # Check if configuration hash has changed in the meantime
        ruleset_dict = self._get_ruleset_configuration(ruleset_name)
        if "configuration_hash" in request:
            validate_config_hash(request["configuration_hash"], ruleset_dict)

        # Check permissions of new rules and rules we are going to delete
        new_ruleset = request["ruleset"]
        folders_set_ruleset = set(new_ruleset.keys())
        folders_obsolete_ruleset = set(ruleset_dict.keys()) - folders_set_ruleset

        for check_folders in [folders_set_ruleset, folders_obsolete_ruleset]:
            for folder_path in check_folders:
                if not watolib.Folder.folder_exists(folder_path):
                    raise MKUserError(None, _("Folder %s does not exist") % folder_path)
                rule_folder = watolib.Folder.folder(folder_path)
                rule_folder.need_permission("write")

        tag_to_group_map = ruleset_matcher.get_tag_to_group_map(config.tags)

        # Verify all rules
        rule_vs = watolib.Ruleset(ruleset_name, tag_to_group_map).rulespec.valuespec

        for folder_path, rules in new_ruleset.items():
            for rule in rules:
                value = rule["value"]

                try:
                    rule_vs.validate_datatype(value, "test_value")
                    rule_vs.validate_value(value, "test_value")
                except MKException as e:
                    raise MKGeneralException("ERROR: %s. Affected Rule %r" % (str(e), rule))

        # Add new rulesets
        for folder_path, rules in new_ruleset.items():
            folder = watolib.Folder.folder(folder_path)

            new_ruleset = watolib.Ruleset(ruleset_name, tag_to_group_map)
            new_ruleset.from_config(folder, rules)

            folder_rulesets = watolib.FolderRulesets(folder)
            folder_rulesets.load()
            # TODO: This add_change() call should be made by the data classes
            watolib.add_change("edit-ruleset",
                               _("Set ruleset '%s' for '%s' with %d rules") % (
                                   new_ruleset.title(),
                                   folder.title(),
                                   len(rules),
                               ),
                               sites=folder.all_site_ids(),
                               object_ref=new_ruleset.object_ref())
            folder_rulesets.set(ruleset_name, new_ruleset)
            folder_rulesets.save()

        # Remove obsolete rulesets
        for folder_path in folders_obsolete_ruleset:
            folder = watolib.Folder.folder(folder_path)

            folder_rulesets = watolib.FolderRulesets(folder)
            folder_rulesets.load()

            new_ruleset = watolib.Ruleset(ruleset_name, tag_to_group_map)
            new_ruleset.from_config(folder, [])

            # TODO: This add_change() call should be made by the data classes
            watolib.add_change("edit-ruleset",
                               _("Deleted ruleset '%s' for '%s'") % (
                                   new_ruleset.title(),
                                   folder.title(),
                               ),
                               sites=folder.all_site_ids(),
                               object_ref=new_ruleset.object_ref())

            folder_rulesets.set(ruleset_name, new_ruleset)
            folder_rulesets.save()
Exemple #23
0
    def _set(self, request):
        # NOTE: This encoding here should be kept
        # Otherwise and unicode encoded text will be written into the
        # configuration file with unknown side effects
        ruleset_name = request["ruleset_name"].encode("utf-8")

        # Future validation, currently the rule API actions are admin only, so the check is pointless
        # may_edit_ruleset(ruleset_name)

        # Check if configuration hash has changed in the meantime
        ruleset_dict = self._get_ruleset_configuration(ruleset_name)
        if "configuration_hash" in request:
            validate_config_hash(request["configuration_hash"], ruleset_dict)

        # Check permissions of new rules and rules we are going to delete
        new_ruleset = request["ruleset"]
        folders_set_ruleset = set(new_ruleset.keys())
        folders_obsolete_ruleset = set(
            ruleset_dict.keys()) - folders_set_ruleset

        for check_folders in [folders_set_ruleset, folders_obsolete_ruleset]:
            for folder_path in check_folders:
                if not watolib.Folder.folder_exists(folder_path):
                    raise MKUserError(
                        None,
                        _("Folder %s does not exist") % folder_path)
                rule_folder = watolib.Folder.folder(folder_path)
                rule_folder.need_permission("write")

        # Verify all rules
        rule_vs = watolib.Ruleset(ruleset_name).rulespec.valuespec
        for folder_path, rules in new_ruleset.items():
            for rule in rules:
                if "negate" in rule:
                    continue  # ugly, rules with a boolean value have a different representation
                value = rule["value"]
                try:
                    rule_vs.validate_datatype(value, "test_value")
                    rule_vs.validate_value(value, "test_value")
                except MKException as e:
                    # TODO: The abstract MKException should never be instanciated directly
                    # Change this call site and make MKException an abstract base class
                    raise MKException("ERROR: %s. Affected Rule %r" %
                                      (str(e), rule))

        # Add new rulesets
        for folder_path, rules in new_ruleset.items():
            folder = watolib.Folder.folder(folder_path)

            new_ruleset = watolib.Ruleset(ruleset_name)
            new_ruleset.from_config(folder, rules)

            folder_rulesets = watolib.FolderRulesets(folder)
            folder_rulesets.load()
            # TODO: This add_change() call should be made by the data classes
            watolib.add_change("edit-ruleset",
                               _("Set ruleset '%s' for '%s' with %d rules") % (
                                   new_ruleset.title(),
                                   folder.title(),
                                   len(rules),
                               ),
                               sites=folder.all_site_ids())
            folder_rulesets.set(ruleset_name, new_ruleset)
            folder_rulesets.save()

        # Remove obsolete rulesets
        for folder_path in folders_obsolete_ruleset:
            folder = watolib.Folder.folder(folder_path)

            folder_rulesets = watolib.FolderRulesets(folder)
            folder_rulesets.load()
            # TODO: This add_change() call should be made by the data classes
            watolib.add_change("edit-ruleset",
                               _("Deleted ruleset '%s' for '%s'") % (
                                   watolib.Ruleset(ruleset_name).title(),
                                   folder.title(),
                               ),
                               sites=folder.all_site_ids())

            new_ruleset = watolib.Ruleset(ruleset_name)
            new_ruleset.from_config(folder, [])
            folder_rulesets.set(ruleset_name, new_ruleset)
            folder_rulesets.save()