cargo fmt
This commit is contained in:
parent
91be1f0acb
commit
ebc349de64
@ -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<String, String>,
|
||||
|
||||
// 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,
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -6,5 +6,5 @@ pub struct HostContactGroups {
|
||||
r#use: bool,
|
||||
use_for_services: bool,
|
||||
recuse_use: bool,
|
||||
recuse_perms: bool
|
||||
recuse_perms: bool,
|
||||
}
|
||||
|
||||
181
src/client.rs
181
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<InnerClient>);
|
||||
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<T> {
|
||||
resolve: Option<SocketAddr>,
|
||||
port: u16,
|
||||
|
||||
_marker: PhantomData<T>
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl <T> ClientBuilder<T> {
|
||||
impl<T> ClientBuilder<T> {
|
||||
fn new() -> ClientBuilder<RequiresLocation> {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientBuilder<RequiresLocation> {
|
||||
pub fn on_host_and_site(self, hostname: String, sitename: String) -> ClientBuilder<RequiresCredentials> {
|
||||
pub fn on_host_and_site(
|
||||
self,
|
||||
hostname: String,
|
||||
sitename: String,
|
||||
) -> ClientBuilder<RequiresCredentials> {
|
||||
ClientBuilder::<RequiresCredentials> {
|
||||
hostname, sitename,
|
||||
hostname,
|
||||
sitename,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientBuilder<RequiresCredentials> {
|
||||
pub fn with_credentials(self, username: String, password: String) -> ClientBuilder<RequiresNothing> {
|
||||
pub fn with_credentials(
|
||||
self,
|
||||
username: String,
|
||||
password: String,
|
||||
) -> ClientBuilder<RequiresNothing> {
|
||||
ClientBuilder {
|
||||
hostname: self.hostname,
|
||||
sitename: self.sitename,
|
||||
username, password,
|
||||
username,
|
||||
password,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
@ -80,8 +93,10 @@ type ClientBuildResult<T> = std::result::Result<T, ClientBuildError>;
|
||||
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<RequiresNothing> {
|
||||
@ -148,7 +163,8 @@ impl ClientBuilder<RequiresNothing> {
|
||||
builder = builder.add_root_certificate(certificate);
|
||||
}
|
||||
|
||||
builder.build()
|
||||
builder
|
||||
.build()
|
||||
.map_err(ClientBuildError::BuildClient)
|
||||
.map_err(Error::BuildClient)?
|
||||
};
|
||||
@ -157,7 +173,11 @@ impl ClientBuilder<RequiresNothing> {
|
||||
// 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<RequiresLocation> {
|
||||
@ -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<String> {
|
||||
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<HeaderValue> {
|
||||
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<E: DomainExtention>(
|
||||
&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<E: DomainExtention>(
|
||||
&self,
|
||||
id: impl Display,
|
||||
query: &E::ReadQuery
|
||||
query: &E::ReadQuery,
|
||||
) -> Result<DomainObject<E>> {
|
||||
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<E: BulkCreateDomainExtention>(
|
||||
&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<Vec<DomainObject<E>>> {
|
||||
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<D: DomainExtention> {
|
||||
inner: Arc<InnerClient>,
|
||||
_marker: PhantomData<D>
|
||||
_marker: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl <D: DomainExtention> ApiClient<D> {
|
||||
impl<D: DomainExtention> ApiClient<D> {
|
||||
pub async fn create(
|
||||
&self,
|
||||
request: &D::CreationRequest,
|
||||
query: &D::CreationQuery
|
||||
query: &D::CreationQuery,
|
||||
) -> Result<()> {
|
||||
self.inner.create_domain_object::<D>(request, query).await
|
||||
}
|
||||
pub async fn read(
|
||||
&self,
|
||||
id: impl Display,
|
||||
query: &D::ReadQuery
|
||||
) -> Result<D> {
|
||||
pub async fn read(&self, id: impl Display, query: &D::ReadQuery) -> Result<D> {
|
||||
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::<D>(id, request)
|
||||
.await
|
||||
pub async fn update(&self, id: impl Display, request: &D::UpdateRequest) -> Result<()> {
|
||||
self.inner.update_domain_object::<D>(id, request).await
|
||||
}
|
||||
pub async fn delete(
|
||||
&self,
|
||||
id: impl Display,
|
||||
query: &D::DeleteQuery
|
||||
) -> Result<()> {
|
||||
self.inner
|
||||
.delete_domain_object::<D>(id, query)
|
||||
.await
|
||||
pub async fn delete(&self, id: impl Display, query: &D::DeleteQuery) -> Result<()> {
|
||||
self.inner.delete_domain_object::<D>(id, query).await
|
||||
}
|
||||
}
|
||||
|
||||
impl <D: BulkCreateDomainExtention> ApiClient<D> {
|
||||
impl<D: BulkCreateDomainExtention> ApiClient<D> {
|
||||
pub async fn bulk_create(
|
||||
&self,
|
||||
request: &[D::CreationRequest],
|
||||
@ -418,39 +430,22 @@ impl <D: BulkCreateDomainExtention> ApiClient<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl <D: BulkReadDomainExtention> ApiClient<D> {
|
||||
pub async fn bulk_read(
|
||||
&self,
|
||||
query: &D::ReadQuery,
|
||||
) -> Result<Vec<D>> {
|
||||
let objs = self.inner
|
||||
.bulk_read_domain_objects::<D>(query)
|
||||
.await?;
|
||||
let exts = objs.into_iter()
|
||||
.map(|obj| obj.extensions)
|
||||
.collect();
|
||||
impl<D: BulkReadDomainExtention> ApiClient<D> {
|
||||
pub async fn bulk_read(&self, query: &D::ReadQuery) -> Result<Vec<D>> {
|
||||
let objs = self.inner.bulk_read_domain_objects::<D>(query).await?;
|
||||
let exts = objs.into_iter().map(|obj| obj.extensions).collect();
|
||||
Ok(exts)
|
||||
}
|
||||
}
|
||||
|
||||
impl <D: BulkUpdateDomainExtention> ApiClient<D> {
|
||||
pub async fn bulk_update(
|
||||
&self,
|
||||
request: &[D::BulkUpdateRequest],
|
||||
) -> Result<()> {
|
||||
self.inner
|
||||
.bulk_update_domain_objects::<D>(request)
|
||||
.await
|
||||
impl<D: BulkUpdateDomainExtention> ApiClient<D> {
|
||||
pub async fn bulk_update(&self, request: &[D::BulkUpdateRequest]) -> Result<()> {
|
||||
self.inner.bulk_update_domain_objects::<D>(request).await
|
||||
}
|
||||
}
|
||||
|
||||
impl <D: BulkDeleteDomainExtention> ApiClient<D> {
|
||||
pub async fn bulk_delete(
|
||||
&self,
|
||||
ids: &[String],
|
||||
) -> Result<()> {
|
||||
self.inner
|
||||
.bulk_delete_domain_objects::<D>(ids)
|
||||
.await
|
||||
impl<D: BulkDeleteDomainExtention> ApiClient<D> {
|
||||
pub async fn bulk_delete(&self, ids: &[String]) -> Result<()> {
|
||||
self.inner.bulk_delete_domain_objects::<D>(ids).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
pub mod api;
|
||||
mod client;
|
||||
mod error;
|
||||
pub mod api;
|
||||
|
||||
pub use error::{Error, Result};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user