main
py 179 lines 5.11 KB
Raw
1 from datetime import datetime
2 from enum import Enum
3 from typing import Any
4 from typing import Dict
5 from typing import List
6 from typing import Optional
7
8 from pydantic import BaseModel
9 from pydantic import ConfigDict
10 from pydantic import Field
11
12
13 class ValidSyslogType(str, Enum):
14 WAZUH = "wazuh"
15
16
17 class CreateAlertRequest(BaseModel):
18 index_name: str = Field(
19 ...,
20 description="The name of the index to search alerts for.",
21 )
22 alert_id: str = Field(..., description="The alert id.")
23
24
25 class CreateAlertRequestRoute(BaseModel):
26 index_name: str = Field(
27 ...,
28 description="The name of the index to search alerts for.",
29 )
30 index_id: str = Field(..., description="The index id.")
31 agent_id: Optional[str] = Field(
32 None,
33 description="The agent id.",
34 )
35 alert_id: Optional[int] = Field(
36 None,
37 description="The alert id.",
38 )
39
40
41 class CreateAlertResponse(BaseModel):
42 success: bool
43 message: str
44 alert_id: int = Field(..., description="The alert id as created in CoPilot.")
45
46
47 # class AutoCreateAlertResponse(BaseModel):
48 # success: bool
49 # message: str
50
51
52 class AutoCreateAlertResponse(BaseModel):
53 success: bool
54 message: str
55 alerts_created: int = 0
56 alerts_failed: int = 0
57 batches_processed: int = 0
58 alerts_remaining: int = 0
59 model_config = ConfigDict(
60 json_schema_extra={
61 "example": {
62 "success": True,
63 "message": "Processed 5 batches: 487 alerts created, 13 failed. 2000 alerts remaining for next run",
64 "alerts_created": 487,
65 "alerts_failed": 13,
66 "batches_processed": 5,
67 "alerts_remaining": 2000,
68 },
69 },
70 )
71
72
73 class IndexNamesResponse(BaseModel):
74 index_names: List[str]
75 success: bool
76 message: str
77
78
79 class FieldNames(BaseModel):
80 field_names: List[str]
81 asset_name: str
82 timefield_name: str
83 alert_title_name: str
84 ioc_field_names: Optional[List[str]] = None
85
86
87 class GenericSourceModel(BaseModel):
88 timestamp: str = Field(..., description="The timestamp of the alert.")
89 timestamp_utc: Optional[str] = Field(
90 None,
91 description="The UTC timestamp of the alert.",
92 )
93 rule_description: Optional[str] = Field(
94 "No autogenerated rule_description found",
95 description="The timefield of the alert to be used when creating the IRIS alert.",
96 )
97 syslog_level: Optional[str] = Field(
98 "No autogenerated syslog_level found",
99 description="The timefield of the alert to be used when creating the IRIS alert.",
100 )
101 syslog_type: Optional[str] = Field(
102 None,
103 description="The timefield of the alert to be used when creating the IRIS alert.",
104 )
105 process_id: Optional[str] = Field(
106 None,
107 description="The process id of the alert.",
108 )
109 agent_name: Optional[str] = Field(
110 None,
111 description="The agent name of the alert.",
112 )
113 model_config = ConfigDict(extra="allow")
114
115 def to_dict(self):
116 return self.model_dump(exclude_none=True)
117
118
119 class GenericAlertModel(BaseModel):
120 # NOTE: Pydantic 2 treats names with a leading underscore as PrivateAttr
121 # and silently drops them from input parsing. Elasticsearch hits use
122 # `_index`, `_id`, `_version`, `_source` as JSON keys, so we expose those
123 # via aliases and access them as `index`/`id`/`version`/`source` in code.
124 index: str = Field(alias="_index")
125 id: str = Field(alias="_id")
126 version: int = Field(alias="_version")
127 source: GenericSourceModel = Field(alias="_source")
128 asset_type_id: Optional[int] = Field(
129 None,
130 description="The asset type id of the alert which is needed for when we add the asset to IRIS.",
131 )
132 ioc_value: Optional[str] = Field(
133 None,
134 description="The IoC value of the alert which is needed for when we add the IoC to IRIS.",
135 )
136 ioc_type: Optional[str] = Field(
137 None,
138 description="The IoC type of the alert which is needed for when we add the IoC to IRIS.",
139 )
140 time_field: Optional[str] = Field(
141 "timestamp",
142 description="The timefield of the alert to be used when creating the IRIS alert.",
143 )
144 syslog_type: Optional[str] = Field(
145 None,
146 description="The type of the alert to be used when creating the CoPilot alert.",
147 )
148 model_config = ConfigDict(extra="allow", populate_by_name=True)
149
150
151 class AlertDetailsResponse(BaseModel):
152 alert_details: GenericAlertModel
153 success: bool
154 message: str
155
156
157 class CreatedAlertPayload(BaseModel):
158 alert_context_payload: dict
159 asset_payload: str
160 timefield_payload: str
161 alert_title_payload: str
162 ioc_payload: Optional[dict] = None
163 source: str
164 index_name: Optional[str] = None
165 index_id: Optional[str] = None
166 alert_id: Optional[int] = None
167
168
169 class CreatedCaseNotificationPayload(BaseModel):
170 case_name: str
171 case_description: str
172 case_creation_time: datetime
173 alerts: List[CreatedAlertPayload]
174
175
176 class AlertTimelineResponse(BaseModel):
177 alert_timeline: List[Dict[str, Any]]
178 success: bool
179 message: str