def test_full_build_and_search(self, with_admin_login, index_builder,
                                index_searcher):
     index_builder.build_full_index()
     assert list(index_searcher.search("**")) == [
         ("Change-dependent",
          [SearchResult(title="change_dependent", url="")]),
         ("Localization-dependent",
          [SearchResult(title="localization_dependent", url="")]),
     ]
Esempio n. 2
0
 def test_full_build_and_search(
     self,
     index_builder: IndexBuilder,
     index_searcher: IndexSearcher,
 ) -> None:
     index_builder.build_full_index()
     assert list(index_searcher.search("**")) == [
         ("Change-dependent", [SearchResult(title="change_dependent", url="")]),
         ("Localization-dependent", [SearchResult(title="localization_dependent", url="")]),
     ]
Esempio n. 3
0
    def _generate_display_texts(
            self, elements: List[LivestatusResult]) -> List[SearchResult]:
        """Creates the text displayed to the user

        Analyzes all display texts and ensures that we have unique ones"""
        for element in elements:
            if self.livestatus_table == "services":
                element.display_text = element.row["description"]
            else:
                element.display_text = element.text_tokens[0][1]

        if self._element_texts_unique(elements):
            return [
                SearchResult(title=e.display_text, url=e.url) for e in elements
            ]

        # Some (ugly) special handling when the results are not unique
        # Whenever this happens we try to find a fitting second value

        if self.livestatus_table in ["hostgroups", "servicegroups"]:
            # Discard redundant hostgroups
            results: List[SearchResult] = []
            used_groups: Set[str] = set()
            for element in elements:
                if element.display_text in used_groups:
                    continue
                results.append(
                    SearchResult(title=element.display_text, url=element.url))
                used_groups.add(element.display_text)
            return results

        # Add additional info to the display text
        for element in elements:
            hostname = element.row.get("host_name", element.row.get("name"))
            if "&host_regex=" not in element.url:
                element.url += "&host_regex=%s" % hostname

            for shortname, text in element.text_tokens:
                if shortname in ["h", "al"
                                 ] and text not in element.display_text:
                    element.display_text += " <b>%s</b>" % text
                    break
            else:
                element.display_text += " <b>%s</b>" % hostname

        return [
            SearchResult(title=e.display_text, url=e.url) for e in elements
        ]
Esempio n. 4
0
    def search(self, query: SearchQuery) -> SearchResultsByTopic:
        query_lowercase = query.lower()
        results = DefaultDict(list)

        index = self._index_store.load_index()
        if self._current_language not in index.localization_dependent:
            build_and_store_index_background()
            raise IndexNotFoundException

        for topic, match_items in chain(
                index.localization_independent.items(),
                index.localization_dependent[self._current_language].items(),
        ):
            if not self._may_see_topic.get(topic, True):
                continue
            permissions_check = self._may_see_item_func.get(
                topic, lambda _: True)

            for match_item in match_items:
                if (any(query_lowercase in match_text
                        for match_text in match_item.match_texts)
                        and permissions_check(match_item.url)):
                    results[match_item.topic].append(
                        SearchResult(
                            match_item.title,
                            match_item.url,
                        ))

        yield from self._sort_search_results(results)
Esempio n. 5
0
    def test_update_with_empty_and_search(
        self,
        monkeypatch: MonkeyPatch,
        match_item_generator_registry: MatchItemGeneratorRegistry,
        index_builder: IndexBuilder,
        index_searcher: IndexSearcher,
    ) -> None:
        """
        Test if things can also be deleted from the index during an update
        """

        def empty_match_item_gen():
            yield from ()

        index_builder.build_full_index()

        monkeypatch.setattr(
            match_item_generator_registry["change_dependent"],
            "generate_match_items",
            empty_match_item_gen,
        )

        index_builder.build_changed_sub_indices("some_change_dependent_whatever")
        assert list(index_searcher.search("**")) == [
            ("Localization-dependent", [SearchResult(title="localization_dependent", url="")]),
        ]
Esempio n. 6
0
    def _search_redis(
        self,
        query: str,
        key_categories: str,
        key_prefix_match_items: str,
        results: DefaultDict[str, List[SearchResult]],
    ) -> None:
        for category in self._redis_client.smembers(key_categories):
            if not self._may_see_category(category):
                continue

            prefix_category = IndexBuilder.add_to_prefix(
                key_prefix_match_items,
                category,
            )
            permissions_check = self._may_see_item_func.get(
                category, lambda _: True)

            for _matched_text, idx_matched_item in self._redis_client.hscan_iter(
                    IndexBuilder.key_match_texts(prefix_category),
                    match=query,
            ):
                match_item_dict = self._redis_client.hgetall(
                    IndexBuilder.add_to_prefix(prefix_category,
                                               idx_matched_item))

                if not permissions_check(match_item_dict["url"]):
                    continue

                results[match_item_dict["topic"]].append(
                    SearchResult(
                        match_item_dict["title"],
                        match_item_dict["url"],
                    ))
