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.
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/PKG-INFO +6 -5
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/README.md +5 -4
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/pyproject.toml +1 -1
- graylog_api_client-0.2.1/src/graylog_api_client/endpoints/__init__.py +13 -0
- graylog_api_client-0.2.1/src/graylog_api_client/endpoints/_template.py +12 -0
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/endpoints/authz.py +11 -5
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/endpoints/plugins/SecurityApp.py +14 -13
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/endpoints/plugins/__init__.py +2 -1
- graylog_api_client-0.2.1/src/graylog_api_client/endpoints/search.py +28 -0
- graylog_api_client-0.2.1/src/graylog_api_client/endpoints/users.py +68 -0
- graylog_api_client-0.2.1/src/graylog_api_client/endpoints/views.py +18 -0
- graylog_api_client-0.2.1/src/graylog_api_client/graylog_api_client.py +123 -0
- graylog_api_client-0.2.0/src/graylog_api_client/graylog_api_client.py +0 -180
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/LICENSE +0 -0
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/__init__.py +0 -0
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/data_structures.py +0 -0
- {graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/exceptions.py +0 -0
- {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.
|
|
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
|
-
|
|
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
|
|
38
|
-
|
|
37
|
+
# Example: Fetch users
|
|
38
|
+
users = api.users.get_users_paginated({"sort": "username"})
|
|
39
39
|
|
|
40
40
|
# Print the result
|
|
41
|
-
|
|
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
|
-
|
|
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
|
|
20
|
-
|
|
19
|
+
# Example: Fetch users
|
|
20
|
+
users = api.users.get_users_paginated({"sort": "username"})
|
|
21
21
|
|
|
22
22
|
# Print the result
|
|
23
|
-
|
|
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:
|
|
@@ -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.
|
{graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/endpoints/authz.py
RENAMED
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
from ..data_structures import GraylogApiResult
|
|
2
2
|
from ..rest_adapter import RestAdapter
|
|
3
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
{graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/data_structures.py
RENAMED
|
File without changes
|
|
File without changes
|
{graylog_api_client-0.2.0 → graylog_api_client-0.2.1}/src/graylog_api_client/rest_adapter.py
RENAMED
|
File without changes
|