binalyze-air-sdk 1.0.1__py3-none-any.whl → 1.0.3__py3-none-any.whl
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.
- binalyze_air/__init__.py +77 -77
- binalyze_air/apis/__init__.py +67 -27
- binalyze_air/apis/acquisitions.py +107 -0
- binalyze_air/apis/api_tokens.py +49 -0
- binalyze_air/apis/assets.py +161 -0
- binalyze_air/apis/audit_logs.py +26 -0
- binalyze_air/apis/{authentication.py → auth.py} +29 -27
- binalyze_air/apis/auto_asset_tags.py +79 -75
- binalyze_air/apis/backup.py +177 -0
- binalyze_air/apis/baseline.py +46 -0
- binalyze_air/apis/cases.py +225 -0
- binalyze_air/apis/cloud_forensics.py +116 -0
- binalyze_air/apis/event_subscription.py +96 -96
- binalyze_air/apis/evidence.py +249 -53
- binalyze_air/apis/interact.py +153 -36
- binalyze_air/apis/investigation_hub.py +234 -0
- binalyze_air/apis/license.py +104 -0
- binalyze_air/apis/logger.py +83 -0
- binalyze_air/apis/multipart_upload.py +201 -0
- binalyze_air/apis/notifications.py +115 -0
- binalyze_air/apis/organizations.py +267 -0
- binalyze_air/apis/params.py +44 -39
- binalyze_air/apis/policies.py +186 -0
- binalyze_air/apis/preset_filters.py +79 -0
- binalyze_air/apis/recent_activities.py +71 -0
- binalyze_air/apis/relay_server.py +104 -0
- binalyze_air/apis/settings.py +395 -27
- binalyze_air/apis/tasks.py +80 -0
- binalyze_air/apis/triage.py +197 -0
- binalyze_air/apis/user_management.py +183 -74
- binalyze_air/apis/webhook_executions.py +50 -0
- binalyze_air/apis/webhooks.py +322 -230
- binalyze_air/base.py +207 -133
- binalyze_air/client.py +217 -1337
- binalyze_air/commands/__init__.py +175 -145
- binalyze_air/commands/acquisitions.py +661 -387
- binalyze_air/commands/api_tokens.py +55 -0
- binalyze_air/commands/assets.py +324 -362
- binalyze_air/commands/{authentication.py → auth.py} +36 -36
- binalyze_air/commands/auto_asset_tags.py +230 -230
- binalyze_air/commands/backup.py +47 -0
- binalyze_air/commands/baseline.py +32 -396
- binalyze_air/commands/cases.py +609 -602
- binalyze_air/commands/cloud_forensics.py +88 -0
- binalyze_air/commands/event_subscription.py +101 -101
- binalyze_air/commands/evidences.py +918 -988
- binalyze_air/commands/interact.py +172 -58
- binalyze_air/commands/investigation_hub.py +315 -0
- binalyze_air/commands/license.py +183 -0
- binalyze_air/commands/logger.py +126 -0
- binalyze_air/commands/multipart_upload.py +363 -0
- binalyze_air/commands/notifications.py +45 -0
- binalyze_air/commands/organizations.py +200 -221
- binalyze_air/commands/policies.py +175 -203
- binalyze_air/commands/preset_filters.py +55 -0
- binalyze_air/commands/recent_activities.py +32 -0
- binalyze_air/commands/relay_server.py +144 -0
- binalyze_air/commands/settings.py +431 -29
- binalyze_air/commands/tasks.py +95 -56
- binalyze_air/commands/triage.py +224 -360
- binalyze_air/commands/user_management.py +351 -126
- binalyze_air/commands/webhook_executions.py +77 -0
- binalyze_air/config.py +244 -244
- binalyze_air/exceptions.py +49 -49
- binalyze_air/http_client.py +426 -305
- binalyze_air/models/__init__.py +287 -285
- binalyze_air/models/acquisitions.py +365 -250
- binalyze_air/models/api_tokens.py +73 -0
- binalyze_air/models/assets.py +438 -438
- binalyze_air/models/audit.py +247 -272
- binalyze_air/models/audit_logs.py +14 -0
- binalyze_air/models/{authentication.py → auth.py} +69 -69
- binalyze_air/models/auto_asset_tags.py +227 -116
- binalyze_air/models/backup.py +138 -0
- binalyze_air/models/baseline.py +231 -231
- binalyze_air/models/cases.py +275 -275
- binalyze_air/models/cloud_forensics.py +145 -0
- binalyze_air/models/event_subscription.py +170 -171
- binalyze_air/models/evidence.py +65 -65
- binalyze_air/models/evidences.py +367 -348
- binalyze_air/models/interact.py +266 -135
- binalyze_air/models/investigation_hub.py +265 -0
- binalyze_air/models/license.py +150 -0
- binalyze_air/models/logger.py +83 -0
- binalyze_air/models/multipart_upload.py +352 -0
- binalyze_air/models/notifications.py +138 -0
- binalyze_air/models/organizations.py +293 -293
- binalyze_air/models/params.py +153 -127
- binalyze_air/models/policies.py +260 -249
- binalyze_air/models/preset_filters.py +79 -0
- binalyze_air/models/recent_activities.py +70 -0
- binalyze_air/models/relay_server.py +121 -0
- binalyze_air/models/settings.py +538 -84
- binalyze_air/models/tasks.py +215 -149
- binalyze_air/models/triage.py +141 -142
- binalyze_air/models/user_management.py +200 -97
- binalyze_air/models/webhook_executions.py +33 -0
- binalyze_air/queries/__init__.py +121 -133
- binalyze_air/queries/acquisitions.py +155 -155
- binalyze_air/queries/api_tokens.py +46 -0
- binalyze_air/queries/assets.py +186 -105
- binalyze_air/queries/audit.py +400 -416
- binalyze_air/queries/{authentication.py → auth.py} +55 -55
- binalyze_air/queries/auto_asset_tags.py +59 -59
- binalyze_air/queries/backup.py +66 -0
- binalyze_air/queries/baseline.py +21 -185
- binalyze_air/queries/cases.py +292 -292
- binalyze_air/queries/cloud_forensics.py +137 -0
- binalyze_air/queries/event_subscription.py +54 -54
- binalyze_air/queries/evidence.py +139 -139
- binalyze_air/queries/evidences.py +279 -279
- binalyze_air/queries/interact.py +140 -28
- binalyze_air/queries/investigation_hub.py +329 -0
- binalyze_air/queries/license.py +85 -0
- binalyze_air/queries/logger.py +58 -0
- binalyze_air/queries/multipart_upload.py +180 -0
- binalyze_air/queries/notifications.py +71 -0
- binalyze_air/queries/organizations.py +222 -222
- binalyze_air/queries/params.py +154 -115
- binalyze_air/queries/policies.py +149 -149
- binalyze_air/queries/preset_filters.py +60 -0
- binalyze_air/queries/recent_activities.py +44 -0
- binalyze_air/queries/relay_server.py +42 -0
- binalyze_air/queries/settings.py +533 -20
- binalyze_air/queries/tasks.py +125 -81
- binalyze_air/queries/triage.py +230 -230
- binalyze_air/queries/user_management.py +193 -83
- binalyze_air/queries/webhook_executions.py +39 -0
- binalyze_air_sdk-1.0.3.dist-info/METADATA +752 -0
- binalyze_air_sdk-1.0.3.dist-info/RECORD +132 -0
- {binalyze_air_sdk-1.0.1.dist-info → binalyze_air_sdk-1.0.3.dist-info}/WHEEL +1 -1
- binalyze_air/apis/endpoints.py +0 -22
- binalyze_air/apis/evidences.py +0 -216
- binalyze_air/apis/users.py +0 -68
- binalyze_air/commands/users.py +0 -101
- binalyze_air/models/endpoints.py +0 -76
- binalyze_air/models/users.py +0 -82
- binalyze_air/queries/endpoints.py +0 -25
- binalyze_air/queries/users.py +0 -69
- binalyze_air_sdk-1.0.1.dist-info/METADATA +0 -635
- binalyze_air_sdk-1.0.1.dist-info/RECORD +0 -82
- {binalyze_air_sdk-1.0.1.dist-info → binalyze_air_sdk-1.0.3.dist-info}/top_level.txt +0 -0
binalyze_air/commands/assets.py
CHANGED
@@ -1,363 +1,325 @@
|
|
1
|
-
"""
|
2
|
-
Asset-related commands for the Binalyze AIR SDK.
|
3
|
-
Fixed to match API documentation exactly.
|
4
|
-
"""
|
5
|
-
|
6
|
-
from typing import List, Union, Optional, Dict, Any
|
7
|
-
|
8
|
-
from ..base import Command
|
9
|
-
from ..models.assets import AssetFilter
|
10
|
-
from ..http_client import HTTPClient
|
11
|
-
|
12
|
-
|
13
|
-
class RebootAssetsCommand(Command[Dict[str, Any]]):
|
14
|
-
"""Command to reboot assets by filter - FIXED to match API documentation."""
|
15
|
-
|
16
|
-
def __init__(
|
17
|
-
self,
|
18
|
-
http_client: HTTPClient,
|
19
|
-
asset_filter: AssetFilter
|
20
|
-
):
|
21
|
-
self.http_client = http_client
|
22
|
-
self.asset_filter = asset_filter
|
23
|
-
|
24
|
-
def execute(self) -> Dict[str, Any]:
|
25
|
-
"""Execute the reboot command with correct payload structure."""
|
26
|
-
# Use the correct payload structure as per API documentation
|
27
|
-
payload = {
|
28
|
-
"filter": self.asset_filter.to_filter_dict()
|
29
|
-
}
|
30
|
-
|
31
|
-
# FIXED: Correct endpoint URL (confirmed from API docs)
|
32
|
-
return self.http_client.post("assets/tasks/reboot", json_data=payload)
|
33
|
-
|
34
|
-
|
35
|
-
class ShutdownAssetsCommand(Command[Dict[str, Any]]):
|
36
|
-
"""Command to shutdown assets by filter - FIXED to match API documentation."""
|
37
|
-
|
38
|
-
def __init__(
|
39
|
-
self,
|
40
|
-
http_client: HTTPClient,
|
41
|
-
asset_filter: AssetFilter
|
42
|
-
):
|
43
|
-
self.http_client = http_client
|
44
|
-
self.asset_filter = asset_filter
|
45
|
-
|
46
|
-
def execute(self) -> Dict[str, Any]:
|
47
|
-
"""Execute the shutdown command with correct payload structure."""
|
48
|
-
payload = {
|
49
|
-
"filter": self.asset_filter.to_filter_dict()
|
50
|
-
}
|
51
|
-
|
52
|
-
# FIXED: Correct endpoint URL (following same pattern as reboot)
|
53
|
-
return self.http_client.post("assets/tasks/shutdown", json_data=payload)
|
54
|
-
|
55
|
-
|
56
|
-
class IsolateAssetsCommand(Command[Dict[str, Any]]):
|
57
|
-
"""Command to isolate assets by filter - FIXED to match API documentation."""
|
58
|
-
|
59
|
-
def __init__(
|
60
|
-
self,
|
61
|
-
http_client: HTTPClient,
|
62
|
-
asset_filter: AssetFilter,
|
63
|
-
isolation_settings: Optional[Dict[str, Any]] = None
|
64
|
-
):
|
65
|
-
self.http_client = http_client
|
66
|
-
self.asset_filter = asset_filter
|
67
|
-
self.isolation_settings = isolation_settings or {}
|
68
|
-
|
69
|
-
def execute(self) -> Dict[str, Any]:
|
70
|
-
"""Execute the isolation command with correct payload structure."""
|
71
|
-
payload = {
|
72
|
-
"enabled": True, # Required field for isolation
|
73
|
-
"filter": self.asset_filter.to_filter_dict()
|
74
|
-
}
|
75
|
-
|
76
|
-
# Add isolation settings if provided
|
77
|
-
if self.isolation_settings:
|
78
|
-
payload.update(self.isolation_settings)
|
79
|
-
|
80
|
-
# FIXED: Correct endpoint URL and payload
|
81
|
-
return self.http_client.post("assets/tasks/isolation", json_data=payload)
|
82
|
-
|
83
|
-
|
84
|
-
class UnisolateAssetsCommand(Command[Dict[str, Any]]):
|
85
|
-
"""Command to unisolate (remove isolation from) assets - FIXED to match API documentation."""
|
86
|
-
|
87
|
-
def __init__(
|
88
|
-
self,
|
89
|
-
http_client: HTTPClient,
|
90
|
-
asset_filter: AssetFilter
|
91
|
-
):
|
92
|
-
self.http_client = http_client
|
93
|
-
self.asset_filter = asset_filter
|
94
|
-
|
95
|
-
def execute(self) -> Dict[str, Any]:
|
96
|
-
"""Execute the unisolate command with correct payload structure."""
|
97
|
-
payload = {
|
98
|
-
"enabled": False, # Disable isolation for unisolate
|
99
|
-
"filter": self.asset_filter.to_filter_dict()
|
100
|
-
}
|
101
|
-
|
102
|
-
# FIXED: Correct endpoint URL and payload
|
103
|
-
return self.http_client.post("assets/tasks/isolation", json_data=payload)
|
104
|
-
|
105
|
-
|
106
|
-
class LogRetrievalCommand(Command[Dict[str, Any]]):
|
107
|
-
"""Command to retrieve logs from assets - FIXED endpoint URL and payload structure."""
|
108
|
-
|
109
|
-
def __init__(
|
110
|
-
self,
|
111
|
-
http_client: HTTPClient,
|
112
|
-
asset_filter: AssetFilter,
|
113
|
-
log_settings: Optional[Dict[str, Any]] = None
|
114
|
-
):
|
115
|
-
self.http_client = http_client
|
116
|
-
self.asset_filter = asset_filter
|
117
|
-
self.log_settings = log_settings or {}
|
118
|
-
|
119
|
-
def execute(self) -> Dict[str, Any]:
|
120
|
-
"""Execute the log retrieval command with correct endpoint and payload."""
|
121
|
-
payload = {
|
122
|
-
"filter": self.asset_filter.to_filter_dict()
|
123
|
-
}
|
124
|
-
|
125
|
-
# Add log retrieval settings if provided
|
126
|
-
if self.log_settings:
|
127
|
-
payload.update(self.log_settings)
|
128
|
-
|
129
|
-
# FIXED: Correct endpoint URL to match API specification
|
130
|
-
return self.http_client.post("assets/tasks/retrieve-logs", json_data=payload)
|
131
|
-
|
132
|
-
|
133
|
-
class VersionUpdateCommand(Command[Dict[str, Any]]):
|
134
|
-
"""Command to update version on assets - FIXED to match API documentation."""
|
135
|
-
|
136
|
-
def __init__(
|
137
|
-
self,
|
138
|
-
http_client: HTTPClient,
|
139
|
-
asset_filter: AssetFilter,
|
140
|
-
update_settings: Optional[Dict[str, Any]] = None
|
141
|
-
):
|
142
|
-
self.http_client = http_client
|
143
|
-
self.asset_filter = asset_filter
|
144
|
-
self.update_settings = update_settings or {}
|
145
|
-
|
146
|
-
def execute(self) -> Dict[str, Any]:
|
147
|
-
"""Execute the version update command with correct payload structure."""
|
148
|
-
payload = {
|
149
|
-
"filter": self.asset_filter.to_filter_dict()
|
150
|
-
}
|
151
|
-
|
152
|
-
# Add version update settings if provided
|
153
|
-
if self.update_settings:
|
154
|
-
payload.update(self.update_settings)
|
155
|
-
|
156
|
-
# FIXED: Correct endpoint URL (following tasks pattern)
|
157
|
-
return self.http_client.post("assets/tasks/version-update", json_data=payload)
|
158
|
-
|
159
|
-
|
160
|
-
class UninstallAssetsCommand(Command[Dict[str, Any]]):
|
161
|
-
"""Command to uninstall assets without purging data - FIXED endpoint URL and HTTP method."""
|
162
|
-
|
163
|
-
def __init__(
|
164
|
-
self,
|
165
|
-
http_client: HTTPClient,
|
166
|
-
asset_filter: AssetFilter
|
167
|
-
):
|
168
|
-
self.http_client = http_client
|
169
|
-
self.asset_filter = asset_filter
|
170
|
-
|
171
|
-
def execute(self) -> Dict[str, Any]:
|
172
|
-
"""Execute the uninstall command with correct endpoint, HTTP method and payload structure."""
|
173
|
-
payload = {
|
174
|
-
"filter": self.asset_filter.to_filter_dict()
|
175
|
-
}
|
176
|
-
|
177
|
-
# FIXED: Correct endpoint URL and HTTP method (DELETE, not POST)
|
178
|
-
return self.http_client.delete("assets/uninstall-without-purge", json_data=payload)
|
179
|
-
|
180
|
-
|
181
|
-
class PurgeAndUninstallAssetsCommand(Command[Dict[str, Any]]):
|
182
|
-
"""Command to purge and uninstall assets - FIXED endpoint URL and HTTP method."""
|
183
|
-
|
184
|
-
def __init__(
|
185
|
-
self,
|
186
|
-
http_client: HTTPClient,
|
187
|
-
asset_filter: AssetFilter
|
188
|
-
):
|
189
|
-
self.http_client = http_client
|
190
|
-
self.asset_filter = asset_filter
|
191
|
-
|
192
|
-
def execute(self) -> Dict[str, Any]:
|
193
|
-
"""Execute the purge and uninstall command with correct endpoint, HTTP method and payload."""
|
194
|
-
payload = {
|
195
|
-
"filter": self.asset_filter.to_filter_dict()
|
196
|
-
}
|
197
|
-
|
198
|
-
# FIXED: Correct endpoint URL and HTTP method (DELETE, not POST)
|
199
|
-
return self.http_client.delete("assets/purge-and-uninstall", json_data=payload)
|
200
|
-
|
201
|
-
|
202
|
-
class AddTagsToAssetsCommand(Command[Dict[str, Any]]):
|
203
|
-
"""Command to add tags to assets - FIXED endpoint URL and payload structure."""
|
204
|
-
|
205
|
-
def __init__(
|
206
|
-
self,
|
207
|
-
http_client: HTTPClient,
|
208
|
-
asset_filter: AssetFilter,
|
209
|
-
tags: List[str]
|
210
|
-
):
|
211
|
-
self.http_client = http_client
|
212
|
-
self.asset_filter = asset_filter
|
213
|
-
self.tags = tags
|
214
|
-
|
215
|
-
def execute(self) -> Dict[str, Any]:
|
216
|
-
"""Execute the add tags command with correct endpoint and payload structure."""
|
217
|
-
payload = {
|
218
|
-
"filter": self.asset_filter.to_filter_dict(),
|
219
|
-
"tags": self.tags
|
220
|
-
}
|
221
|
-
|
222
|
-
# FIXED: Correct endpoint URL (from API documentation)
|
223
|
-
return self.http_client.post("assets/tags", json_data=payload)
|
224
|
-
|
225
|
-
|
226
|
-
class RemoveTagsFromAssetsCommand(Command[Dict[str, Any]]):
|
227
|
-
"""Command to remove tags from assets - FIXED
|
228
|
-
|
229
|
-
def __init__(
|
230
|
-
self,
|
231
|
-
http_client: HTTPClient,
|
232
|
-
asset_filter: AssetFilter,
|
233
|
-
tags: List[str]
|
234
|
-
):
|
235
|
-
self.http_client = http_client
|
236
|
-
self.asset_filter = asset_filter
|
237
|
-
self.tags = tags
|
238
|
-
|
239
|
-
def execute(self) -> Dict[str, Any]:
|
240
|
-
"""Execute the remove tags command with correct
|
241
|
-
payload = {
|
242
|
-
"filter": self.asset_filter.to_filter_dict(),
|
243
|
-
"tags": self.tags
|
244
|
-
}
|
245
|
-
|
246
|
-
# FIXED: Correct endpoint URL and HTTP method
|
247
|
-
return self.http_client.delete("assets/tags", json_data=payload)
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
def __init__(
|
327
|
-
self,
|
328
|
-
http_client: HTTPClient,
|
329
|
-
endpoint_ids: Union[str, List[str]],
|
330
|
-
organization_ids: Optional[List[Union[int, str]]] = None
|
331
|
-
):
|
332
|
-
self.http_client = http_client
|
333
|
-
asset_filter = create_asset_filter_from_endpoint_ids(endpoint_ids, organization_ids)
|
334
|
-
self.command = ShutdownAssetsCommand(http_client, asset_filter)
|
335
|
-
|
336
|
-
def execute(self) -> Dict[str, Any]:
|
337
|
-
"""Execute through the correct filter-based command."""
|
338
|
-
return self.command.execute()
|
339
|
-
|
340
|
-
|
341
|
-
# Export the main corrected classes
|
342
|
-
__all__ = [
|
343
|
-
# Main corrected commands
|
344
|
-
'RebootAssetsCommand',
|
345
|
-
'ShutdownAssetsCommand',
|
346
|
-
'IsolateAssetsCommand',
|
347
|
-
'UnisolateAssetsCommand',
|
348
|
-
'LogRetrievalCommand',
|
349
|
-
'VersionUpdateCommand',
|
350
|
-
'UninstallAssetsCommand',
|
351
|
-
'PurgeAndUninstallAssetsCommand',
|
352
|
-
'AddTagsToAssetsCommand',
|
353
|
-
'RemoveTagsFromAssetsCommand',
|
354
|
-
|
355
|
-
# Legacy compatibility commands
|
356
|
-
'IsolateAssetsByIdCommand',
|
357
|
-
'UnisolateAssetsByIdCommand',
|
358
|
-
'RebootAssetsByIdCommand',
|
359
|
-
'ShutdownAssetsByIdCommand',
|
360
|
-
|
361
|
-
# Utility functions
|
362
|
-
'create_asset_filter_from_endpoint_ids'
|
1
|
+
"""
|
2
|
+
Asset-related commands for the Binalyze AIR SDK.
|
3
|
+
Fixed to match API documentation exactly.
|
4
|
+
"""
|
5
|
+
|
6
|
+
from typing import List, Union, Optional, Dict, Any
|
7
|
+
|
8
|
+
from ..base import Command
|
9
|
+
from ..models.assets import AssetFilter
|
10
|
+
from ..http_client import HTTPClient
|
11
|
+
|
12
|
+
|
13
|
+
class RebootAssetsCommand(Command[Dict[str, Any]]):
|
14
|
+
"""Command to reboot assets by filter - FIXED to match API documentation."""
|
15
|
+
|
16
|
+
def __init__(
|
17
|
+
self,
|
18
|
+
http_client: HTTPClient,
|
19
|
+
asset_filter: AssetFilter
|
20
|
+
):
|
21
|
+
self.http_client = http_client
|
22
|
+
self.asset_filter = asset_filter
|
23
|
+
|
24
|
+
def execute(self) -> Dict[str, Any]:
|
25
|
+
"""Execute the reboot command with correct payload structure."""
|
26
|
+
# Use the correct payload structure as per API documentation
|
27
|
+
payload = {
|
28
|
+
"filter": self.asset_filter.to_filter_dict()
|
29
|
+
}
|
30
|
+
|
31
|
+
# FIXED: Correct endpoint URL (confirmed from API docs)
|
32
|
+
return self.http_client.post("assets/tasks/reboot", json_data=payload)
|
33
|
+
|
34
|
+
|
35
|
+
class ShutdownAssetsCommand(Command[Dict[str, Any]]):
|
36
|
+
"""Command to shutdown assets by filter - FIXED to match API documentation."""
|
37
|
+
|
38
|
+
def __init__(
|
39
|
+
self,
|
40
|
+
http_client: HTTPClient,
|
41
|
+
asset_filter: AssetFilter
|
42
|
+
):
|
43
|
+
self.http_client = http_client
|
44
|
+
self.asset_filter = asset_filter
|
45
|
+
|
46
|
+
def execute(self) -> Dict[str, Any]:
|
47
|
+
"""Execute the shutdown command with correct payload structure."""
|
48
|
+
payload = {
|
49
|
+
"filter": self.asset_filter.to_filter_dict()
|
50
|
+
}
|
51
|
+
|
52
|
+
# FIXED: Correct endpoint URL (following same pattern as reboot)
|
53
|
+
return self.http_client.post("assets/tasks/shutdown", json_data=payload)
|
54
|
+
|
55
|
+
|
56
|
+
class IsolateAssetsCommand(Command[Dict[str, Any]]):
|
57
|
+
"""Command to isolate assets by filter - FIXED to match API documentation."""
|
58
|
+
|
59
|
+
def __init__(
|
60
|
+
self,
|
61
|
+
http_client: HTTPClient,
|
62
|
+
asset_filter: AssetFilter,
|
63
|
+
isolation_settings: Optional[Dict[str, Any]] = None
|
64
|
+
):
|
65
|
+
self.http_client = http_client
|
66
|
+
self.asset_filter = asset_filter
|
67
|
+
self.isolation_settings = isolation_settings or {}
|
68
|
+
|
69
|
+
def execute(self) -> Dict[str, Any]:
|
70
|
+
"""Execute the isolation command with correct payload structure."""
|
71
|
+
payload = {
|
72
|
+
"enabled": True, # Required field for isolation
|
73
|
+
"filter": self.asset_filter.to_filter_dict()
|
74
|
+
}
|
75
|
+
|
76
|
+
# Add isolation settings if provided
|
77
|
+
if self.isolation_settings:
|
78
|
+
payload.update(self.isolation_settings)
|
79
|
+
|
80
|
+
# FIXED: Correct endpoint URL and payload
|
81
|
+
return self.http_client.post("assets/tasks/isolation", json_data=payload)
|
82
|
+
|
83
|
+
|
84
|
+
class UnisolateAssetsCommand(Command[Dict[str, Any]]):
|
85
|
+
"""Command to unisolate (remove isolation from) assets - FIXED to match API documentation."""
|
86
|
+
|
87
|
+
def __init__(
|
88
|
+
self,
|
89
|
+
http_client: HTTPClient,
|
90
|
+
asset_filter: AssetFilter
|
91
|
+
):
|
92
|
+
self.http_client = http_client
|
93
|
+
self.asset_filter = asset_filter
|
94
|
+
|
95
|
+
def execute(self) -> Dict[str, Any]:
|
96
|
+
"""Execute the unisolate command with correct payload structure."""
|
97
|
+
payload = {
|
98
|
+
"enabled": False, # Disable isolation for unisolate
|
99
|
+
"filter": self.asset_filter.to_filter_dict()
|
100
|
+
}
|
101
|
+
|
102
|
+
# FIXED: Correct endpoint URL and payload
|
103
|
+
return self.http_client.post("assets/tasks/isolation", json_data=payload)
|
104
|
+
|
105
|
+
|
106
|
+
class LogRetrievalCommand(Command[Dict[str, Any]]):
|
107
|
+
"""Command to retrieve logs from assets - FIXED endpoint URL and payload structure."""
|
108
|
+
|
109
|
+
def __init__(
|
110
|
+
self,
|
111
|
+
http_client: HTTPClient,
|
112
|
+
asset_filter: AssetFilter,
|
113
|
+
log_settings: Optional[Dict[str, Any]] = None
|
114
|
+
):
|
115
|
+
self.http_client = http_client
|
116
|
+
self.asset_filter = asset_filter
|
117
|
+
self.log_settings = log_settings or {}
|
118
|
+
|
119
|
+
def execute(self) -> Dict[str, Any]:
|
120
|
+
"""Execute the log retrieval command with correct endpoint and payload."""
|
121
|
+
payload = {
|
122
|
+
"filter": self.asset_filter.to_filter_dict()
|
123
|
+
}
|
124
|
+
|
125
|
+
# Add log retrieval settings if provided
|
126
|
+
if self.log_settings:
|
127
|
+
payload.update(self.log_settings)
|
128
|
+
|
129
|
+
# FIXED: Correct endpoint URL to match API specification
|
130
|
+
return self.http_client.post("assets/tasks/retrieve-logs", json_data=payload)
|
131
|
+
|
132
|
+
|
133
|
+
class VersionUpdateCommand(Command[Dict[str, Any]]):
|
134
|
+
"""Command to update version on assets - FIXED to match API documentation."""
|
135
|
+
|
136
|
+
def __init__(
|
137
|
+
self,
|
138
|
+
http_client: HTTPClient,
|
139
|
+
asset_filter: AssetFilter,
|
140
|
+
update_settings: Optional[Dict[str, Any]] = None
|
141
|
+
):
|
142
|
+
self.http_client = http_client
|
143
|
+
self.asset_filter = asset_filter
|
144
|
+
self.update_settings = update_settings or {}
|
145
|
+
|
146
|
+
def execute(self) -> Dict[str, Any]:
|
147
|
+
"""Execute the version update command with correct payload structure."""
|
148
|
+
payload = {
|
149
|
+
"filter": self.asset_filter.to_filter_dict()
|
150
|
+
}
|
151
|
+
|
152
|
+
# Add version update settings if provided
|
153
|
+
if self.update_settings:
|
154
|
+
payload.update(self.update_settings)
|
155
|
+
|
156
|
+
# FIXED: Correct endpoint URL (following tasks pattern)
|
157
|
+
return self.http_client.post("assets/tasks/version-update", json_data=payload)
|
158
|
+
|
159
|
+
|
160
|
+
class UninstallAssetsCommand(Command[Dict[str, Any]]):
|
161
|
+
"""Command to uninstall assets without purging data - FIXED endpoint URL and HTTP method."""
|
162
|
+
|
163
|
+
def __init__(
|
164
|
+
self,
|
165
|
+
http_client: HTTPClient,
|
166
|
+
asset_filter: AssetFilter
|
167
|
+
):
|
168
|
+
self.http_client = http_client
|
169
|
+
self.asset_filter = asset_filter
|
170
|
+
|
171
|
+
def execute(self) -> Dict[str, Any]:
|
172
|
+
"""Execute the uninstall command with correct endpoint, HTTP method and payload structure."""
|
173
|
+
payload = {
|
174
|
+
"filter": self.asset_filter.to_filter_dict()
|
175
|
+
}
|
176
|
+
|
177
|
+
# FIXED: Correct endpoint URL and HTTP method (DELETE, not POST)
|
178
|
+
return self.http_client.delete("assets/uninstall-without-purge", json_data=payload)
|
179
|
+
|
180
|
+
|
181
|
+
class PurgeAndUninstallAssetsCommand(Command[Dict[str, Any]]):
|
182
|
+
"""Command to purge and uninstall assets - FIXED endpoint URL and HTTP method."""
|
183
|
+
|
184
|
+
def __init__(
|
185
|
+
self,
|
186
|
+
http_client: HTTPClient,
|
187
|
+
asset_filter: AssetFilter
|
188
|
+
):
|
189
|
+
self.http_client = http_client
|
190
|
+
self.asset_filter = asset_filter
|
191
|
+
|
192
|
+
def execute(self) -> Dict[str, Any]:
|
193
|
+
"""Execute the purge and uninstall command with correct endpoint, HTTP method and payload."""
|
194
|
+
payload = {
|
195
|
+
"filter": self.asset_filter.to_filter_dict()
|
196
|
+
}
|
197
|
+
|
198
|
+
# FIXED: Correct endpoint URL and HTTP method (DELETE, not POST)
|
199
|
+
return self.http_client.delete("assets/purge-and-uninstall", json_data=payload)
|
200
|
+
|
201
|
+
|
202
|
+
class AddTagsToAssetsCommand(Command[Dict[str, Any]]):
|
203
|
+
"""Command to add tags to assets - FIXED endpoint URL and payload structure."""
|
204
|
+
|
205
|
+
def __init__(
|
206
|
+
self,
|
207
|
+
http_client: HTTPClient,
|
208
|
+
asset_filter: AssetFilter,
|
209
|
+
tags: List[str]
|
210
|
+
):
|
211
|
+
self.http_client = http_client
|
212
|
+
self.asset_filter = asset_filter
|
213
|
+
self.tags = tags
|
214
|
+
|
215
|
+
def execute(self) -> Dict[str, Any]:
|
216
|
+
"""Execute the add tags command with correct endpoint and payload structure."""
|
217
|
+
payload = {
|
218
|
+
"filter": self.asset_filter.to_filter_dict(),
|
219
|
+
"tags": self.tags
|
220
|
+
}
|
221
|
+
|
222
|
+
# FIXED: Correct endpoint URL (from API documentation)
|
223
|
+
return self.http_client.post("assets/tags", json_data=payload)
|
224
|
+
|
225
|
+
|
226
|
+
class RemoveTagsFromAssetsCommand(Command[Dict[str, Any]]):
|
227
|
+
"""Command to remove tags from assets by filter - FIXED to match API documentation."""
|
228
|
+
|
229
|
+
def __init__(
|
230
|
+
self,
|
231
|
+
http_client: HTTPClient,
|
232
|
+
asset_filter: AssetFilter,
|
233
|
+
tags: List[str]
|
234
|
+
):
|
235
|
+
self.http_client = http_client
|
236
|
+
self.asset_filter = asset_filter
|
237
|
+
self.tags = tags
|
238
|
+
|
239
|
+
def execute(self) -> Dict[str, Any]:
|
240
|
+
"""Execute the remove tags command with correct payload structure."""
|
241
|
+
payload = {
|
242
|
+
"filter": self.asset_filter.to_filter_dict(),
|
243
|
+
"tags": self.tags
|
244
|
+
}
|
245
|
+
|
246
|
+
# FIXED: Correct endpoint URL and HTTP method
|
247
|
+
return self.http_client.delete("assets/tags", json_data=payload)
|
248
|
+
|
249
|
+
|
250
|
+
class DeleteAssetTagByIdCommand(Command[Dict[str, Any]]):
|
251
|
+
"""Command to delete an asset tag by ID."""
|
252
|
+
|
253
|
+
def __init__(self, http_client: HTTPClient, organization_id: int, tag_id: str):
|
254
|
+
self.http_client = http_client
|
255
|
+
self.organization_id = organization_id
|
256
|
+
self.tag_id = tag_id
|
257
|
+
|
258
|
+
def execute(self) -> Dict[str, Any]:
|
259
|
+
"""Execute the delete asset tag command."""
|
260
|
+
return self.http_client.delete(f"asset-tags/{self.organization_id}/{self.tag_id}")
|
261
|
+
|
262
|
+
|
263
|
+
class DeleteAssetTagsByOrganizationIdCommand(Command[Dict[str, Any]]):
|
264
|
+
"""Command to delete asset tags by organization ID."""
|
265
|
+
|
266
|
+
def __init__(self, http_client: HTTPClient, organization_id: int):
|
267
|
+
self.http_client = http_client
|
268
|
+
self.organization_id = organization_id
|
269
|
+
|
270
|
+
def execute(self) -> Dict[str, Any]:
|
271
|
+
"""Execute the delete asset tags by organization ID command."""
|
272
|
+
return self.http_client.delete(f"asset-tags/{self.organization_id}/all")
|
273
|
+
|
274
|
+
|
275
|
+
# Convenience functions for backward compatibility
|
276
|
+
def create_asset_filter_from_endpoint_ids(
|
277
|
+
endpoint_ids: Union[str, List[str]],
|
278
|
+
organization_ids: Optional[List[Union[int, str]]] = None
|
279
|
+
) -> AssetFilter:
|
280
|
+
"""
|
281
|
+
Create an AssetFilter from endpoint IDs - helper function.
|
282
|
+
|
283
|
+
Args:
|
284
|
+
endpoint_ids: Single endpoint ID or list of endpoint IDs
|
285
|
+
organization_ids: Optional list of organization IDs
|
286
|
+
|
287
|
+
Returns:
|
288
|
+
AssetFilter: Configured filter object
|
289
|
+
"""
|
290
|
+
# Convert single endpoint ID to list
|
291
|
+
if isinstance(endpoint_ids, str):
|
292
|
+
endpoint_ids = [endpoint_ids]
|
293
|
+
|
294
|
+
# Set default organization IDs if not provided and convert to integers
|
295
|
+
if organization_ids is None:
|
296
|
+
org_ids = [0]
|
297
|
+
else:
|
298
|
+
org_ids = [int(org_id) for org_id in organization_ids]
|
299
|
+
|
300
|
+
# Create and return the filter
|
301
|
+
return AssetFilter(
|
302
|
+
included_endpoint_ids=endpoint_ids,
|
303
|
+
organization_ids=org_ids
|
304
|
+
)
|
305
|
+
|
306
|
+
|
307
|
+
# Export the main corrected classes
|
308
|
+
__all__ = [
|
309
|
+
# Main corrected commands
|
310
|
+
'RebootAssetsCommand',
|
311
|
+
'ShutdownAssetsCommand',
|
312
|
+
'IsolateAssetsCommand',
|
313
|
+
'UnisolateAssetsCommand',
|
314
|
+
'LogRetrievalCommand',
|
315
|
+
'VersionUpdateCommand',
|
316
|
+
'UninstallAssetsCommand',
|
317
|
+
'PurgeAndUninstallAssetsCommand',
|
318
|
+
'AddTagsToAssetsCommand',
|
319
|
+
'RemoveTagsFromAssetsCommand',
|
320
|
+
'DeleteAssetTagByIdCommand',
|
321
|
+
'DeleteAssetTagsByOrganizationIdCommand',
|
322
|
+
|
323
|
+
# Utility functions
|
324
|
+
'create_asset_filter_from_endpoint_ids'
|
363
325
|
]
|