test and troubleshoot hostconfig
This commit is contained in:
parent
8e34f31810
commit
20d0c76e7a
@ -3,6 +3,7 @@ use std::fmt::Display;
|
|||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::api::rules::contactgroups::HostContactGroups;
|
use crate::api::rules::contactgroups::HostContactGroups;
|
||||||
use crate::api::rules::snmp::SnmpCommunity;
|
use crate::api::rules::snmp::SnmpCommunity;
|
||||||
@ -39,15 +40,33 @@ pub struct FolderAttributes {
|
|||||||
/// this attribute is not optional when queried from the api.
|
/// this attribute is not optional when queried from the api.
|
||||||
/// It cannot be filled in when creating a new folder.
|
/// It cannot be filled in when creating a new folder.
|
||||||
pub meta_data: Option<MetaData>,
|
pub meta_data: Option<MetaData>,
|
||||||
#[serde(flatten, skip_serializing_if = "HashMap::is_empty")]
|
// Additional attributes that can be used to categorize hosts. every tag is part of a tag_group
|
||||||
/// 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_"
|
||||||
/// NOTE that checkmk always returns taggroups prefixed with "tag_"
|
#[serde(default, flatten, skip_serializing_if = "HashMap::is_empty")]
|
||||||
pub tags: HashMap<String, String>,
|
pub tags: HashMap<String, String>,
|
||||||
// TODO: to be implemented
|
|
||||||
// #[serde(flatten, default)]
|
|
||||||
// pub networkscan: NetworkScan,
|
// these fields are used to prevent tags from taking them up
|
||||||
// #[serde(flatten, default)]
|
#[serde(default)]
|
||||||
// pub management: ManagementProtocol,
|
management_snmp_community: Option<SnmpCommunity>,
|
||||||
|
#[serde(default, skip_serializing)]
|
||||||
|
management_address: Value,
|
||||||
|
#[serde(default, skip_serializing)]
|
||||||
|
management_protocol: Value,
|
||||||
|
#[serde(default, skip_serializing)]
|
||||||
|
management_ipmi_credentials: Value,
|
||||||
|
#[serde(default, skip_serializing)]
|
||||||
|
network_scan: Value,
|
||||||
|
#[serde(default, skip_serializing)]
|
||||||
|
network_scan_result: Value,
|
||||||
|
#[serde(default, skip_serializing)]
|
||||||
|
waiting_for_discovery: Value,
|
||||||
|
#[serde(default, skip_serializing)]
|
||||||
|
inventory_failed: Value,
|
||||||
|
#[serde(default, skip_serializing)]
|
||||||
|
locked_attributes: Value,
|
||||||
|
#[serde(default, skip_serializing)]
|
||||||
|
locked_by: Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FolderAttributes {
|
impl FolderAttributes {
|
||||||
@ -93,7 +112,7 @@ impl FolderAttributes {
|
|||||||
|
|
||||||
pub fn add_tag(&mut self, taggroup: impl Display, tagvalue: String) {
|
pub fn add_tag(&mut self, taggroup: impl Display, tagvalue: String) {
|
||||||
self.tags
|
self.tags
|
||||||
.insert(format!("tag_{taggroup}"), tagvalue.to_string());
|
.insert(format!("tag_{taggroup}"), tagvalue);
|
||||||
}
|
}
|
||||||
pub fn with_tag(mut self, taggroup: impl Display, tagvalue: String) -> Self {
|
pub fn with_tag(mut self, taggroup: impl Display, tagvalue: String) -> Self {
|
||||||
self.add_tag(taggroup, tagvalue);
|
self.add_tag(taggroup, tagvalue);
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::api::folders::FolderAttributes;
|
use crate::api::folders::FolderAttributes;
|
||||||
@ -16,13 +18,31 @@ impl Client {
|
|||||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
pub struct HostConfig {
|
pub struct HostConfig {
|
||||||
pub folder: String,
|
pub folder: String,
|
||||||
pub attributes: FolderAttributes,
|
pub attributes: HostAttributes,
|
||||||
pub effective_attributes: FolderAttributes,
|
pub effective_attributes: HostAttributes,
|
||||||
pub is_cluster: bool,
|
pub is_cluster: bool,
|
||||||
pub is_offline: bool,
|
pub is_offline: bool,
|
||||||
pub cluster_nodes: Option<Vec<String>>,
|
pub cluster_nodes: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct HostAttributes {
|
||||||
|
#[serde(default)]
|
||||||
|
alias: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
ipaddress: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
ipv6address: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
additional_ipv4addresses: Vec<Ipv4Addr>,
|
||||||
|
#[serde(default)]
|
||||||
|
additional_ipv6addresses: Vec<Ipv6Addr>,
|
||||||
|
|
||||||
|
#[serde(flatten, default)]
|
||||||
|
folder_attributes: FolderAttributes
|
||||||
|
}
|
||||||
|
|
||||||
impl DomainExtension for HostConfig {
|
impl DomainExtension for HostConfig {
|
||||||
const DOMAIN_TYPE: super::DomainType = super::DomainType::HostConfig;
|
const DOMAIN_TYPE: super::DomainType = super::DomainType::HostConfig;
|
||||||
|
|
||||||
@ -35,7 +55,7 @@ impl DomainExtension for HostConfig {
|
|||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct HostCreationRequest {
|
pub struct HostCreationRequest {
|
||||||
pub hostname: String,
|
pub host_name: String,
|
||||||
pub folder: String,
|
pub folder: String,
|
||||||
pub attributes: FolderAttributes,
|
pub attributes: FolderAttributes,
|
||||||
}
|
}
|
||||||
@ -60,7 +80,7 @@ pub struct HostUpdateRequest {
|
|||||||
impl HostCreationRequest {
|
impl HostCreationRequest {
|
||||||
pub fn new(hostname: String, folder: String, attributes: FolderAttributes) -> Self {
|
pub fn new(hostname: String, folder: String, attributes: FolderAttributes) -> Self {
|
||||||
HostCreationRequest {
|
HostCreationRequest {
|
||||||
hostname,
|
host_name: hostname,
|
||||||
folder,
|
folder,
|
||||||
attributes,
|
attributes,
|
||||||
}
|
}
|
||||||
|
|||||||
65
src/main.rs
65
src/main.rs
@ -24,6 +24,7 @@ async fn main() -> Result<()> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
test_folders(client.clone()).await?;
|
test_folders(client.clone()).await?;
|
||||||
|
test_hosts(client.clone()).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -48,11 +49,13 @@ async fn test_folders(client: Client) -> Result<()> {
|
|||||||
.create(&creq, &())
|
.create(&creq, &())
|
||||||
.await
|
.await
|
||||||
.inspect_err(|e| error!("failed to create folder: {e}"))?;
|
.inspect_err(|e| error!("failed to create folder: {e}"))?;
|
||||||
|
|
||||||
let folder = folderapi
|
let folder = folderapi
|
||||||
.read(TESTDIRQRY, &())
|
.read(TESTDIRQRY, &())
|
||||||
.await
|
.await
|
||||||
.inspect_err(|e| error!("failed to read folder: {e}"))?;
|
.inspect_err(|e| error!("failed to read folder: {e}"))?;
|
||||||
info!("folder config on site: {folder:?}");
|
info!("folder config on site: {folder:?}");
|
||||||
|
|
||||||
info!("updating folder");
|
info!("updating folder");
|
||||||
folderapi
|
folderapi
|
||||||
.update(TESTDIRQRY, &ureq1)
|
.update(TESTDIRQRY, &ureq1)
|
||||||
@ -64,6 +67,7 @@ async fn test_folders(client: Client) -> Result<()> {
|
|||||||
.await
|
.await
|
||||||
.inspect_err(|e| error!("failed to read all folders: {e}"));
|
.inspect_err(|e| error!("failed to read all folders: {e}"));
|
||||||
info!("folder config on site: {folders:?}");
|
info!("folder config on site: {folders:?}");
|
||||||
|
|
||||||
folderapi
|
folderapi
|
||||||
.bulk_update(&[FolderBulkUpdateRequest::new(TESTDIRQRY.to_string(), ureq2)])
|
.bulk_update(&[FolderBulkUpdateRequest::new(TESTDIRQRY.to_string(), ureq2)])
|
||||||
.await
|
.await
|
||||||
@ -77,3 +81,64 @@ async fn test_folders(client: Client) -> Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn test_hosts(client: Client) -> Result<()> {
|
||||||
|
use checkmk_api::api::hosts::*;
|
||||||
|
use checkmk_api::api::folders::FolderAttributes;
|
||||||
|
const TESTHOST: &str = "test-host";
|
||||||
|
info!("testing hosts");
|
||||||
|
|
||||||
|
let hostapi = client.host_api();
|
||||||
|
let creq = HostCreationRequest::new(
|
||||||
|
TESTHOST.to_string(),
|
||||||
|
"~".to_string(),
|
||||||
|
FolderAttributes::default().with_site("dev".to_string())
|
||||||
|
);
|
||||||
|
let cquery = HostCreationQuery::new(false);
|
||||||
|
let rquery = HostReadQuery::new(true);
|
||||||
|
let ureq1 = HostUpdateRequest::replace(
|
||||||
|
FolderAttributes::default()
|
||||||
|
.with_site("dev".to_string())
|
||||||
|
.with_label("environment".to_string(), "test".to_string())
|
||||||
|
);
|
||||||
|
let ureq2 = HostUpdateRequest::update(
|
||||||
|
FolderAttributes::default().with_label("purpose".to_string(), "testing".to_string())
|
||||||
|
);
|
||||||
|
|
||||||
|
info!("creating test host");
|
||||||
|
hostapi
|
||||||
|
.create(&creq, &cquery)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| error!("failed to create host: {e}"))?;
|
||||||
|
|
||||||
|
let host = hostapi
|
||||||
|
.read(TESTHOST, &rquery)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| error!("failed to read host: {e}"))?;
|
||||||
|
info!("host config: {host:#?}");
|
||||||
|
|
||||||
|
info!("updating host");
|
||||||
|
hostapi
|
||||||
|
.update(TESTHOST, &ureq1)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| error!("failed to update host: {e}"))?;
|
||||||
|
|
||||||
|
let hosts = hostapi
|
||||||
|
.bulk_read(&HostBulkReadQuery::new().with_effective_attributes(true))
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| error!("failed to read all hosts: {e}"));
|
||||||
|
info!("all hosts: {hosts:?}");
|
||||||
|
|
||||||
|
hostapi
|
||||||
|
.bulk_update(&[HostBulkUpdateRequest::new(TESTHOST.to_string(), ureq2)])
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| error!("failed to do a bulk update of hosts: {e}"))?;
|
||||||
|
|
||||||
|
info!("deleting host");
|
||||||
|
hostapi
|
||||||
|
.delete(TESTHOST, &())
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| error!("failed to delete host: {e}"))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user