diff --git a/.github/workflows/rust-build-release.yml b/.github/workflows/rust-build-release.yml index 33b85da..4e6f76d 100644 --- a/.github/workflows/rust-build-release.yml +++ b/.github/workflows/rust-build-release.yml @@ -90,7 +90,7 @@ jobs: - name: Download All Artifacts uses: actions/download-artifact@v4 with: - path: autokuma + path: dist pattern: autokuma-* merge-multiple: true @@ -99,6 +99,6 @@ jobs: uses: softprops/action-gh-release@v1 with: token: ${{ secrets.GITHUB_TOKEN }} - title: Release ${{ github.ref }} + name: Release ${{ github.ref }} body: ${{ steps.changelog.outputs.description }} - files: autokuma/* + files: dist/* diff --git a/Cargo.lock b/Cargo.lock index 9f45a50..86e6829 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,17 +23,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" -[[package]] -name = "ahash" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "aho-corasick" version = "1.1.2" @@ -167,7 +156,7 @@ dependencies = [ "strum", "thiserror", "tokio", - "toml 0.8.8", + "toml", ] [[package]] @@ -196,12 +185,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.6" @@ -219,6 +202,9 @@ name = "bitflags" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -235,7 +221,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f03db470b3c0213c47e978da93200259a1eb4dae2e5512cba9955e2b540a6fc6" dependencies = [ - "base64 0.21.6", + "base64", "bollard-stubs", "bytes", "futures-core", @@ -364,11 +350,12 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "config" -version = "0.13.4" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" +checksum = "7328b20597b53c2454f0b1919720c25c7339051c02b72b7e05409e00b14132be" dependencies = [ "async-trait", + "convert_case 0.6.0", "json5", "lazy_static", "nom", @@ -377,10 +364,30 @@ dependencies = [ "rust-ini", "serde", "serde_json", - "toml 0.5.11", + "toml", "yaml-rust", ] +[[package]] +name = "const-random" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaf16c9c2c612020bcfd042e170f6e32de9b9d75adb5277cdbbd2e2c8c8299a" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + [[package]] name = "const-str" version = "0.5.6" @@ -433,6 +440,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -458,6 +474,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -563,9 +585,12 @@ dependencies = [ [[package]] name = "dlv-list" -version = "0.3.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] [[package]] name = "either" @@ -611,6 +636,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "example" +version = "0.0.0" +dependencies = [ + "kuma_client", + "serde_json", + "tokio", +] + [[package]] name = "fastrand" version = "2.0.1" @@ -772,9 +806,12 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" [[package]] name = "hashbrown" @@ -1042,7 +1079,7 @@ dependencies = [ "serde_json", "serde_yaml", "tokio", - "toml 0.8.8", + "toml", ] [[package]] @@ -1307,12 +1344,12 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-multimap" -version = "0.4.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +checksum = "4ed8acf08e98e744e5384c8bc63ceb0364e68a6854187221c18df61c4797690e" dependencies = [ "dlv-list", - "hashbrown 0.12.3", + "hashbrown 0.13.2", ] [[package]] @@ -1582,7 +1619,7 @@ version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64 0.21.6", + "base64", "bytes", "encoding_rs", "futures-core", @@ -1618,20 +1655,21 @@ dependencies = [ [[package]] name = "ron" -version = "0.7.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", + "base64", + "bitflags 2.4.1", "serde", + "serde_derive", ] [[package]] name = "rust-ini" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +checksum = "7e2a3bcec1f113553ef1c88aae6c020a369d03d55b58de9869a0908930385091" dependencies = [ "cfg-if", "ordered-multimap", @@ -1645,7 +1683,7 @@ dependencies = [ "adler32", "async-stream", "async-trait", - "base64 0.21.6", + "base64", "bytes", "futures-util", "http", @@ -1668,7 +1706,7 @@ dependencies = [ "adler32", "async-stream", "backoff", - "base64 0.21.6", + "base64", "bytes", "futures-util", "log", @@ -1762,13 +1800,13 @@ dependencies = [ [[package]] name = "serde-inline-default" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa824cde50b5f01ff28a955114d8152a07cd62d81f53459dad0f2610136be844" +checksum = "9980133dc534d02ab08df3b384295223a45090c40a4c46240e3eaa982b495910" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -1777,7 +1815,7 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2be4d78e3674912678d7c86b8c507fa72ebff66a8dd3359dc54ec97164b68474" dependencies = [ - "convert_case", + "convert_case 0.4.0", "proc-macro-error", "proc-macro2", "quote", @@ -1855,7 +1893,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" dependencies = [ - "base64 0.21.6", + "base64", "chrono", "hex", "indexmap 1.9.3", @@ -1968,18 +2006,18 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" dependencies = [ "heck", "proc-macro2", @@ -2104,6 +2142,15 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2187,15 +2234,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - [[package]] name = "toml" version = "0.8.8" @@ -2343,6 +2381,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + [[package]] name = "unicode-xid" version = "0.2.4" diff --git a/Cargo.toml b/Cargo.toml index e628f03..0c17faf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["autokuma", "kuma-cli", "kuma-client"] +members = ["autokuma", "example", "kuma-cli", "kuma-client"] resolver = "2" [workspace.package] @@ -9,7 +9,7 @@ edition = "2021" [workspace.dependencies] bollard = { version = "0.15.0" } clap = { version = "4.4.14", features = ["derive"] } -config = { version = "0.13.4" } +config = { version = "0.14.0" } const-str = { version = "0.5.6", features = ["proc"] } cute_custom_default = { version = "2.1.0" } derivative = { version = "2.2.0" } @@ -29,10 +29,10 @@ serde_json = { version = "1.0.111" } serde_merge = { version = "0.1.3" } serde_repr = { version = "0.1.18" } serde_with = { version = "3.4.0", features = ["time_0_3"] } -serde-inline-default = { version = "0.1.1" } +serde-inline-default = { version = "0.2.0" } serde_yaml = { version = "0.9.30" } shadow-rs = { version = "*" } -strum = { version = "0.25.0", features = ["derive"] } +strum = { version = "0.26.1", features = ["derive"] } thiserror = { version = "1.0.56" } time = { version = "0.3.31", features = ["serde"] } tokio = { version = "1.35.1", features = ["full"] } diff --git a/autokuma/src/error.rs b/autokuma/src/error.rs index 4f3a47c..28c3ea2 100644 --- a/autokuma/src/error.rs +++ b/autokuma/src/error.rs @@ -1,4 +1,4 @@ -pub use kuma_client::Error as KumaError; +pub use kuma_client::error::Error as KumaError; use thiserror::Error; #[derive(Error, Debug)] diff --git a/autokuma/src/sync.rs b/autokuma/src/sync.rs index d487bc4..71b8a90 100644 --- a/autokuma/src/sync.rs +++ b/autokuma/src/sync.rs @@ -7,7 +7,11 @@ use bollard::{ container::ListContainersOptions, service::ContainerSummary, Docker, API_DEFAULT_VERSION, }; use itertools::Itertools; -use kuma_client::{Client, Monitor, MonitorType, Tag, TagDefinition}; +use kuma_client::{ + monitor::{Monitor, MonitorType}, + tag::{Tag, TagDefinition}, + Client, +}; use log::{info, warn}; use std::{ collections::{BTreeMap, HashMap}, @@ -218,7 +222,7 @@ impl Sync { .filter_map(|(_, monitor)| { match monitor .common() - .tags + .tags() .iter() .filter(|tag| tag.name.as_deref() == Some(&self.config.tag_name)) .find_map(|tag| tag.value.as_ref()) @@ -269,14 +273,14 @@ impl Sync { let current_tags = current .common() - .tags + .tags() .iter() .filter_map(|tag| tag.tag_id.as_ref().map(|id| (*id, tag))) .collect::>(); let merged_tags: Vec = new .common_mut() - .tags + .tags_mut() .drain(..) .chain(addition_tags.unwrap_or_default()) .map(|new_tag| { @@ -292,7 +296,7 @@ impl Sync { }) .collect_vec(); - new.common_mut().tags = merged_tags; + *new.common_mut().tags_mut() = merged_tags; serde_merge::omerge(current, new).unwrap() } @@ -349,7 +353,7 @@ impl Sync { .filter_map(|(id, monitor)| { monitor .common() - .id + .id() .as_ref() .map(|parent_id| (parent_id, id)) }) @@ -382,7 +386,7 @@ impl Sync { let mut tag = Tag::from(autokuma_tag.clone()); tag.value = Some(id.clone()); - monitor.common_mut().tags.push(tag); + monitor.common_mut().tags_mut().push(tag); match kuma.add_monitor(monitor).await { Ok(_) => Ok(()), @@ -404,12 +408,10 @@ impl Sync { let merge: Monitor = self.merge_monitors(current, new, Some(vec![tag])); if current != &merge - || merge.common().parent_name.is_some() != current.common().parent.is_some() - || merge - .common() - .parent_name - .as_ref() - .is_some_and(|name| Some(name) != current.common().parent.map(|id| groups[&id])) + || merge.common().parent_name().is_some() != current.common().parent().is_some() + || merge.common().parent_name().as_ref().is_some_and(|name| { + Some(name) != current.common().parent().map(|id| groups[&id]) + }) { info!("Updating monitor: {}", id); kuma.edit_monitor(merge).await?; @@ -418,8 +420,8 @@ impl Sync { for (id, monitor) in to_delete { info!("Deleting monitor: {}", id); - if let Some(id) = monitor.common().id { - kuma.delete_monitor(id).await?; + if let Some(id) = monitor.common().id() { + kuma.delete_monitor(*id).await?; } } @@ -433,7 +435,7 @@ impl Sync { if let Err(err) = self.do_sync().await { warn!("Encountered error during sync: {}", err); } - tokio::time::sleep(Duration::from_secs(5)).await; + tokio::time::sleep(Duration::from_secs_f64(self.config.sync_interval)).await; } } } diff --git a/example/Cargo.toml b/example/Cargo.toml new file mode 100644 index 0000000..396fc09 --- /dev/null +++ b/example/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "example" +version.workspace = true +edition.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +kuma_client = { path = "../kuma-client" } +tokio = { version = "1.35.1", features = ["full"] } +serde_json = { version = "1.0.111" } diff --git a/example/src/main.rs b/example/src/main.rs new file mode 100644 index 0000000..d29d80d --- /dev/null +++ b/example/src/main.rs @@ -0,0 +1,16 @@ +use kuma_client::{Client, Config, Url}; + +#[tokio::main()] +async fn main() { + let client = Client::connect(Config { + url: Url::parse("http://localhost:3001").expect("Invalid URL"), + username: Some("Username".to_owned()), + password: Some("Password".to_owned()), + ..Default::default() + }) + .await + .expect("Failed to connect to server"); + + let monitors = client.get_monitors().await.expect("Failed to get monitors"); + println!("{:?}", monitors); +} diff --git a/kuma-cli/src/main.rs b/kuma-cli/src/main.rs index 4362478..c2439e3 100644 --- a/kuma-cli/src/main.rs +++ b/kuma-cli/src/main.rs @@ -10,7 +10,7 @@ use serde_json::json; use std::path::PathBuf; use tokio::task; -type Result = kuma_client::Result; +type Result = kuma_client::error::Result; const VERSION: &str = const_str::format!( "{}{}", diff --git a/kuma-client/src/client.rs b/kuma-client/src/client.rs index f3887b2..2e85dfa 100644 --- a/kuma-client/src/client.rs +++ b/kuma-client/src/client.rs @@ -1,10 +1,14 @@ -use super::{ - util::ResultLogger, Config, Error, Event, LoginResponse, Monitor, MonitorList, MonitorType, - Result, Tag, TagDefinition, -}; use crate::{ + error::{Error, Result}, + event::Event, maintenance::{Maintenance, MaintenanceList, MaintenanceMonitor, MaintenanceStatusPage}, - Notification, NotificationList, PublicGroupList, StatusPage, StatusPageList, + monitor::{Monitor, MonitorList, MonitorType}, + notification::{Notification, NotificationList}, + response::LoginResponse, + status_page::{PublicGroupList, StatusPage, StatusPageList}, + tag::{Tag, TagDefinition}, + util::ResultLogger, + Config, }; use futures_util::FutureExt; use itertools::Itertools; @@ -459,9 +463,7 @@ impl Worker { } async fn resolve_group(self: &Arc, monitor: &mut Monitor) -> Result<()> { - if let Some(group_name) = monitor.common().parent_name.clone() { - monitor.common_mut().parent_name = None; - + if let Some(group_name) = monitor.common().parent_name().clone() { if let Some(Some(group_id)) = self .monitors .lock() @@ -469,7 +471,7 @@ impl Worker { .iter() .find(|x| { x.1.monitor_type() == MonitorType::Group - && x.1.common().tags.iter().any(|tag| { + && x.1.common().tags().iter().any(|tag| { tag.name.as_ref().is_some_and(|tag| tag == "AutoKuma") && tag .value @@ -477,14 +479,14 @@ impl Worker { .is_some_and(|tag_value| tag_value == &group_name) }) }) - .map(|x| x.1.common().id) + .map(|x| *x.1.common().id()) { - monitor.common_mut().parent = Some(group_id); + *monitor.common_mut().parent_mut() = Some(group_id); } else { return Err(Error::GroupNotFound(group_name)); } } else { - monitor.common_mut().parent = None; + *monitor.common_mut().parent_mut() = None; } return Ok(()); } @@ -498,14 +500,14 @@ impl Worker { if let Some(monitor) = self.monitors.lock().await.get(&monitor_id.to_string()) { let current_tags = monitor .common() - .tags + .tags() .iter() .filter_map(|tag| tag.tag_id.and_then(|id| Some((id, tag)))) .collect::>(); let duplicates = monitor .common() - .tags + .tags() .iter() .duplicates_by(|tag| tag.tag_id) .filter_map(|tag| tag.tag_id.as_ref().map(|id| (id, tag))) @@ -565,8 +567,8 @@ impl Worker { pub async fn add_monitor(self: &Arc, monitor: &mut Monitor) -> Result<()> { self.resolve_group(monitor).await?; - let tags = mem::take(&mut monitor.common_mut().tags); - let notifications = mem::take(&mut monitor.common_mut().notification_id_list); + let tags = mem::take(monitor.common_mut().tags_mut()); + let notifications = mem::take(monitor.common_mut().notification_id_list_mut()); let id: i32 = self .clone() @@ -578,9 +580,9 @@ impl Worker { ) .await?; - monitor.common_mut().id = Some(id); - monitor.common_mut().notification_id_list = notifications; - monitor.common_mut().tags = tags; + *monitor.common_mut().id_mut() = Some(id); + *monitor.common_mut().notification_id_list_mut() = notifications; + *monitor.common_mut().tags_mut() = tags; self.edit_monitor(monitor).await?; @@ -611,7 +613,7 @@ impl Worker { pub async fn edit_monitor(self: &Arc, monitor: &mut Monitor) -> Result<()> { self.resolve_group(monitor).await?; - let tags = mem::take(&mut monitor.common_mut().tags); + let tags = mem::take(monitor.common_mut().tags_mut()); let id: i32 = self .call( @@ -624,7 +626,7 @@ impl Worker { self.update_monitor_tags(id, &tags).await?; - monitor.common_mut().tags = tags; + *monitor.common_mut().tags_mut() = tags; Ok(()) } @@ -1002,6 +1004,7 @@ impl Worker { debug!("Waiting for connection"); + debug!("Connection opened!"); *self.socket_io.lock().await = client; for i in 0..10 { @@ -1029,6 +1032,7 @@ impl Worker { _ = socket_io.disconnect().await; } drop(socket_io); + *self_ref.socket_io.lock().await = None; debug!("Connection closed!"); }); @@ -1040,11 +1044,13 @@ impl Worker { } } +/// A client for interacting with Uptime Kuma. pub struct Client { worker: Arc, } impl Client { + /// Establishes a connection to Uptime Kuma with the provided configuration. pub async fn connect(config: Config) -> Result { let worker = Worker::new(config); worker.connect().await?; @@ -1052,6 +1058,7 @@ impl Client { Ok(Self { worker }) } + /// Retrieves a list of monitors from Uptime Kuma. pub async fn get_monitors(&self) -> Result { match self.worker.is_ready().await { true => Ok(self.worker.monitors.lock().await.clone()), @@ -1059,36 +1066,44 @@ impl Client { } } + /// Retrieves information about a specific monitor identified by its ID. pub async fn get_monitor(&self, monitor_id: i32) -> Result { self.worker.get_monitor(monitor_id).await } + /// Adds a new monitor to Uptime Kuma. pub async fn add_monitor(&self, mut monitor: Monitor) -> Result { self.worker.add_monitor(&mut monitor).await?; Ok(monitor) } + /// Edits an existing monitor in Uptime Kuma. pub async fn edit_monitor(&self, mut monitor: Monitor) -> Result { self.worker.edit_monitor(&mut monitor).await?; Ok(monitor) } + /// Deletes a monitor from Uptime Kuma based on its ID. pub async fn delete_monitor(&self, monitor_id: i32) -> Result<()> { self.worker.delete_monitor(monitor_id).await } + /// Pauses a monitor in Uptime Kuma based on its ID. pub async fn pause_monitor(&self, monitor_id: i32) -> Result<()> { self.worker.pause_monitor(monitor_id).await } + /// Resumes a paused monitor in Uptime Kuma based on its ID. pub async fn resume_monitor(&self, monitor_id: i32) -> Result<()> { self.worker.resume_monitor(monitor_id).await } + /// Retrieves a list of tags from Uptime Kuma. pub async fn get_tags(&self) -> Result> { self.worker.get_tags().await } + /// Retrieves information about a specific tag identified by its ID. pub async fn get_tag(&self, tag_id: i32) -> Result { self.worker.get_tags().await.and_then(|tags| { tags.into_iter() @@ -1097,20 +1112,24 @@ impl Client { }) } + /// Adds a new tag to Uptime Kuma. pub async fn add_tag(&self, mut tag: TagDefinition) -> Result { self.worker.add_tag(&mut tag).await?; Ok(tag) } + /// Edits an existing tag in Uptime Kuma. pub async fn edit_tag(&self, mut tag: TagDefinition) -> Result { self.worker.edit_tag(&mut tag).await?; Ok(tag) } + /// Deletes a tag from Uptime Kuma based on its ID. pub async fn delete_tag(&self, tag_id: i32) -> Result<()> { self.worker.delete_tag(tag_id).await } + /// Retrieves a list of notifications from Uptime Kuma. pub async fn get_notifications(&self) -> Result { match self.worker.is_ready().await { true => Ok(self.worker.notifications.lock().await.clone()), @@ -1118,6 +1137,7 @@ impl Client { } } + /// Retrieves information about a specific notification identified by its ID. pub async fn get_notification(&self, notification_id: i32) -> Result { self.get_notifications().await.and_then(|notifications| { notifications @@ -1127,20 +1147,24 @@ impl Client { }) } + /// Adds a new notification to Uptime Kuma. pub async fn add_notification(&self, mut notification: Notification) -> Result { self.worker.add_notification(&mut notification).await?; Ok(notification) } + /// Edits an existing notification in Uptime Kuma. pub async fn edit_notification(&self, mut notification: Notification) -> Result { self.worker.edit_notification(&mut notification).await?; Ok(notification) } + /// Deletes a notification from Uptime Kuma based on its ID. pub async fn delete_notification(&self, notification_id: i32) -> Result<()> { self.worker.delete_notification(notification_id).await } + /// Retrieves a list of maintenances from Uptime Kuma. pub async fn get_maintenances(&self) -> Result { match self.worker.is_ready().await { true => Ok(self.worker.maintenances.lock().await.clone()), @@ -1148,32 +1172,39 @@ impl Client { } } + /// Retrieves information about a specific maintenance identified by its ID. pub async fn get_maintenance(&self, maintenance_id: i32) -> Result { self.worker.get_maintenance(maintenance_id).await } + /// Adds a new maintenance to Uptime Kuma. pub async fn add_maintenance(&self, mut maintenance: Maintenance) -> Result { self.worker.add_maintenance(&mut maintenance).await?; Ok(maintenance) } + /// Edits an existing maintenance in Uptime Kuma. pub async fn edit_maintenance(&self, mut maintenance: Maintenance) -> Result { self.worker.edit_maintenance(&mut maintenance).await?; Ok(maintenance) } + /// Deletes a maintenance from Uptime Kuma based on its ID. pub async fn delete_maintenance(&self, maintenance_id: i32) -> Result<()> { self.worker.delete_maintenance(maintenance_id).await } + /// Pauses a maintenance in Uptime Kuma based on its ID. pub async fn pause_maintenance(&self, maintenance_id: i32) -> Result<()> { self.worker.pause_maintenance(maintenance_id).await } + /// Resumes a paused maintenance in Uptime Kuma based on its ID. pub async fn resume_maintenance(&self, maintenance_id: i32) -> Result<()> { self.worker.resume_maintenance(maintenance_id).await } + /// Retrieves a list of status pages from Uptime Kuma. pub async fn get_status_pages(&self) -> Result { match self.worker.is_ready().await { true => Ok(self.worker.status_pages.lock().await.clone()), @@ -1181,24 +1212,29 @@ impl Client { } } + /// Retrieves information about a specific status page identified by its slug. pub async fn get_status_page(&self, slug: &str) -> Result { self.worker.get_status_page(slug).await } + /// Adds a new status page to Uptime Kuma. pub async fn add_status_page(&self, mut status_page: StatusPage) -> Result { self.worker.add_status_page(&mut status_page).await?; Ok(status_page) } + /// Edits an existing status page in Uptime Kuma. pub async fn edit_status_page(&self, mut status_page: StatusPage) -> Result { self.worker.edit_status_page(&mut status_page).await?; Ok(status_page) } + /// Deletes a status page from Uptime Kuma based on its slug. pub async fn delete_status_page(&self, slug: &str) -> Result<()> { self.worker.delete_status_page(slug).await } + /// Disconnects the client from Uptime Kuma. pub async fn disconnect(&self) -> Result<()> { self.worker.disconnect().await } diff --git a/kuma-client/src/config.rs b/kuma-client/src/config.rs index 05898e0..486308b 100644 --- a/kuma-client/src/config.rs +++ b/kuma-client/src/config.rs @@ -5,6 +5,7 @@ use serde_inline_default::serde_inline_default; use serde_with::{formats::CommaSeparator, serde_as, PickFirst, StringWithSeparator}; use url::Url; +/// Configuration for the [Client](crate::Client). #[serde_alias(ScreamingSnakeCase)] #[serde_inline_default] #[serde_as] @@ -37,3 +38,17 @@ pub struct Config { #[serde_inline_default(30.0)] pub call_timeout: f64, } + +impl Default for Config { + fn default() -> Self { + Self { + url: Url::parse("http://localhost:3001").unwrap(), + username: None, + password: None, + mfa_token: None, + headers: Vec::new(), + connect_timeout: 30.0, + call_timeout: 30.0, + } + } +} diff --git a/kuma-client/src/deserialize.rs b/kuma-client/src/deserialize.rs index 197d84c..fd1824f 100644 --- a/kuma-client/src/deserialize.rs +++ b/kuma-client/src/deserialize.rs @@ -9,7 +9,7 @@ use serde_with::{DeserializeAs, SerializeAs}; use std::{collections::HashMap, hash::Hash, marker::PhantomData, str::FromStr}; use time::{format_description::well_known::Iso8601, PrimitiveDateTime, Time}; -pub struct DeserializeNumberLenient; +pub(crate) struct DeserializeNumberLenient; impl<'de, T> DeserializeAs<'de, T> for DeserializeNumberLenient where @@ -56,7 +56,7 @@ where } } -pub struct DeserializeBoolLenient; +pub(crate) struct DeserializeBoolLenient; impl<'de> DeserializeAs<'de, bool> for DeserializeBoolLenient { fn deserialize_as(deserializer: D) -> Result @@ -100,7 +100,7 @@ where } } -pub struct DeserializeVecLenient(PhantomData); +pub(crate) struct DeserializeVecLenient(PhantomData); impl<'de, T> DeserializeAs<'de, Vec> for DeserializeVecLenient where @@ -138,7 +138,7 @@ where } } -pub struct DeserializeHashMapLenient(PhantomData, PhantomData); +pub(crate) struct DeserializeHashMapLenient(PhantomData, PhantomData); impl<'de, K, V> DeserializeAs<'de, HashMap> for DeserializeHashMapLenient where @@ -177,7 +177,7 @@ where } } -pub struct DeserializeValueLenient; +pub(crate) struct DeserializeValueLenient; impl<'de> DeserializeAs<'de, Value> for DeserializeValueLenient { fn deserialize_as(deserializer: D) -> Result @@ -212,7 +212,7 @@ where } } -pub struct SerializeDateTime; +pub(crate) struct SerializeDateTime; impl<'de> DeserializeAs<'de, PrimitiveDateTime> for DeserializeBoolLenient { fn deserialize_as(deserializer: D) -> Result @@ -235,7 +235,7 @@ impl SerializeAs for SerializeDateTime { .serialize(serializer) } } -pub struct SerializeDateRange; +pub(crate) struct SerializeDateRange; impl<'de> DeserializeAs<'de, Range> for SerializeDateRange { fn deserialize_as(deserializer: D) -> Result, D::Error> @@ -284,13 +284,13 @@ impl SerializeAs> for SerializeDateRange { } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -pub struct TimePoint { - pub hours: u8, - pub minutes: u8, - pub seconds: u8, +pub(crate) struct TimePoint { + pub(crate) hours: u8, + pub(crate) minutes: u8, + pub(crate) seconds: u8, } -pub struct SerializeTimeRange; +pub(crate) struct SerializeTimeRange; impl<'de> DeserializeAs<'de, Range