def _load_folder_rulesets( self, folder: CREFolder, only_varname: Optional[RulesetName] = None ) -> None: path = folder.rules_file_path() if not os.path.exists(path): return # Do not initialize rulesets when no rule at all exists config_dict = { "ALL_HOSTS": ALL_HOSTS, "ALL_SERVICES": ALL_SERVICES, "NEGATE": NEGATE, "FOLDER_PATH": folder.path(), } # Prepare empty rulesets so that rules.mk has something to # append to. We need to initialize all variables here, even # when only loading with only_varname. for varname in rulespec_registry.keys(): if ":" in varname: dictname, _subkey = varname.split(":") config_dict[dictname] = {} else: config_dict[varname] = [] self.from_config(folder, store.load_mk_file(path, config_dict), only_varname)
def dump_structure(wato_folder: hosts_and_folders.CREFolder, indent=0): indent_space = " " * indent * 6 sys.stdout.write( f"{indent_space + '->' + str(wato_folder):80} {wato_folder.path()}\n" ) sys.stdout.write("\n".join( f"{indent_space} {x}" for x in pprint.pformat(wato_folder.attributes()).split("\n")) + "\n") for subfolder in wato_folder.subfolders(): dump_structure(subfolder, indent + 1)
def _load_rulesets_recursively( self, folder: CREFolder, only_varname: Optional[RulesetName] = None ) -> None: for subfolder in folder.subfolders(): self._load_rulesets_recursively(subfolder, only_varname) self._load_folder_rulesets(folder, only_varname)
def _parse_dict_rule( cls, folder: CREFolder, ruleset: Ruleset, rule_config: Dict[Any, Any], ) -> Rule: # cmk-update-config uses this to load rules from the config file for rewriting them To make # this possible, we need to accept missing "id" fields here. During runtime this is not # needed anymore, since cmk-update-config has updated all rules from the user configuration. id_ = rule_config["id"] if "id" in rule_config else utils.gen_id() assert isinstance(id_, str) rule_options = rule_config.get("options", {}) assert all(isinstance(k, str) for k in rule_options) conditions = rule_config["condition"].copy() # Is known because of the folder associated with this object. Remove the # rendundant information here. It will be added dynamically in to_config() # for writing it back conditions.pop("host_folder", None) rule_conditions = RuleConditions(folder.path()) rule_conditions.from_config(conditions) return cls( id_, folder, ruleset, rule_conditions, RuleOptions.from_config(rule_options), rule_config["value"], )
def to_config(self, folder: CREFolder) -> str: content = "" if ":" in self.name: dictname, subkey = self.name.split(":") varname = "%s[%r]" % (dictname, subkey) content += "\n%s.setdefault(%r, [])\n" % (dictname, subkey) else: varname = self.name content += "\nglobals().setdefault(%r, [])\n" % (varname) if self.is_optional(): content += "\nif %s is None:\n %s = []\n" % (varname, varname) content += "\n%s = [\n" % varname for rule in self._rules[folder.path()]: # When using pprint we get a deterministic representation of the # data structures because it cares about sorting of the dict keys if active_config.wato_use_git: text = pprint.pformat(rule.to_config()) else: text = repr(rule.to_config()) content += "%s,\n" % text content += "] + %s\n\n" % varname return content
def append_rule(self, folder: CREFolder, rule: Rule) -> int: rules = self._rules.setdefault(folder.path(), []) index = len(rules) rules.append(rule) self._rules_by_id[rule.id] = rule self._on_change() return index
def _find_usages_of_contact_group_in_hosts_and_folders( name: GroupName, folder: CREFolder ) -> List[Tuple[str, str]]: used_in = [] for subfolder in folder.subfolders(): used_in += _find_usages_of_contact_group_in_hosts_and_folders(name, subfolder) attributes = folder.attributes() if name in attributes.get("contactgroups", {}).get("groups", []): used_in.append((_("Folder: %s") % folder.alias_path(), folder.edit_url())) for host in folder.hosts().values(): attributes = host.attributes() if name in attributes.get("contactgroups", {}).get("groups", []): used_in.append((_("Host: %s") % host.name(), host.edit_url())) return used_in
def folder_slug(folder: CREFolder) -> str: """Create a tilde separated path identifier to be used in URLs Args: folder: The folder instance for which to generate the URL. Returns: A path looking like this: `~folder~subfolder~leaf_folder` """ return "~" + folder.path().rstrip("/").replace("/", "~")
def from_config(self, folder: CREFolder, rules_config) -> None: if not rules_config: return if folder.path() in self._rules: for rule in self._rules[folder.path()]: del self._rules_by_id[rule.id] # Resets the rules of this ruleset for this folder! self._rules[folder.path()] = [] self.tuple_transformer.transform_in_place(rules_config, is_service=self.rulespec.is_for_services, is_binary=self.rulespec.is_binary_ruleset, use_ruleset_id_cache=False) for rule_config in rules_config: rule = Rule(folder, self) rule.from_config(rule_config) self._rules[folder.path()].append(rule) self._rules_by_id[rule.id] = rule
def _serialize_folder(folder: CREFolder, show_hosts): links = [] if not folder.is_root(): links.append( constructors.link_rel( rel="cmk/move", href=constructors.object_action_href( "folder_config", folder_slug(folder), action_name="move", ), method="post", title="Move the folder", )) rv = constructors.domain_object( domain_type="folder_config", identifier=folder_slug(folder), title=folder.title(), extensions={ "path": "/" + folder.path(), "attributes": folder.attributes().copy(), }, links=links, ) if show_hosts: rv["members"]["hosts"] = constructors.collection_property( name="hosts", base=constructors.object_href("folder_config", folder_slug(folder)), value=[ constructors.collection_item( domain_type="host_config", identifier=host.id(), title=host.name(), ) for host in folder.hosts().values() ], ) return rv
def from_ruleset_defaults(cls, folder: CREFolder, ruleset: Ruleset) -> Rule: return Rule( utils.gen_id(), folder, ruleset, RuleConditions(folder.path()), RuleOptions( disabled=False, description="", comment="", docu_url="", predefined_condition_id=None, ), ruleset.valuespec().default_value(), )
def _determine_gateway_attributes(self, task: ParentScanTask, settings: ParentScanSettings, gateway: ParentScanResult, gw_folder: CREFolder) -> dict: new_host_attributes = { "ipaddress": gateway.ip, } if settings.alias: new_host_attributes["alias"] = settings.alias if gw_folder.site_id() != task.site_id: new_host_attributes["site"] = task.site_id return new_host_attributes
def make_folder_status_link(folder: CREFolder, view_name: str) -> PageMenuEntry: return PageMenuEntry( title=_("Status"), icon_name="status", item=make_simple_link( makeuri_contextless( request, [ ("view_name", view_name), ("wato_folder", folder.path()), ], filename="view.py", )), )
def _log_rule_change( _rule: Rule, _old_folder: CREFolder, _message: str, _dest_folder: typing.Optional[CREFolder] = None, ): yield affected_sites = _old_folder.all_site_ids() if _dest_folder is not None: affected_sites.extend(_dest_folder.all_site_ids()) add_change( "edit-rule", _message, sites=list(set(affected_sites)), object_ref=_rule.object_ref(), )
def get_rule(self, folder: CREFolder, rule_index: int) -> Rule: return self._rules[folder.path()][rule_index]
def prepend_rule(self, folder: CREFolder, rule: Rule) -> None: rules = self._rules.setdefault(folder.path(), []) rules.insert(0, rule) self._rules_by_id[rule.id] = rule self._on_change()
def get_folder_rules(self, folder: CREFolder) -> List[Rule]: try: return self._rules[folder.path()] except KeyError: return []
def _save_rulesets_recursively(self, folder: CREFolder) -> None: for subfolder in folder.subfolders(): self._save_rulesets_recursively(subfolder) self._save_folder(folder)
def etag_of_folder(folder: CREFolder) -> ETags: return constructors.etag_of_dict({ "path": folder.path(), "attributes": folder.attributes(), "hosts": folder.host_names(), })