graylog-api-client 0.2.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (18) hide show
  1. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/PKG-INFO +6 -5
  2. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/README.md +5 -4
  3. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/pyproject.toml +1 -1
  4. graylog_api_client-0.2.1/src/graylog_api_client/endpoints/__init__.py +13 -0
  5. graylog_api_client-0.2.1/src/graylog_api_client/endpoints/_template.py +12 -0
  6. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/endpoints/authz.py +11 -5
  7. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/endpoints/plugins/SecurityApp.py +14 -13
  8. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/endpoints/plugins/__init__.py +2 -1
  9. graylog_api_client-0.2.1/src/graylog_api_client/endpoints/search.py +28 -0
  10. graylog_api_client-0.2.1/src/graylog_api_client/endpoints/users.py +68 -0
  11. graylog_api_client-0.2.1/src/graylog_api_client/endpoints/views.py +18 -0
  12. graylog_api_client-0.2.1/src/graylog_api_client/graylog_api_client.py +123 -0
  13. graylog_api_client-0.2.0/src/graylog_api_client/graylog_api_client.py +0 -180
  14. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/LICENSE +0 -0
  15. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/__init__.py +0 -0
  16. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/data_structures.py +0 -0
  17. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/exceptions.py +0 -0
  18. {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/rest_adapter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graylog-api-client
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: A Python wrapper for the Graylog REST API
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -19,7 +19,7 @@ Description-Content-Type: text/markdown
19
19
  ### This is a low level Graylog API Wrapper heavily based on the guide by [pretzel](https://www.pretzellogix.net/2021/12/08/how-to-write-a-python3-sdk-library-module-for-a-json-rest-api/).
20
20
  As there are a lot of endpoints not all of them are implemented by now. I started by implementing the GET requests first.
21
21
  Also the API responses all follow very different schemas and an implementation of that into Python is probably not worth the effort which is why the responses from this API are so low-level.
22
- Feel free to add endpoints or schemas in PRs if you need them :)
22
+ Due to the amount of Endpoints and the frequent changes, this project does not aim to implement all of them. Instead, only the ones that are needed are added. If some are missing that you need, create an issue or PR. When adding calls to a new Endpoint, follow the schema that is already used (e.g. all authz calls are located in [endpoints.authz.py](/src/graylog_api_client/endpoints/authz.py)).
23
23
  #### Last tested Graylog Major Version is: 7
24
24
 
25
25
  ### Example Usage
@@ -34,11 +34,12 @@ api = GraylogAPI(
34
34
  ssl_verify=True # /path/to/cert for custom certificate
35
35
  )
36
36
 
37
- # Example: Fetch all streams
38
- streams = api.get_streams()
37
+ # Example: Fetch users
38
+ users = api.users.get_users_paginated({"sort": "username"})
39
39
 
40
40
  # Print the result
41
- print("Streams:", streams.data)
41
+ for user in users.data.get("users", []):
42
+ print(f"Username: {user['username']}, Email: {user['email']}, id: {user['id']}")
42
43
  ```
43
44
 
44
45
  Planned:
@@ -1,7 +1,7 @@
1
1
  ### This is a low level Graylog API Wrapper heavily based on the guide by [pretzel](https://www.pretzellogix.net/2021/12/08/how-to-write-a-python3-sdk-library-module-for-a-json-rest-api/).
2
2
  As there are a lot of endpoints not all of them are implemented by now. I started by implementing the GET requests first.
3
3
  Also the API responses all follow very different schemas and an implementation of that into Python is probably not worth the effort which is why the responses from this API are so low-level.
4
- Feel free to add endpoints or schemas in PRs if you need them :)
4
+ Due to the amount of Endpoints and the frequent changes, this project does not aim to implement all of them. Instead, only the ones that are needed are added. If some are missing that you need, create an issue or PR. When adding calls to a new Endpoint, follow the schema that is already used (e.g. all authz calls are located in [endpoints.authz.py](/src/graylog_api_client/endpoints/authz.py)).
5
5
  #### Last tested Graylog Major Version is: 7
6
6
 
7
7
  ### Example Usage
@@ -16,11 +16,12 @@ api = GraylogAPI(
16
16
  ssl_verify=True # /path/to/cert for custom certificate
17
17
  )
18
18
 
19
- # Example: Fetch all streams
20
- streams = api.get_streams()
19
+ # Example: Fetch users
20
+ users = api.users.get_users_paginated({"sort": "username"})
21
21
 
22
22
  # Print the result
23
- print("Streams:", streams.data)
23
+ for user in users.data.get("users", []):
24
+ print(f"Username: {user['username']}, Email: {user['email']}, id: {user['id']}")
24
25
  ```
