1use std::fmt::Display;
2
3use crate::error::ContractError;
4use crate::CustomInterval;
5use crate::{DriftType, TimeInterval};
6use chrono::{DateTime, Utc};
7use pyo3::prelude::*;
8use serde::Deserialize;
9use serde::Serialize;
10use tracing::error;
11
12#[pyclass]
13#[derive(Serialize, Deserialize, Debug, Clone)]
14pub struct GetProfileRequest {
15 pub name: String,
16 pub space: String,
17 pub version: String,
18 pub drift_type: DriftType,
19}
20
21#[pymethods]
22impl GetProfileRequest {
23 #[new]
24 #[pyo3(signature = (name, space, version, drift_type))]
25 pub fn new(name: String, space: String, version: String, drift_type: DriftType) -> Self {
26 GetProfileRequest {
27 name,
28 space,
29 version,
30 drift_type,
31 }
32 }
33}
34
35#[pyclass]
36#[derive(Serialize, Deserialize, Debug, Clone, Default)]
37pub struct DriftRequest {
38 pub space: String,
39 pub name: String,
40 pub version: String,
41 pub time_interval: TimeInterval,
42 pub max_data_points: i32,
43 pub drift_type: DriftType,
44 pub begin_custom_datetime: Option<DateTime<Utc>>,
45 pub end_custom_datetime: Option<DateTime<Utc>>,
46}
47
48#[pymethods]
49impl DriftRequest {
50 #[new]
51 #[pyo3(signature = (name, space, version, time_interval, max_data_points, drift_type, begin_datetime=None, end_datetime=None))]
52 #[allow(clippy::too_many_arguments)]
53 pub fn new(
54 name: String,
55 space: String,
56 version: String,
57 time_interval: TimeInterval,
58 max_data_points: i32,
59 drift_type: DriftType,
60 begin_datetime: Option<DateTime<Utc>>,
61 end_datetime: Option<DateTime<Utc>>,
62 ) -> Result<Self, ContractError> {
63 let custom_interval = match (begin_datetime, end_datetime) {
65 (Some(begin), Some(end)) => Some(CustomInterval::new(begin, end)?),
66 _ => None,
67 };
68
69 Ok(DriftRequest {
70 name,
71 space,
72 version,
73 time_interval,
74 max_data_points,
75 drift_type,
76 begin_custom_datetime: custom_interval.as_ref().map(|interval| interval.start),
77 end_custom_datetime: custom_interval.as_ref().map(|interval| interval.end),
78 })
79 }
80}
81
82impl DriftRequest {
83 pub fn has_custom_interval(&self) -> bool {
84 self.begin_custom_datetime.is_some() && self.end_custom_datetime.is_some()
85 }
86
87 pub fn to_custom_interval(&self) -> Option<CustomInterval> {
88 if self.has_custom_interval() {
89 Some(
90 CustomInterval::new(
91 self.begin_custom_datetime.unwrap(),
92 self.end_custom_datetime.unwrap(),
93 )
94 .unwrap(),
95 )
96 } else {
97 None
98 }
99 }
100}
101
102#[pyclass]
103#[derive(Serialize, Deserialize, Debug, Clone)]
104pub struct ProfileRequest {
105 pub space: String,
106 pub drift_type: DriftType,
107 pub profile: String,
108}
109
110#[pyclass]
111#[derive(Serialize, Deserialize, Debug, Clone)]
112pub struct ProfileStatusRequest {
113 pub name: String,
114 pub space: String,
115 pub version: String,
116 pub active: bool,
117 pub drift_type: Option<DriftType>,
118 pub deactivate_others: bool,
119}
120
121#[pymethods]
122impl ProfileStatusRequest {
123 #[new]
124 #[pyo3(signature = (name, space, version, drift_type=None, active=false, deactivate_others=false))]
125 pub fn new(
126 name: String,
127 space: String,
128 version: String,
129 drift_type: Option<DriftType>,
130 active: bool,
131 deactivate_others: bool,
132 ) -> Self {
133 ProfileStatusRequest {
134 name,
135 space,
136 version,
137 active,
138 drift_type,
139 deactivate_others,
140 }
141 }
142}
143
144#[pyclass]
145#[derive(Serialize, Deserialize, Debug, Clone)]
146pub struct DriftAlertRequest {
147 pub name: String,
148 pub space: String,
149 pub version: String,
150 pub limit_datetime: Option<DateTime<Utc>>,
151 pub active: Option<bool>,
152 pub limit: Option<i32>,
153}
154
155#[pymethods]
156impl DriftAlertRequest {
157 #[new]
158 #[pyo3(signature = (name, space, version, active=false, limit_datetime=None, limit=None))]
159 pub fn new(
160 name: String,
161 space: String,
162 version: String,
163 active: bool,
164 limit_datetime: Option<DateTime<Utc>>,
165 limit: Option<i32>,
166 ) -> Self {
167 DriftAlertRequest {
168 name,
169 space,
170 version,
171 limit_datetime,
172 active: Some(active),
173 limit,
174 }
175 }
176}
177
178#[derive(Serialize, Deserialize, Debug, Clone)]
179pub struct ServiceInfo {
180 pub space: String,
181 pub name: String,
182 pub version: String,
183}
184
185#[derive(Serialize, Deserialize, Debug, Clone)]
186pub struct DriftTaskInfo {
187 pub space: String,
188 pub name: String,
189 pub version: String,
190 pub uid: String,
191 pub drift_type: DriftType,
192}
193
194#[derive(Serialize, Deserialize, Debug, Clone)]
195pub struct ObservabilityMetricRequest {
196 pub name: String,
197 pub space: String,
198 pub version: String,
199 pub time_interval: String,
200 pub max_data_points: i32,
201}
202
203#[derive(Serialize, Deserialize, Debug, Clone)]
204pub struct UpdateAlertStatus {
205 pub id: i32,
206 pub active: bool,
207 pub space: String,
208}
209
210#[derive(Serialize, Deserialize, Debug, Clone)]
212pub struct ScouterServerError {
213 pub error: String,
214}
215
216impl ScouterServerError {
217 pub fn permission_denied() -> Self {
218 ScouterServerError {
219 error: "Permission denied".to_string(),
220 }
221 }
222
223 pub fn need_admin_permission() -> Self {
224 error!("User does not have admin permissions");
225 ScouterServerError {
226 error: "Need admin permission".to_string(),
227 }
228 }
229
230 pub fn user_already_exists() -> Self {
231 ScouterServerError {
232 error: "User already exists".to_string(),
233 }
234 }
235
236 pub fn create_user_error<T: Display>(e: T) -> Self {
237 error!("Failed to create user: {}", e);
238 ScouterServerError {
239 error: "Failed to create user".to_string(),
240 }
241 }
242
243 pub fn user_not_found() -> Self {
244 ScouterServerError {
245 error: "User not found".to_string(),
246 }
247 }
248
249 pub fn get_user_error<T: Display>(e: T) -> Self {
250 error!("Failed to get user: {}", e);
251 ScouterServerError {
252 error: "Failed to get user".to_string(),
253 }
254 }
255
256 pub fn list_users_error<T: Display>(e: T) -> Self {
257 error!("Failed to list users: {}", e);
258 ScouterServerError {
259 error: "Failed to list users".to_string(),
260 }
261 }
262
263 pub fn update_user_error<T: Display>(e: T) -> Self {
264 error!("Failed to update user: {}", e);
265 ScouterServerError {
266 error: "Failed to update user".to_string(),
267 }
268 }
269 pub fn delete_user_error<T: Display>(e: T) -> Self {
270 error!("Failed to delete user: {}", e);
271 ScouterServerError {
272 error: "Failed to delete user".to_string(),
273 }
274 }
275
276 pub fn check_last_admin_error<T: Display>(e: T) -> Self {
277 error!("Failed to check admin status: {}", e);
278 ScouterServerError {
279 error: "Failed to check admin status".to_string(),
280 }
281 }
282
283 pub fn cannot_delete_last_admin() -> Self {
284 error!("Cannot delete the last admin user");
285 ScouterServerError {
286 error: "Cannot delete the last admin user".to_string(),
287 }
288 }
289 pub fn username_header_not_found() -> Self {
290 error!("Username header not found");
291 ScouterServerError {
292 error: "Username header not found".to_string(),
293 }
294 }
295
296 pub fn invalid_username_format() -> Self {
297 error!("Invalid username format");
298 ScouterServerError {
299 error: "Invalid username format".to_string(),
300 }
301 }
302
303 pub fn password_header_not_found() -> Self {
304 error!("Password header not found");
305 ScouterServerError {
306 error: "Password header not found".to_string(),
307 }
308 }
309 pub fn invalid_password_format() -> Self {
310 error!("Invalid password format");
311 ScouterServerError {
312 error: "Invalid password format".to_string(),
313 }
314 }
315
316 pub fn user_validation_error() -> Self {
317 error!("User validation failed");
318 ScouterServerError {
319 error: "User validation failed".to_string(),
320 }
321 }
322
323 pub fn failed_token_validation() -> Self {
324 error!("Failed to validate token");
325 ScouterServerError {
326 error: "Failed to validate token".to_string(),
327 }
328 }
329
330 pub fn bearer_token_not_found() -> Self {
331 error!("Bearer token not found");
332 ScouterServerError {
333 error: "Bearer token not found".to_string(),
334 }
335 }
336
337 pub fn refresh_token_error<T: Display>(e: T) -> Self {
338 error!("Failed to refresh token: {}", e);
339 ScouterServerError {
340 error: "Failed to refresh token".to_string(),
341 }
342 }
343
344 pub fn unauthorized<T: Display>(e: T) -> Self {
345 error!("Unauthorized: {}", e);
346 ScouterServerError {
347 error: "Unauthorized".to_string(),
348 }
349 }
350
351 pub fn jwt_decode_error(e: String) -> Self {
352 error!("Failed to decode JWT token: {}", e);
353 ScouterServerError {
354 error: "Failed to decode JWT token".to_string(),
355 }
356 }
357
358 pub fn no_refresh_token() -> Self {
359 error!("No refresh token provided");
360 ScouterServerError {
361 error: "No refresh token provided".to_string(),
362 }
363 }
364
365 pub fn new(error: String) -> Self {
366 ScouterServerError { error }
367 }
368
369 pub fn query_records_error<T: Display>(e: T) -> Self {
370 let msg = format!("Failed to query records: {e}");
371 ScouterServerError { error: msg }
372 }
373
374 pub fn query_alerts_error<T: Display>(e: T) -> Self {
375 let msg = format!("Failed to query alerts: {e}");
376 ScouterServerError { error: msg }
377 }
378
379 pub fn query_profile_error<T: Display>(e: T) -> Self {
380 let msg = format!("Failed to query profile: {e}");
381 ScouterServerError { error: msg }
382 }
383}
384
385#[derive(Serialize, Deserialize, Debug, Clone)]
386pub struct ScouterResponse {
387 pub status: String,
388 pub message: String,
389}
390
391impl ScouterResponse {
392 pub fn new(status: String, message: String) -> Self {
393 ScouterResponse { status, message }
394 }
395}
396
397#[derive(Serialize, Deserialize, Debug, Clone)]
398pub struct UpdateAlertResponse {
399 pub updated: bool,
400}