binalyze-air-sdk 1.0.2__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.2.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.2.dist-info/METADATA +0 -706
- binalyze_air_sdk-1.0.2.dist-info/RECORD +0 -82
- {binalyze_air_sdk-1.0.2.dist-info → binalyze_air_sdk-1.0.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
"""
|
2
|
+
Policies API for the Binalyze AIR SDK using CQRS pattern.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional, Dict, Any, Union
|
6
|
+
from ..http_client import HTTPClient
|
7
|
+
from ..models.policies import (
|
8
|
+
Policy, PolicyFilter, PolicyAssignment, PolicyExecution,
|
9
|
+
CreatePolicyRequest, UpdatePolicyRequest, AssignPolicyRequest
|
10
|
+
)
|
11
|
+
from ..queries.policies import (
|
12
|
+
ListPoliciesQuery,
|
13
|
+
GetPolicyQuery,
|
14
|
+
GetPolicyAssignmentsQuery,
|
15
|
+
GetPolicyExecutionsQuery,
|
16
|
+
)
|
17
|
+
from ..commands.policies import (
|
18
|
+
CreatePolicyCommand,
|
19
|
+
UpdatePolicyCommand,
|
20
|
+
DeletePolicyCommand,
|
21
|
+
ActivatePolicyCommand,
|
22
|
+
DeactivatePolicyCommand,
|
23
|
+
AssignPolicyCommand,
|
24
|
+
UnassignPolicyCommand,
|
25
|
+
ExecutePolicyCommand,
|
26
|
+
)
|
27
|
+
|
28
|
+
|
29
|
+
class PoliciesAPI:
|
30
|
+
"""Policies API with CQRS pattern - separated queries and commands."""
|
31
|
+
|
32
|
+
def __init__(self, http_client: HTTPClient):
|
33
|
+
self.http_client = http_client
|
34
|
+
|
35
|
+
# QUERIES (Read operations)
|
36
|
+
def list(self, filter_params: Optional[PolicyFilter] = None, organization_ids: Optional[List[int]] = None) -> List[Policy]:
|
37
|
+
"""List policies with optional filtering."""
|
38
|
+
query = ListPoliciesQuery(self.http_client, filter_params, organization_ids)
|
39
|
+
result = query.execute()
|
40
|
+
# Extract the policies list from the paginated response
|
41
|
+
if hasattr(result, 'entities'):
|
42
|
+
return result.entities
|
43
|
+
elif isinstance(result, list):
|
44
|
+
return result
|
45
|
+
else:
|
46
|
+
return []
|
47
|
+
|
48
|
+
def get(self, policy_id: str) -> Policy:
|
49
|
+
"""Get a specific policy by ID."""
|
50
|
+
query = GetPolicyQuery(self.http_client, policy_id)
|
51
|
+
return query.execute()
|
52
|
+
|
53
|
+
def get_assignments(self, policy_id: str) -> List[PolicyAssignment]:
|
54
|
+
"""Get policy assignments."""
|
55
|
+
query = GetPolicyAssignmentsQuery(self.http_client, policy_id)
|
56
|
+
return query.execute()
|
57
|
+
|
58
|
+
def get_executions(self, policy_id: str) -> List[PolicyExecution]:
|
59
|
+
"""Get policy executions."""
|
60
|
+
query = GetPolicyExecutionsQuery(self.http_client, policy_id)
|
61
|
+
return query.execute()
|
62
|
+
|
63
|
+
def get_match_stats(self, filter_params: Optional[Dict[str, Any]] = None, organization_ids: Optional[List[int]] = None) -> Dict[str, Any]:
|
64
|
+
"""Get policy match statistics with filtering.
|
65
|
+
|
66
|
+
Args:
|
67
|
+
filter_params: Optional filter parameters (name, platform, tags, etc.)
|
68
|
+
organization_ids: List of organization IDs (defaults to [0])
|
69
|
+
|
70
|
+
Returns:
|
71
|
+
Dictionary containing policy match statistics
|
72
|
+
"""
|
73
|
+
try:
|
74
|
+
# Fix API-001: Ensure organizationIds are provided to prevent errors
|
75
|
+
if organization_ids is None or len(organization_ids) == 0:
|
76
|
+
organization_ids = [0] # Default to organization 0
|
77
|
+
|
78
|
+
# Build payload with default filter structure
|
79
|
+
payload = {
|
80
|
+
"name": "",
|
81
|
+
"searchTerm": "",
|
82
|
+
"ipAddress": "",
|
83
|
+
"groupId": "",
|
84
|
+
"groupFullPath": "",
|
85
|
+
"managedStatus": [],
|
86
|
+
"isolationStatus": [],
|
87
|
+
"platform": [],
|
88
|
+
"issue": "",
|
89
|
+
"onlineStatus": [],
|
90
|
+
"tags": [],
|
91
|
+
"version": "",
|
92
|
+
"policy": "",
|
93
|
+
"includedEndpointIds": [],
|
94
|
+
"excludedEndpointIds": [],
|
95
|
+
"organizationIds": organization_ids
|
96
|
+
}
|
97
|
+
|
98
|
+
# Apply custom filter parameters if provided
|
99
|
+
if filter_params:
|
100
|
+
for key, value in filter_params.items():
|
101
|
+
if key in payload:
|
102
|
+
payload[key] = value
|
103
|
+
|
104
|
+
# Use correct API endpoint: POST policies/match-stats (not GET policies/stats)
|
105
|
+
response = self.http_client.post("policies/match-stats", json_data=payload)
|
106
|
+
return response
|
107
|
+
|
108
|
+
except Exception as e:
|
109
|
+
# Return a simulated response for testing
|
110
|
+
return {
|
111
|
+
"success": False,
|
112
|
+
"error": str(e),
|
113
|
+
"result": []
|
114
|
+
}
|
115
|
+
|
116
|
+
# COMMANDS (Write operations)
|
117
|
+
def create(self, policy_data: Union[CreatePolicyRequest, Dict[str, Any]]) -> Policy:
|
118
|
+
"""Create a new policy."""
|
119
|
+
command = CreatePolicyCommand(self.http_client, policy_data)
|
120
|
+
return command.execute()
|
121
|
+
|
122
|
+
def update(self, policy_id: str, update_data: Union[UpdatePolicyRequest, Dict[str, Any]]) -> Policy:
|
123
|
+
"""Update an existing policy."""
|
124
|
+
command = UpdatePolicyCommand(self.http_client, policy_id, update_data)
|
125
|
+
return command.execute()
|
126
|
+
|
127
|
+
def delete(self, policy_id: str) -> Dict[str, Any]:
|
128
|
+
"""Delete a policy."""
|
129
|
+
command = DeletePolicyCommand(self.http_client, policy_id)
|
130
|
+
return command.execute()
|
131
|
+
|
132
|
+
def activate(self, policy_id: str) -> Policy:
|
133
|
+
"""Activate a policy."""
|
134
|
+
command = ActivatePolicyCommand(self.http_client, policy_id)
|
135
|
+
return command.execute()
|
136
|
+
|
137
|
+
def deactivate(self, policy_id: str) -> Policy:
|
138
|
+
"""Deactivate a policy."""
|
139
|
+
command = DeactivatePolicyCommand(self.http_client, policy_id)
|
140
|
+
return command.execute()
|
141
|
+
|
142
|
+
def assign(self, assignment_data: Union[AssignPolicyRequest, Dict[str, Any]]) -> Dict[str, Any]:
|
143
|
+
"""Assign policy to endpoints."""
|
144
|
+
command = AssignPolicyCommand(self.http_client, assignment_data)
|
145
|
+
return command.execute()
|
146
|
+
|
147
|
+
def unassign(self, policy_id: str, endpoint_ids: List[str]) -> Dict[str, Any]:
|
148
|
+
"""Unassign policy from endpoints."""
|
149
|
+
command = UnassignPolicyCommand(self.http_client, policy_id, endpoint_ids)
|
150
|
+
return command.execute()
|
151
|
+
|
152
|
+
def execute(self, policy_id: str, endpoint_ids: Optional[List[str]] = None) -> Dict[str, Any]:
|
153
|
+
"""Execute a policy on assigned endpoints."""
|
154
|
+
command = ExecutePolicyCommand(self.http_client, policy_id, endpoint_ids)
|
155
|
+
return command.execute()
|
156
|
+
|
157
|
+
def update_priorities(self, policy_ids: List[str], organization_ids: Optional[List[int]] = None) -> Dict[str, Any]:
|
158
|
+
"""Update policy priorities.
|
159
|
+
|
160
|
+
Args:
|
161
|
+
policy_ids: List of policy IDs in priority order (System policy must be first)
|
162
|
+
organization_ids: List of organization IDs (defaults to [0])
|
163
|
+
|
164
|
+
Returns:
|
165
|
+
Response dictionary with success status
|
166
|
+
"""
|
167
|
+
try:
|
168
|
+
# Fix API-001: Ensure organizationIds are provided to prevent issues
|
169
|
+
if organization_ids is None or len(organization_ids) == 0:
|
170
|
+
organization_ids = [0] # Default to organization 0
|
171
|
+
|
172
|
+
# Use correct API parameter names according to specification
|
173
|
+
payload = {
|
174
|
+
"ids": policy_ids, # API expects 'ids', not 'policyIds'
|
175
|
+
"organizationIds": organization_ids # Required parameter
|
176
|
+
}
|
177
|
+
|
178
|
+
response = self.http_client.put("policies/priorities", json_data=payload)
|
179
|
+
return response
|
180
|
+
except Exception as e:
|
181
|
+
# Return a simulated response for testing
|
182
|
+
return {
|
183
|
+
"success": False,
|
184
|
+
"error": str(e),
|
185
|
+
"updated_policies": []
|
186
|
+
}
|
@@ -0,0 +1,79 @@
|
|
1
|
+
"""
|
2
|
+
Preset Filters API for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Optional, Union, Dict, Any, List
|
6
|
+
|
7
|
+
from ..http_client import HTTPClient
|
8
|
+
from ..models.preset_filters import (
|
9
|
+
PresetFilter, PresetFiltersList, PresetFiltersFilter, CreatePresetFilterRequest, UpdatePresetFilterRequest
|
10
|
+
)
|
11
|
+
from ..queries.preset_filters import GetPresetFiltersQuery, GetPresetFilterByIdQuery
|
12
|
+
from ..commands.preset_filters import CreatePresetFilterCommand, UpdatePresetFilterCommand, DeletePresetFilterCommand
|
13
|
+
|
14
|
+
|
15
|
+
class PresetFiltersAPI:
|
16
|
+
"""Preset Filters API with CQRS pattern - separated queries and commands."""
|
17
|
+
|
18
|
+
def __init__(self, http_client: HTTPClient):
|
19
|
+
self.http_client = http_client
|
20
|
+
|
21
|
+
# QUERIES (Read operations)
|
22
|
+
def get_preset_filters(self, filter_params: Optional[PresetFiltersFilter] = None) -> PresetFiltersList:
|
23
|
+
"""Get preset filters with optional filtering."""
|
24
|
+
query = GetPresetFiltersQuery(self.http_client, filter_params)
|
25
|
+
return query.execute()
|
26
|
+
|
27
|
+
def get_preset_filter_by_id(self, filter_id: Union[int, str]) -> Optional[PresetFilter]:
|
28
|
+
"""Get a specific preset filter by ID."""
|
29
|
+
query = GetPresetFilterByIdQuery(self.http_client, str(filter_id))
|
30
|
+
return query.execute()
|
31
|
+
|
32
|
+
# Convenience methods for common queries
|
33
|
+
def get_preset_filters_by_organization(self, organization_id: Union[int, str]) -> PresetFiltersList:
|
34
|
+
"""Get preset filters by organization ID."""
|
35
|
+
filter_params = PresetFiltersFilter()
|
36
|
+
filter_params.organization_id = int(organization_id)
|
37
|
+
return self.get_preset_filters(filter_params)
|
38
|
+
|
39
|
+
def get_preset_filters_by_type(self, filter_type: str, organization_id: Optional[Union[int, str]] = None) -> PresetFiltersList:
|
40
|
+
"""Get preset filters by type (e.g., 'ENDPOINT')."""
|
41
|
+
filter_params = PresetFiltersFilter()
|
42
|
+
filter_params.type = filter_type
|
43
|
+
if organization_id is not None:
|
44
|
+
filter_params.organization_id = int(organization_id)
|
45
|
+
return self.get_preset_filters(filter_params)
|
46
|
+
|
47
|
+
# COMMANDS (Write operations)
|
48
|
+
def create_preset_filter(self, preset_filter_data: CreatePresetFilterRequest) -> PresetFilter:
|
49
|
+
"""Create a new preset filter."""
|
50
|
+
command = CreatePresetFilterCommand(self.http_client, preset_filter_data)
|
51
|
+
return command.execute()
|
52
|
+
|
53
|
+
def update_preset_filter(self, filter_id: Union[int, str], preset_filter_data: UpdatePresetFilterRequest) -> PresetFilter:
|
54
|
+
"""Update an existing preset filter."""
|
55
|
+
command = UpdatePresetFilterCommand(self.http_client, str(filter_id), preset_filter_data)
|
56
|
+
return command.execute()
|
57
|
+
|
58
|
+
def delete_preset_filter(self, filter_id: Union[int, str]) -> Dict[str, Any]:
|
59
|
+
"""Delete a preset filter by ID."""
|
60
|
+
command = DeletePresetFilterCommand(self.http_client, str(filter_id))
|
61
|
+
return command.execute()
|
62
|
+
|
63
|
+
# Convenience methods
|
64
|
+
def create_endpoint_filter(
|
65
|
+
self, name: str, organization_id: Union[int, str], filter_criteria: List[Dict[str, Any]], created_by: str
|
66
|
+
) -> PresetFilter:
|
67
|
+
"""Create an endpoint preset filter."""
|
68
|
+
preset_filter_data = CreatePresetFilterRequest(
|
69
|
+
name=name,
|
70
|
+
organizationId=int(organization_id),
|
71
|
+
type="ENDPOINT",
|
72
|
+
filter=filter_criteria,
|
73
|
+
createdBy=created_by
|
74
|
+
)
|
75
|
+
return self.create_preset_filter(preset_filter_data)
|
76
|
+
|
77
|
+
def get_endpoint_filters(self, organization_id: Optional[Union[int, str]] = None) -> PresetFiltersList:
|
78
|
+
"""Get all endpoint preset filters."""
|
79
|
+
return self.get_preset_filters_by_type("ENDPOINT", organization_id)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
"""
|
2
|
+
Recent Activities API for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Optional, Union, Dict, Any
|
6
|
+
|
7
|
+
from ..http_client import HTTPClient
|
8
|
+
from ..models.recent_activities import RecentActivity, RecentActivitiesList, RecentActivitiesFilter, CreateRecentActivityRequest
|
9
|
+
from ..queries.recent_activities import GetRecentActivitiesQuery
|
10
|
+
from ..commands.recent_activities import CreateRecentActivityCommand
|
11
|
+
|
12
|
+
|
13
|
+
class RecentActivitiesAPI:
|
14
|
+
"""Recent Activities API with CQRS pattern - separated queries and commands."""
|
15
|
+
|
16
|
+
def __init__(self, http_client: HTTPClient):
|
17
|
+
self.http_client = http_client
|
18
|
+
|
19
|
+
# QUERIES (Read operations)
|
20
|
+
def get_recent_activities(self, filter_params: Optional[RecentActivitiesFilter] = None) -> RecentActivitiesList:
|
21
|
+
"""Get recent activities with optional filtering."""
|
22
|
+
query = GetRecentActivitiesQuery(self.http_client, filter_params)
|
23
|
+
return query.execute()
|
24
|
+
|
25
|
+
# Convenience methods for common queries
|
26
|
+
def get_recent_activities_by_organization(self, organization_id: Union[int, str]) -> RecentActivitiesList:
|
27
|
+
"""Get recent activities by organization ID."""
|
28
|
+
filter_params = RecentActivitiesFilter()
|
29
|
+
filter_params.organization_id = int(organization_id)
|
30
|
+
return self.get_recent_activities(filter_params)
|
31
|
+
|
32
|
+
def get_recent_activities_by_type(self, activity_type: str, organization_id: Optional[Union[int, str]] = None) -> RecentActivitiesList:
|
33
|
+
"""Get recent activities by type (e.g., 'asset', 'case', 'task', 'report')."""
|
34
|
+
filter_params = RecentActivitiesFilter()
|
35
|
+
filter_params.type = activity_type
|
36
|
+
if organization_id is not None:
|
37
|
+
filter_params.organization_id = int(organization_id)
|
38
|
+
return self.get_recent_activities(filter_params)
|
39
|
+
|
40
|
+
def get_recent_activities_by_user(self, username: str, organization_id: Optional[Union[int, str]] = None) -> RecentActivitiesList:
|
41
|
+
"""Get recent activities by username."""
|
42
|
+
filter_params = RecentActivitiesFilter()
|
43
|
+
filter_params.username = username
|
44
|
+
if organization_id is not None:
|
45
|
+
filter_params.organization_id = int(organization_id)
|
46
|
+
return self.get_recent_activities(filter_params)
|
47
|
+
|
48
|
+
def search_recent_activities(self, search_term: str, organization_id: Optional[Union[int, str]] = None) -> RecentActivitiesList:
|
49
|
+
"""Search recent activities by search term."""
|
50
|
+
filter_params = RecentActivitiesFilter()
|
51
|
+
filter_params.search_term = search_term
|
52
|
+
if organization_id is not None:
|
53
|
+
filter_params.organization_id = int(organization_id)
|
54
|
+
return self.get_recent_activities(filter_params)
|
55
|
+
|
56
|
+
# COMMANDS (Write operations)
|
57
|
+
def create_recent_activity(self, activity_data: CreateRecentActivityRequest) -> Dict[str, Any]:
|
58
|
+
"""Create a new recent activity."""
|
59
|
+
command = CreateRecentActivityCommand(self.http_client, activity_data)
|
60
|
+
return command.execute()
|
61
|
+
|
62
|
+
# Convenience methods
|
63
|
+
def get_recent_activities_count(self, organization_id: Optional[Union[int, str]] = None) -> int:
|
64
|
+
"""Get total recent activities count."""
|
65
|
+
filter_params = RecentActivitiesFilter()
|
66
|
+
if organization_id is not None:
|
67
|
+
filter_params.organization_id = int(organization_id)
|
68
|
+
filter_params.page_size = 1 # We only need the count
|
69
|
+
|
70
|
+
result = self.get_recent_activities(filter_params)
|
71
|
+
return result.total_entity_count or 0
|
@@ -0,0 +1,104 @@
|
|
1
|
+
"""
|
2
|
+
Relay Server API for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Optional, Union, Dict, Any
|
6
|
+
|
7
|
+
from ..http_client import HTTPClient
|
8
|
+
from ..models.relay_server import (
|
9
|
+
RelayServer, RelayServersList, RelayServersFilter,
|
10
|
+
RebootTaskRequest, ShutdownTaskRequest, LogRetrievalTaskRequest, VersionUpdateTaskRequest,
|
11
|
+
UpdateTagsRequest, UpdateLabelRequest, UpdateAddressRequest
|
12
|
+
)
|
13
|
+
from ..queries.relay_server import GetRelayServersQuery, GetRelayServerByIdQuery
|
14
|
+
from ..commands.relay_server import (
|
15
|
+
AssignRebootTaskCommand, AssignShutdownTaskCommand, AssignLogRetrievalTaskCommand,
|
16
|
+
AssignVersionUpdateTaskCommand, DeleteRelayServerCommand, UpdateTagsCommand,
|
17
|
+
UpdateLabelCommand, UpdateAddressCommand
|
18
|
+
)
|
19
|
+
|
20
|
+
|
21
|
+
class RelayServerAPI:
|
22
|
+
"""Relay Server API with CQRS pattern - separated queries and commands."""
|
23
|
+
|
24
|
+
def __init__(self, http_client: HTTPClient):
|
25
|
+
self.http_client = http_client
|
26
|
+
|
27
|
+
# QUERIES (Read operations)
|
28
|
+
def get_relay_servers(self, filter_params: Optional[RelayServersFilter] = None) -> RelayServersList:
|
29
|
+
"""Get relay servers with optional filtering."""
|
30
|
+
query = GetRelayServersQuery(self.http_client, filter_params)
|
31
|
+
return query.execute()
|
32
|
+
|
33
|
+
def get_relay_server_by_id(self, server_id: Union[int, str]) -> Optional[RelayServer]:
|
34
|
+
"""Get a specific relay server by ID."""
|
35
|
+
query = GetRelayServerByIdQuery(self.http_client, str(server_id))
|
36
|
+
return query.execute()
|
37
|
+
|
38
|
+
# Convenience methods for common queries
|
39
|
+
def get_relay_servers_by_organization(self, organization_id: Union[int, str]) -> RelayServersList:
|
40
|
+
"""Get relay servers by organization ID."""
|
41
|
+
filter_params = RelayServersFilter()
|
42
|
+
filter_params.organization_id = int(organization_id)
|
43
|
+
return self.get_relay_servers(filter_params)
|
44
|
+
|
45
|
+
def get_online_relay_servers(self, organization_id: Optional[Union[int, str]] = None) -> RelayServersList:
|
46
|
+
"""Get online relay servers."""
|
47
|
+
filter_params = RelayServersFilter()
|
48
|
+
filter_params.online_status = "online"
|
49
|
+
if organization_id is not None:
|
50
|
+
filter_params.organization_id = int(organization_id)
|
51
|
+
return self.get_relay_servers(filter_params)
|
52
|
+
|
53
|
+
# COMMANDS (Write operations - Task assignments)
|
54
|
+
def assign_reboot_task(self, relay_server_id: Union[int, str], task_request: RebootTaskRequest) -> Dict[str, Any]:
|
55
|
+
"""Assign reboot task to relay server."""
|
56
|
+
command = AssignRebootTaskCommand(self.http_client, str(relay_server_id), task_request)
|
57
|
+
return command.execute()
|
58
|
+
|
59
|
+
def assign_shutdown_task(self, relay_server_id: Union[int, str], task_request: ShutdownTaskRequest) -> Dict[str, Any]:
|
60
|
+
"""Assign shutdown task to relay server."""
|
61
|
+
command = AssignShutdownTaskCommand(self.http_client, str(relay_server_id), task_request)
|
62
|
+
return command.execute()
|
63
|
+
|
64
|
+
def assign_log_retrieval_task(self, relay_server_id: Union[int, str], task_request: LogRetrievalTaskRequest) -> Dict[str, Any]:
|
65
|
+
"""Assign log retrieval task to relay server."""
|
66
|
+
command = AssignLogRetrievalTaskCommand(self.http_client, str(relay_server_id), task_request)
|
67
|
+
return command.execute()
|
68
|
+
|
69
|
+
def assign_version_update_task(self, relay_server_id: Union[int, str], task_request: VersionUpdateTaskRequest) -> Dict[str, Any]:
|
70
|
+
"""Assign version update task to relay server."""
|
71
|
+
command = AssignVersionUpdateTaskCommand(self.http_client, str(relay_server_id), task_request)
|
72
|
+
return command.execute()
|
73
|
+
|
74
|
+
# COMMANDS (Write operations - Server management)
|
75
|
+
def delete_relay_server(self, server_id: Union[int, str]) -> Dict[str, Any]:
|
76
|
+
"""Delete a relay server by ID."""
|
77
|
+
command = DeleteRelayServerCommand(self.http_client, str(server_id))
|
78
|
+
return command.execute()
|
79
|
+
|
80
|
+
def update_tags(self, relay_server_id: Union[int, str], tags_request: UpdateTagsRequest) -> Dict[str, Any]:
|
81
|
+
"""Update tags for a relay server."""
|
82
|
+
command = UpdateTagsCommand(self.http_client, str(relay_server_id), tags_request)
|
83
|
+
return command.execute()
|
84
|
+
|
85
|
+
def update_label(self, relay_server_id: Union[int, str], label_request: UpdateLabelRequest) -> Dict[str, Any]:
|
86
|
+
"""Update label for a relay server."""
|
87
|
+
command = UpdateLabelCommand(self.http_client, str(relay_server_id), label_request)
|
88
|
+
return command.execute()
|
89
|
+
|
90
|
+
def update_address(self, relay_server_id: Union[int, str], address_request: UpdateAddressRequest) -> Dict[str, Any]:
|
91
|
+
"""Update address for a relay server."""
|
92
|
+
command = UpdateAddressCommand(self.http_client, str(relay_server_id), address_request)
|
93
|
+
return command.execute()
|
94
|
+
|
95
|
+
# Convenience methods
|
96
|
+
def get_relay_servers_count(self, organization_id: Optional[Union[int, str]] = None) -> int:
|
97
|
+
"""Get total relay servers count."""
|
98
|
+
filter_params = RelayServersFilter()
|
99
|
+
if organization_id is not None:
|
100
|
+
filter_params.organization_id = int(organization_id)
|
101
|
+
filter_params.page_size = 1 # We only need the count
|
102
|
+
|
103
|
+
result = self.get_relay_servers(filter_params)
|
104
|
+
return result.total_entity_count or 0
|