25
26
 
26
27
  Planned:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "graylog-api-client"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "A Python wrapper for the Graylog REST API"
5
5
  authors = [
6
6
  {name = "Chrxxxxs",email = "134285960+Chrxxxxs@users.noreply.github.com"}
@@ -0,0 +1,13 @@
1
+ from .plugins import Plugins
2
+ from .authz import Endpoint_AUTH
3
+ from .search import Endpoint_SEARCH
4
+ from .users import Endpoint_USER
5
+ from .views import Endpoint_VIEWS
6
+
7
+ __all__ = [
8
+ "Plugins",
9
+ "Endpoint_AUTH",
10
+ "Endpoint_SEARCH",
11
+ "Endpoint_USER",
12
+ "Endpoint_VIEWS"
13
+ ]
@@ -0,0 +1,12 @@
1
+ from ..data_structures import GraylogApiResult
2
+ from ..rest_adapter import RestAdapter
3
+
4
+
5
+ class Endpoint_TEMPLATE:
6
+ # Graylog Endpoint for /template
7
+ def __init__(self, rest_adapter: RestAdapter):
8
+ self._rest_adapter = rest_adapter
9
+
10
+
11
+ # New Endpoints should be created using this template. The class name should be changed to the name of the endpoint, and the methods should be added as needed.
12
+ _ = GraylogApiResult # This is a placeholder to avoid linter errors for unused imports.
@@ -1,27 +1,33 @@
1
1
  from ..data_structures import GraylogApiResult
2
2
  from ..rest_adapter import RestAdapter
3
- from typing import Dict
3
+
4
4
 
5
5
  class Endpoint_AUTH:
6
+ # Graylog Endpoint for /authz
6
7
  def __init__(self, rest_adapter: RestAdapter):
7
8
  self._rest_adapter = rest_adapter
8
9
 
9
10
  def get_grants_overview(self) -> GraylogApiResult:
11
+ """Graylog API Route: GET /authz/grants-overview"""
10
12
  overview = self._rest_adapter.get("authz/grants-overview")
11
13
  return overview
12
14
 
13
- def get_roles(self, parameters: Dict = None) -> GraylogApiResult:
15
+ def get_roles(self, parameters: dict | None = None) -> GraylogApiResult:
16
+ """Graylog API Route: GET /authz/roles"""
14
17
  roles = self._rest_adapter.get("authz/roles", parameters)
15
18
  return roles
16
19
 
17
- def get_roles_of_user(self, username: str, parameters: Dict = None) -> GraylogApiResult:
20
+ def get_roles_of_user(self, username: str, parameters: dict | None = None) -> GraylogApiResult:
21
+ """Graylog API Route: GET /authz/roles/user/{username}"""
18
22
  roles = self._rest_adapter.get(f"authz/roles/user/{username}", parameters)
19
23
  return roles
20
24
 
21
25
  def get_role_by_id(self, role_id: str) -> GraylogApiResult:
26
+ """Graylog API Route: GET /authz/roles/{role_id}"""
22
27
  roles = self._rest_adapter.get(f"authz/roles/{role_id}")
23
28
  return roles
24
29
 
25
- def get_assignees_of_role(self, role_id: str, parameters: Dict = None) -> GraylogApiResult:
30
+ def get_assignees_of_role(self, role_id: str, parameters: dict | None = None) -> GraylogApiResult:
31
+ """Graylog API Route: GET /authz/roles/{role_id}/assignees"""
26
32
  assignees = self._rest_adapter.get(f"authz/roles/{role_id}/assignees", parameters)
27
- return assignees
33
+ return assignees
@@ -1,19 +1,21 @@
1
1
  from ...data_structures import GraylogApiResult
2
2
  from ...rest_adapter import RestAdapter
3
- from typing import Union, Dict
4
- from datetime import datetime
3
+
5
4
 
6
5
  class SecurityApp:
6
+ # Graylog Endpoint for /plugins/org.graylog.plugins.securityapp
7
7
  def __init__(self, rest_adapter: RestAdapter):
8
8
  self._rest_adapter = rest_adapter
9
9
  self.Assets = Assets(rest_adapter)
10
10
 
11
+
11
12
  class Assets:
13
+ # Graylog Endpoint for /plugins/org.graylog.plugins.securityapp.asset
12
14
  def __init__(self, rest_adapter: RestAdapter):
13
15
  self._rest_adapter = rest_adapter
14
-
15
- def get_assets(self, *, sort: str = "name", page: int = 1, per_page: int = 15, query: str = "",\
16
- filters: str = "", direction: str = "asc") -> GraylogApiResult:
16
+
17
+ def get_assets(self, *, sort: str = "name", page: int = 1, per_page: int = 15, query: str = "",
18
+ filters: str = "", direction: str = "asc") -> GraylogApiResult:
17
19
  parameters = {
18
20
  "sort": sort,
19
21
  "page": page,
@@ -24,7 +26,7 @@ class Assets:
24
26
  }
25
27
  result = self._rest_adapter.get("plugins/org.graylog.plugins.securityapp.asset/assets", parameters)
26
28
  return result
27
-
29
+
28
30
  # The API Browser is very confusing/wrong for creating assets
29
31
  def create_user_asset(
30
32
  self, *, name: str, usernames: list[str], user_ids: list[str] = [], email_addresses: list[str] = [], first_name: str = "", last_name: str = "", category: list[str] = [], priority: int = 1
@@ -45,10 +47,10 @@ class Assets:
45
47
  }
46
48
  result = self._rest_adapter.post("plugins/org.graylog.plugins.securityapp.asset/assets", data=data)
47
49
  return result
48
-
50
+
49
51
  def create_machine_asset(
50
52
  self, *, name: str, hostnames: list[str], ip_addresses: list[str] = [], mac_addresses: list[str] = [], category: list[str] = [], custom_fields: dict[str, str] = {},
51
- description: str = "", geo_info: dict[str, int|str] = {}, owner: str = "", priority: int = 1
53
+ description: str = "", geo_info: dict[str, int | str] = {}, owner: str = "", priority: int = 1
52
54
  ) -> GraylogApiResult:
53
55
  """Create a machine asset."""
54
56
  data = {
@@ -68,9 +70,8 @@ class Assets:
68
70
  }
69
71
  result = self._rest_adapter.post("plugins/org.graylog.plugins.securityapp.asset/assets", data=data)
70
72
  return result
71
-
73
+
72
74
  def add_categories_to_multiple_assets(self, *, asset_ids: list[str], categories: list[str]) -> GraylogApiResult:
73
- # Untested
74
75
  data = {
75
76
  "asset_ids": asset_ids,
76
77
  "categories": categories,
@@ -83,7 +84,7 @@ class Assets:
83
84
  f"plugins/org.graylog.plugins.securityapp.asset/assets/{asset_id}"
84
85
  )
85
86
  return result
86
-
87
+
87
88
  def edit_asset_by_id(self, asset_id: str, **updates) -> GraylogApiResult:
88
89
  """Edit the asset with the given ID by passing the updates as keyword arguments."""
89
90
  current_state = self.get_asset_by_id_detailed(asset_id)
@@ -93,9 +94,9 @@ class Assets:
93
94
  f"plugins/org.graylog.plugins.securityapp.asset/assets/{asset_id}", data=payload
94
95
  )
