From 33b9a9406b76776eaeff2d48b2fede15a26da38d Mon Sep 17 00:00:00 2001 From: Pascal Zimmermann Date: Tue, 8 Oct 2024 22:14:17 +0200 Subject: [PATCH] fix: Adjust the user search functionality --- docs/content/grafana_api/user.md | 43 +++++++++++++++++++++--- grafana_api/user.py | 56 +++++++++++++++++++++++++++++--- tests/unittests/test_user.py | 55 +++++++++++++++++++++++++++++-- 3 files changed, 143 insertions(+), 11 deletions(-) diff --git a/docs/content/grafana_api/user.md b/docs/content/grafana_api/user.md index 129fdbf..83ca8b3 100644 --- a/docs/content/grafana_api/user.md +++ b/docs/content/grafana_api/user.md @@ -3,6 +3,7 @@ * [user](#user) * [User](#user.User) * [search\_users](#user.User.search_users) + * [search\_users\_with\_paging](#user.User.search_users_with_paging) * [get\_user\_by\_id](#user.User.get_user_by_id) * [get\_user\_by\_username\_or\_email](#user.User.get_user_by_username_or_email) * [update\_user](#user.User.update_user) @@ -51,11 +52,44 @@ HINT: Note Grafana Enterprise API need required permissions if fine-grained acce ```python def search_users(results_per_page: int = 1000, - pages: int = 1, - query: str = None) -> list + page: int = 1, + sort: str = None) -> list ``` -The method includes a functionality to get all Grafana system users specified by the optional query and paging functionality +The method includes a functionality to get all Grafana system users specified by the optional results_per_page, page and sort option + +Required Permissions: +Action: users:read +Scope: global.users:* + +**Arguments**: + +- `results_per_page` _int_ - Specify the results_per_page as integer (default 1000) +- `page` _int_ - Specify the page as integer (default 1) +- `sort` _str_ - Specify the sort option. Valid values are login-asc, login-desc, email-asc, email-desc, name-asc, name-desc, lastSeenAtAge-asc and lastSeenAtAge-desc. By default, if sort is not specified, the user list will be ordered by login, email in ascending order (default None) + + +**Raises**: + +- `Exception` - Unspecified error by executing the API call + + +**Returns**: + +- `api_call` _list_ - Returns the list of Grafana users + + + +#### search\_users\_with\_paging + +```python +def search_users_with_paging(results_per_page: int = 1000, + pages: int = 1, + query: str = None, + sort: str = None) -> dict +``` + +The method includes a functionality to get all Grafana system users specified by the optional results_per_page, page, query, sort and general paging functionality Required Permissions: Action: users:read @@ -66,6 +100,7 @@ Scope: global.users:* - `results_per_page` _int_ - Specify the results_per_page as integer (default 1000) - `pages` _int_ - Specify the pages as integer (default 1) - `query` _str_ - Specify the query (default None) +- `sort` _str_ - Specify the sort option. Valid values are login-asc, login-desc, email-asc, email-desc, name-asc, name-desc, lastSeenAtAge-asc and lastSeenAtAge-desc. By default, if sort is not specified, the user list will be ordered by login, email in ascending order (default None) **Raises**: @@ -75,7 +110,7 @@ Scope: global.users:* **Returns**: -- `api_call` _list_ - Returns the list of Grafana users +- `api_call` _dict_ - Returns the Grafana users diff --git a/grafana_api/user.py b/grafana_api/user.py index f06010b..da1e008 100644 --- a/grafana_api/user.py +++ b/grafana_api/user.py @@ -26,12 +26,54 @@ def __init__(self, grafana_api_model: APIModel): self.grafana_api_model = grafana_api_model def search_users( + self, + results_per_page: int = 1000, + page: int = 1, + sort: str = None, + ) -> list: + """The method includes a functionality to get all Grafana system users specified by the optional results_per_page, page and sort option + + Required Permissions: + Action: users:read + Scope: global.users:* + + Args: + results_per_page (int): Specify the results_per_page as integer (default 1000) + page (int): Specify the page as integer (default 1) + sort (str): Specify the sort option. Valid values are login-asc, login-desc, email-asc, email-desc, name-asc, name-desc, lastSeenAtAge-asc and lastSeenAtAge-desc. By default, if sort is not specified, the user list will be ordered by login, email in ascending order (default None) + + Raises: + Exception: Unspecified error by executing the API call + + Returns: + api_call (list): Returns the list of Grafana users + """ + + api_request_url: str = ( + f"{APIEndpoints.USERS.value}?perpage={results_per_page}&page={page}" + ) + + if sort is not None and len(sort) != 0: + api_request_url: str = f"{api_request_url}&sort={sort}" + + api_call: list = Api(self.grafana_api_model).call_the_api( + api_request_url, + ) + + if api_call == list() or api_call[0].get("id") is None: + logging.error(f"Check the error: {api_call}.") + raise Exception + else: + return api_call + + def search_users_with_paging( self, results_per_page: int = 1000, pages: int = 1, query: str = None, - ) -> list: - """The method includes a functionality to get all Grafana system users specified by the optional query and paging functionality + sort: str = None + ) -> dict: + """The method includes a functionality to get all Grafana system users specified by the optional results_per_page, page, query, sort and general paging functionality Required Permissions: Action: users:read @@ -41,12 +83,13 @@ def search_users( results_per_page (int): Specify the results_per_page as integer (default 1000) pages (int): Specify the pages as integer (default 1) query (str): Specify the query (default None) + sort (str): Specify the sort option. Valid values are login-asc, login-desc, email-asc, email-desc, name-asc, name-desc, lastSeenAtAge-asc and lastSeenAtAge-desc. By default, if sort is not specified, the user list will be ordered by login, email in ascending order (default None) Raises: Exception: Unspecified error by executing the API call Returns: - api_call (list): Returns the list of Grafana users + api_call (dict): Returns the Grafana users """ api_request_url: str = ( @@ -56,11 +99,14 @@ def search_users( if query is not None and len(query) != 0: api_request_url: str = f"{api_request_url}&query={query}" - api_call: list = Api(self.grafana_api_model).call_the_api( + if sort is not None and len(sort) != 0: + api_request_url: str = f"{api_request_url}&sort={sort}" + + api_call: dict = Api(self.grafana_api_model).call_the_api( api_request_url, ) - if api_call == list() or api_call[0].get("id") is None: + if api_call == dict() or api_call.get("users") is None: logging.error(f"Check the error: {api_call}.") raise Exception else: diff --git a/tests/unittests/test_user.py b/tests/unittests/test_user.py index 49cc4f5..f591410 100644 --- a/tests/unittests/test_user.py +++ b/tests/unittests/test_user.py @@ -18,7 +18,7 @@ def test_search_users(self, call_the_api_mock): self.assertEqual(list([{"id": 1}]), user.search_users()) @patch("grafana_api.api.Api.call_the_api") - def test_search_users_query(self, call_the_api_mock): + def test_search_users_sort(self, call_the_api_mock): model: APIModel = APIModel( host=MagicMock(), username=MagicMock(), password=MagicMock() ) @@ -28,7 +28,7 @@ def test_search_users_query(self, call_the_api_mock): self.assertEqual( list([{"id": 1}]), - user.search_users(query="Test"), + user.search_users(sort="login-asc"), ) @patch("grafana_api.api.Api.call_the_api") @@ -43,6 +43,57 @@ def test_search_users_no_users(self, call_the_api_mock): with self.assertRaises(Exception): user.search_users() + @patch("grafana_api.api.Api.call_the_api") + def test_search_users_with_paging(self, call_the_api_mock): + model: APIModel = APIModel( + host=MagicMock(), username=MagicMock(), password=MagicMock() + ) + user: User = User(grafana_api_model=model) + + call_the_api_mock.return_value = dict({"users": []}) + + self.assertEqual(dict({"users": []}), user.search_users_with_paging()) + + @patch("grafana_api.api.Api.call_the_api") + def test_search_users_with_paging_query(self, call_the_api_mock): + model: APIModel = APIModel( + host=MagicMock(), username=MagicMock(), password=MagicMock() + ) + user: User = User(grafana_api_model=model) + + call_the_api_mock.return_value = dict({"users": []}) + + self.assertEqual( + dict({"users": []}), + user.search_users_with_paging(query="test"), + ) + + @patch("grafana_api.api.Api.call_the_api") + def test_search_users_with_paging_sort(self, call_the_api_mock): + model: APIModel = APIModel( + host=MagicMock(), username=MagicMock(), password=MagicMock() + ) + user: User = User(grafana_api_model=model) + + call_the_api_mock.return_value = dict({"users": []}) + + self.assertEqual( + dict({"users": []}), + user.search_users_with_paging(sort="login-asc"), + ) + + @patch("grafana_api.api.Api.call_the_api") + def test_search_users_with_paging_no_users(self, call_the_api_mock): + model: APIModel = APIModel( + host=MagicMock(), username=MagicMock(), password=MagicMock() + ) + user: User = User(grafana_api_model=model) + + call_the_api_mock.return_value = dict() + + with self.assertRaises(Exception): + user.search_users_with_paging() + @patch("grafana_api.api.Api.call_the_api") def test_get_user_by_id(self, call_the_api_mock): model: APIModel = APIModel(