kuma_client/models/
monitor.rs

1//! Models related to Uptime Kuma monitors
2
3use 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>;