diff --git a/src/api/folders.rs b/src/api/folders.rs index b97315b..4064963 100644 --- a/src/api/folders.rs +++ b/src/api/folders.rs @@ -34,7 +34,6 @@ pub struct FolderAttributes { /// Additional attributes that can be used to categorize hosts. every tag is part of a tag_group /// NOTE that checkmk always returns taggroups prefixed with "tag_" pub tags: HashMap, - // TODO: to be implemented // #[serde(flatten, default)] // pub networkscan: NetworkScan, @@ -116,16 +115,11 @@ pub struct FolderCreationRequest { pub name: String, pub title: String, pub parent: String, - pub attributes: FolderAttributes + pub attributes: FolderAttributes, } impl FolderCreationRequest { - pub fn new( - name: String, - title: String, - parent: String, - attributes: FolderAttributes - ) -> Self { + pub fn new(name: String, title: String, parent: String, attributes: FolderAttributes) -> Self { Self { name, title, @@ -154,7 +148,7 @@ impl FolderUpdateRequest { title, attributes: Some(attributes), update_attributes: None, - remove_attributes: None + remove_attributes: None, } } pub fn update(title: String, attributes: FolderAttributes) -> Self { @@ -162,7 +156,7 @@ impl FolderUpdateRequest { title, attributes: None, update_attributes: Some(attributes), - remove_attributes: None + remove_attributes: None, } } pub fn remove(title: String, attributes: FolderAttributes) -> Self { @@ -170,14 +164,14 @@ impl FolderUpdateRequest { title, attributes: None, update_attributes: None, - remove_attributes: Some(attributes) + remove_attributes: Some(attributes), } } } #[derive(Debug, Serialize)] pub struct FolderDeleteQuery { - pub delete_mode: FolderDeleteMode + pub delete_mode: FolderDeleteMode, } impl FolderDeleteQuery { @@ -190,5 +184,5 @@ impl FolderDeleteQuery { #[serde(rename_all = "snake_case")] pub enum FolderDeleteMode { Recursive, - AbotyOnNonEmpty + AbotyOnNonEmpty, } diff --git a/src/api/mod.rs b/src/api/mod.rs index bbf09ba..89c7411 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -29,7 +29,6 @@ impl fmt::Display for DomainType { } } - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "UPPERCASE")] pub enum HttpMethod { diff --git a/src/api/rules/contactgroups.rs b/src/api/rules/contactgroups.rs index d8bb91a..2e70b4f 100644 --- a/src/api/rules/contactgroups.rs +++ b/src/api/rules/contactgroups.rs @@ -6,5 +6,5 @@ pub struct HostContactGroups { r#use: bool, use_for_services: bool, recuse_use: bool, - recuse_perms: bool + recuse_perms: bool, } diff --git a/src/client.rs b/src/client.rs index b2039a8..5a905cc 100644 --- a/src/client.rs +++ b/src/client.rs @@ -4,20 +4,22 @@ use std::net::{IpAddr, SocketAddr}; use std::sync::Arc; use log::trace; -use reqwest::{Certificate, Request}; use reqwest::header::{HeaderName, HeaderValue}; +use reqwest::{Certificate, Request}; use serde::de::DeserializeOwned; use tokio::sync::Semaphore; -use crate::api::{BulkCreateDomainExtention, BulkDeleteDomainExtention, BulkReadDomainExtention, BulkUpdateDomainExtention, DomainCollection, DomainExtention, DomainObject, DomainType}; +use crate::api::{ + BulkCreateDomainExtention, BulkDeleteDomainExtention, BulkReadDomainExtention, + BulkUpdateDomainExtention, DomainCollection, DomainExtention, DomainObject, DomainType, +}; use crate::{Error, Result}; - pub struct Client(Arc); struct InnerClient { http: reqwest::Client, url: String, - semaphore: Semaphore + semaphore: Semaphore, } #[derive(Default, PartialEq, Eq)] @@ -25,7 +27,8 @@ enum SslStrategy { NoSll, IngoreHostname, IgnoreCertificate, - #[default] Strict + #[default] + Strict, } #[derive(Default)] @@ -45,30 +48,40 @@ pub struct ClientBuilder { resolve: Option, port: u16, - _marker: PhantomData + _marker: PhantomData, } -impl ClientBuilder { +impl ClientBuilder { fn new() -> ClientBuilder { Default::default() } } impl ClientBuilder { - pub fn on_host_and_site(self, hostname: String, sitename: String) -> ClientBuilder { + pub fn on_host_and_site( + self, + hostname: String, + sitename: String, + ) -> ClientBuilder { ClientBuilder:: { - hostname, sitename, + hostname, + sitename, ..Default::default() } } } impl ClientBuilder { - pub fn with_credentials(self, username: String, password: String) -> ClientBuilder { + pub fn with_credentials( + self, + username: String, + password: String, + ) -> ClientBuilder { ClientBuilder { hostname: self.hostname, sitename: self.sitename, - username, password, + username, + password, ..Default::default() } } @@ -80,8 +93,10 @@ type ClientBuildResult = std::result::Result; pub enum ClientBuildError { #[error("failed to build client: {0}")] BuildClient(#[from] reqwest::Error), - #[error("invalid credentials. thise can only consist of visibly ASCII characters (ie. (32-127))")] - InvalidCredentials(#[from] reqwest::header::InvalidHeaderValue) + #[error( + "invalid credentials. thise can only consist of visibly ASCII characters (ie. (32-127))" + )] + InvalidCredentials(#[from] reqwest::header::InvalidHeaderValue), } impl ClientBuilder { @@ -148,7 +163,8 @@ impl ClientBuilder { builder = builder.add_root_certificate(certificate); } - builder.build() + builder + .build() .map_err(ClientBuildError::BuildClient) .map_err(Error::BuildClient)? }; @@ -157,7 +173,11 @@ impl ClientBuilder { // not sure if this has been inproved since 2.2 let semaphore = Semaphore::new(10); - Ok(Client(Arc::new(InnerClient { http, url, semaphore }))) + Ok(Client(Arc::new(InnerClient { + http, + url, + semaphore, + }))) } } @@ -166,7 +186,7 @@ impl Client { Self(Arc::new(InnerClient { http: client, semaphore: Semaphore::new(10), - url + url, })) } pub fn builder() -> ClientBuilder { @@ -182,26 +202,27 @@ impl InnerClient { format!("{}/domain-types/{}/collections/all", self.url, domain_type) } pub(crate) fn bulk_action_url(&self, domain_type: DomainType, action: BulkAction) -> String { - format!("{}/domain-types/{}/actions/bulk-{}/invoke",self.url, domain_type, action) + format!( + "{}/domain-types/{}/actions/bulk-{}/invoke", + self.url, domain_type, action + ) } pub(crate) async fn handle_request(&self, request: Request) -> Result { trace!("sending {}-request to {}", request.method(), request.url()); - let response = self.http + let response = self + .http .execute(request) .await .map_err(Error::SendRequest)?; let status = response.status(); - let body = response.text() - .await - .map_err(Error::ReceiveBody)?; + let body = response.text().await.map_err(Error::ReceiveBody)?; if status.is_success() { Ok(body) } else { - let cmkerror = serde_json::from_str(&body) - .map_err(Error::DeserializeResponse)?; + let cmkerror = serde_json::from_str(&body).map_err(Error::DeserializeResponse)?; Err(Error::CheckmkError(cmkerror)) } } @@ -215,22 +236,21 @@ impl InnerClient { } pub(crate) async fn get_etag(&self, object_url: &str) -> Result { - let mut response = self.http + let mut response = self + .http .head(object_url) .send() .await .map_err(Error::SendRequest)?; if response.status().is_success() { - response.headers_mut() + response + .headers_mut() .remove("ETag") .ok_or(Error::MissingHeader("ETag")) } else { - let body = response.text() - .await - .map_err(Error::ReceiveBody)?; - let cmkerror = serde_json::from_str(&body) - .map_err(Error::DeserializeResponse)?; + let body = response.text().await.map_err(Error::ReceiveBody)?; + let cmkerror = serde_json::from_str(&body).map_err(Error::DeserializeResponse)?; Err(Error::CheckmkError(cmkerror)) } } @@ -238,9 +258,10 @@ impl InnerClient { pub(crate) async fn create_domain_object( &self, body: &E::CreationRequest, - query: &E::CreationQuery + query: &E::CreationQuery, ) -> Result<()> { - let request = self.http + let request = self + .http .post(self.collection_url(E::DOMAIN_TYPE)) .json(body) .query(query) @@ -252,9 +273,10 @@ impl InnerClient { pub(crate) async fn read_domain_object( &self, id: impl Display, - query: &E::ReadQuery + query: &E::ReadQuery, ) -> Result> { - let request = self.http + let request = self + .http .get(self.object_url(E::DOMAIN_TYPE, id)) .query(query) .build() @@ -269,7 +291,8 @@ impl InnerClient { ) -> Result<()> { let url = self.object_url(E::DOMAIN_TYPE, id); let etag = self.get_etag(&url).await?; - let request = self.http + let request = self + .http .put(url) .json(&request) .header(reqwest::header::IF_MATCH, etag) @@ -283,7 +306,8 @@ impl InnerClient { id: impl Display, query: &E::DeleteQuery, ) -> Result<()> { - let request = self.http + let request = self + .http .delete(self.object_url(E::DOMAIN_TYPE, id)) .query(&query) .build() @@ -295,9 +319,10 @@ impl InnerClient { pub(crate) async fn bulk_create_domain_objects( &self, request: &[E::CreationRequest], - query: &E::CreationQuery + query: &E::CreationQuery, ) -> Result<()> { - let request = self.http + let request = self + .http .post(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Create)) .json(request) .query(query) @@ -310,7 +335,8 @@ impl InnerClient { &self, query: &E::ReadQuery, ) -> Result>> { - let request = self.http + let request = self + .http .get(self.collection_url(E::DOMAIN_TYPE)) .query(query) .build() @@ -323,7 +349,8 @@ impl InnerClient { &self, body: &[E::BulkUpdateRequest], ) -> Result<()> { - let request = self.http + let request = self + .http .put(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Update)) .json(body) .build() @@ -335,7 +362,8 @@ impl InnerClient { &self, ids: &[String], ) -> Result<()> { - let request = self.http + let request = self + .http .post(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Delete)) .json(&ids) .build() @@ -365,48 +393,32 @@ impl Display for BulkAction { pub struct ApiClient { inner: Arc, - _marker: PhantomData + _marker: PhantomData, } -impl ApiClient { +impl ApiClient { pub async fn create( &self, request: &D::CreationRequest, - query: &D::CreationQuery + query: &D::CreationQuery, ) -> Result<()> { self.inner.create_domain_object::(request, query).await } - pub async fn read( - &self, - id: impl Display, - query: &D::ReadQuery - ) -> Result { + pub async fn read(&self, id: impl Display, query: &D::ReadQuery) -> Result { self.inner .read_domain_object(id, query) .await .map(|obj| obj.extensions) } - pub async fn update( - &self, - id: impl Display, - request: &D::UpdateRequest - ) -> Result<()> { - self.inner - .update_domain_object::(id, request) - .await + pub async fn update(&self, id: impl Display, request: &D::UpdateRequest) -> Result<()> { + self.inner.update_domain_object::(id, request).await } - pub async fn delete( - &self, - id: impl Display, - query: &D::DeleteQuery - ) -> Result<()> { - self.inner - .delete_domain_object::(id, query) - .await + pub async fn delete(&self, id: impl Display, query: &D::DeleteQuery) -> Result<()> { + self.inner.delete_domain_object::(id, query).await } } -impl ApiClient { +impl ApiClient { pub async fn bulk_create( &self, request: &[D::CreationRequest], @@ -418,39 +430,22 @@ impl ApiClient { } } -impl ApiClient { - pub async fn bulk_read( - &self, - query: &D::ReadQuery, - ) -> Result> { - let objs = self.inner - .bulk_read_domain_objects::(query) - .await?; - let exts = objs.into_iter() - .map(|obj| obj.extensions) - .collect(); +impl ApiClient { + pub async fn bulk_read(&self, query: &D::ReadQuery) -> Result> { + let objs = self.inner.bulk_read_domain_objects::(query).await?; + let exts = objs.into_iter().map(|obj| obj.extensions).collect(); Ok(exts) } } -impl ApiClient { - pub async fn bulk_update( - &self, - request: &[D::BulkUpdateRequest], - ) -> Result<()> { - self.inner - .bulk_update_domain_objects::(request) - .await +impl ApiClient { + pub async fn bulk_update(&self, request: &[D::BulkUpdateRequest]) -> Result<()> { + self.inner.bulk_update_domain_objects::(request).await } } -impl ApiClient { - pub async fn bulk_delete( - &self, - ids: &[String], - ) -> Result<()> { - self.inner - .bulk_delete_domain_objects::(ids) - .await +impl ApiClient { + pub async fn bulk_delete(&self, ids: &[String]) -> Result<()> { + self.inner.bulk_delete_domain_objects::(ids).await } } diff --git a/src/lib.rs b/src/lib.rs index 39870c8..5f16b1e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ +pub mod api; mod client; mod error; -pub mod api; pub use error::{Error, Result};