95
96
  return result
96
-
97
+
97
98
  def delete_asset_by_id(self, asset_id: str) -> GraylogApiResult:
98
99
  result = self._rest_adapter.delete(
99
100
  f"plugins/org.graylog.plugins.securityapp.asset/assets/{asset_id}"
100
101
  )
101
- return result
102
+ return result
@@ -1,7 +1,8 @@
1
1
  from ...rest_adapter import RestAdapter
2
2
  from .SecurityApp import SecurityApp
3
3
 
4
+
4
5
  class Plugins:
5
6
  def __init__(self, rest_adapter: RestAdapter):
6
7
  self._rest_adapter = rest_adapter
7
- self.SecurityApp = SecurityApp(rest_adapter)
8
+ self.SecurityApp = SecurityApp(rest_adapter)
@@ -0,0 +1,28 @@
1
+ from ..data_structures import GraylogApiResult
2
+ from ..rest_adapter import RestAdapter
3
+ from typing import Literal
4
+
5
+
6
+ class Endpoint_SEARCH:
7
+ # Graylog Endpoint for /search
8
+ def __init__(self, rest_adapter: RestAdapter):
9
+ self._rest_adapter = rest_adapter
10
+
11
+ def post_search_query(self, query: str, start: int, timerange: dict, streams: list[str], stream_categories: list[str] | None = None,
12
+ sort: str | None = None, sort_order: Literal["Ascending", "Descending"] | None = None,
13
+ fields: list[str] | None = None, size: int = 50) -> GraylogApiResult:
14
+ """Graylog API Route: POST /search/messages \n
15
+ start replaces the "from" parameter in the API."""
16
+ data = {
17
+ "query": query,
18
+ "from": str(start),
19
+ "timerange": timerange,
20
+ "streams": streams,
21
+ "stream_categories": stream_categories,
22
+ "sort": sort,
23
+ "sort_order": sort_order,
24
+ "fields": fields,
25
+ "size": str(size),
26
+ }
27
+ result = self._rest_adapter.post("search/messages", data=data)
28
+ return result
@@ -0,0 +1,68 @@
1
+ from ..data_structures import GraylogApiResult
2
+ from ..rest_adapter import RestAdapter
3
+ from warnings import deprecated
4
+
5
+
6
+ class Endpoint_USER:
7
+ # Graylog Endpoint for /users
8
+ def __init__(self, rest_adapter: RestAdapter):
9
+ self._rest_adapter = rest_adapter
10
+
11
+ def create_user(self, username: str, first_name: str, last_name: str, email: str, password: str, permissions: list[str], data: dict | None = None) -> GraylogApiResult:
12
+ """Graylog API Route: POST /users"""
13
+ user_data = {
14
+ "username": username,
15
+ "first_name": first_name,
16
+ "last_name": last_name,
17
+ "email": email,
18
+ "password": password,
19
+ }
20
+ if permissions:
21
+ user_data["permissions"] = permissions
22
+ if data:
23
+ user_data.update(data)
24
+ result = self._rest_adapter.post("users", data=user_data)
25
+ return result
26
+
27
+ @deprecated("This method is marked as deprecated by Graylog and will not work with future Graylog versions. Use the 'get_users_paginated' method instead.")
28
+ def get_users(self, parameters: dict | None = None) -> GraylogApiResult:
29
+ """Graylog API Route: GET /users"""
30
+ result = self._rest_adapter.get("users", parameters)
31
+ return result
32
+
33
+ def get_users_paginated(self, parameters: dict | None = None) -> GraylogApiResult:
34
+ """Graylog API Route: GET /users/paginated"""
35
+ result = self._rest_adapter.get("users/paginated", parameters)
36
+ return result
37
+
38
+ def get_user_by_id(self, user_id: str) -> GraylogApiResult:
39
+ """Graylog API Route: GET /users/id/{user_id}"""
40
+ result = self._rest_adapter.get(f"users/id/{user_id}")
41
+ return result
42
+
43
+ def get_user_by_username(self, username: str) -> GraylogApiResult:
44
+ """Graylog API Route: GET /users/{username}"""
45
+ result = self._rest_adapter.get(f"users/{username}")
46
+ return result
47
+
48
+ def get_user_tokens_by_id(self, user_id: str) -> GraylogApiResult:
49
+ """Graylog API Route: GET /users/{user_id}/tokens"""
50
+ result = self._rest_adapter.get(f"users/{user_id}/tokens")
51
+ return result
52
+
53
+ def delete_user_by_id(self, user_id: str) -> GraylogApiResult:
54
+ """Graylog API Route: DELETE /users/id/{user_id}"""
55
+ result = self._rest_adapter.delete(f"users/id/{user_id}")
56
+ return result
57
+
58
+ def delete_user_by_username(self, username: str) -> GraylogApiResult:
59
+ """Graylog API Route: DELETE /users/{username}"""
60
+ result = self._rest_adapter.delete(f"users/{username}")
61
+ return result
62
+
63
+ def change_user_status(self, user_id: str, status: str) -> GraylogApiResult:
64
+ """Graylog API Route: PUT /users/{user_id}/status/{status}"""
65
+ if status not in ["enabled", "disabled", "deleted"]:
66
+ raise ValueError(f"Status must be either 'enabled', 'disabled' or 'deleted' but was: {status}")
67
+ result = self._rest_adapter.put(f"users/{user_id}/status/{status}")
68
+ return result
@@ -0,0 +1,18 @@
1
+ from ..data_structures import GraylogApiResult
2
+ from ..rest_adapter import RestAdapter
3
+
4
+
5
+ class Endpoint_VIEWS:
6
+ # Graylog Endpoint for /views
7
+ def __init__(self, rest_adapter: RestAdapter):
8
+ self._rest_adapter = rest_adapter
9
+
10
+ def get_views(self, parameters: dict | None = None) -> GraylogApiResult:
11
+ """Graylog API Route: GET /views"""
12
+ result = self._rest_adapter.get("views", parameters)
13
+ return result
14
+
15
+ def get_view_by_id(self, view_id: str) -> GraylogApiResult:
16
+ """Graylog API Route: GET /views/{view_id}"""
17
+ result = self._rest_adapter.get(f"views/{view_id}")
18
+ return result
@@ -0,0 +1,123 @@
1
+ import logging
2
+ from typing import Literal
3
+ from warnings import deprecated
4
+
5
+ from .rest_adapter import RestAdapter
6
+ from .data_structures import GraylogApiResult
7
+ from .endpoints import Plugins, Endpoint_AUTH, Endpoint_SEARCH, Endpoint_USER, Endpoint_VIEWS
8
+
9
+
10
+ class GraylogAPI:
11
+ def __init__(self, host: str, api_key: str, ssl_verify: str | bool = True, logger: logging.Logger | None = None):
12
+ """GraylogAPI client
13
+
14
+ :param host: The hostname of the Graylog API endpoint plus the protocol. Example: https://graylog.com/api
15
+ :param api_key: An API Key to authenticate with Graylog
16
+ :param ssl_verify: Enables or Disables TLS Certificate verification. For a custom certificate, this value must a path pointing to the certificate, defaults to True
17
+ :param logger: The logger being used by the Adapter, will use a new one if none is given, defaults to None
18
+ """
19
+ self._rest_adapter = RestAdapter(host=host, api_key=api_key, ssl_verify=ssl_verify, logger=logger)
20
+ self.plugins = Plugins(rest_adapter=self._rest_adapter)
21
+ self.authz = Endpoint_AUTH(rest_adapter=self._rest_adapter)
22
+ self.users = Endpoint_USER(rest_adapter=self._rest_adapter)
23
+ self.views = Endpoint_VIEWS(rest_adapter=self._rest_adapter)
24
+ self.search = Endpoint_SEARCH(rest_adapter=self._rest_adapter)
25
+
26
+ # The endpoints grouped like they are in the api-browser
27
+ # /authz Authorization
28
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'authz' attribute instead.")
29
+ def get_auth_grants_overview(self) -> GraylogApiResult:
30
+ overview = self.authz.get_grants_overview()
31
+ return overview
32
+
33
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'authz' attribute instead.")
34
+ def get_auth_roles(self, parameters: dict | None = None) -> GraylogApiResult:
35
+ roles = self.authz.get_roles(parameters)
36
+ return roles
37
+
38
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'authz' attribute instead.")
39
+ def get_auth_roles_of_user(self, username: str, parameters: dict | None = None) -> GraylogApiResult:
40
+ roles = self.authz.get_roles_of_user(username, parameters)
41
+ return roles
42
+
43
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'authz' attribute instead.")
44
+ def get_auth_role_by_id(self, role_id: str) -> GraylogApiResult:
45
+ roles = self.authz.get_role_by_id(role_id)
46
+ return roles
47
+
48
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'authz' attribute instead.")
49
+ def get_auth_assignees_of_role(self, role_id: str, parameters: dict | None = None) -> GraylogApiResult:
50
+ assignees = self.authz.get_assignees_of_role(role_id, parameters)
51
+ return assignees
52
+
53
+ # /search Search Options (Decorators, Export, Functions etc.)
54
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'search' attribute instead.")
55
+ def post_search_query(self, query: str, start: int, timerange: dict, streams: list[str], stream_categories: list[str] | None = None,
56
+ sort: str | None = None, sort_order: Literal["Ascending", "Descending"] | None = None,
57
+ fields: list[str] | None = None, size: int = 50) -> GraylogApiResult:
58
+ """start replaces the "from" parameter in the API"""
59
+ result = self.search.post_search_query(query, start, timerange, streams, stream_categories, sort, sort_order, fields, size)
60
+ return result
61
+
62
+ # /streams
63
+ @deprecated("This method is deprecated by Graylog and will not work with future Graylog versions")
64
+ def get_streams(self) -> GraylogApiResult:
65
+ result = self._rest_adapter.get("streams")
66
+ return result
67
+
68
+ # /users
69
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'users' attribute instead.")
70
+ def create_user(self, username: str, first_name: str, last_name: str, email: str, password: str, permissions: list[str], data: dict | None = None) -> GraylogApiResult:
71
+ result = self.users.create_user(username, first_name, last_name, email, password, permissions, data)
72
+ return result
73
+
74
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'users' attribute instead.")
75
+ def get_users(self, parameters: dict | None = None) -> GraylogApiResult:
76
+ result = self.users.get_users(parameters)
77
+ return result
78
+
79
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'users' attribute instead.")
80
+ def get_users_paginated(self, parameters: dict | None = None) -> GraylogApiResult:
81
+ result = self.users.get_users_paginated(parameters)
82
+ return result
83
+
84
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'users' attribute instead.")
85
+ def get_user_by_id(self, user_id: str) -> GraylogApiResult:
86
+ result = self.users.get_user_by_id(user_id)
87
+ return result
88
+
89
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'users' attribute instead.")
90
+ def get_user_by_username(self, username: str) -> GraylogApiResult:
91
+ result = self.users.get_user_by_username(username)
92
+ return result
93
+
94
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'users' attribute instead.")
95
+ def get_user_tokens_by_id(self, user_id: str) -> GraylogApiResult:
96
+ result = self.users.get_user_tokens_by_id(user_id)
97
+ return result
98
+
99
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'users' attribute instead.")
100
+ def delete_user_by_id(self, user_id: str) -> GraylogApiResult:
101
+ result = self.users.delete_user_by_id(user_id)
102
+ return result
103
+
104
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'users' attribute instead.")
105
+ def delete_user_by_username(self, username: str) -> GraylogApiResult:
106
+ result = self.users.delete_user_by_username(username)
107
+ return result
108
+
109
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'users' attribute instead.")
110
+ def change_user_status(self, user_id: str, status: str) -> GraylogApiResult:
111
+ result = self.users.change_user_status(user_id, status)
112
+ return result
113
+
114
+ # /views Main Views Endpoints
115
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'views' attribute instead.")
116
+ def get_views(self, parameters: dict | None = None) -> GraylogApiResult:
117
+ result = self.views.get_views(parameters)
118
+ return result
119
+
120
+ @deprecated("This method is deprecated and will be removed in a future version. Use the 'views' attribute instead.")
121
+ def get_view_by_id(self, view_id: str) -> GraylogApiResult:
122
+ result = self.views.get_view_by_id(view_id)
123
+ return result
@@ -1,180 +0,0 @@
1
- import logging
2
- from datetime import datetime
3
- from typing import List, Literal, Union, Dict
4
-
5
- from .rest_adapter import RestAdapter
6
- from .data_structures import GraylogApiResult
7
- from .endpoints.authz import Endpoint_AUTH
8
- from .endpoints.plugins import Plugins
9
-
10
-
11
- class GraylogAPI:
12
- def __init__(self, host: str, api_key: str, ssl_verify: Union[str, bool] = True, logger: logging.Logger = None):
13
- """GraylogAPI client
14
-
15
- :param host: The hostname of the Graylog API endpoint plus the protocol. Example: https://graylog.com/api
16
- :param api_key: An API Key to authenticate with Graylog
17
- :param ssl_verify: Enables or Disables TLS Certificate verification. For a custom certificate, this value must a path pointing to the certificate, defaults to True
18
- :param logger: The logger being used by the Adapter, will use a new one if none is given, defaults to None
19
- """
20
- self._rest_adapter = RestAdapter(host=host, api_key=api_key, ssl_verify=ssl_verify, logger=logger)
21
- self.authz = Endpoint_AUTH(rest_adapter=self._rest_adapter)
22
- self.plugins = Plugins(rest_adapter=self._rest_adapter)
23
-
24
- # The endpoints grouped like they are in the api-browser
25
- # /authz Authorization
26
- def get_auth_grants_overview(self) -> GraylogApiResult:
27
- overview = self.authz.get_grants_overview()
28
- return overview
29
-
30
- def get_auth_roles(self, parameters: Dict = None) -> GraylogApiResult:
31
- roles = self.authz.get_roles(parameters)
32
- return roles
33
-
34
- def get_auth_roles_of_user(self, username: str, parameters: Dict = None) -> GraylogApiResult:
35
- roles = self.authz.get_roles_of_user(username, parameters)
36
- return roles
37
-
38
- def get_auth_role_by_id(self, role_id: str) -> GraylogApiResult:
39
- roles = self.authz.get_role_by_id(role_id)
40
- return roles
41
-
42
- def get_auth_assignees_of_role(self, role_id: str, parameters: Dict = None) -> GraylogApiResult:
43
- assignees = self.authz.get_assignees_of_role(role_id, parameters)
44
- return assignees
45
-
46
- # /ca
47
- def get_ca(self) -> GraylogApiResult:
48
- result = self._rest_adapter.get("ca")
49
- return result
50
-
51
- # /certificates
52
- def get_certificates(self) -> GraylogApiResult:
53
- result = self._rest_adapter.get("certificates")
54
- return result
55
-
56
- # /cluster
57
- def get_cluster(self) -> GraylogApiResult:
58
- result = self._rest_adapter.get("cluster")
59
- return result
60
-
61
- def get_processbufferdump(self, node_id: str = "") -> GraylogApiResult:
62
- result = self._rest_adapter.get(f"cluster/{node_id}/processbufferdump".replace("//", "/"))
63
- return result
64
-
65
- def get_jvminfo(self, node_id: str) -> GraylogApiResult:
66
- result = self._rest_adapter.get(f"cluster/{node_id}/jvm")
67
- return result
68
-
69
- # /contentstream
70
- # /dashboards
71
- # /datanodes
72
- # /datanode
73
- # /api-docs API-Documentation
74
- # /enterprise
75
- # /entitylists
76
- # /entity_scopes
77
- # /entity_suggestions
78
- # /events
79
- # /system/inputs/{inputId}/extractors Extractors
80
- # /favorites
81
- # /views/fields FieldTypes
82
- # /system/indexer Indexer
83
- # /search/universal/absolute Legacy Message Search
84
- # /messages
85
- # /migration
86
- # /system/pipelines Pipelines
87
- # /plugins
88
- # /remote-reindex-migration
89
- # /roles
90
- # /views/search Search
91
- # /search Search Options (Decorators, Export, Functions etc.)
92
- def post_search_query(self, query: str, start: int, timerange: dict, streams: list[str], stream_categories: list[str] = None,\
93
- sort: str = None, sort_order: Literal["Ascending", "Descending"] = None,\
94
- fields: list[str] = None, size: int = 50) -> GraylogApiResult:
95
- """start replaces the "from" parameter in the API"""
96
- data = {
97
- "query": query,
98
- "from": str(start),
99
- "timerange": timerange,
100
- "streams": streams,
101
- "stream_categories": stream_categories,
102
- "sort": sort,
103
- "sort_order": sort_order,
104
- "fields": fields,
105
- "size": str(size),
106
- }
107
- result = self._rest_adapter.post("search/messages", data=data)
108
- return result
109
-
110
- # /views/searchjobs Searchjobs
111
- # /sidecars
112
- # /sidecar
113
- # /startpage
114
- # /system/inputs/{inputId}/staticfields Staticfields
115
- # /streams
116
- def get_streams(self) -> GraylogApiResult:
117
- result = self._rest_adapter.get("streams")
118
- return result
119
-
120
- # /system Main System endpoints
121
- # /telemetry
122
- # /token_usage
123
- # /users
124
- def create_user(self, username: str, first_name: str, last_name: str, email: str, password: str, permissions: List[str], data: Dict = None) -> GraylogApiResult:
125
- user_data = {
126
- "username": username,
127
- "first_name": first_name,
128
- "last_name": last_name,
129
- "email": email,
130
- "password": password,
131
- }
132
- if permissions:
133
- user_data["permissions"] = permissions
134
- if data:
135
- user_data.update(data)
136
- result = self._rest_adapter.post("users", data=user_data)
137
- return result
138
-
139
- def get_users(self, parameters: Dict = None) -> GraylogApiResult:
140
- result = self._rest_adapter.get("users", parameters)
141
- return result
142
-
143
- def get_users_paginated(self, parameters: Dict = None) -> GraylogApiResult:
144
- result = self._rest_adapter.get("users/paginated", parameters)
145
- return result
146
-
147
- def get_user_by_id(self, user_id: str) -> GraylogApiResult:
148
- result = self._rest_adapter.get(f"users/id/{user_id}")
149
- return result
150
-
151
- def get_user_by_username(self, username: str) -> GraylogApiResult:
152
- result = self._rest_adapter.get(f"users/{username}")
153
- return result
154
-
155
- def get_user_tokens_by_id(self, user_id: str) -> GraylogApiResult:
156
- result = self._rest_adapter.get(f"users/{user_id}/tokens")
157
- return result
158
-
159
- def delete_user_by_id(self, user_id: str) -> GraylogApiResult:
160
- result = self._rest_adapter.delete(f"users/id/{user_id}")
161
- return result
162
-
163
- def delete_user_by_username(self, username: str) -> GraylogApiResult:
164
- result = self._rest_adapter.delete(f"users/{username}")
165
- return result
166
-
167
- def change_user_status(self, user_id: str, status: str) -> GraylogApiResult:
168
- if status not in ["enabled", "disabled", "deleted"]:
169
- raise ValueError(f"Status must be either 'enabled', 'disabled' or 'deleted' but was: {status}")
170
- result = self._rest_adapter.put(f"users/{user_id}/status/{status}")
171
- return result
172
-
173
- # /views Main Views Endpoints
174
- def get_views(self, parameters: Dict = None) -> GraylogApiResult:
175
- result = self._rest_adapter.get("views", parameters)
176
- return result
177
-
178
- def get_view_by_id(self, view_id: str) -> GraylogApiResult:
179
- result = self._rest_adapter.get(f"views/{view_id}")
180
- return result