1use crate::{
4 deserialize::{
5 DeserializeBoolLenient, DeserializeHashMapLenient, DeserializeNumberLenient,
6 DeserializeVecLenient,
7 },
8 error::{Error, Result},
9 models::tag::Tag,
10};
11use derivative::Derivative;
12use regex::Regex;
13use serde::{Deserialize, Serialize, Serializer};
14use serde_inline_default::serde_inline_default;
15use serde_with::{serde_as, skip_serializing_none};
16use std::collections::{HashMap, HashSet};
17
18pub trait MonitorCommon {
19 fn id(&self) -> &Option<i32>;
20 fn id_mut(&mut self) -> &mut Option<i32>;
21 fn name(&self) -> &Option<String>;
22 fn name_mut(&mut self) -> &mut Option<String>;
23 fn description(&self) -> &Option<String>;
24 fn description_mut(&mut self) -> &mut Option<String>;
25 fn interval(&self) -> &Option<i32>;
26 fn interval_mut(&mut self) -> &mut Option<i32>;
27 fn active(&self) -> &Option<bool>;
28 fn active_mut(&mut self) -> &mut Option<bool>;
29 fn max_retries(&self) -> &Option<i32>;
30 fn max_retries_mut(&mut self) -> &mut Option<i32>;
31 fn retry_interval(&self) -> &Option<i32>;
32 fn retry_interval_mut(&mut self) -> &mut Option<i32>;
33 fn upside_down(&self) -> &Option<bool>;
34 fn upside_down_mut(&mut self) -> &mut Option<bool>;
35 fn parent(&self) -> &Option<i32>;
36 fn parent_mut(&mut self) -> &mut Option<i32>;
37 fn tags(&self) -> &Vec<Tag>;
38 fn tags_mut(&mut self) -> &mut Vec<Tag>;
39 fn notification_id_list(&self) -> &Option<HashMap<String, bool>>;
40 fn notification_id_list_mut(&mut self) -> &mut Option<HashMap<String, bool>>;
41 fn accepted_statuscodes(&self) -> &Vec<String>;
42 fn accepted_statuscodes_mut(&mut self) -> &mut Vec<String>;
43
44 #[cfg(feature = "private-api")]
45 fn parent_name(&self) -> &Option<String>;
46 #[cfg(feature = "private-api")]
47 fn parent_name_mut(&mut self) -> &mut Option<String>;
48 #[cfg(feature = "private-api")]
49 fn create_paused(&self) -> &Option<bool>;
50 #[cfg(feature = "private-api")]
51 fn create_paused_mut(&mut self) -> &mut Option<bool>;
52 #[cfg(feature = "private-api")]
53 fn notification_names(&self) -> &Option<Vec<String>>;
54 #[cfg(feature = "private-api")]
55 fn notification_names_mut(&mut self) -> &mut Option<Vec<String>>;
56 #[cfg(feature = "private-api")]
57 fn tag_names(&self) -> &Option<Vec<super::tag::TagValue>>;
58 #[cfg(feature = "private-api")]
59 fn tag_names_mut(&mut self) -> &mut Option<Vec<super::tag::TagValue>>;
60}
61
62macro_rules! monitor_type {
63 ($struct_name:ident $type:ident {
64 $($field:tt)*
65 }) => {
66 #[serde_inline_default]
67 #[skip_serializing_none]
68 #[serde_as]
69 #[derive(Clone, Debug, Derivative, Serialize, Deserialize)]
70 #[derivative(PartialEq)]
71 pub struct $struct_name {
72 #[serde(rename = "id")]
73 #[serde_as(as = "Option<DeserializeNumberLenient>")]
74 pub id: Option<i32>,
75
76 #[serde(rename = "name")]
77 pub name: Option<String>,
78
79 #[serde(rename = "description")]
80 pub description: Option<String>,
81
82 #[serde(rename = "interval")]
83 #[serde_inline_default(Some(60))]
84 #[serde_as(as = "Option<DeserializeNumberLenient>")]
85 pub interval: Option<i32>,
86
87 #[serde(rename = "active")]
88 #[serde_inline_default(None)]
89 #[serde_as(as = "Option<DeserializeBoolLenient>")]
90 #[derivative(PartialEq="ignore")]
91 #[derivative(Hash = "ignore")]
92 pub active: Option<bool>,
93
94 #[serde(rename = "maxretries")]
95 #[serde(alias = "max_retries")]
96 #[serde_as(as = "Option<DeserializeNumberLenient>")]
97 pub max_retries: Option<i32>,
98
99 #[serde(rename = "retryInterval")]
100 #[serde(alias = "retry_interval")]
101 #[serde_inline_default(Some(60))]
102 #[serde_as(as = "Option<DeserializeNumberLenient>")]
103 pub retry_interval: Option<i32>,
104
105 #[serde(rename = "upsideDown")]
106 #[serde(alias = "upside_down")]
107 #[serde_as(as = "Option<DeserializeBoolLenient>")]
108 pub upside_down: Option<bool>,
109
110 #[serde(rename = "parent")]
111 #[serde_as(as = "Option<DeserializeNumberLenient>")]
112 #[serialize_always]
113 pub parent: Option<i32>,
114
115 #[serde(rename = "tags")]
116 #[serde(skip_serializing_if = "Vec::is_empty")]
117 #[serde(default)]
118 #[serde_as(as = "DeserializeVecLenient<Tag>")]
119 #[derivative(PartialEq(compare_with = "compare_tags"))]
120 pub tags: Vec<Tag>,
121
122 #[serde(rename = "notificationIDList")]
123 #[serde(alias = "notification_id_list")]
124 #[serde_as(as = "Option<DeserializeHashMapLenient<String, bool>>")]
125 pub notification_id_list: Option<HashMap<String, bool>>,
126
127 #[serde(rename = "accepted_statuscodes")]
128 #[serde_as(as = "DeserializeVecLenient<String>")]
129 #[serde_inline_default(vec!["200-299".to_owned()])]
130 pub accepted_statuscodes: Vec<String>,
131
132 #[cfg(feature = "private-api")]
133 #[serde(rename = "parent_name")]
134 #[derivative(PartialEq = "ignore")]
135 #[derivative(Hash = "ignore")]
136 pub parent_name: Option<String>,
137
138 #[cfg(feature = "private-api")]
139 #[serde(rename = "create_paused")]
140 #[serde_inline_default(None)]
141 #[serde_as(as = "Option<DeserializeBoolLenient>")]
142 #[derivative(PartialEq = "ignore")]
143 #[derivative(Hash = "ignore")]
144 pub create_paused: Option<bool>,
145
146 #[cfg(feature = "private-api")]
147 #[serde(rename = "notification_name_list")]
148 #[derivative(PartialEq = "ignore")]
149 #[derivative(Hash = "ignore")]
150 #[serde_as(as = "Option<DeserializeVecLenient<String>>")]
151 pub notification_names: Option<Vec<String>>,
152
153 #[cfg(feature = "private-api")]
154 #[serde(rename = "tag_names")]
155 #[derivative(PartialEq = "ignore")]
156 #[derivative(Hash = "ignore")]
157 #[serde_as(as = "Option<DeserializeVecLenient<super::tag::TagValue>>")]
158 pub tag_names: Option<Vec<super::tag::TagValue>>,
159
160
161 #[cfg(not(feature = "uptime-kuma-v1"))]
162 #[serde(rename = "conditions")]
163 #[serde_as(as = "DeserializeVecLenient<MonitorCondition>")]
164 #[serde_inline_default(vec![])]
165 pub conditions: Vec<MonitorCondition>,
166
167 $($field)*
168 }
169
170 impl MonitorCommon for $struct_name {
171 fn id(&self) -> &Option<i32> { &self.id }
172 fn id_mut(&mut self) -> &mut Option<i32> { &mut self.id }
173 fn name(&self) -> &Option<String> { &self.name }
174 fn name_mut(&mut self) -> &mut Option<String> { &mut self.name }
175 fn description(&self) -> &Option<String> { &self.description }
176 fn description_mut(&mut self) -> &mut Option<String> { &mut self.description }
177 fn interval(&self) -> &Option<i32> { &self.interval }
178 fn interval_mut(&mut self) -> &mut Option<i32> { &mut self.interval }
179 fn active(&self) -> &Option<bool> { &self.active }
180 fn active_mut(&mut self) -> &mut Option<bool> { &mut self.active }
181 fn max_retries(&self) -> &Option<i32> { &self.max_retries }
182 fn max_retries_mut(&mut self) -> &mut Option<i32> { &mut self.max_retries }
183 fn retry_interval(&self) -> &Option<i32> { &self.retry_interval }
184 fn retry_interval_mut(&mut self) -> &mut Option<i32> { &mut self.retry_interval }
185 fn upside_down(&self) -> &Option<bool> { &self.upside_down }
186 fn upside_down_mut(&mut self) -> &mut Option<bool> { &mut self.upside_down }
187 fn parent(&self) -> &Option<i32> { &self.parent }
188 fn parent_mut(&mut self) -> &mut Option<i32> { &mut self.parent }
189 fn tags(&self) -> &Vec<Tag> { &self.tags }
190 fn tags_mut(&mut self) -> &mut Vec<Tag> { &mut self.tags }
191 fn notification_id_list(&self) -> &Option<HashMap<String, bool>> { &self.notification_id_list }
192 fn notification_id_list_mut(&mut self) -> &mut Option<HashMap<String, bool>> { &mut self.notification_id_list }
193 fn accepted_statuscodes(&self) -> &Vec<String> { &self.accepted_statuscodes }
194 fn accepted_statuscodes_mut(&mut self) -> &mut Vec<String> { &mut self.accepted_statuscodes }
195
196 #[cfg(feature = "private-api")]
197 fn parent_name(&self) -> &Option<String> { &self.parent_name }
198 #[cfg(feature = "private-api")]
199 fn parent_name_mut(&mut self) -> &mut Option<String> { &mut self.parent_name }
200 #[cfg(feature = "private-api")]
201 fn create_paused(&self) -> &Option<bool> { &self.create_paused }
202 #[cfg(feature = "private-api")]
203 fn create_paused_mut(&mut self) -> &mut Option<bool> { &mut self.create_paused }
204 #[cfg(feature = "private-api")]
205 fn notification_names(&self) -> &Option<Vec<String>> { &self.notification_names }
206 #[cfg(feature = "private-api")]
207 fn notification_names_mut(&mut self) -> &mut Option<Vec<String>> { &mut self.notification_names }
208 #[cfg(feature = "private-api")]
209 fn tag_names(&self) -> &Option<Vec<super::tag::TagValue>> { &self.tag_names }
210 #[cfg(feature = "private-api")]
211 fn tag_names_mut(&mut self) -> &mut Option<Vec<super::tag::TagValue>> { &mut self.tag_names }
212 }
213
214 impl From<$struct_name> for Monitor {
215 fn from(value: $struct_name) -> Self {
216 Monitor::$type { value: value }
217 }
218 }
219
220 crate::default_from_serde!($struct_name);
221 };
222}
223
224#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
225pub enum MonitorType {
226 #[serde(rename = "dns")]
227 Dns,
228
229 #[serde(rename = "docker")]
230 Docker,
231
232 #[serde(rename = "gamedig")]
233 GameDig,
234
235 #[serde(rename = "group")]
236 Group,
237
238 #[serde(rename = "grpc-keyword")]
239 GrpcKeyword,
240
241 #[serde(rename = "http")]
242 Http,
243
244 #[serde(rename = "json-query")]
245 JsonQuery,
246
247 #[serde(rename = "kafka-producer")]
248 KafkaProducer,
249
250 #[serde(rename = "keyword")]
251 Keyword,
252
253 #[serde(rename = "mongodb")]
254 Mongodb,
255
256 #[serde(rename = "mqtt")]
257 Mqtt,
258
259 #[serde(rename = "mysql")]
260 Mysql,
261
262 #[serde(rename = "ping")]
263 Ping,
264
265 #[serde(rename = "port")]
266 Port,
267
268 #[serde(rename = "postgres")]
269 Postgres,
270
271 #[serde(rename = "push")]
272 Push,
273
274 #[serde(rename = "radius")]
275 Radius,
276
277 #[serde(rename = "real-browser")]
278 RealBrowser,
279
280 #[serde(rename = "redis")]
281 Redis,
282
283 #[serde(rename = "steam")]
284 Steam,
285
286 #[serde(rename = "sqlserver")]
287 SqlServer,
288
289 #[serde(rename = "tailscale-ping")]
290 TailscalePing,
291
292 #[cfg(not(feature = "uptime-kuma-v1"))]
293 #[serde(rename = "snmp")]
294 SNMP,
295
296 #[cfg(not(feature = "uptime-kuma-v1"))]
297 #[serde(rename = "rabbitmq")]
298 RabbitMQ,
299}
300
301#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
302pub enum DnsResolverType {
303 A,
304 AAAA,
305 CAA,
306 CNAME,
307 MX,
308 NS,
309 PTR,
310 SOA,
311 SRV,
312 TXT,
313}
314
315#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
316pub enum HttpMethod {
317 DELETE,
318 GET,
319 HEAD,
320 OPTIONS,
321 PATCH,
322 POST,
323 PUT,
324}
325
326#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
327#[serde(tag = "mechanism")]
328pub enum KafkaProducerSaslOptions {
329 #[serde(rename = "None")]
330 None,
331
332 #[serde(rename = "plain")]
333 Plain {
334 #[serde(rename = "username")]
335 username: Option<String>,
336
337 #[serde(rename = "password")]
338 password: Option<String>,
339 },
340
341 #[serde(rename = "scram-sha-256")]
342 ScramSha256 {
343 #[serde(rename = "username")]
344 username: Option<String>,
345
346 #[serde(rename = "password")]
347 password: Option<String>,
348 },
349
350 #[serde(rename = "scram-sha-512")]
351 ScramSha512 {
352 #[serde(rename = "username")]
353 username: Option<String>,
354
355 #[serde(rename = "password")]
356 password: Option<String>,
357 },
358
359 #[serde(rename = "aws")]
360 AWS {
361 #[serde(rename = "authorizationIdentity")]
362 #[serde(alias = "authorization_identity")]
363 authorization_identity: Option<String>,
364
365 #[serde(rename = "accessKeyId")]
366 #[serde(alias = "access_key_id")]
367 access_key_id: Option<String>,
368
369 #[serde(rename = "secretAccessKey")]
370 #[serde(alias = "secret_access_key")]
371 secret_access_key: Option<String>,
372
373 #[serde(alias = "sessionToken")]
374 #[serde(rename = "session_token")]
375 session_token: Option<String>,
376 },
377}
378
379fn compare_tags(a: &Vec<Tag>, b: &Vec<Tag>) -> bool {
380 if a.len() != b.len() {
381 return false;
382 }
383
384 a.iter().collect::<HashSet<_>>() == b.iter().collect::<HashSet<_>>()
385}
386
387#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
388pub enum HttpOAuthMethod {
389 #[serde(rename = "client_secret_basic")]
390 ClientSecretBasic,
391
392 #[serde(rename = "client_secret_post")]
393 ClientSecretPost,
394}
395
396#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
397#[serde(tag = "authMethod")]
398pub enum HttpAuth {
399 #[serde(rename = "null")]
400 None,
401
402 #[serde(rename = "basic")]
403 Basic {
404 #[serde(rename = "basic_auth_user")]
405 username: Option<String>,
406
407 #[serde(rename = "basic_auth_pass")]
408 password: Option<String>,
409 },
410
411 #[serde(rename = "oauth2-cc")]
412 OAuth2 {
413 #[serde(rename = "oauth_auth_method")]
414 method: Option<HttpOAuthMethod>,
415
416 #[serde(rename = "oauth_client_id")]
417 client_id: Option<String>,
418
419 #[serde(rename = "oauth_token_url")]
420 token_url: Option<String>,
421
422 #[serde(rename = "oauth_client_secret")]
423 client_secret: Option<String>,
424
425 #[serde(rename = "oauth_scopes")]
426 scopes: Option<String>,
427 },
428
429 #[serde(rename = "ntlm")]
430 NTLM {
431 #[serde(rename = "basic_auth_user")]
432 basic_auth_user: Option<String>,
433
434 #[serde(rename = "basic_auth_pass")]
435 basic_auth_pass: Option<String>,
436
437 #[serde(rename = "authDomain")]
438 #[serde(alias = "auth_domain")]
439 auth_domain: Option<String>,
440
441 #[serde(rename = "authWorkstation")]
442 #[serde(alias = "auth_workstation")]
443 auth_workstation: Option<String>,
444 },
445
446 #[serde(rename = "mtls")]
447 MTLS {
448 #[serde(rename = "tlsCert")]
449 #[serde(alias = "tls_cert")]
450 tls_cert: Option<String>,
451
452 #[serde(rename = "tlsKey")]
453 #[serde(alias = "tls_key")]
454 tls_key: Option<String>,
455
456 #[serde(rename = "tlsCa")]
457 #[serde(alias = "tls_ca")]
458 tls_ca: Option<String>,
459 },
460}
461
462#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
463pub enum MonitorConditionOperator {
464 #[serde(rename = "equals")]
465 Equals,
466 #[serde(rename = "not_equals")]
467 NotEquals,
468 #[serde(rename = "contains")]
469 Contains,
470 #[serde(rename = "not_contains")]
471 NotContains,
472 #[serde(rename = "starts_with")]
473 StartsWith,
474 #[serde(rename = "not_starts_with")]
475 NotStartsWith,
476 #[serde(rename = "ends_with")]
477 EndsWith,
478 #[serde(rename = "not_ends_with")]
479 NotEndsWith,
480}
481
482#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
483pub enum MonitorConditionConjunction {
484 #[serde(rename = "and")]
485 And,
486 #[serde(rename = "or")]
487 Or,
488}
489
490#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
491#[serde(tag = "type")]
492pub enum MonitorCondition {
493 #[serde(rename = "expression")]
494 Expression {
495 #[serde(rename = "variable")]
496 variable: Option<String>,
497 #[serde(rename = "operator")]
498 operator: Option<MonitorConditionOperator>,
499 #[serde(rename = "value")]
500 value: Option<String>,
501 #[serde(rename = "andOr")]
502 conjunction: Option<MonitorConditionConjunction>,
503 },
504
505 #[serde(rename = "group")]
506 Group {
507 #[serde(rename = "children")]
508 children: Option<Vec<MonitorCondition>>,
509 },
510}
511
512#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
513pub enum SNMPVersion {
514 #[serde(rename = "1")]
515 SNMPv1,
516
517 #[serde(rename = "2c")]
518 SNMPv2c,
519}
520
521#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)]
522pub enum HttpBodyEncoding {
523 #[default]
524 #[serde(rename = "json")]
525 Json,
526
527 #[cfg(not(feature = "uptime-kuma-v1"))]
528 #[serde(rename = "form")]
529 Form,
530
531 #[serde(rename = "xml")]
532 Xml,
533}
534
535#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)]
536pub enum MqttCheckType {
537 #[default]
538 #[serde(rename = "keyword")]
539 Keyword,
540
541 #[serde(rename = "json-query")]
542 JsonQuery,
543}
544
545#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)]
546pub enum JsonPathOperator {
547 #[serde(rename = ">")]
548 Greater,
549
550 #[serde(rename = ">=")]
551 GreaterEqual,
552
553 #[serde(rename = "<")]
554 Less,
555
556 #[serde(rename = "<=")]
557 LessEqual,
558
559 #[serde(rename = "!=")]
560 NotEqual,
561
562 #[default]
563 #[serde(rename = "==")]
564 Equal,
565
566 #[serde(rename = "contains")]
567 Contains,
568}
569
570#[derive(Clone, Debug, PartialEq, Deserialize)]
571#[serde(untagged)]
572pub enum ExpectedValue {
573 String(String),
574 Number(f64),
575}
576
577impl Serialize for ExpectedValue {
578 #[inline]
579 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
580 where
581 S: Serializer,
582 {
583 match self {
584 ExpectedValue::String(ref s) => serializer.serialize_str(s),
585 ExpectedValue::Number(n) => serializer.serialize_str(&n.to_string()),
586 }
587 }
588}
589
590monitor_type! {
591 MonitorGroup Group {
592
593 }
594}
595
596monitor_type! {
597 MonitorSqlServer SqlServer {
598 #[serde(rename = "databaseConnectionString")]
599 #[serde(alias = "database_connection_string")]
600 pub database_connection_string: Option<String>,
601
602 #[serde(rename = "databaseQuery")]
603 #[serde(alias = "query")]
604 pub query: Option<String>,
605 }
606}
607
608monitor_type! {
609 MonitorPostgres Postgres {
610 #[serde(rename = "databaseConnectionString")]
611 #[serde(alias = "database_connection_string")]
612 pub database_connection_string: Option<String>,
613
614 #[serde(rename = "databaseQuery")]
615 #[serde(alias = "query")]
616 pub query: Option<String>,
617 }
618}
619
620monitor_type! {
621 MonitorMongoDB Mongodb {
622 #[serde(rename = "databaseConnectionString")]
623 #[serde(alias = "database_connection_string")]
624 pub database_connection_string: Option<String>,
625
626 #[cfg(not(feature = "uptime-kuma-v1"))]
627 #[serde(rename = "databaseQuery")]
628 #[serde(alias = "command")]
629 pub command: Option<String>,
630
631 #[cfg(not(feature = "uptime-kuma-v1"))]
632 #[serde(rename = "jsonPath")]
633 #[serde(alias = "json_path")]
634 pub json_path: Option<String>,
635
636 #[cfg(not(feature = "uptime-kuma-v1"))]
637 #[serde(rename = "expectedValue")]
638 #[serde(alias = "expected_value")]
639 pub expected_value: Option<ExpectedValue>,
640 }
641}
642
643monitor_type! {
644 MonitorMysql Mysql {
645 #[serde(rename = "databaseConnectionString")]
646 #[serde(alias = "database_connection_string")]
647 pub database_connection_string: Option<String>,
648
649 #[serde(rename = "radiusPassword")]
650 #[serde(alias = "radius_password")]
651 pub password: Option<String>,
652
653 #[serde(rename = "databaseQuery")]
654 #[serde(alias = "query")]
655 pub query: Option<String>,
656 }
657}
658
659monitor_type! {
660 MonitorRedis Redis {
661 #[serde(rename = "databaseConnectionString")]
662 #[serde(alias = "database_connection_string")]
663 pub database_connection_string: Option<String>,
664
665 #[cfg(not(feature = "uptime-kuma-v1"))]
666 #[serde(rename = "ignoreTls")]
667 #[serde(alias = "ignore_tls")]
668 #[serde_as(as = "Option<DeserializeBoolLenient>")]
669 pub ignore_tls: Option<bool>,
670 }
671}
672
673monitor_type! {
674 MonitorDns Dns {
675 #[serde(rename = "hostname")]
676 pub hostname: Option<String>,
677
678 #[serde(rename = "dns_resolve_server")]
679 #[serde_inline_default(Some("1.1.1.1".to_owned()))]
680 pub dns_resolve_server: Option<String>,
681
682 #[serde(rename = "port")]
683 #[serde_as(as = "Option<DeserializeNumberLenient>")]
684 pub port: Option<u16>,
685
686 #[serde(rename = "dns_resolve_type")]
687 #[serde_inline_default(Some(DnsResolverType::A))]
688 pub dns_resolve_type: Option<DnsResolverType>,
689 }
690}
691
692monitor_type! {
693 MonitorDocker Docker {
694 #[serde(rename = "docker_container")]
695 pub docker_container: Option<String>,
696
697 #[serde(rename = "docker_host")]
698 #[serde_as(as = "Option<DeserializeNumberLenient>")]
699 pub docker_host: Option<i32>,
700
701 #[cfg(feature = "private-api")]
702 #[serde(rename = "docker_host_name")]
703 #[derivative(PartialEq = "ignore")]
704 #[derivative(Hash = "ignore")]
705 pub docker_host_name: Option<String>,
706 }
707}
708
709monitor_type! {
710 MonitorGameDig GameDig {
711 #[serde(rename = "game")]
712 pub game: Option<String>,
713
714 #[serde(rename = "hostname")]
715 pub hostname: Option<String>,
716
717 #[serde(rename = "port")]
718 #[serde_as(as = "Option<DeserializeNumberLenient>")]
719 pub port: Option<u16>,
720
721 #[serde(rename = "gamedigGivenPortOnly")]
722 #[serde(alias = "gamedig_given_port_only")]
723 #[serde_as(as = "Option<DeserializeBoolLenient>")]
724 pub gamedig_given_port_only: Option<bool>,
725 }
726}
727
728monitor_type! {
729 MonitorGrpcKeyword GrpcKeyword {
730 #[serde(rename = "keyword")]
731 pub keyword: Option<String>,
732
733 #[serde_as(as = "Option<DeserializeBoolLenient>")]
734 pub invert_keyword: Option<bool>,
735
736 #[serde(rename = "grpcUrl")]
737 #[serde(alias = "grpc_url")]
738 pub grpc_url: Option<String>,
739
740 #[serde(rename = "maxredirects")]
741 #[serde(alias = "max_redirects")]
742 #[serde_inline_default(Some(10))]
743 #[serde_as(as = "Option<DeserializeNumberLenient>")]
744 pub max_redirects: Option<i32>,
745
746 #[serde(rename = "grpcEnableTls")]
747 #[serde(alias = "grpc_enable_tls")]
748 #[serde_as(as = "Option<DeserializeBoolLenient>")]
749 pub grpc_enable_tls: Option<bool>,
750
751 #[serde(rename = "grpcServiceName")]
752 #[serde(alias = "grpc_service_name")]
753 pub grpc_service_name: Option<String>,
754
755 #[serde(rename = "grpcMethod")]
756 #[serde(alias = "grpc_method")]
757 pub grpc_method: Option<String>,
758
759 #[serde(rename = "grpcProtobuf")]
760 #[serde(alias = "grpc_protobuf")]
761 pub grpc_protobuf: Option<String>,
762
763 #[serde(rename = "grpcBody")]
764 #[serde(alias = "grpc_body")]
765 pub grpc_body: Option<String>,
766
767 #[serde(rename = "grpcMetadata")]
768 #[serde(alias = "grpc_metadata")]
769 pub grpc_metadata: Option<String>,
770
771 #[cfg(not(feature = "uptime-kuma-v1"))]
772 #[serde(rename = "cacheBust")]
773 #[serde(alias = "cache_bust")]
774 #[serde_as(as = "Option<DeserializeBoolLenient>")]
775 pub cache_bust: Option<bool>,
776 }
777}
778
779monitor_type! {
780 MonitorHttp Http {
781 #[serde(rename = "url")]
782 pub url: Option<String>,
783
784 #[serde(rename = "timeout")]
785 #[serde_inline_default(Some(48))]
786 #[serde_as(as = "Option<DeserializeNumberLenient>")]
787 pub timeout: Option<i32>,
788
789 #[serde(rename = "resendInterval")]
790 #[serde(alias = "resend_interval")]
791 #[serde_as(as = "Option<DeserializeNumberLenient>")]
792 pub resend_interval: Option<i32>,
793
794 #[serde(rename = "expiryNotification")]
795 #[serde(alias = "expiry_notification")]
796 #[serde_as(as = "Option<DeserializeBoolLenient>")]
797 pub expiry_notification: Option<bool>,
798
799 #[serde(rename = "ignoreTls")]
800 #[serde(alias = "ignore_tls")]
801 #[serde_as(as = "Option<DeserializeBoolLenient>")]
802 pub ignore_tls: Option<bool>,
803
804 #[serde(rename = "maxredirects")]
805 #[serde(alias = "max_redirects")]
806 #[serde_as(as = "Option<DeserializeNumberLenient>")]
807 pub max_redirects: Option<i32>,
808
809 #[serde(rename = "proxyId")]
810 #[serde(alias = "proxy_id")]
811 #[serde_as(as = "Option<DeserializeNumberLenient>")]
812 pub proxy_id: Option<i32>,
813
814 #[serde(rename = "method")]
815 #[serde_inline_default(Some(HttpMethod::GET))]
816 pub method: Option<HttpMethod>,
817
818 #[serde(rename = "httpBodyEncoding")]
819 #[serde(alias = "http_body_encoding")]
820 pub http_body_encoding: Option<HttpBodyEncoding>,
821
822 #[serde(rename = "body")]
823 pub body: Option<String>,
824
825 #[serde(rename = "headers")]
826 pub headers: Option<String>,
827
828 #[serde(flatten)]
829 pub auth: Option<HttpAuth>,
830
831 #[cfg(not(feature = "uptime-kuma-v1"))]
832 #[serde(rename = "cacheBust")]
833 #[serde(alias = "cache_bust")]
834 #[serde_as(as = "Option<DeserializeBoolLenient>")]
835 pub cache_bust: Option<bool>,
836 }
837}
838
839monitor_type! {
840 MonitorJsonQuery JsonQuery {
841 #[serde(rename = "jsonPath")]
842 #[serde(alias = "json_path")]
843 pub json_path: Option<String>,
844
845 #[cfg(not(feature = "uptime-kuma-v1"))]
846 #[serde(rename = "jsonPathOperator")]
847 #[serde(alias = "json_path_operator")]
848 pub json_path_operator: Option<JsonPathOperator>,
849
850 #[serde(rename = "expectedValue")]
851 #[serde(alias = "expected_value")]
852 pub expected_value: Option<ExpectedValue>,
853
854 #[serde(rename = "url")]
855 pub url: Option<String>,
856
857 #[serde(rename = "timeout")]
858 #[serde_inline_default(Some(48))]
859 #[serde_as(as = "Option<DeserializeNumberLenient>")]
860 pub timeout: Option<i32>,
861
862 #[serde(rename = "resendInterval")]
863 #[serde(alias = "resend_interval")]
864 #[serde_as(as = "Option<DeserializeNumberLenient>")]
865 pub resend_interval: Option<i32>,
866
867 #[serde(rename = "expiryNotification")]
868 #[serde(alias = "expiry_notification")]
869 #[serde_as(as = "Option<DeserializeBoolLenient>")]
870 pub expiry_notification: Option<bool>,
871
872 #[serde(rename = "ignoreTls")]
873 #[serde(alias = "ignore_tls")]
874 #[serde_as(as = "Option<DeserializeBoolLenient>")]
875 pub ignore_tls: Option<bool>,
876
877 #[serde(rename = "maxredirects")]
878 #[serde(alias = "max_redirects")]
879 #[serde_as(as = "Option<DeserializeNumberLenient>")]
880 pub max_redirects: Option<i32>,
881
882 #[serde(rename = "proxyId")]
883 #[serde(alias = "proxy_id")]
884 pub proxy_id: Option<String>,
885
886 #[serde(rename = "method")]
887 #[serde_inline_default(Some(HttpMethod::GET))]
888 pub method: Option<HttpMethod>,
889
890 #[serde(rename = "httpBodyEncoding")]
891 #[serde(alias = "http_body_encoding")]
892 pub http_body_encoding: Option<HttpBodyEncoding>,
893
894 #[serde(rename = "body")]
895 pub body: Option<String>,
896
897 #[serde(rename = "headers")]
898 pub headers: Option<String>,
899
900 #[serde(flatten)]
901 pub auth: Option<HttpAuth>,
902
903 #[cfg(not(feature = "uptime-kuma-v1"))]
904 #[serde(rename = "grpcMetadata")]
905 #[serde(alias = "grpc_metadata")]
906 #[serde_as(as = "Option<DeserializeBoolLenient>")]
907 pub cache_bust: Option<bool>,
908 }
909}
910
911monitor_type! {
912 MonitorKafkaProducer KafkaProducer {
913 #[serde(rename = "kafkaProducerBrokers")]
914 #[serde(alias = "kafka_producer_brokers")]
915 #[serde_as(as = "DeserializeVecLenient<String>")]
916 pub kafka_producer_brokers: Vec<String>,
917
918 #[serde(rename = "kafkaProducerTopic")]
919 #[serde(alias = "kafka_producer_topic")]
920 pub kafka_producer_topic: Option<String>,
921
922 #[serde(rename = "kafkaProducerMessage")]
923 #[serde(alias = "kafka_producer_message")]
924 pub kafka_producer_message: Option<String>,
925
926 #[serde(rename = "kafkaProducerSsl")]
927 #[serde(alias = "kafka_producer_ssl")]
928 #[serde_as(as = "Option<DeserializeBoolLenient>")]
929 pub kafka_producer_ssl: Option<bool>,
930
931 #[serde(rename = "kafkaProducerAllowAutoTopicCreation")]
932 #[serde(alias = "kafka_producer_allow_auto_topic_creation")]
933 #[serde_as(as = "Option<DeserializeBoolLenient>")]
934 pub kafka_producer_allow_auto_topic_creation: Option<bool>,
935
936 #[serde(rename = "kafkaProducerSaslOptions")]
937 #[serde(alias = "kafka_producer_sasl_options")]
938 pub kafka_producer_sasl_options: Option<KafkaProducerSaslOptions>,
939 }
940}
941
942monitor_type! {
943 MonitorKeyword Keyword {
944 #[serde(rename = "keyword")]
945 pub keyword: Option<String>,
946
947 #[serde(rename = "invertKeyword")]
948 #[serde(alias = "invert_keyword")]
949 #[serde_as(as = "Option<DeserializeBoolLenient>")]
950 pub invert_keyword: Option<bool>,
951
952 #[serde(rename = "url")]
953 pub url: Option<String>,
954
955 #[serde(rename = "timeout")]
956 #[serde_inline_default(Some(48))]
957 #[serde_as(as = "Option<DeserializeNumberLenient>")]
958 pub timeout: Option<i32>,
959
960 #[serde(rename = "resendInterval")]
961 #[serde(alias = "resend_interval")]
962 #[serde_as(as = "Option<DeserializeNumberLenient>")]
963 pub resend_interval: Option<i32>,
964
965 #[serde(rename = "expiryNotification")]
966 #[serde(alias = "expiry_notification")]
967 #[serde_as(as = "Option<DeserializeBoolLenient>")]
968 pub expiry_notification: Option<bool>,
969
970 #[serde(rename = "ignoreTls")]
971 #[serde(alias = "ignore_tls")]
972 #[serde_as(as = "Option<DeserializeBoolLenient>")]
973 pub ignore_tls: Option<bool>,
974
975 #[serde(rename = "maxredirects")]
976 #[serde(alias = "max_redirects")]
977 #[serde_as(as = "Option<DeserializeNumberLenient>")]
978 pub max_redirects: Option<i32>,
979
980 #[serde(rename = "proxyId")]
981 #[serde(alias = "proxy_id")]
982 pub proxy_id: Option<String>,
983
984 #[serde(rename = "method")]
985 #[serde_inline_default(Some(HttpMethod::GET))]
986 pub method: Option<HttpMethod>,
987
988 #[serde(rename = "httpBodyEncoding")]
989 #[serde(alias = "http_body_encoding")]
990 pub http_body_encoding: Option<HttpBodyEncoding>,
991
992 #[serde(rename = "body")]
993 pub body: Option<String>,
994
995 #[serde(rename = "headers")]
996 pub headers: Option<String>,
997
998 #[serde(flatten)]
999 pub auth: Option<HttpAuth>,
1000 }
1001}
1002
1003monitor_type! {
1004 MonitorMqtt Mqtt {
1005 #[serde(rename = "hostname")]
1006 pub hostname: Option<String>,
1007
1008 #[serde(rename = "port")]
1009 #[serde_as(as = "Option<DeserializeNumberLenient>")]
1010 pub port: Option<u16>,
1011
1012 #[serde(rename = "mqttUsername")]
1013 #[serde(alias = "mqtt_username")]
1014 pub mqtt_username: Option<String>,
1015
1016 #[serde(rename = "mqttPassword")]
1017 #[serde(alias = "mqtt_password")]
1018 pub mqtt_password: Option<String>,
1019
1020 #[serde(rename = "mqttTopic")]
1021 #[serde(alias = "mqtt_topic")]
1022 pub mqtt_topic: Option<String>,
1023
1024 #[serde(rename = "mqttCheckType")]
1025 #[serde(alias = "mqtt_check_type")]
1026 pub mqtt_check_type: Option<MqttCheckType>,
1027
1028 #[serde(rename = "mqttSuccessMessage")]
1029 #[serde(alias = "mqtt_success_message")]
1030 pub mqtt_success_message: Option<String>,
1031
1032 #[cfg(not(feature = "uptime-kuma-v1"))]
1033 #[serde(rename = "jsonPath")]
1034 #[serde(alias = "json_path")]
1035 pub json_path: Option<String>,
1036
1037 #[cfg(not(feature = "uptime-kuma-v1"))]
1038 #[serde(rename = "jsonPathOperator")]
1039 #[serde(alias = "json_path_operator")]
1040 pub json_path_operator: Option<JsonPathOperator>,
1041
1042 #[serde(rename = "expectedValue")]
1043 #[serde(alias = "expected_value")]
1044 pub expected_value: Option<ExpectedValue>,
1045 }
1046}
1047
1048monitor_type! {
1049 MonitorPing Ping {
1050 #[serde(rename = "hostname")]
1051 pub hostname: Option<String>,
1052
1053 #[serde(rename = "packetSize")]
1054 #[serde(alias = "packet_size")]
1055 #[serde_inline_default(Some(56))]
1056 #[serde_as(as = "Option<DeserializeNumberLenient>")]
1057 pub packet_size: Option<i32>,
1058 }
1059}
1060
1061monitor_type! {
1062 MonitorPort Port {
1063 #[serde(rename = "hostname")]
1064 pub hostname: Option<String>,
1065
1066 #[serde(rename = "port")]
1067 #[serde_as(as = "Option<DeserializeNumberLenient>")]
1068 pub port: Option<u16>,
1069 }
1070}
1071
1072monitor_type! {
1073 MonitorPush Push {
1074 #[serde(rename = "pushToken")]
1075 #[serde(alias = "push_token")]
1076 pub push_token: Option<String>,
1077 }
1078}
1079
1080monitor_type! {
1081 MonitorRadius Radius {
1082 #[serde(rename = "hostname")]
1083 pub hostname: Option<String>,
1084
1085 #[serde(rename = "port")]
1086 #[serde_as(as = "Option<DeserializeNumberLenient>")]
1087 pub port: Option<u16>,
1088
1089 #[serde(rename = "radiusUsername")]
1090 #[serde(alias = "radius_username")]
1091 pub radius_username: Option<String>,
1092
1093 #[serde(rename = "radiusPassword")]
1094 #[serde(alias = "radius_password")]
1095 pub radius_password: Option<String>,
1096
1097 #[serde(rename = "radiusSecret")]
1098 #[serde(alias = "radius_secret")]
1099 pub radius_secret: Option<String>,
1100
1101 #[serde(rename = "radiusCalledStationId")]
1102 #[serde(alias = "radius_called_station_id")]
1103 pub radius_called_station_id: Option<String>,
1104
1105 #[serde(rename = "radiusCallingStationId")]
1106 #[serde(alias = "radius_calling_station_id")]
1107 pub radius_calling_station_id: Option<String>,
1108 }
1109}
1110
1111monitor_type! {
1112 MonitorRealBrowser RealBrowser {
1113 #[serde(rename = "url")]
1114 pub url: Option<String>,
1115
1116 #[serde(rename = "remoteBrowsersToggle")]
1117 #[serde(alias = "remote_browsers_toggle")]
1118 #[serde_as(as = "Option<DeserializeBoolLenient>")]
1119 pub remote_browsers_toggle: Option<bool>,
1120
1121 #[serde(rename = "remote_browser")]
1122 pub remote_browser: Option<String>,
1123 }
1124}
1125
1126monitor_type! {
1127 MonitorSteam Steam {
1128 #[serde(rename = "hostname")]
1129 pub hostname: Option<String>,
1130
1131 #[serde(rename = "port")]
1132 #[serde_as(as = "Option<DeserializeNumberLenient>")]
1133 pub port: Option<u16>,
1134 }
1135}
1136
1137monitor_type! {
1138 MonitorTailscalePing TailscalePing {
1139 #[serde(rename = "hostname")]
1140 hostname: Option<String>,
1141 }
1142}
1143
1144#[cfg(not(feature = "uptime-kuma-v1"))]
1145monitor_type! {
1146 MonitorSNMP SNMP {
1147 #[serde(rename = "hostname")]
1148 pub hostname: Option<String>,
1149
1150 #[serde(rename = "port")]
1151 #[serde_as(as = "Option<DeserializeNumberLenient>")]
1152 pub port: Option<u16>,
1153
1154 #[serde(rename = "radiusPassword")]
1155 #[serde(alias = "radius_password")]
1156 pub password: Option<String>,
1157
1158 #[serde(rename = "snmpOid")]
1159 #[serde(alias = "oid")]
1160 pub oid: Option<String>,
1161
1162 #[serde(rename = "snmp_version")]
1163 #[serde(alias = "version")]
1164 pub version: Option<SNMPVersion>,
1165
1166 #[serde(rename = "jsonPath")]
1167 #[serde(alias = "json_path")]
1168 pub json_path: Option<String>,
1169
1170 #[cfg(not(feature = "uptime-kuma-v1"))]
1171 #[serde(rename = "jsonPathOperator")]
1172 #[serde(alias = "json_path_operator")]
1173 pub json_path_operator: Option<JsonPathOperator>,
1174
1175 #[serde(rename = "expectedValue")]
1176 #[serde(alias = "expected_value")]
1177 pub expected_value: Option<ExpectedValue>,
1178 }
1179}
1180
1181#[cfg(not(feature = "uptime-kuma-v1"))]
1182monitor_type! {
1183 MonitorRabbitMQ RabbitMQ {
1184 #[serde(rename = "rabbitmqNodes")]
1185 #[serde_as(as = "DeserializeVecLenient<String>")]
1186 #[serde_inline_default(vec![])]
1187 pub nodes: Vec<String>,
1188
1189 #[serde(rename = "rabbitmqUsername")]
1190 #[serde(alias = "username")]
1191 pub username: Option<String>,
1192
1193 #[serde(rename = "rabbitmqPassword")]
1194 #[serde(alias = "password")]
1195 pub password: Option<String>,
1196 }
1197}
1198
1199#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1200#[serde(tag = "type")]
1201pub enum Monitor {
1202 #[serde(rename = "group")]
1203 Group {
1204 #[serde(flatten)]
1205 value: MonitorGroup,
1206 },
1207
1208 #[serde(rename = "http")]
1209 Http {
1210 #[serde(flatten)]
1211 value: MonitorHttp,
1212 },
1213
1214 #[serde(rename = "port")]
1215 Port {
1216 #[serde(flatten)]
1217 value: MonitorPort,
1218 },
1219
1220 #[serde(rename = "ping")]
1221 Ping {
1222 #[serde(flatten)]
1223 value: MonitorPing,
1224 },
1225
1226 #[serde(rename = "keyword")]
1227 Keyword {
1228 #[serde(flatten)]
1229 value: MonitorKeyword,
1230 },
1231
1232 #[serde(rename = "json-query")]
1233 JsonQuery {
1234 #[serde(flatten)]
1235 value: MonitorJsonQuery,
1236 },
1237
1238 #[serde(rename = "grpc-keyword")]
1239 GrpcKeyword {
1240 #[serde(flatten)]
1241 value: MonitorGrpcKeyword,
1242 },
1243
1244 #[serde(rename = "dns")]
1245 Dns {
1246 #[serde(flatten)]
1247 value: MonitorDns,
1248 },
1249
1250 #[serde(rename = "docker")]
1251 Docker {
1252 #[serde(flatten)]
1253 value: MonitorDocker,
1254 },
1255
1256 #[serde(rename = "real-browser")]
1257 RealBrowser {
1258 #[serde(flatten)]
1259 value: MonitorRealBrowser,
1260 },
1261
1262 #[serde(rename = "push")]
1263 Push {
1264 #[serde(flatten)]
1265 value: MonitorPush,
1266 },
1267
1268 #[serde(rename = "steam")]
1269 Steam {
1270 #[serde(flatten)]
1271 value: MonitorSteam,
1272 },
1273
1274 #[serde(rename = "gamedig")]
1275 GameDig {
1276 #[serde(flatten)]
1277 value: MonitorGameDig,
1278 },
1279
1280 #[serde(rename = "mqtt")]
1281 Mqtt {
1282 #[serde(flatten)]
1283 value: MonitorMqtt,
1284 },
1285
1286 #[serde(rename = "kafka-producer")]
1287 KafkaProducer {
1288 #[serde(flatten)]
1289 value: MonitorKafkaProducer,
1290 },
1291
1292 #[serde(rename = "sqlserver")]
1293 SqlServer {
1294 #[serde(flatten)]
1295 value: MonitorSqlServer,
1296 },
1297
1298 #[serde(rename = "postgres")]
1299 Postgres {
1300 #[serde(flatten)]
1301 value: MonitorPostgres,
1302 },
1303
1304 #[serde(rename = "mysql")]
1305 Mysql {
1306 #[serde(flatten)]
1307 value: MonitorMysql,
1308 },
1309
1310 #[serde(rename = "mongodb")]
1311 Mongodb {
1312 #[serde(flatten)]
1313 value: MonitorMongoDB,
1314 },
1315
1316 #[serde(rename = "radius")]
1317 Radius {
1318 #[serde(flatten)]
1319 value: MonitorRadius,
1320 },
1321
1322 #[serde(rename = "redis")]
1323 Redis {
1324 #[serde(flatten)]
1325 value: MonitorRedis,
1326 },
1327
1328 #[serde(rename = "tailscale-ping")]
1329 TailscalePing {
1330 #[serde(flatten)]
1331 value: MonitorTailscalePing,
1332 },
1333 #[cfg(not(feature = "uptime-kuma-v1"))]
1334 #[serde(rename = "snmp")]
1335 SNMP {
1336 #[serde(flatten)]
1337 value: MonitorSNMP,
1338 },
1339 #[cfg(not(feature = "uptime-kuma-v1"))]
1340 #[serde(rename = "rabbitmq")]
1341 RabbitMQ {
1342 #[serde(flatten)]
1343 value: MonitorRabbitMQ,
1344 },
1345}
1346
1347impl Monitor {
1348 pub fn monitor_type(&self) -> MonitorType {
1349 match self {
1350 Monitor::Group { .. } => MonitorType::Group,
1351 Monitor::Http { .. } => MonitorType::Http,
1352 Monitor::Port { .. } => MonitorType::Port,
1353 Monitor::Ping { .. } => MonitorType::Ping,
1354 Monitor::Keyword { .. } => MonitorType::Keyword,
1355 Monitor::JsonQuery { .. } => MonitorType::JsonQuery,
1356 Monitor::GrpcKeyword { .. } => MonitorType::GrpcKeyword,
1357 Monitor::Dns { .. } => MonitorType::Dns,
1358 Monitor::Docker { .. } => MonitorType::Docker,
1359 Monitor::RealBrowser { .. } => MonitorType::RealBrowser,
1360 Monitor::Push { .. } => MonitorType::Push,
1361 Monitor::Steam { .. } => MonitorType::Steam,
1362 Monitor::GameDig { .. } => MonitorType::GameDig,
1363 Monitor::Mqtt { .. } => MonitorType::Mqtt,
1364 Monitor::KafkaProducer { .. } => MonitorType::KafkaProducer,
1365 Monitor::SqlServer { .. } => MonitorType::SqlServer,
1366 Monitor::Postgres { .. } => MonitorType::Postgres,
1367 Monitor::Mysql { .. } => MonitorType::Mysql,
1368 Monitor::Mongodb { .. } => MonitorType::Mongodb,
1369 Monitor::Radius { .. } => MonitorType::Radius,
1370 Monitor::Redis { .. } => MonitorType::Redis,
1371 Monitor::TailscalePing { .. } => MonitorType::TailscalePing,
1372 #[cfg(not(feature = "uptime-kuma-v1"))]
1373 Monitor::SNMP { .. } => MonitorType::SNMP,
1374 #[cfg(not(feature = "uptime-kuma-v1"))]
1375 Monitor::RabbitMQ { .. } => MonitorType::RabbitMQ,
1376 }
1377 }
1378
1379 pub fn common(&self) -> Box<&dyn MonitorCommon> {
1380 match self {
1381 Monitor::Group { value } => Box::new(value),
1382 Monitor::Http { value } => Box::new(value),
1383 Monitor::Port { value } => Box::new(value),
1384 Monitor::Ping { value } => Box::new(value),
1385 Monitor::Keyword { value } => Box::new(value),
1386 Monitor::JsonQuery { value } => Box::new(value),
1387 Monitor::GrpcKeyword { value } => Box::new(value),
1388 Monitor::Dns { value } => Box::new(value),
1389 Monitor::Docker { value } => Box::new(value),
1390 Monitor::RealBrowser { value } => Box::new(value),
1391 Monitor::Push { value } => Box::new(value),
1392 Monitor::Steam { value } => Box::new(value),
1393 Monitor::GameDig { value } => Box::new(value),
1394 Monitor::Mqtt { value } => Box::new(value),
1395 Monitor::KafkaProducer { value } => Box::new(value),
1396 Monitor::SqlServer { value } => Box::new(value),
1397 Monitor::Postgres { value } => Box::new(value),
1398 Monitor::Mysql { value } => Box::new(value),
1399 Monitor::Mongodb { value } => Box::new(value),
1400 Monitor::Radius { value } => Box::new(value),
1401 Monitor::Redis { value } => Box::new(value),
1402 Monitor::TailscalePing { value } => Box::new(value),
1403 #[cfg(not(feature = "uptime-kuma-v1"))]
1404 Monitor::SNMP { value } => Box::new(value),
1405 #[cfg(not(feature = "uptime-kuma-v1"))]
1406 Monitor::RabbitMQ { value } => Box::new(value),
1407 }
1408 }
1409
1410 pub fn common_mut(&mut self) -> Box<&mut dyn MonitorCommon> {
1411 match self {
1412 Monitor::Group { value } => Box::new(value),
1413 Monitor::Http { value } => Box::new(value),
1414 Monitor::Port { value } => Box::new(value),
1415 Monitor::Ping { value } => Box::new(value),
1416 Monitor::Keyword { value } => Box::new(value),
1417 Monitor::JsonQuery { value } => Box::new(value),
1418 Monitor::GrpcKeyword { value } => Box::new(value),
1419 Monitor::Dns { value } => Box::new(value),
1420 Monitor::Docker { value } => Box::new(value),
1421 Monitor::RealBrowser { value } => Box::new(value),
1422 Monitor::Push { value } => Box::new(value),
1423 Monitor::Steam { value } => Box::new(value),
1424 Monitor::GameDig { value } => Box::new(value),
1425 Monitor::Mqtt { value } => Box::new(value),
1426 Monitor::KafkaProducer { value } => Box::new(value),
1427 Monitor::SqlServer { value } => Box::new(value),
1428 Monitor::Postgres { value } => Box::new(value),
1429 Monitor::Mysql { value } => Box::new(value),
1430 Monitor::Mongodb { value } => Box::new(value),
1431 Monitor::Radius { value } => Box::new(value),
1432 Monitor::Redis { value } => Box::new(value),
1433 Monitor::TailscalePing { value } => Box::new(value),
1434 #[cfg(not(feature = "uptime-kuma-v1"))]
1435 Monitor::SNMP { value } => Box::new(value),
1436 #[cfg(not(feature = "uptime-kuma-v1"))]
1437 Monitor::RabbitMQ { value } => Box::new(value),
1438 }
1439 }
1440
1441 pub fn validate(&self, id: impl AsRef<str>) -> Result<()> {
1442 let mut errors = vec![];
1443
1444 if self.common().name().is_none() {
1445 errors.push("Missing property 'name'".to_owned());
1446 }
1447
1448 if let &Monitor::Push { value } = &self {
1449 if let Some(push_token) = &value.push_token {
1450 let regex = Regex::new("^[A-Za-z0-9]{32}$").unwrap();
1451 if !regex.is_match(&push_token) {
1452 errors.push("Invalid push_token, push token should be 32 characters and contain only letters and numbers".to_owned());
1453 }
1454 }
1455 }
1456
1457 if !errors.is_empty() {
1458 return Err(Error::ValidationError(id.as_ref().to_owned(), errors));
1459 }
1460
1461 Ok(())
1462 }
1463}
1464
1465pub type MonitorList = HashMap<String, Monitor>;