main
py 136 lines 4.18 KB
Raw
1 from datetime import datetime
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 AgentModel(BaseModel):
14 id: Optional[int] = None
15 os: Optional[str] = None
16 label: Optional[str] = None
17 wazuh_last_seen: Optional[datetime] = None
18 velociraptor_last_seen: Optional[datetime] = None
19 velociraptor_agent_version: Optional[str] = None
20 ip_address: Optional[str] = None
21 agent_id: Optional[str] = None
22 hostname: Optional[str] = None
23 critical_asset: Optional[bool] = None
24 velociraptor_id: Optional[str] = None
25 wazuh_agent_version: Optional[str] = None
26 customer_code: Optional[str] = None
27 model_config = ConfigDict(from_attributes=True)
28
29
30 class ExtendedAgentModel(AgentModel):
31 unhealthy_wazuh_agent: Optional[bool] = Field(
32 None,
33 description="Whether the agent is unhealthy in Wazuh",
34 )
35 unhealthy_velociraptor_agent: Optional[bool] = Field(
36 None,
37 description="Whether the agent is unhealthy in Velociraptor",
38 )
39 unhealthy_recent_logs_collected: Optional[bool] = Field(
40 None,
41 description="Whether the agent has not collected logs recently",
42 )
43
44
45 class AgentHealthCheckResponse(BaseModel):
46 healthy_wazuh_agents: Optional[List[ExtendedAgentModel]] = None
47 unhealthy_wazuh_agents: Optional[List[ExtendedAgentModel]] = None
48 healthy_velociraptor_agents: Optional[List[ExtendedAgentModel]] = None
49 unhealthy_velociraptor_agents: Optional[List[ExtendedAgentModel]] = None
50 healthy_recent_logs_collected: Optional[List[ExtendedAgentModel]] = None
51 unhealthy_recent_logs_collected: Optional[List[ExtendedAgentModel]] = None
52 message: str
53 success: bool
54
55
56 class TimeCriteriaModel(BaseModel):
57 minutes: int = Field(
58 60,
59 description="Number of minutes within which the agent should have been last seen to be considered healthy.",
60 )
61 hours: int = Field(
62 0,
63 description="Number of hours within which the agent should have been last seen to be considered healthy.",
64 )
65 days: int = Field(
66 0,
67 description="Number of days within which the agent should have been last seen to be considered healthy.",
68 )
69
70
71 ########## Logs Schemas ##########
72
73
74 class Log(BaseModel):
75 index_name: str
76 total_logs: int
77 logs: Optional[List[Dict[str, Any]]] = Field(
78 [],
79 description="The logs returned from the search.",
80 )
81
82
83 class LogsSearchBody(BaseModel):
84 size: int = Field(1, description="The number of logs to return.")
85 timerange: str = Field("24h", description="The time range to search logs in.")
86 log_field: str = Field("syslog_level", description="The field to search logs in.")
87 log_value: str = Field("INFO", description="The value to search logs for.")
88 timestamp_field: str = Field(
89 "timestamp_utc",
90 description="The timestamp field to search logs in.",
91 )
92
93 @field_validator("timerange")
94 @classmethod
95 def validate_timerange(cls, value):
96 if value[-1] not in ("h", "d", "w", "m"):
97 raise ValueError(
98 "Invalid timerange format. The string should end with either 'h', 'd', 'w', or 'm'.",
99 )
100
101 # Optionally, you can check that the prefix is a number
102 if not value[:-1].isdigit():
103 raise ValueError(
104 "Invalid timerange format. The string should start with a number.",
105 )
106
107 return value
108
109
110 class LogsSearchResponse(BaseModel):
111 logs_summary: List[Log]
112 success: bool
113 message: str
114
115
116 class CollectLogsResponse(BaseModel):
117 logs: List[Dict[str, Any]]
118 success: bool
119 message: str
120
121
122 class HostLogsSearchBody(LogsSearchBody):
123 agent_name: str = Field(
124 ...,
125 description="The name of the agent to search logs for.",
126 )
127
128
129 class HostLogsSearchResponse(BaseModel):
130 logs_summary: Optional[List[Log]] = Field(
131 [],
132 description="The logs summary returned from the search.",
133 )
134 healthy: bool = Field(False, description="Whether the host is healthy or not.")
135 success: bool
136 message: str