main
py 164 lines 4.24 KB
Raw
1 from enum import Enum
2 from typing import Any
3 from typing import Dict
4 from typing import List
5 from typing import Optional
6
7 from pydantic import BaseModel
8 from pydantic import ConfigDict
9 from pydantic import Field
10 from pydantic import field_validator
11
12
13 class Alert(BaseModel):
14 index_name: str
15 total_alerts: int
16 alerts: Optional[List[Dict[str, Any]]] = Field(
17 [],
18 description="The alerts returned from the search.",
19 )
20
21 model_config = ConfigDict(from_attributes=True)
22
23
24 class AlertsSearchBody(BaseModel):
25 size: int = Field(10, description="The number of alerts to return.")
26 timerange: str = Field("24h", description="The time range to search alerts in.")
27 alert_field: str = Field(
28 "syslog_level",
29 description="The field to search alerts in.",
30 )
31 alert_value: str = Field("ALERT", description="The value to search alerts for.")
32 timestamp_field: str = Field(
33 "timestamp_utc",
34 description="The timestamp field to search alerts in.",
35 )
36
37 @field_validator("timerange")
38 @classmethod
39 def validate_timerange(cls, value):
40 if value[-1] not in ("h", "d", "w"):
41 raise ValueError(
42 "Invalid timerange format. The string should end with either 'h', 'd', 'w'.",
43 )
44
45 # Optionally, you can check that the prefix is a number
46 if not value[:-1].isdigit():
47 raise ValueError(
48 "Invalid timerange format. The string should start with a number.",
49 )
50
51 return value
52
53
54 class AlertsSearchResponse(BaseModel):
55 alerts_summary: List[Alert]
56 success: bool
57 message: str
58
59
60 class CollectAlertsResponse(BaseModel):
61 alerts: List[Dict[str, Any]]
62 success: bool
63 message: str
64
65
66 class HostAlertsSearchBody(AlertsSearchBody):
67 agent_name: str = Field(
68 ...,
69 description="The name of the agent to search alerts for.",
70 )
71
72
73 class HostAlertsSearchResponse(BaseModel):
74 alerts_summary: List[Alert]
75 success: bool
76 message: str
77
78
79 class IndexAlertsSearchBody(AlertsSearchBody):
80 index_name: str = Field(
81 ...,
82 description="The name of the index to search alerts for.",
83 )
84
85
86 class IndexAlertsSearchResponse(BaseModel):
87 alerts_summary: List[Alert]
88 success: bool
89 message: str
90
91
92 class AlertsByHost(BaseModel):
93 agent_name: str
94 number_of_alerts: int
95
96
97 class AlertsByHostResponse(BaseModel):
98 alerts_by_host: List[AlertsByHost]
99 success: bool
100 message: str
101
102
103 class AlertsByRule(BaseModel):
104 rule: str
105 number_of_alerts: int
106
107
108 class AlertsByRuleResponse(BaseModel):
109 alerts_by_rule: List[AlertsByRule]
110 success: bool
111 message: str
112
113
114 class AlertsByRulePerHost(BaseModel):
115 agent_name: str
116 number_of_alerts: int
117 rule: str
118
119
120 class AlertsByRulePerHostResponse(BaseModel):
121 alerts_by_rule_per_host: List[AlertsByRulePerHost]
122 success: bool
123 message: str
124
125
126 class GraylogAlertsSearchBody(BaseModel):
127 size: int = Field(10, description="The number of alerts to return.")
128 timerange: str = Field("24h", description="The time range to search alerts in.")
129 index_prefix: str = Field(
130 "gl-events*",
131 description="The index prefix to search alerts in.",
132 )
133
134 @field_validator("timerange")
135 @classmethod
136 def validate_timerange(cls, value):
137 if value[-1] not in ("h", "d", "w"):
138 raise ValueError(
139 "Invalid timerange format. The string should end with either 'h', 'd', 'w'.",
140 )
141
142 # Optionally, you can check that the prefix is a number
143 if not value[:-1].isdigit():
144 raise ValueError(
145 "Invalid timerange format. The string should start with a number.",
146 )
147
148 return value
149
150
151 ############# ! PASSABLE MESSAGES FROM ES CLIENT ! #############
152 class SkippableWazuhIndexerClientErrors(Enum):
153 NO_MAPPING_FOR_TIMESTAMP = "No mapping found for [timestamp_utc] in order to sort on"
154 # Add other error messages here, for example:
155 # ANOTHER_ERROR = "Another specific error message"
156
157
158 class AlertNotFound(BaseModel):
159 index: str = Field(alias="_index")
160 id: str = Field(alias="_id")
161 source: Dict[str, str] = Field(alias="_source")
162
163 def to_dict(self) -> Dict[str, str]:
164 return self.model_dump(by_alias=True)