binalyze-air-sdk 1.0.1__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 -0
- binalyze_air/apis/__init__.py +27 -0
- binalyze_air/apis/authentication.py +27 -0
- binalyze_air/apis/auto_asset_tags.py +75 -0
- binalyze_air/apis/endpoints.py +22 -0
- binalyze_air/apis/event_subscription.py +97 -0
- binalyze_air/apis/evidence.py +53 -0
- binalyze_air/apis/evidences.py +216 -0
- binalyze_air/apis/interact.py +36 -0
- binalyze_air/apis/params.py +40 -0
- binalyze_air/apis/settings.py +27 -0
- binalyze_air/apis/user_management.py +74 -0
- binalyze_air/apis/users.py +68 -0
- binalyze_air/apis/webhooks.py +231 -0
- binalyze_air/base.py +133 -0
- binalyze_air/client.py +1338 -0
- binalyze_air/commands/__init__.py +146 -0
- binalyze_air/commands/acquisitions.py +387 -0
- binalyze_air/commands/assets.py +363 -0
- binalyze_air/commands/authentication.py +37 -0
- binalyze_air/commands/auto_asset_tags.py +231 -0
- binalyze_air/commands/baseline.py +396 -0
- binalyze_air/commands/cases.py +603 -0
- binalyze_air/commands/event_subscription.py +102 -0
- binalyze_air/commands/evidences.py +988 -0
- binalyze_air/commands/interact.py +58 -0
- binalyze_air/commands/organizations.py +221 -0
- binalyze_air/commands/policies.py +203 -0
- binalyze_air/commands/settings.py +29 -0
- binalyze_air/commands/tasks.py +56 -0
- binalyze_air/commands/triage.py +360 -0
- binalyze_air/commands/user_management.py +126 -0
- binalyze_air/commands/users.py +101 -0
- binalyze_air/config.py +245 -0
- binalyze_air/exceptions.py +50 -0
- binalyze_air/http_client.py +306 -0
- binalyze_air/models/__init__.py +285 -0
- binalyze_air/models/acquisitions.py +251 -0
- binalyze_air/models/assets.py +439 -0
- binalyze_air/models/audit.py +273 -0
- binalyze_air/models/authentication.py +70 -0
- binalyze_air/models/auto_asset_tags.py +117 -0
- binalyze_air/models/baseline.py +232 -0
- binalyze_air/models/cases.py +276 -0
- binalyze_air/models/endpoints.py +76 -0
- binalyze_air/models/event_subscription.py +172 -0
- binalyze_air/models/evidence.py +66 -0
- binalyze_air/models/evidences.py +349 -0
- binalyze_air/models/interact.py +136 -0
- binalyze_air/models/organizations.py +294 -0
- binalyze_air/models/params.py +128 -0
- binalyze_air/models/policies.py +250 -0
- binalyze_air/models/settings.py +84 -0
- binalyze_air/models/tasks.py +149 -0
- binalyze_air/models/triage.py +143 -0
- binalyze_air/models/user_management.py +97 -0
- binalyze_air/models/users.py +82 -0
- binalyze_air/queries/__init__.py +134 -0
- binalyze_air/queries/acquisitions.py +156 -0
- binalyze_air/queries/assets.py +105 -0
- binalyze_air/queries/audit.py +417 -0
- binalyze_air/queries/authentication.py +56 -0
- binalyze_air/queries/auto_asset_tags.py +60 -0
- binalyze_air/queries/baseline.py +185 -0
- binalyze_air/queries/cases.py +293 -0
- binalyze_air/queries/endpoints.py +25 -0
- binalyze_air/queries/event_subscription.py +55 -0
- binalyze_air/queries/evidence.py +140 -0
- binalyze_air/queries/evidences.py +280 -0
- binalyze_air/queries/interact.py +28 -0
- binalyze_air/queries/organizations.py +223 -0
- binalyze_air/queries/params.py +115 -0
- binalyze_air/queries/policies.py +150 -0
- binalyze_air/queries/settings.py +20 -0
- binalyze_air/queries/tasks.py +82 -0
- binalyze_air/queries/triage.py +231 -0
- binalyze_air/queries/user_management.py +83 -0
- binalyze_air/queries/users.py +69 -0
- binalyze_air_sdk-1.0.1.dist-info/METADATA +635 -0
- binalyze_air_sdk-1.0.1.dist-info/RECORD +82 -0
- binalyze_air_sdk-1.0.1.dist-info/WHEEL +5 -0
- binalyze_air_sdk-1.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,349 @@
|
|
1
|
+
"""
|
2
|
+
Evidences/Repositories-related data models for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Optional, List, Dict, Any
|
6
|
+
from datetime import datetime
|
7
|
+
from pydantic import Field, field_validator
|
8
|
+
|
9
|
+
from ..base import AIRBaseModel, Filter
|
10
|
+
|
11
|
+
|
12
|
+
class EvidenceRepository(AIRBaseModel):
|
13
|
+
"""Base evidence repository model."""
|
14
|
+
|
15
|
+
id: str = Field(alias="_id")
|
16
|
+
name: str
|
17
|
+
description: Optional[str] = None
|
18
|
+
type: str # "amazon-s3", "azure-storage", "ftps", "sftp", "smb"
|
19
|
+
path: Optional[str] = None
|
20
|
+
username: Optional[str] = None
|
21
|
+
password: Optional[str] = None
|
22
|
+
host: Optional[str] = None
|
23
|
+
port: Optional[int] = None
|
24
|
+
organization_id: Optional[int] = Field(default=None, alias="organizationId")
|
25
|
+
organization_ids: Optional[List[int]] = Field(default=None, alias="organizationIds")
|
26
|
+
is_active: bool = Field(default=True, alias="isActive")
|
27
|
+
is_default: bool = Field(default=False, alias="isDefault")
|
28
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
29
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
30
|
+
created_by: Optional[str] = Field(default=None, alias="createdBy")
|
31
|
+
|
32
|
+
@field_validator('organization_id', mode='after')
|
33
|
+
@classmethod
|
34
|
+
def derive_organization_id(cls, v, info):
|
35
|
+
"""Derive organization_id from organization_ids if not provided."""
|
36
|
+
if v is None and 'organization_ids' in info.data:
|
37
|
+
org_ids = info.data['organization_ids']
|
38
|
+
if org_ids and len(org_ids) > 0:
|
39
|
+
return org_ids[0]
|
40
|
+
return 0 # Default to 0 if no organization IDs
|
41
|
+
return v
|
42
|
+
|
43
|
+
|
44
|
+
class AmazonS3Repository(AIRBaseModel):
|
45
|
+
"""Amazon S3 evidence repository model."""
|
46
|
+
|
47
|
+
id: str
|
48
|
+
name: str
|
49
|
+
description: Optional[str] = None
|
50
|
+
bucketName: str
|
51
|
+
region: str
|
52
|
+
accessKeyId: str
|
53
|
+
secretAccessKey: str
|
54
|
+
prefix: Optional[str] = None
|
55
|
+
organizationId: int
|
56
|
+
isActive: bool = True
|
57
|
+
isDefault: bool = False
|
58
|
+
createdAt: Optional[datetime] = None
|
59
|
+
updatedAt: Optional[datetime] = None
|
60
|
+
|
61
|
+
|
62
|
+
class CreateAmazonS3RepositoryRequest(AIRBaseModel):
|
63
|
+
"""Create Amazon S3 repository request model."""
|
64
|
+
|
65
|
+
name: str
|
66
|
+
description: Optional[str] = None
|
67
|
+
bucketName: str
|
68
|
+
region: str
|
69
|
+
accessKeyId: str
|
70
|
+
secretAccessKey: str
|
71
|
+
prefix: Optional[str] = None
|
72
|
+
organizationId: int
|
73
|
+
isDefault: bool = False
|
74
|
+
|
75
|
+
|
76
|
+
class UpdateAmazonS3RepositoryRequest(AIRBaseModel):
|
77
|
+
"""Update Amazon S3 repository request model."""
|
78
|
+
|
79
|
+
name: Optional[str] = None
|
80
|
+
description: Optional[str] = None
|
81
|
+
bucketName: Optional[str] = None
|
82
|
+
region: Optional[str] = None
|
83
|
+
accessKeyId: Optional[str] = None
|
84
|
+
secretAccessKey: Optional[str] = None
|
85
|
+
prefix: Optional[str] = None
|
86
|
+
isDefault: Optional[bool] = None
|
87
|
+
|
88
|
+
|
89
|
+
class AzureStorageRepository(AIRBaseModel):
|
90
|
+
"""Azure Storage evidence repository model."""
|
91
|
+
|
92
|
+
id: str
|
93
|
+
name: str
|
94
|
+
description: Optional[str] = None
|
95
|
+
accountName: str
|
96
|
+
accountKey: str
|
97
|
+
containerName: str
|
98
|
+
prefix: Optional[str] = None
|
99
|
+
organizationId: int
|
100
|
+
isActive: bool = True
|
101
|
+
isDefault: bool = False
|
102
|
+
createdAt: Optional[datetime] = None
|
103
|
+
updatedAt: Optional[datetime] = None
|
104
|
+
|
105
|
+
|
106
|
+
class CreateAzureStorageRepositoryRequest(AIRBaseModel):
|
107
|
+
"""Create Azure Storage repository request model."""
|
108
|
+
|
109
|
+
name: str
|
110
|
+
description: Optional[str] = None
|
111
|
+
accountName: str
|
112
|
+
accountKey: str
|
113
|
+
containerName: str
|
114
|
+
prefix: Optional[str] = None
|
115
|
+
organizationId: int
|
116
|
+
isDefault: bool = False
|
117
|
+
|
118
|
+
|
119
|
+
class UpdateAzureStorageRepositoryRequest(AIRBaseModel):
|
120
|
+
"""Update Azure Storage repository request model."""
|
121
|
+
|
122
|
+
name: Optional[str] = None
|
123
|
+
description: Optional[str] = None
|
124
|
+
accountName: Optional[str] = None
|
125
|
+
accountKey: Optional[str] = None
|
126
|
+
containerName: Optional[str] = None
|
127
|
+
prefix: Optional[str] = None
|
128
|
+
isDefault: Optional[bool] = None
|
129
|
+
|
130
|
+
|
131
|
+
class FTPSRepository(AIRBaseModel):
|
132
|
+
"""FTPS evidence repository model."""
|
133
|
+
|
134
|
+
id: str
|
135
|
+
name: str
|
136
|
+
description: Optional[str] = None
|
137
|
+
host: str
|
138
|
+
port: int = 21
|
139
|
+
username: str
|
140
|
+
password: str
|
141
|
+
remotePath: Optional[str] = None
|
142
|
+
passive: bool = True
|
143
|
+
organizationId: int
|
144
|
+
isActive: bool = True
|
145
|
+
isDefault: bool = False
|
146
|
+
createdAt: Optional[datetime] = None
|
147
|
+
updatedAt: Optional[datetime] = None
|
148
|
+
|
149
|
+
|
150
|
+
class CreateFTPSRepositoryRequest(AIRBaseModel):
|
151
|
+
"""Create FTPS repository request model."""
|
152
|
+
|
153
|
+
name: str
|
154
|
+
description: Optional[str] = None
|
155
|
+
host: str
|
156
|
+
port: int = 21
|
157
|
+
username: str
|
158
|
+
password: str
|
159
|
+
remotePath: Optional[str] = None
|
160
|
+
passive: bool = True
|
161
|
+
organizationId: int
|
162
|
+
isDefault: bool = False
|
163
|
+
|
164
|
+
|
165
|
+
class UpdateFTPSRepositoryRequest(AIRBaseModel):
|
166
|
+
"""Update FTPS repository request model."""
|
167
|
+
|
168
|
+
name: Optional[str] = None
|
169
|
+
description: Optional[str] = None
|
170
|
+
host: Optional[str] = None
|
171
|
+
port: Optional[int] = None
|
172
|
+
username: Optional[str] = None
|
173
|
+
password: Optional[str] = None
|
174
|
+
remotePath: Optional[str] = None
|
175
|
+
passive: Optional[bool] = None
|
176
|
+
isDefault: Optional[bool] = None
|
177
|
+
|
178
|
+
|
179
|
+
class SFTPRepository(AIRBaseModel):
|
180
|
+
"""SFTP evidence repository model."""
|
181
|
+
|
182
|
+
id: str
|
183
|
+
name: str
|
184
|
+
description: Optional[str] = None
|
185
|
+
host: str
|
186
|
+
port: int = 22
|
187
|
+
username: str
|
188
|
+
password: Optional[str] = None
|
189
|
+
privateKey: Optional[str] = None
|
190
|
+
remotePath: Optional[str] = None
|
191
|
+
organizationId: int
|
192
|
+
isActive: bool = True
|
193
|
+
isDefault: bool = False
|
194
|
+
createdAt: Optional[datetime] = None
|
195
|
+
updatedAt: Optional[datetime] = None
|
196
|
+
|
197
|
+
|
198
|
+
class CreateSFTPRepositoryRequest(AIRBaseModel):
|
199
|
+
"""Create SFTP repository request model."""
|
200
|
+
|
201
|
+
name: str
|
202
|
+
description: Optional[str] = None
|
203
|
+
host: str
|
204
|
+
port: int = 22
|
205
|
+
username: str
|
206
|
+
password: Optional[str] = None
|
207
|
+
privateKey: Optional[str] = None
|
208
|
+
remotePath: Optional[str] = None
|
209
|
+
organizationId: int
|
210
|
+
isDefault: bool = False
|
211
|
+
|
212
|
+
|
213
|
+
class UpdateSFTPRepositoryRequest(AIRBaseModel):
|
214
|
+
"""Update SFTP repository request model."""
|
215
|
+
|
216
|
+
name: Optional[str] = None
|
217
|
+
description: Optional[str] = None
|
218
|
+
host: Optional[str] = None
|
219
|
+
port: Optional[int] = None
|
220
|
+
username: Optional[str] = None
|
221
|
+
password: Optional[str] = None
|
222
|
+
privateKey: Optional[str] = None
|
223
|
+
remotePath: Optional[str] = None
|
224
|
+
isDefault: Optional[bool] = None
|
225
|
+
|
226
|
+
|
227
|
+
class SMBRepository(AIRBaseModel):
|
228
|
+
"""SMB evidence repository model."""
|
229
|
+
|
230
|
+
id: str
|
231
|
+
name: str
|
232
|
+
description: Optional[str] = None
|
233
|
+
path: str
|
234
|
+
username: str
|
235
|
+
password: str
|
236
|
+
domainName: Optional[str] = None
|
237
|
+
organizationId: int
|
238
|
+
organizationIds: Optional[List[int]] = None
|
239
|
+
isActive: bool = True
|
240
|
+
isDefault: bool = False
|
241
|
+
createdAt: Optional[datetime] = None
|
242
|
+
updatedAt: Optional[datetime] = None
|
243
|
+
|
244
|
+
|
245
|
+
class CreateSMBRepositoryRequest(AIRBaseModel):
|
246
|
+
"""Create SMB repository request model."""
|
247
|
+
|
248
|
+
name: str
|
249
|
+
description: Optional[str] = None
|
250
|
+
path: str
|
251
|
+
username: str
|
252
|
+
password: str
|
253
|
+
domainName: Optional[str] = None
|
254
|
+
organizationId: int
|
255
|
+
organizationIds: Optional[List[int]] = None
|
256
|
+
isDefault: bool = False
|
257
|
+
|
258
|
+
|
259
|
+
class UpdateSMBRepositoryRequest(AIRBaseModel):
|
260
|
+
"""Update SMB repository request model."""
|
261
|
+
|
262
|
+
name: Optional[str] = None
|
263
|
+
description: Optional[str] = None
|
264
|
+
path: Optional[str] = None
|
265
|
+
username: Optional[str] = None
|
266
|
+
password: Optional[str] = None
|
267
|
+
domainName: Optional[str] = None
|
268
|
+
isDefault: Optional[bool] = None
|
269
|
+
|
270
|
+
|
271
|
+
class ValidateRepositoryRequest(AIRBaseModel):
|
272
|
+
"""Validate repository request model."""
|
273
|
+
|
274
|
+
repositoryType: str # "amazon-s3", "azure-storage", "ftps"
|
275
|
+
config: Dict[str, Any] # Repository-specific configuration
|
276
|
+
|
277
|
+
|
278
|
+
class ValidationResult(AIRBaseModel):
|
279
|
+
"""Repository validation result model."""
|
280
|
+
|
281
|
+
isValid: bool
|
282
|
+
message: str
|
283
|
+
errors: List[str] = []
|
284
|
+
warnings: List[str] = []
|
285
|
+
|
286
|
+
|
287
|
+
class RepositoryFilter(Filter):
|
288
|
+
"""Filter for repository queries."""
|
289
|
+
|
290
|
+
name: Optional[str] = None
|
291
|
+
type: Optional[str] = None
|
292
|
+
organization_id: Optional[int] = None
|
293
|
+
all_organizations: Optional[bool] = None
|
294
|
+
path: Optional[str] = None
|
295
|
+
username: Optional[str] = None
|
296
|
+
host: Optional[str] = None
|
297
|
+
is_active: Optional[bool] = None
|
298
|
+
is_default: Optional[bool] = None
|
299
|
+
created_by: Optional[str] = None
|
300
|
+
|
301
|
+
def to_params(self) -> Dict[str, Any]:
|
302
|
+
"""Convert filter to API parameters with proper field mapping."""
|
303
|
+
params = {}
|
304
|
+
|
305
|
+
# Pagination parameters (not in filter namespace)
|
306
|
+
if self.page_number is not None:
|
307
|
+
params["pageNumber"] = self.page_number
|
308
|
+
if self.page_size is not None:
|
309
|
+
params["pageSize"] = self.page_size
|
310
|
+
if self.sort_by is not None:
|
311
|
+
params["sortBy"] = self.sort_by
|
312
|
+
if self.sort_type is not None:
|
313
|
+
params["sortType"] = self.sort_type
|
314
|
+
|
315
|
+
# Filter parameters with proper field mapping
|
316
|
+
field_mappings = {
|
317
|
+
"search_term": "searchTerm",
|
318
|
+
"organization_ids": "organizationIds",
|
319
|
+
"organization_id": "organizationIds", # Map to organizationIds for API
|
320
|
+
"all_organizations": "allOrganizations",
|
321
|
+
"name": "name",
|
322
|
+
"type": "type",
|
323
|
+
"path": "path",
|
324
|
+
"username": "username",
|
325
|
+
"host": "host",
|
326
|
+
"is_active": "isActive",
|
327
|
+
"is_default": "isDefault",
|
328
|
+
"created_by": "createdBy"
|
329
|
+
}
|
330
|
+
|
331
|
+
for field_name, field_value in self.model_dump(exclude_none=True).items():
|
332
|
+
# Skip pagination/sorting fields as they're handled above
|
333
|
+
if field_name in ["page_number", "page_size", "sort_by", "sort_type"]:
|
334
|
+
continue
|
335
|
+
|
336
|
+
if field_value is not None:
|
337
|
+
api_field_name = field_mappings.get(field_name, field_name)
|
338
|
+
|
339
|
+
# Special handling for organization_ids - use first ID for organizationIds filter
|
340
|
+
if field_name == "organization_ids" and isinstance(field_value, list) and len(field_value) > 0:
|
341
|
+
params[f"filter[{api_field_name}]"] = ",".join(map(str, field_value))
|
342
|
+
elif field_name == "organization_id":
|
343
|
+
params[f"filter[organizationIds]"] = str(field_value)
|
344
|
+
elif isinstance(field_value, list):
|
345
|
+
params[f"filter[{api_field_name}]"] = ",".join(map(str, field_value))
|
346
|
+
else:
|
347
|
+
params[f"filter[{api_field_name}]"] = str(field_value)
|
348
|
+
|
349
|
+
return params
|
@@ -0,0 +1,136 @@
|
|
1
|
+
"""
|
2
|
+
Interact API models for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional, Dict, Any
|
6
|
+
from datetime import datetime
|
7
|
+
from enum import Enum
|
8
|
+
from pydantic import Field
|
9
|
+
|
10
|
+
from ..base import AIRBaseModel
|
11
|
+
|
12
|
+
|
13
|
+
class SendToLocation(str, Enum):
|
14
|
+
"""Send to location options."""
|
15
|
+
USER_LOCAL = "user-local"
|
16
|
+
REPOSITORY = "repository"
|
17
|
+
EVIDENCE_REPOSITORY = "evidence-repository"
|
18
|
+
|
19
|
+
|
20
|
+
class TaskConfigChoice(str, Enum):
|
21
|
+
"""Task configuration choice options."""
|
22
|
+
USE_POLICY = "use-policy"
|
23
|
+
USE_CUSTOM_OPTIONS = "use-custom-options"
|
24
|
+
|
25
|
+
|
26
|
+
class SendToConfig(AIRBaseModel):
|
27
|
+
"""Send to configuration model."""
|
28
|
+
|
29
|
+
location: SendToLocation
|
30
|
+
repository_id: Optional[str] = Field(default=None, alias="repositoryId")
|
31
|
+
evidence_repository_id: Optional[str] = Field(default=None, alias="evidenceRepositoryId")
|
32
|
+
|
33
|
+
|
34
|
+
class BandwidthConfig(AIRBaseModel):
|
35
|
+
"""Bandwidth configuration model."""
|
36
|
+
|
37
|
+
limit: Optional[int] = None
|
38
|
+
|
39
|
+
|
40
|
+
class DiskSpaceConfig(AIRBaseModel):
|
41
|
+
"""Disk space configuration model."""
|
42
|
+
|
43
|
+
reserve: Optional[int] = None
|
44
|
+
|
45
|
+
|
46
|
+
class TaskConfig(AIRBaseModel):
|
47
|
+
"""Task configuration model."""
|
48
|
+
|
49
|
+
choice: TaskConfigChoice
|
50
|
+
send_to: Optional[SendToConfig] = Field(default=None, alias="sendTo")
|
51
|
+
bandwidth: Optional[BandwidthConfig] = None
|
52
|
+
disk_space: Optional[DiskSpaceConfig] = Field(default=None, alias="diskSpace")
|
53
|
+
|
54
|
+
|
55
|
+
class AssignInteractiveShellTaskRequest(AIRBaseModel):
|
56
|
+
"""Request model for assigning interactive shell task."""
|
57
|
+
|
58
|
+
asset_id: str = Field(alias="assetId")
|
59
|
+
case_id: str = Field(alias="caseId")
|
60
|
+
task_config: TaskConfig = Field(alias="taskConfig")
|
61
|
+
|
62
|
+
|
63
|
+
class InteractiveShellTaskResponse(AIRBaseModel):
|
64
|
+
"""Response model for interactive shell task assignment."""
|
65
|
+
|
66
|
+
session_id: str = Field(alias="sessionId")
|
67
|
+
idle_timeout: int = Field(alias="idleTimeout")
|
68
|
+
config: TaskConfig
|
69
|
+
|
70
|
+
|
71
|
+
# Legacy models for backward compatibility (deprecated)
|
72
|
+
class InteractionType(str, Enum):
|
73
|
+
"""Interaction types."""
|
74
|
+
SHELL = "shell"
|
75
|
+
POWERSHELL = "powershell"
|
76
|
+
CMD = "cmd"
|
77
|
+
BASH = "bash"
|
78
|
+
|
79
|
+
|
80
|
+
class InteractionStatus(str, Enum):
|
81
|
+
"""Interaction status."""
|
82
|
+
PENDING = "pending"
|
83
|
+
RUNNING = "running"
|
84
|
+
COMPLETED = "completed"
|
85
|
+
FAILED = "failed"
|
86
|
+
CANCELLED = "cancelled"
|
87
|
+
TIMEOUT = "timeout"
|
88
|
+
|
89
|
+
|
90
|
+
class ShellInteraction(AIRBaseModel):
|
91
|
+
"""Shell interaction model (legacy)."""
|
92
|
+
|
93
|
+
id: str
|
94
|
+
task_id: str
|
95
|
+
endpoint_id: str
|
96
|
+
endpoint_name: str
|
97
|
+
interaction_type: InteractionType
|
98
|
+
command: str
|
99
|
+
output: Optional[str] = None
|
100
|
+
error_output: Optional[str] = None
|
101
|
+
exit_code: Optional[int] = None
|
102
|
+
status: InteractionStatus = InteractionStatus.PENDING
|
103
|
+
timeout: int = 300 # seconds
|
104
|
+
organization_id: int
|
105
|
+
created_by: Optional[str] = None
|
106
|
+
created_at: Optional[datetime] = None
|
107
|
+
started_at: Optional[datetime] = None
|
108
|
+
completed_at: Optional[datetime] = None
|
109
|
+
duration: Optional[int] = None # seconds
|
110
|
+
environment_variables: Optional[Dict[str, str]] = None
|
111
|
+
working_directory: Optional[str] = None
|
112
|
+
|
113
|
+
|
114
|
+
class AssignShellTaskRequest(AIRBaseModel):
|
115
|
+
"""Request model for assigning shell interaction tasks (legacy)."""
|
116
|
+
|
117
|
+
endpoint_ids: List[str]
|
118
|
+
command: str
|
119
|
+
interaction_type: InteractionType = InteractionType.SHELL
|
120
|
+
timeout: Optional[int] = 300
|
121
|
+
organization_ids: Optional[List[int]] = None
|
122
|
+
case_id: Optional[str] = None
|
123
|
+
environment_variables: Optional[Dict[str, str]] = None
|
124
|
+
working_directory: Optional[str] = None
|
125
|
+
description: Optional[str] = None
|
126
|
+
|
127
|
+
|
128
|
+
class ShellTaskResponse(AIRBaseModel):
|
129
|
+
"""Response model for shell task assignment (legacy)."""
|
130
|
+
|
131
|
+
task_id: str
|
132
|
+
endpoint_interactions: List[ShellInteraction]
|
133
|
+
success_count: int
|
134
|
+
failure_count: int
|
135
|
+
total_count: int
|
136
|
+
errors: Optional[List[Dict[str, Any]]] = None
|