add hosts and implement (bulk)crud operations
This commit is contained in:
parent
38c21b0b7e
commit
cabb054dc5
@ -4,11 +4,10 @@ use std::fmt::Display;
|
|||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{Client, Result};
|
use crate::{ApiClient, Client, Result};
|
||||||
use crate::api::{BulkReadDomainExtention, BulkUpdateDomainExtention, DomainExtention};
|
use crate::api::{BulkReadDomainExtention, BulkUpdateDomainExtention, DomainExtention};
|
||||||
use crate::api::rules::contactgroups::HostContactGroups;
|
use crate::api::rules::contactgroups::HostContactGroups;
|
||||||
use crate::api::rules::snmp::SnmpCommunity;
|
use crate::api::rules::snmp::SnmpCommunity;
|
||||||
use crate::client::ApiClient;
|
|
||||||
|
|
||||||
pub const ROOT_FOLDER: &str = "/";
|
pub const ROOT_FOLDER: &str = "/";
|
||||||
|
|
||||||
@ -120,34 +119,46 @@ impl DomainExtention for FolderConfig {
|
|||||||
type DeleteQuery = FolderDeleteQuery;
|
type DeleteQuery = FolderDeleteQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Default, Clone, Serialize)]
|
||||||
pub struct FolderCreationRequest {
|
pub struct FolderCreationRequest {
|
||||||
pub name: String,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub name: Option<String>,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub parent: String,
|
pub parent: String,
|
||||||
pub attributes: FolderAttributes,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub attributes: Option<FolderAttributes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FolderCreationRequest {
|
impl FolderCreationRequest {
|
||||||
pub fn new(name: String, title: String, parent: String, attributes: FolderAttributes) -> Self {
|
pub fn new(title: String, parent: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
title, parent,
|
||||||
title,
|
name: None,
|
||||||
parent,
|
attributes: None
|
||||||
attributes,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_name(&mut self, name: String) {
|
||||||
|
self.name = Some(name);
|
||||||
|
}
|
||||||
|
pub fn with_name(mut self, name: String) -> Self {
|
||||||
|
self.set_name(name);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_attributes(&mut self, attributes: FolderAttributes) {
|
||||||
|
self.attributes = Some(attributes);
|
||||||
|
}
|
||||||
|
pub fn with_attributes(mut self, attributes: FolderAttributes) -> Self {
|
||||||
|
self.set_attributes(attributes);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct FolderCreationQuery;
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct FolderReadQuery;
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct FolderUpdateRequest {
|
pub struct FolderUpdateRequest {
|
||||||
#[serde(skip_serializing_if = "String::is_empty")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub title: String,
|
pub title: Option<String>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub attributes: Option<FolderAttributes>,
|
pub attributes: Option<FolderAttributes>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@ -159,7 +170,7 @@ pub struct FolderUpdateRequest {
|
|||||||
impl FolderUpdateRequest {
|
impl FolderUpdateRequest {
|
||||||
pub fn replace(attributes: FolderAttributes) -> Self {
|
pub fn replace(attributes: FolderAttributes) -> Self {
|
||||||
Self {
|
Self {
|
||||||
title: String::new(),
|
title: None,
|
||||||
attributes: Some(attributes),
|
attributes: Some(attributes),
|
||||||
update_attributes: None,
|
update_attributes: None,
|
||||||
remove_attributes: Vec::new(),
|
remove_attributes: Vec::new(),
|
||||||
@ -167,7 +178,7 @@ impl FolderUpdateRequest {
|
|||||||
}
|
}
|
||||||
pub fn update(attributes: FolderAttributes) -> Self {
|
pub fn update(attributes: FolderAttributes) -> Self {
|
||||||
Self {
|
Self {
|
||||||
title: String::new(),
|
title: None,
|
||||||
attributes: None,
|
attributes: None,
|
||||||
update_attributes: Some(attributes),
|
update_attributes: Some(attributes),
|
||||||
remove_attributes: Vec::new(),
|
remove_attributes: Vec::new(),
|
||||||
@ -175,7 +186,7 @@ impl FolderUpdateRequest {
|
|||||||
}
|
}
|
||||||
pub fn remove(attributes: Vec<String>) -> Self {
|
pub fn remove(attributes: Vec<String>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
title: String::new(),
|
title: None,
|
||||||
attributes: None,
|
attributes: None,
|
||||||
update_attributes: None,
|
update_attributes: None,
|
||||||
remove_attributes: attributes,
|
remove_attributes: attributes,
|
||||||
@ -184,14 +195,14 @@ impl FolderUpdateRequest {
|
|||||||
|
|
||||||
pub fn title(title: String) -> Self {
|
pub fn title(title: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
title,
|
title: Some(title),
|
||||||
attributes: None,
|
attributes: None,
|
||||||
update_attributes: None,
|
update_attributes: None,
|
||||||
remove_attributes: Vec::new()
|
remove_attributes: Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn set_title(&mut self, title: String) {
|
pub fn set_title(&mut self, title: String) {
|
||||||
self.title = title;
|
self.title = Some(title);
|
||||||
}
|
}
|
||||||
pub fn with_title(mut self, title: String) -> Self {
|
pub fn with_title(mut self, title: String) -> Self {
|
||||||
self.set_title(title);
|
self.set_title(title);
|
||||||
|
|||||||
177
src/api/hosts.rs
Normal file
177
src/api/hosts.rs
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{Client, ApiClient};
|
||||||
|
use crate::api::{BulkCreateDomainExtention, BulkDeleteDomainExtention, BulkReadDomainExtention, BulkUpdateDomainExtention, DomainExtention};
|
||||||
|
use crate::api::folders::FolderAttributes;
|
||||||
|
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub fn host_api(&self) -> ApiClient<HostConfig> {
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct HostConfig {
|
||||||
|
pub folder: String,
|
||||||
|
pub attributes: FolderAttributes,
|
||||||
|
pub effective_attributes: FolderAttributes,
|
||||||
|
pub is_cluster: bool,
|
||||||
|
pub is_offline: bool,
|
||||||
|
pub cluster_nodes: Option<Vec<String>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DomainExtention for HostConfig {
|
||||||
|
const DOMAIN_TYPE: super::DomainType = super::DomainType::HostConfig;
|
||||||
|
|
||||||
|
type CreationRequest = HostCreationRequest;
|
||||||
|
type CreationQuery = HostCreationQuery;
|
||||||
|
type ReadQuery = HostReadQuery;
|
||||||
|
type UpdateRequest = HostUpdateRequest;
|
||||||
|
type DeleteQuery = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct HostCreationRequest {
|
||||||
|
pub hostname: String,
|
||||||
|
pub folder: String,
|
||||||
|
pub attributes: FolderAttributes
|
||||||
|
}
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct HostCreationQuery {
|
||||||
|
pub bake_agent: bool
|
||||||
|
}
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct HostReadQuery {
|
||||||
|
pub effective_attributes: bool
|
||||||
|
}
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct HostUpdateRequest {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub attributes: Option<FolderAttributes>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub update_attributes: Option<FolderAttributes>,
|
||||||
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub remove_attributes: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HostCreationRequest {
|
||||||
|
pub fn new(hostname: String, folder: String, attributes: FolderAttributes) -> Self {
|
||||||
|
HostCreationRequest { hostname, folder, attributes }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HostCreationQuery {
|
||||||
|
pub fn new(bake_agent: bool) -> Self {
|
||||||
|
Self { bake_agent }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HostReadQuery {
|
||||||
|
pub fn new(effective_attributes: bool) -> Self {
|
||||||
|
Self { effective_attributes }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HostUpdateRequest {
|
||||||
|
pub fn replace(attributes: FolderAttributes) -> Self {
|
||||||
|
Self {
|
||||||
|
attributes: Some(attributes),
|
||||||
|
update_attributes: None,
|
||||||
|
remove_attributes: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn update(attributes: FolderAttributes) -> Self {
|
||||||
|
Self {
|
||||||
|
attributes: None,
|
||||||
|
update_attributes: Some(attributes),
|
||||||
|
remove_attributes: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn remove(attributes: Vec<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
attributes: None,
|
||||||
|
update_attributes: None,
|
||||||
|
remove_attributes: attributes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BulkCreateDomainExtention for HostConfig {}
|
||||||
|
impl BulkReadDomainExtention for HostConfig {
|
||||||
|
type BulkReadQuery = HostBulkReadQuery;
|
||||||
|
}
|
||||||
|
impl BulkUpdateDomainExtention for HostConfig {
|
||||||
|
type BulkUpdateRequest = HostBulkUpdateRequest;
|
||||||
|
}
|
||||||
|
impl BulkDeleteDomainExtention for HostConfig {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize)]
|
||||||
|
pub struct HostBulkReadQuery {
|
||||||
|
effective_attributes: bool,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
fields: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
|
hostnames: Vec<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
site: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HostBulkReadQuery {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_effective_attributes(&mut self, effective_attributes: bool) {
|
||||||
|
self.effective_attributes = effective_attributes;
|
||||||
|
}
|
||||||
|
pub fn with_effective_attributes(mut self, effective_attributes: bool) -> Self {
|
||||||
|
self.set_effective_attributes(effective_attributes);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_fields(&mut self, fields: String) {
|
||||||
|
self.fields = Some(fields);
|
||||||
|
}
|
||||||
|
pub fn with_fields(mut self, fields: String) -> Self {
|
||||||
|
self.set_fields(fields);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_hostname(&mut self, hostname: String) {
|
||||||
|
self.hostnames.push(hostname);
|
||||||
|
}
|
||||||
|
pub fn with_hostname(mut self, hostname: String) -> Self {
|
||||||
|
self.add_hostname(hostname);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_hostnames(&mut self, hostnames: Vec<String>) {
|
||||||
|
self.hostnames = hostnames;
|
||||||
|
}
|
||||||
|
pub fn with_hostnames(mut self, hostnames: Vec<String>) -> Self {
|
||||||
|
self.set_hostnames(hostnames);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_site(&mut self, site: String) {
|
||||||
|
self.site = Some(site);
|
||||||
|
}
|
||||||
|
pub fn with_site(mut self, site: String) -> Self {
|
||||||
|
self.set_site(site);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct HostBulkUpdateRequest {
|
||||||
|
host_name: String,
|
||||||
|
#[serde(flatten)]
|
||||||
|
update_request: HostUpdateRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HostBulkUpdateRequest {
|
||||||
|
pub fn new(host_name: String, update_request: HostUpdateRequest) -> Self {
|
||||||
|
Self { host_name, update_request }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
pub mod folders;
|
pub mod folders;
|
||||||
|
pub mod hosts;
|
||||||
pub(crate) mod rules;
|
pub(crate) mod rules;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -92,6 +93,7 @@ pub trait DomainExtention: DeserializeOwned + Serialize {
|
|||||||
|
|
||||||
// these are essentials tags for domain extentions to signal that bulk operations are possible
|
// these are essentials tags for domain extentions to signal that bulk operations are possible
|
||||||
// not every extention supports bulk operations. and not all extentions that do support all of them
|
// not every extention supports bulk operations. and not all extentions that do support all of them
|
||||||
|
// and those that do tend to have a bit different types
|
||||||
pub trait BulkCreateDomainExtention: DomainExtention {}
|
pub trait BulkCreateDomainExtention: DomainExtention {}
|
||||||
pub trait BulkReadDomainExtention: DomainExtention {
|
pub trait BulkReadDomainExtention: DomainExtention {
|
||||||
type BulkReadQuery: Serialize;
|
type BulkReadQuery: Serialize;
|
||||||
|
|||||||
@ -345,13 +345,18 @@ impl InnerClient {
|
|||||||
|
|
||||||
pub(crate) async fn bulk_create_domain_objects<E: BulkCreateDomainExtention>(
|
pub(crate) async fn bulk_create_domain_objects<E: BulkCreateDomainExtention>(
|
||||||
&self,
|
&self,
|
||||||
request: &[E::CreationRequest],
|
entries: &[E::CreationRequest],
|
||||||
query: &E::CreationQuery,
|
query: &E::CreationQuery,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Request<'a, D: BulkCreateDomainExtention> {
|
||||||
|
entries: &'a [D::CreationRequest]
|
||||||
|
}
|
||||||
|
|
||||||
let request = self
|
let request = self
|
||||||
.http
|
.http
|
||||||
.post(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Create))
|
.post(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Create))
|
||||||
.json(request)
|
.json(&Request::<E>{ entries })
|
||||||
.query(query)
|
.query(query)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -392,12 +397,17 @@ impl InnerClient {
|
|||||||
}
|
}
|
||||||
pub(crate) async fn bulk_delete_domain_objects<E: BulkDeleteDomainExtention>(
|
pub(crate) async fn bulk_delete_domain_objects<E: BulkDeleteDomainExtention>(
|
||||||
&self,
|
&self,
|
||||||
ids: &[String],
|
entries: &[String],
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Request<'a> {
|
||||||
|
entries: &'a [String]
|
||||||
|
}
|
||||||
|
|
||||||
let request = self
|
let request = self
|
||||||
.http
|
.http
|
||||||
.post(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Delete))
|
.post(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Delete))
|
||||||
.json(&ids)
|
.json(&Request { entries })
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -4,3 +4,4 @@ mod error;
|
|||||||
|
|
||||||
pub use error::{Error, Result};
|
pub use error::{Error, Result};
|
||||||
pub use client::{Client, ClientBuilder};
|
pub use client::{Client, ClientBuilder};
|
||||||
|
pub(crate) use client::ApiClient;
|
||||||
|
|||||||
@ -37,11 +37,10 @@ async fn test_folders(client: Client) -> Result<()> {
|
|||||||
|
|
||||||
let folderapi = client.folder_api();
|
let folderapi = client.folder_api();
|
||||||
let creq = FolderCreationRequest::new(
|
let creq = FolderCreationRequest::new(
|
||||||
TESTDIR.to_string(),
|
|
||||||
"Testing".to_string(),
|
"Testing".to_string(),
|
||||||
ROOT_FOLDER.to_string(),
|
ROOT_FOLDER.to_string(),
|
||||||
FolderAttributes::default()
|
)
|
||||||
);
|
.with_name(TESTDIR.to_string());
|
||||||
let ureq1 = FolderUpdateRequest::replace(
|
let ureq1 = FolderUpdateRequest::replace(
|
||||||
FolderAttributes::default()
|
FolderAttributes::default()
|
||||||
.with_site("dev".to_string())
|
.with_site("dev".to_string())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user