Esempio n. 7
0
 def test_sort_search_results(self) -> None:
     assert list(
         IndexSearcher._sort_search_results(
             {
                 "Hosts": [SearchResult(title="host", url="")],
                 "Setup": [SearchResult(title="setup_menu_entry", url="")],
                 "Global settings": [SearchResult(title="global_setting", url="")],
                 "Other topic": [SearchResult(title="other_item", url="")],
                 "Another topic": [SearchResult(title="another_item", url="")],
             }
         )
     ) == [
         ("Setup", [SearchResult(title="setup_menu_entry", url="")]),
         ("Hosts", [SearchResult(title="host", url="")]),
         ("Another topic", [SearchResult(title="another_item", url="")]),
         ("Other topic", [SearchResult(title="other_item", url="")]),
         ("Global settings", [SearchResult(title="global_setting", url="")]),
     ]
 def test_sort_search_results(self):
     assert list(
         IndexSearcher._sort_search_results({
             "Hosts": [SearchResult(title="host", url="")],
             "Setup": [SearchResult(title="setup_menu_entry", url="")],
             "Global settings":
             [SearchResult(title="global_setting", url="")],
             "Other topic": [SearchResult(title="other_item", url="")],
             "Another topic": [SearchResult(title="another_item", url="")],
         })) == [
             ('Setup', [SearchResult(title='setup_menu_entry', url='')]),
             ('Hosts', [SearchResult(title='host', url='')]),
             ('Another topic', [SearchResult(title='another_item',
                                             url='')]),
             ('Other topic', [SearchResult(title='other_item', url='')]),
             ('Global settings',
              [SearchResult(title='global_setting', url='')]),
         ]
Esempio n. 9
0
 def test_update_and_search_with_update(
     self,
     index_builder: IndexBuilder,
     index_searcher: IndexSearcher,
 ) -> None:
     index_builder._mark_index_as_built()
     index_builder.build_changed_sub_indices("some_change_dependent_whatever")
     assert list(index_searcher.search("**")) == [
         ("Change-dependent", [SearchResult(title="change_dependent", url="")]),
     ]
Esempio n. 10
0
 def search(self, query: SearchQuery) -> SearchResultsByTopic:
     query_lowercase = query.lower()
     results: Dict[str, List[SearchResult]] = {}
     for match_item in self._index_store.all_match_items():
         if any(query_lowercase in match_text for match_text in match_item.match_texts):
             results.setdefault(
                 match_item.topic,
                 [],
             ).append(SearchResult(
                 match_item.title,
                 match_item.url,
             ))
     return results
Esempio n. 11
0
    def _search_redis(
        self,
        query: str,
        key_categories: str,
        key_prefix_match_items: str,
        results: DefaultDict[str, List[SearchResult]],
    ) -> None:
        for category in self._redis_client.smembers(key_categories):
            if not self._may_see_category(category):
                continue

            prefix_category = IndexBuilder.add_to_prefix(
                key_prefix_match_items,
                category,
            )
            permissions_check = self._may_see_item_func.get(
                category, lambda _: True)

            for _matched_text, idx_matched_item in self._redis_client.hscan_iter(
                    IndexBuilder.key_match_texts(prefix_category),
                    match=query,
            ):
                match_item_dict = self._redis_client.hgetall(
                    IndexBuilder.add_to_prefix(prefix_category,
                                               idx_matched_item))

                if not permissions_check(match_item_dict["url"]):
                    continue

                # This call to i18n._ with a non-constant string is ok. Here, we translate the
                # topics of our search results. For localization-dependent search results, such as
                # rulesets, they are already localized anyway. However, for localization-independent
                # results, such as hosts, they are not. For example, "Hosts" in French is "Hôtes".
                # Without this call to i18n._, found hosts would be displayed under the topic
                # "Hosts" instead of "Hôtes" in the setup search.
                # pylint: disable=translation-of-non-string
                results[_(match_item_dict["topic"])].append(
                    SearchResult(
                        match_item_dict["title"],
                        match_item_dict["url"],
                    ))
Esempio n. 12
0
    def search(self, query: SearchQuery) -> SearchResultsByTopic:
        query_lowercase = query.lower()
        results = DefaultDict(list)

        for topic, match_items in self._index_store.load_index().items():
            if not self._may_see_topic.get(topic, True):
                continue
            permissions_check = self._may_see_item_func.get(
                topic, lambda _: True)

            for match_item in match_items:
                if (any(query_lowercase in match_text
                        for match_text in match_item.match_texts)
                        and permissions_check(match_item.url)):
                    results[match_item.topic].append(
                        SearchResult(
                            match_item.title,
                            match_item.url,
                        ))

        yield from self._sort_search_results(results)
Esempio n. 13
0
    def search(self, query: SearchQuery) -> SearchResultsByTopic:
        query_lowercase = query.lower()
        results: Dict[str, List[SearchResult]] = {}

        for topic, match_items in self._index_store.load_index().items():
            if not self._may_see_topic.get(topic, True):
                continue
            permissions_check = self._may_see_item_func.get(
                topic, lambda _: True)

            for match_item in match_items:
                if (any(query_lowercase in match_text
                        for match_text in match_item.match_texts)
                        and permissions_check(match_item.url)):
                    results.setdefault(
                        match_item.topic,
                        [],
                    ).append(SearchResult(
                        match_item.title,
                        match_item.url,
                    ))
        return results
Esempio n. 14
0
    def test_update_with_empty_and_search(
        self,
        with_admin_login,
        match_item_generator_registry,
        index_builder,
        index_searcher,
    ):
        """
        Test if things can also be deleted from the index during an update
        """
        def empty_match_item_gen():
            yield from ()

        index_builder.build_full_index()
        match_item_generator_registry[
            "change_dependent"].generate_match_items = empty_match_item_gen
        index_builder.build_changed_sub_indices(
            "some_change_dependent_whatever")
        assert list(index_searcher.search("**")) == [
            ("Localization-dependent",
             [SearchResult(title="localization_dependent", url="")]),
        ]