Esempio n. 1
0
    def rename_host_in_folder_rules(folder):
        rulesets = watolib.FolderRulesets(folder)
        rulesets.load()

        changed_folder_rulesets = []
        for varname, ruleset in rulesets.get_rulesets().items():
            for _rule_folder, _rulenr, rule in ruleset.get_rules():
                orig_rule = rule.clone(preserve_id=True)
                if rule.replace_explicit_host_condition(oldname, newname):
                    changed_folder_rulesets.append(varname)

                    log_audit(
                        "edit-rule",
                        _('Renamed host condition from "%s" to "%s"') % (oldname, newname),
                        diff_text=make_diff_text(orig_rule.to_log(), rule.to_log()),
                        object_ref=rule.object_ref(),
                    )

        if changed_folder_rulesets:
            add_change(
                "edit-ruleset",
                _("Renamed host in %d rulesets of folder %s")
                % (len(changed_folder_rulesets), folder.title()),
                object_ref=folder.object_ref(),
                sites=folder.all_site_ids(),
            )
            rulesets.save()

        changed_rulesets.extend(changed_folder_rulesets)

        for subfolder in folder.subfolders():
            rename_host_in_folder_rules(subfolder)
Esempio n. 2
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))
Esempio n. 3
0
def list_rulesets(param):
    """Search rule sets"""
    all_sets = (watolib.FolderRulesets(param["folder"])
                if param.get("folder") else watolib.AllRulesets())
    all_sets.load()

    def _get_search_options(params):
        # We remove 'folder' because that has already been handled at the start of the endpoint.
        options = dict(params)
        if "folder" in options:
            del options["folder"]
        return options

    if search_options := _get_search_options(param):
        all_sets = watolib.SearchedRulesets(all_sets, search_options)
Esempio n. 4
0
    def rename_host_in_folder_rules(folder):
        rulesets = watolib.FolderRulesets(folder)
        rulesets.load()

        changed = False
        for varname, ruleset in rulesets.get_rulesets().items():
            for _rule_folder, _rulenr, rule in ruleset.get_rules():
                if rule.replace_explicit_host_condition(oldname, newname):
                    changed_rulesets.append(varname)
                    changed = True

        if changed:
            add_change("edit-ruleset",
                       _("Renamed host in %d rulesets of folder %s") %
                       (len(changed_rulesets), folder.title),
                       obj=folder,
                       sites=folder.all_site_ids())
            rulesets.save()

        for subfolder in folder.subfolders():
            rename_host_in_folder_rules(subfolder)
Esempio n. 5
0
def _change_host_tags_in_rules(operation, mode, folder):
    """Update tags in all rules

    The function parses all rules in all rulesets and looks for host tags that
    have been removed or renamed. If tags are removed then the depending on the
    mode affected rules are either deleted ("delete") or the vanished tags are
    removed from the rule ("remove").

    See _rename_tags_after_confirmation() doc string for additional information.
    """
    affected_rulesets = set()

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

    for ruleset in rulesets.get_rulesets().values():
        for _folder, _rulenr, rule in ruleset.get_rules():
            affected_rulesets.update(_change_host_tags_in_rule(operation, mode, ruleset, rule))

    if affected_rulesets and mode != TagCleanupMode.CHECK:
        rulesets.save()

    return sorted(affected_rulesets, key=lambda x: x.title())
Esempio n. 6
0
    def rename_host_in_folder_rules(folder):
        rulesets = watolib.FolderRulesets(folder)
        rulesets.load()

        changed = False
        for varname, ruleset in rulesets.get_rulesets().items():
            for _rule_folder, _rulenr, rule in ruleset.get_rules():
                # TODO: Move to rule?
                if watolib.rename_host_in_list(rule.host_list, oldname,
                                               newname):
                    changed_rulesets.append(varname)
                    changed = True

        if changed:
            add_change("edit-ruleset",
                       _("Renamed host in %d rulesets of folder %s") %
                       (len(changed_rulesets), folder.title),
                       obj=folder,
                       sites=folder.all_site_ids())
            rulesets.save()

        for subfolder in folder.all_subfolders().values():
            rename_host_in_folder_rules(subfolder)
Esempio n. 7
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()
Esempio n. 8
0
def _change_host_tags_in_rules(folder, operations, mode):
    """Update tags in all rules

    The function parses all rules in all rulesets and looks for host tags that
    have been removed or renamed. If tags are removed then the depending on the
    mode affected rules are either deleted ("delete") or the vanished tags are
    removed from the rule ("remove").
    """
    need_save = False
    affected_rulesets = set([])

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

    for ruleset in rulesets.get_rulesets().itervalues():
        for _folder, _rulenr, rule in ruleset.get_rules():
            # Handle deletion of complete tag group
            if isinstance(operations, list):  # this list of tags to remove
                for tag in operations:
                    if tag is not None and (tag in rule.tag_specs or "!" + tag in rule.tag_specs):
                        affected_rulesets.add(ruleset)

                        if mode != "check":
                            need_save = True
                            if tag in rule.tag_specs and mode == "delete":
                                ruleset.delete_rule(rule)
                            elif tag in rule.tag_specs:
                                rule.tag_specs.remove(tag)
                            elif "+" + tag in rule.tag_specs:
                                rule.tag_specs.remove("!" + tag)

            # Removal or renamal of single tag choices
            else:
                for old_tag, new_tag in operations.items():
                    # The case that old_tag is None (an empty tag has got a name)
                    # cannot be handled when it comes to rules. Rules do not support
                    # such None-values.
                    if not old_tag:
                        continue

                    if old_tag in rule.tag_specs or ("!" + old_tag) in rule.tag_specs:
                        affected_rulesets.add(ruleset)

                        if mode != "check":
                            need_save = True
                            if old_tag in rule.tag_specs:
                                rule.tag_specs.remove(old_tag)
                                if new_tag:
                                    rule.tag_specs.append(new_tag)
                                elif mode == "delete":
                                    ruleset.delete_rule(rule)

                            # negated tag has been renamed or removed
                            if "!" + old_tag in rule.tag_specs:
                                rule.tag_specs.remove("!" + old_tag)
                                if new_tag:
                                    rule.tag_specs.append("!" + new_tag)
                                # the case "delete" need not be handled here. Negated
                                # tags can always be removed without changing the rule's
                                # behaviour.

    if need_save:
        rulesets.save()

    return sorted(affected_rulesets, key=lambda x: x.title())
Esempio n. 9
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()