diff --git a/src/api/groups.rs b/src/api/groups.rs index 72f4791..ebfb6d7 100644 --- a/src/api/groups.rs +++ b/src/api/groups.rs @@ -5,9 +5,23 @@ use serde::{Deserialize, Serialize}; use schemars::JsonSchema; use crate::api::{ - BulkCreateDomainExtension, BulkDeleteDomainExtension, BulkReadDomainExtension, - BulkUpdateDomainExtension, DomainExtension, DomainType + DomainObject, DomainType }; +use crate::{ApiClient, Client, Result}; + +impl Client { + pub fn host_group_api(&self) -> ApiClient { + self.into() + } + + pub fn service_group_api(&self) -> ApiClient { + self.into() + } + + pub fn contact_group_api(&self) -> ApiClient { + self.into() + } +} #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "schemars", derive(JsonSchema))] @@ -22,33 +36,12 @@ impl Group { } } -#[derive(Debug, Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "schemars", derive(JsonSchema))] -pub struct GroupAlias { - alias: String -} - -impl GroupAlias { - pub fn new(alias: String) -> Self { - Self { alias } +impl From> for Group { + fn from(value: DomainObject) -> Self { + Self::new(value.id, value.title.unwrap_or_default()) } } -#[derive(Debug, Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "schemars", derive(JsonSchema))] -pub struct BulkGroupUpdate { - name: String, - attributes: GroupAlias -} - -impl BulkGroupUpdate { - pub fn new(name: String, alias: String) -> Self { - Self { - name, - attributes: GroupAlias::new(alias) - } - } -} macro_rules! domain_group { ($id:ident, $typ:expr) => { @@ -70,25 +63,80 @@ macro_rules! domain_group { } } - impl DomainExtension for $id { - const DOMAIN_TYPE: DomainType = $typ; - - type CreationRequest = Group; - type CreationQuery = (); - type ReadQuery = (); - type UpdateRequest = GroupAlias; - type DeleteQuery = (); + impl From> for $id { + fn from(value: DomainObject) -> Self { + Self(Group::from(value)) + } } - impl BulkCreateDomainExtension for $id {} - impl BulkReadDomainExtension for $id { - type BulkReadQuery = (); + impl From<&Client> for ApiClient<$id> { + fn from(value: &Client) -> Self { + Self::new(value) + } } - impl BulkUpdateDomainExtension for $id { - type BulkUpdateRequest = BulkGroupUpdate; - } - impl BulkDeleteDomainExtension for $id {} + impl ApiClient<$id> { + pub async fn create(&self, group: &$id) -> Result<()> { + self.inner.create($typ, group, &()).await + } + pub async fn read(&self, id: &str) -> Result<$id> { + let obj: DomainObject = + self.inner.read($typ, id, &()).await?; + Ok($id::from(obj)) + } + pub async fn update(&self, id: &str, alias: &str) -> Result<()> { + #[derive(Serialize)] + struct Body<'a> { + alias: &'a str + } + + self.inner.update($typ, id, &Body { alias }).await + } + pub async fn delete(&self, id: &str) -> Result<()> { + self.inner.delete($typ, id, &()).await + } + + pub async fn bulk_create(&self, entries: &[$id]) -> Result<()> { + self.inner.bulk_create($typ, entries, &()).await + } + pub async fn bulk_read(&self) -> Result> { + let entries: Vec> = + self.inner.bulk_read($typ, &()).await?; + let objects = entries.into_iter() + .map($id::from) + .collect(); + Ok(objects) + } + pub async fn bulk_update(&self, entries: &[Group]) -> Result<()> { + #[derive(Serialize)] + struct UpdateAttributes<'a> { + alias: &'a str + } + #[derive(Serialize)] + struct UpdateRequest<'a> { + name: &'a str, + attributes: UpdateAttributes<'a> + } + impl <'a> UpdateRequest<'a> { + fn from(value: &'a Group) -> Self { + Self { + name: value.name.as_str(), + attributes: UpdateAttributes { + alias: value.alias.as_str() + } + } + } + } + + let entries = entries.iter() + .map(UpdateRequest::from) + .collect::>(); + self.inner.bulk_update($typ, &entries).await + } + pub async fn bulk_delete(&self, entries: &[String]) -> Result<()> { + self.inner.bulk_delete($typ, entries).await + } + } } } diff --git a/src/main.rs b/src/main.rs index cf60bbe..22afebb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,9 +8,13 @@ const PASSWORD: &str = "C5t71DUPAu2D"; #[tokio::main] async fn main() -> Result<()> { + let log_config = simplelog::ConfigBuilder::new() + .set_location_level(simplelog::LevelFilter::Error) + .build(); + simplelog::TermLogger::init( simplelog::LevelFilter::Trace, - simplelog::Config::default(), + log_config, simplelog::TerminalMode::Stderr, simplelog::ColorChoice::Auto, ) @@ -26,6 +30,9 @@ async fn main() -> Result<()> { test_folders(client.clone()).await?; test_hosts(client.clone()).await?; test_hosttags(client.clone()).await?; + test_host_groups(client.clone()).await?; + test_service_groups(client.clone()).await?; + test_contact_groups(client.clone()).await?; info!("tests done; all pass"); Ok(()) @@ -194,3 +201,186 @@ async fn test_hosttags(client: Client) -> Result<()> { Ok(()) } + +async fn test_host_groups(client: Client) -> Result<()> { + use checkmk_api::api::groups::*; + const TESTGROUP: &str = "test-host-group"; + info!("testing host groups"); + + let api = client.host_group_api(); + + info!("creating test host group"); + api.create(&HostGroup::new(TESTGROUP.to_string(), "Test Host Group".to_string())) + .await + .inspect_err(|e| error!("failed to create host group: {e}"))?; + + let group = api + .read(TESTGROUP) + .await + .inspect_err(|e| error!("failed to read host group: {e}"))?; + info!("host group config: {group:#?}"); + + info!("updating host group"); + api.update(TESTGROUP, "Updated Test Host Group") + .await + .inspect_err(|e| error!("failed to update host group: {e}"))?; + + info!("bulk creating additional host groups"); + api.bulk_create(&[ + HostGroup::new("test-host-group-2".to_string(), "Test Host Group 2".to_string()), + HostGroup::new("test-host-group-3".to_string(), "Test Host Group 3".to_string()), + ]) + .await + .inspect_err(|e| error!("failed to bulk create host groups: {e}"))?; + + let groups = api + .bulk_read() + .await + .inspect_err(|e| error!("failed to bulk read host groups: {e}")); + info!("all host groups: {groups:?}"); + + info!("bulk updating host groups"); + api.bulk_update(&[ + Group::new("test-host-group-2".to_string(), "Updated Host Group 2".to_string()), + Group::new("test-host-group-3".to_string(), "Updated Host Group 3".to_string()), + ]) + .await + .inspect_err(|e| error!("failed to bulk update host groups: {e}"))?; + + info!("bulk deleting extra host groups"); + api.bulk_delete(&[ + "test-host-group-2".to_string(), + "test-host-group-3".to_string(), + ]) + .await + .inspect_err(|e| error!("failed to bulk delete host groups: {e}"))?; + + info!("deleting test host group"); + api.delete(TESTGROUP) + .await + .inspect_err(|e| error!("failed to delete host group: {e}"))?; + + Ok(()) +} + +async fn test_service_groups(client: Client) -> Result<()> { + use checkmk_api::api::groups::*; + const TESTGROUP: &str = "test-service-group"; + info!("testing service groups"); + + let api = client.service_group_api(); + + info!("creating test service group"); + api.create(&ServiceGroup::new(TESTGROUP.to_string(), "Test Service Group".to_string())) + .await + .inspect_err(|e| error!("failed to create service group: {e}"))?; + + let group = api + .read(TESTGROUP) + .await + .inspect_err(|e| error!("failed to read service group: {e}"))?; + info!("service group config: {group:#?}"); + + info!("updating service group"); + api.update(TESTGROUP, "Updated Test Service Group") + .await + .inspect_err(|e| error!("failed to update service group: {e}"))?; + + info!("bulk creating additional service groups"); + api.bulk_create(&[ + ServiceGroup::new("test-service-group-2".to_string(), "Test Service Group 2".to_string()), + ServiceGroup::new("test-service-group-3".to_string(), "Test Service Group 3".to_string()), + ]) + .await + .inspect_err(|e| error!("failed to bulk create service groups: {e}"))?; + + let groups = api + .bulk_read() + .await + .inspect_err(|e| error!("failed to bulk read service groups: {e}")); + info!("all service groups: {groups:?}"); + + info!("bulk updating service groups"); + api.bulk_update(&[ + Group::new("test-service-group-2".to_string(), "Updated Service Group 2".to_string()), + Group::new("test-service-group-3".to_string(), "Updated Service Group 3".to_string()), + ]) + .await + .inspect_err(|e| error!("failed to bulk update service groups: {e}"))?; + + info!("bulk deleting extra service groups"); + api.bulk_delete(&[ + "test-service-group-2".to_string(), + "test-service-group-3".to_string(), + ]) + .await + .inspect_err(|e| error!("failed to bulk delete service groups: {e}"))?; + + info!("deleting test service group"); + api.delete(TESTGROUP) + .await + .inspect_err(|e| error!("failed to delete service group: {e}"))?; + + Ok(()) +} + +async fn test_contact_groups(client: Client) -> Result<()> { + use checkmk_api::api::groups::*; + const TESTGROUP: &str = "test-contact-group"; + info!("testing contact groups"); + + let api = client.contact_group_api(); + + info!("creating test contact group"); + api.create(&ContactGroup::new(TESTGROUP.to_string(), "Test Contact Group".to_string())) + .await + .inspect_err(|e| error!("failed to create contact group: {e}"))?; + + let group = api + .read(TESTGROUP) + .await + .inspect_err(|e| error!("failed to read contact group: {e}"))?; + info!("contact group config: {group:#?}"); + + info!("updating contact group"); + api.update(TESTGROUP, "Updated Test Contact Group") + .await + .inspect_err(|e| error!("failed to update contact group: {e}"))?; + + info!("bulk creating additional contact groups"); + api.bulk_create(&[ + ContactGroup::new("test-contact-group-2".to_string(), "Test Contact Group 2".to_string()), + ContactGroup::new("test-contact-group-3".to_string(), "Test Contact Group 3".to_string()), + ]) + .await + .inspect_err(|e| error!("failed to bulk create contact groups: {e}"))?; + + let groups = api + .bulk_read() + .await + .inspect_err(|e| error!("failed to bulk read contact groups: {e}")); + info!("all contact groups: {groups:?}"); + + info!("bulk updating contact groups"); + api.bulk_update(&[ + Group::new("test-contact-group-2".to_string(), "Updated Contact Group 2".to_string()), + Group::new("test-contact-group-3".to_string(), "Updated Contact Group 3".to_string()), + ]) + .await + .inspect_err(|e| error!("failed to bulk update contact groups: {e}"))?; + + info!("bulk deleting extra contact groups"); + api.bulk_delete(&[ + "test-contact-group-2".to_string(), + "test-contact-group-3".to_string(), + ]) + .await + .inspect_err(|e| error!("failed to bulk delete contact groups: {e}"))?; + + info!("deleting test contact group"); + api.delete(TESTGROUP) + .await + .inspect_err(|e| error!("failed to delete contact group: {e}"))?; + + Ok(()) +}