def _condition_cache_id( self, hostlist: Optional[HostOrServiceConditions], tag_conditions: TaggroupIDToTagCondition, labels: Any, rule_path: Any, ) -> Tuple[Tuple[str, ...], Tuple[Tuple[str, Any], ...], Tuple[Tuple[ Any, Any], ...], Any]: host_parts: List[str] = [] if hostlist is not None: negate, hostlist = parse_negated_condition_list(hostlist) if negate: host_parts.append("!") for h in hostlist: if isinstance(h, dict): if "$regex" not in h: raise NotImplementedError() host_parts.append("~%s" % h["$regex"]) continue host_parts.append(h) return ( tuple(sorted(host_parts)), tuple((taggroup_id, _tags_or_labels_cache_id(tag_condition)) for taggroup_id, tag_condition in tag_conditions.items()), tuple((label_id, _tags_or_labels_cache_id(label_spec)) for label_id, label_spec in labels.items()), rule_path, )
def matches_host_tags( self, hosttags: Set[Tuple[TaggroupID, TagID]], required_tags: TaggroupIDToTagCondition, ) -> bool: return all( matches_tag_condition(taggroup_id, tag_condition, hosttags) for taggroup_id, tag_condition in required_tags.items())
def _match_hosts_by_tags( self, cache_id, valid_hosts: Set[HostName], tag_conditions: TaggroupIDToTagCondition, ): matching = set() negative_match_tags = set() positive_match_tags = set() for taggroup_id, tag_condition in tag_conditions.items(): if isinstance(tag_condition, dict): if "$ne" in tag_condition: negative_match_tags.add(( taggroup_id, cast(TagConditionNE, tag_condition)["$ne"], )) continue if "$or" in tag_condition: return None # Can not be optimized, makes _all_matching_hosts proceed if "$nor" in tag_condition: return None # Can not be optimized, makes _all_matching_hosts proceed raise NotImplementedError() positive_match_tags.add((taggroup_id, tag_condition)) # TODO: # if has_specific_folder_tag or self._all_processed_hosts_similarity < 3.0: if self._all_processed_hosts_similarity < 3.0: # Without shared folders for hostname in valid_hosts: if positive_match_tags <= self._host_tags[ hostname] and not negative_match_tags.intersection( self._host_tags[hostname]): matching.add(hostname) self._all_matching_hosts_match_cache[cache_id] = matching return matching # With shared folders checked_hosts: Set[str] = set() for hostname in valid_hosts: if hostname in checked_hosts: continue hosts_with_same_tag = self._filter_hosts_with_same_tags_as_host( hostname, valid_hosts) checked_hosts.update(hosts_with_same_tag) if positive_match_tags <= self._host_tags[ hostname] and not negative_match_tags.intersection( self._host_tags[hostname]): matching.update(hosts_with_same_tag) self._all_matching_hosts_match_cache[cache_id] = matching return matching
def filter_host_tags( self, hosts: Iterable[BIHostData], tag_conditions: TaggroupIDToTagCondition, ) -> Iterable[BIHostData]: return ( host for host in hosts # if all( matches_tag_condition( taggroup_id, tag_condition, host.tags, ) for taggroup_id, tag_condition in tag_conditions.items()))