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)
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))
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)
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)
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())
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)
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()
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())
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()