Compare commits
No commits in common. "f08b37cb7d0b432464216bbaa43348d078d567f8" and "96402420c13b45fc7e8a4c36e76e4e0d5ffe5cff" have entirely different histories.
f08b37cb7d
...
96402420c1
@ -10,12 +10,16 @@ use schemars::JsonSchema;
|
|||||||
|
|
||||||
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::api::{DomainExtension, domain_bulk_read, domain_bulk_update, domain_client, domain_create, domain_delete, domain_read, domain_update};
|
use crate::api::{BulkReadDomainExtension, BulkUpdateDomainExtension, DomainExtension};
|
||||||
use crate::{ApiClient, Client, Result};
|
use crate::{ApiClient, Client, Result};
|
||||||
|
|
||||||
pub const ROOT_FOLDER: &str = "/";
|
pub const ROOT_FOLDER: &str = "/";
|
||||||
|
|
||||||
domain_client!(FolderConfig, folder_api);
|
impl Client {
|
||||||
|
pub fn folder_api(&self) -> ApiClient<FolderConfig> {
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
@ -132,6 +136,12 @@ pub struct MetaData {
|
|||||||
|
|
||||||
impl DomainExtension for FolderConfig {
|
impl DomainExtension for FolderConfig {
|
||||||
const DOMAIN_TYPE: super::DomainType = super::DomainType::FolderConfig;
|
const DOMAIN_TYPE: super::DomainType = super::DomainType::FolderConfig;
|
||||||
|
|
||||||
|
type CreationRequest = FolderCreationRequest;
|
||||||
|
type CreationQuery = ();
|
||||||
|
type ReadQuery = ();
|
||||||
|
type UpdateRequest = FolderUpdateRequest;
|
||||||
|
type DeleteQuery = FolderDeleteQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize)]
|
#[derive(Debug, Default, Clone, Serialize)]
|
||||||
@ -249,6 +259,10 @@ pub enum FolderDeleteMode {
|
|||||||
AbortOnNonEmpty,
|
AbortOnNonEmpty,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BulkReadDomainExtension for FolderConfig {
|
||||||
|
type BulkReadQuery = FolderBulkReadQuery;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
pub struct FolderBulkReadQuery {
|
pub struct FolderBulkReadQuery {
|
||||||
@ -262,6 +276,10 @@ impl FolderBulkReadQuery {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BulkUpdateDomainExtension for FolderConfig {
|
||||||
|
type BulkUpdateRequest = FolderBulkUpdateRequest;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
pub struct FolderBulkUpdateRequest {
|
pub struct FolderBulkUpdateRequest {
|
||||||
@ -279,27 +297,28 @@ impl FolderBulkUpdateRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiClient<FolderConfig> {
|
|
||||||
pub async fn move_folder(&self, id: impl Display, destination: &str) -> Result<()> {
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct MoveFolderRequest<'a> {
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
destination: &'a str,
|
pub struct MoveFolderRequest {
|
||||||
|
destination: String,
|
||||||
}
|
}
|
||||||
let request = MoveFolderRequest { destination };
|
|
||||||
|
|
||||||
|
impl MoveFolderRequest {
|
||||||
|
pub fn new(destination: String) -> Self {
|
||||||
|
Self { destination }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApiClient<FolderConfig> {
|
||||||
|
pub async fn move_folder(&self, id: impl Display, request: &MoveFolderRequest) -> Result<()> {
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{}/actions/move/invoke",
|
"{}/actions/move/invoke",
|
||||||
self.inner.object_url(FolderConfig::DOMAIN_TYPE, id)
|
self.inner.object_url(FolderConfig::DOMAIN_TYPE, id)
|
||||||
);
|
);
|
||||||
let request = self.inner.http.post(url).json(&request).build().unwrap();
|
let request = self.inner.http.post(url).json(request).build().unwrap();
|
||||||
|
|
||||||
self.inner.invoke_api(request).await
|
self.inner.invoke_api(request).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
domain_create!(FolderConfig, FolderCreationRequest);
|
// TODO: add show hosts api call
|
||||||
domain_read!(FolderConfig);
|
|
||||||
domain_update!(FolderConfig, FolderUpdateRequest);
|
|
||||||
domain_delete!(FolderConfig, FolderDeleteQuery);
|
|
||||||
domain_bulk_read!(FolderConfig, FolderBulkReadQuery);
|
|
||||||
domain_bulk_update!(FolderConfig, FolderBulkUpdateRequest);
|
|
||||||
|
|||||||
@ -5,23 +5,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
|
|
||||||
use crate::api::{
|
use crate::api::{
|
||||||
DomainObject, DomainType
|
BulkCreateDomainExtension, BulkDeleteDomainExtension, BulkReadDomainExtension,
|
||||||
|
BulkUpdateDomainExtension, DomainExtension, DomainType
|
||||||
};
|
};
|
||||||
use crate::{ApiClient, Client, Result};
|
|
||||||
|
|
||||||
impl Client {
|
|
||||||
pub fn host_group_api(&self) -> ApiClient<HostGroup> {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn service_group_api(&self) -> ApiClient<ServiceGroup> {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn contact_group_api(&self) -> ApiClient<ContactGroup> {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
@ -36,12 +22,33 @@ impl Group {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DomainObject<serde_json::Value>> for Group {
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
fn from(value: DomainObject<serde_json::Value>) -> Self {
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
Self::new(value.id, value.title.unwrap_or_default())
|
pub struct GroupAlias {
|
||||||
|
alias: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GroupAlias {
|
||||||
|
pub fn new(alias: String) -> Self {
|
||||||
|
Self { alias }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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 {
|
macro_rules! domain_group {
|
||||||
($id:ident, $typ:expr) => {
|
($id:ident, $typ:expr) => {
|
||||||
@ -63,80 +70,25 @@ macro_rules! domain_group {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DomainObject<serde_json::Value>> for $id {
|
impl DomainExtension for $id {
|
||||||
fn from(value: DomainObject<serde_json::Value>) -> Self {
|
const DOMAIN_TYPE: DomainType = $typ;
|
||||||
Self(Group::from(value))
|
|
||||||
}
|
type CreationRequest = Group;
|
||||||
|
type CreationQuery = ();
|
||||||
|
type ReadQuery = ();
|
||||||
|
type UpdateRequest = GroupAlias;
|
||||||
|
type DeleteQuery = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Client> for ApiClient<$id> {
|
impl BulkCreateDomainExtension for $id {}
|
||||||
fn from(value: &Client) -> Self {
|
impl BulkReadDomainExtension for $id {
|
||||||
Self::new(value)
|
type BulkReadQuery = ();
|
||||||
}
|
}
|
||||||
|
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<serde_json::Value> =
|
|
||||||
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<Vec<$id>> {
|
|
||||||
let entries: Vec<DomainObject<serde_json::Value>> =
|
|
||||||
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::<Vec<_>>();
|
|
||||||
self.inner.bulk_update($typ, &entries).await
|
|
||||||
}
|
|
||||||
pub async fn bulk_delete(&self, entries: &[String]) -> Result<()> {
|
|
||||||
self.inner.bulk_delete($typ, entries).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
use std::fmt::Display;
|
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -7,12 +6,16 @@ use schemars::JsonSchema;
|
|||||||
|
|
||||||
use crate::api::folders::FolderAttributes;
|
use crate::api::folders::FolderAttributes;
|
||||||
use crate::api::{
|
use crate::api::{
|
||||||
DomainExtension, domain_bulk_create, domain_bulk_delete, domain_bulk_read, domain_bulk_update, domain_client, domain_create, domain_delete, domain_read, domain_update
|
BulkCreateDomainExtension, BulkDeleteDomainExtension, BulkReadDomainExtension,
|
||||||
|
BulkUpdateDomainExtension, DomainExtension,
|
||||||
};
|
};
|
||||||
use crate::{ApiClient, Client, Result};
|
use crate::{ApiClient, Client};
|
||||||
|
|
||||||
|
impl Client {
|
||||||
domain_client!(HostConfig, host_api);
|
pub fn host_api(&self) -> ApiClient<HostConfig> {
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
@ -46,6 +49,12 @@ pub struct HostAttributes {
|
|||||||
|
|
||||||
impl DomainExtension for HostConfig {
|
impl DomainExtension for HostConfig {
|
||||||
const DOMAIN_TYPE: super::DomainType = super::DomainType::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)]
|
#[derive(Serialize)]
|
||||||
@ -124,6 +133,15 @@ impl HostUpdateRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BulkCreateDomainExtension for HostConfig {}
|
||||||
|
impl BulkReadDomainExtension for HostConfig {
|
||||||
|
type BulkReadQuery = HostBulkReadQuery;
|
||||||
|
}
|
||||||
|
impl BulkUpdateDomainExtension for HostConfig {
|
||||||
|
type BulkUpdateRequest = HostBulkUpdateRequest;
|
||||||
|
}
|
||||||
|
impl BulkDeleteDomainExtension for HostConfig {}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize)]
|
#[derive(Debug, Default, Clone, Serialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
pub struct HostBulkReadQuery {
|
pub struct HostBulkReadQuery {
|
||||||
@ -198,12 +216,3 @@ impl HostBulkUpdateRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
domain_create!(HostConfig, HostCreationRequest, HostCreationQuery);
|
|
||||||
domain_read!(HostConfig, HostReadQuery);
|
|
||||||
domain_update!(HostConfig, HostUpdateRequest);
|
|
||||||
domain_delete!(HostConfig);
|
|
||||||
domain_bulk_create!(HostConfig, HostCreationRequest, HostCreationQuery);
|
|
||||||
domain_bulk_read!(HostConfig, HostBulkReadQuery);
|
|
||||||
domain_bulk_update!(HostConfig, HostBulkUpdateRequest);
|
|
||||||
domain_bulk_delete!(HostConfig);
|
|
||||||
|
|||||||
261
src/api/mod.rs
261
src/api/mod.rs
@ -5,13 +5,10 @@ pub mod groups;
|
|||||||
pub(crate) mod rules;
|
pub(crate) mod rules;
|
||||||
pub mod tags;
|
pub mod tags;
|
||||||
|
|
||||||
use std::fmt::{self, Display};
|
use std::fmt;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize, de::DeserializeOwned};
|
use serde::{Deserialize, Serialize, de::DeserializeOwned};
|
||||||
|
|
||||||
use crate::Result;
|
|
||||||
use crate::client::InnerClient;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum DomainType {
|
pub enum DomainType {
|
||||||
@ -91,248 +88,22 @@ pub(crate) struct DomainCollection<E> {
|
|||||||
|
|
||||||
pub trait DomainExtension: DeserializeOwned + Serialize {
|
pub trait DomainExtension: DeserializeOwned + Serialize {
|
||||||
const DOMAIN_TYPE: DomainType;
|
const DOMAIN_TYPE: DomainType;
|
||||||
|
|
||||||
|
type CreationRequest: Serialize;
|
||||||
|
type CreationQuery: Serialize;
|
||||||
|
type ReadQuery: Serialize;
|
||||||
|
type UpdateRequest: Serialize;
|
||||||
|
type DeleteQuery: Serialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InnerClient {
|
// these are essential tags for domain extensions to signal that bulk operations are possible
|
||||||
pub(crate) async fn create_domain_object<E, O, Q>(
|
// not every extension supports bulk operations. and not all extensions that do support all of them
|
||||||
&self,
|
// and those that do tend to have a bit different types
|
||||||
object: &O,
|
pub trait BulkCreateDomainExtension: DomainExtension {}
|
||||||
query: &Q,
|
pub trait BulkReadDomainExtension: DomainExtension {
|
||||||
) -> Result<()>
|
type BulkReadQuery: Serialize;
|
||||||
where
|
|
||||||
E: DomainExtension,
|
|
||||||
O: Serialize,
|
|
||||||
Q: Serialize
|
|
||||||
{
|
|
||||||
self.create(E::DOMAIN_TYPE, object, query).await
|
|
||||||
}
|
}
|
||||||
pub(crate) async fn read_domain_object<E, Q>(
|
pub trait BulkUpdateDomainExtension: DomainExtension {
|
||||||
&self,
|
type BulkUpdateRequest: Serialize;
|
||||||
id: impl Display,
|
|
||||||
query: &Q,
|
|
||||||
) -> Result<DomainObject<E>>
|
|
||||||
where
|
|
||||||
E: DomainExtension,
|
|
||||||
Q: Serialize
|
|
||||||
{
|
|
||||||
self.read(E::DOMAIN_TYPE, id, query).await
|
|
||||||
}
|
}
|
||||||
pub(crate) async fn update_domain_object<E, O>(
|
pub trait BulkDeleteDomainExtension: DomainExtension {}
|
||||||
&self,
|
|
||||||
id: impl Display,
|
|
||||||
object: &O,
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
E: DomainExtension,
|
|
||||||
O: Serialize
|
|
||||||
{
|
|
||||||
self.update(E::DOMAIN_TYPE, id, object).await
|
|
||||||
}
|
|
||||||
pub(crate) async fn delete_domain_object<E, Q>(
|
|
||||||
&self,
|
|
||||||
id: impl Display,
|
|
||||||
query: &Q,
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
E: DomainExtension,
|
|
||||||
Q: Serialize
|
|
||||||
{
|
|
||||||
self.delete(E::DOMAIN_TYPE, id, query).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn bulk_create_domain_objects<E, O, Q>(
|
|
||||||
&self,
|
|
||||||
entries: &[O],
|
|
||||||
query: &Q,
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
E: DomainExtension,
|
|
||||||
O: Serialize,
|
|
||||||
Q: Serialize
|
|
||||||
{
|
|
||||||
self.bulk_create(E::DOMAIN_TYPE, entries, query).await
|
|
||||||
}
|
|
||||||
pub(crate) async fn bulk_read_domain_objects<E, Q>(
|
|
||||||
&self,
|
|
||||||
query: &Q,
|
|
||||||
) -> Result<Vec<DomainObject<E>>>
|
|
||||||
where
|
|
||||||
E: DomainExtension,
|
|
||||||
Q: Serialize
|
|
||||||
{
|
|
||||||
self.bulk_read(E::DOMAIN_TYPE, query).await
|
|
||||||
}
|
|
||||||
pub(crate) async fn bulk_update_domain_objects<E, O>(
|
|
||||||
&self,
|
|
||||||
entries: &[O],
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
E: DomainExtension,
|
|
||||||
O: Serialize
|
|
||||||
{
|
|
||||||
self.bulk_update(E::DOMAIN_TYPE, entries).await
|
|
||||||
}
|
|
||||||
pub(crate) async fn bulk_delete_domain_objects<E>(
|
|
||||||
&self,
|
|
||||||
entries: &[String],
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
E: DomainExtension
|
|
||||||
{
|
|
||||||
self.bulk_delete(E::DOMAIN_TYPE, entries).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
macro_rules! domain_client {
|
|
||||||
($id:ident, $func:ident) => {
|
|
||||||
impl Client {
|
|
||||||
pub fn $func(&self) -> ApiClient<$id> {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
domain_client!($id);
|
|
||||||
};
|
|
||||||
($id:ident) => {
|
|
||||||
impl From<&Client> for ApiClient<$id> {
|
|
||||||
fn from(value: &Client) -> Self {
|
|
||||||
Self::new(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub(super) use domain_client;
|
|
||||||
|
|
||||||
macro_rules! domain_create {
|
|
||||||
($id:ident, $object:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn create(&self, object: &$object) -> Result<()> {
|
|
||||||
self.inner.create_domain_object::<$id, _, _>(object, &()).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
($id:ident, $object:ident, $qry:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn create(&self, object: &$object, query: &$qry) -> Result<()> {
|
|
||||||
self.inner.create_domain_object::<$id, _, _>(object, query).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(super) use domain_create;
|
|
||||||
|
|
||||||
macro_rules! domain_read {
|
|
||||||
($id:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn read(&self, id: impl Display) -> Result<$id> {
|
|
||||||
self.inner.read_domain_object::<$id, _>(id, &()).await
|
|
||||||
.map(|obj| obj.extensions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
($id:ident, $qry:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn read(&self, id: impl Display, query: &$qry) -> Result<$id> {
|
|
||||||
self.inner.read_domain_object::<$id, _>(id, &query).await
|
|
||||||
.map(|obj| obj.extensions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(super) use domain_read;
|
|
||||||
|
|
||||||
macro_rules! domain_update {
|
|
||||||
($id:ident, $object:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn update(&self, id: impl Display, object: &$object) -> Result<()> {
|
|
||||||
self.inner.update_domain_object::<$id, _>(id, object).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(super) use domain_update;
|
|
||||||
|
|
||||||
macro_rules! domain_delete {
|
|
||||||
($id:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn delete(&self, id: impl Display) -> Result<()> {
|
|
||||||
self.inner.delete_domain_object::<$id, _>(id, &()).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
($id:ident, $qry:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn delete(&self, id: impl Display, query: &$qry) -> Result<()> {
|
|
||||||
self.inner.delete_domain_object::<$id, _>(id, &query).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(super) use domain_delete;
|
|
||||||
|
|
||||||
macro_rules! domain_bulk_create {
|
|
||||||
($id:ident, $object:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn bulk_create(&self, entries: &[$object]) -> Result<()> {
|
|
||||||
self.inner.bulk_create_domain_objects::<$id, _, _>(entries, &()).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
($id:ident, $object:ident, $qry:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn bulk_create(&self, entries: &[$object], query: &$qry) -> Result<()> {
|
|
||||||
self.inner.bulk_create_domain_objects::<$id, _, _>(entries, query).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(super) use domain_bulk_create;
|
|
||||||
|
|
||||||
macro_rules! domain_bulk_read {
|
|
||||||
($id:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn bulk_read(&self) -> Result<Vec<$id>> {
|
|
||||||
let objs = self.inner.bulk_read_domain_objects::<$id, _>(&()).await?;
|
|
||||||
let objs = objs.into_iter()
|
|
||||||
.map(|obj| obj.extensions)
|
|
||||||
.collect();
|
|
||||||
Ok(objs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
($id:ident, $qry:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn bulk_read(&self, query: &$qry) -> Result<Vec<$id>> {
|
|
||||||
let objs = self.inner.bulk_read_domain_objects::<$id, _>(&query).await?;
|
|
||||||
let objs = objs.into_iter()
|
|
||||||
.map(|obj| obj.extensions)
|
|
||||||
.collect();
|
|
||||||
Ok(objs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(super) use domain_bulk_read;
|
|
||||||
|
|
||||||
macro_rules! domain_bulk_update {
|
|
||||||
($id:ident, $object:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn bulk_update(&self, entries: &[$object]) -> Result<()> {
|
|
||||||
self.inner.bulk_update_domain_objects::<$id, _>(entries).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(super) use domain_bulk_update;
|
|
||||||
|
|
||||||
macro_rules! domain_bulk_delete {
|
|
||||||
($id:ident) => {
|
|
||||||
impl ApiClient<$id> {
|
|
||||||
pub async fn bulk_delete(&self, entries: &[String]) -> Result<()> {
|
|
||||||
self.inner.bulk_delete_domain_objects::<$id>(entries).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(super) use domain_bulk_delete;
|
|
||||||
|
|||||||
@ -6,9 +6,9 @@ use schemars::JsonSchema;
|
|||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
pub struct HostContactGroups {
|
pub struct HostContactGroups {
|
||||||
pub groups: Vec<String>,
|
groups: Vec<String>,
|
||||||
pub r#use: bool,
|
r#use: bool,
|
||||||
pub use_for_services: bool,
|
use_for_services: bool,
|
||||||
pub recurse_use: bool,
|
recurse_use: bool,
|
||||||
pub recurse_perms: bool,
|
recurse_perms: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,8 @@
|
|||||||
use crate::api::Display;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "schemars")]
|
#[cfg(feature = "schemars")]
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
|
|
||||||
use crate::api::{DomainExtension, DomainType, domain_bulk_read, domain_client, domain_create, domain_delete, domain_read, domain_update};
|
use crate::api::{BulkReadDomainExtension, DomainExtension, DomainType};
|
||||||
use crate::{ApiClient, Client, Result};
|
|
||||||
|
|
||||||
domain_client!(TagGroup, tag_api);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
|
||||||
@ -149,10 +144,17 @@ pub enum TagDeleteMode {
|
|||||||
|
|
||||||
impl DomainExtension for TagGroup {
|
impl DomainExtension for TagGroup {
|
||||||
const DOMAIN_TYPE: super::DomainType = DomainType::HostTagGroup;
|
const DOMAIN_TYPE: super::DomainType = DomainType::HostTagGroup;
|
||||||
|
|
||||||
|
type CreationRequest = ExtendedTagGroup;
|
||||||
|
type CreationQuery = ();
|
||||||
|
type ReadQuery = ();
|
||||||
|
type UpdateRequest = TagUpdateRequest;
|
||||||
|
type DeleteQuery = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
domain_create!(TagGroup, ExtendedTagGroup);
|
// TODO: id and title are in the "DomainObject".
|
||||||
domain_read!(TagGroup);
|
// should be added to during query?
|
||||||
domain_update!(TagGroup, TagUpdateRequest);
|
// maybe add "with_title_and_id" to DomainExtension, defaulting to no-op?
|
||||||
domain_delete!(TagGroup);
|
impl BulkReadDomainExtension for TagGroup {
|
||||||
domain_bulk_read!(TagGroup);
|
type BulkReadQuery = ();
|
||||||
|
}
|
||||||
|
|||||||
204
src/client.rs
204
src/client.rs
@ -11,7 +11,8 @@ use serde::de::DeserializeOwned;
|
|||||||
use tokio::sync::Semaphore;
|
use tokio::sync::Semaphore;
|
||||||
|
|
||||||
use crate::api::{
|
use crate::api::{
|
||||||
DomainCollection, DomainObject, DomainType,
|
BulkCreateDomainExtension, BulkDeleteDomainExtension, BulkReadDomainExtension,
|
||||||
|
BulkUpdateDomainExtension, DomainCollection, DomainExtension, DomainObject, DomainType,
|
||||||
};
|
};
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Result};
|
||||||
|
|
||||||
@ -205,15 +206,12 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InnerClient {
|
impl InnerClient {
|
||||||
#[inline]
|
|
||||||
pub(crate) fn object_url(&self, domain_type: DomainType, id: impl Display) -> String {
|
pub(crate) fn object_url(&self, domain_type: DomainType, id: impl Display) -> String {
|
||||||
format!("{}/objects/{}/{}", self.url, domain_type, id)
|
format!("{}/objects/{}/{}", self.url, domain_type, id)
|
||||||
}
|
}
|
||||||
#[inline]
|
|
||||||
pub(crate) fn collection_url(&self, domain_type: DomainType) -> String {
|
pub(crate) fn collection_url(&self, domain_type: DomainType) -> String {
|
||||||
format!("{}/domain-types/{}/collections/all", self.url, domain_type)
|
format!("{}/domain-types/{}/collections/all", self.url, domain_type)
|
||||||
}
|
}
|
||||||
#[inline]
|
|
||||||
pub(crate) fn bulk_action_url(&self, domain_type: DomainType, action: BulkAction) -> String {
|
pub(crate) fn bulk_action_url(&self, domain_type: DomainType, action: BulkAction) -> String {
|
||||||
format!(
|
format!(
|
||||||
"{}/domain-types/{}/actions/bulk-{}/invoke",
|
"{}/domain-types/{}/actions/bulk-{}/invoke",
|
||||||
@ -284,83 +282,60 @@ impl InnerClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn create<O, Q>(
|
pub(crate) async fn create_domain_object<E: DomainExtension>(
|
||||||
&self,
|
&self,
|
||||||
domain_type: DomainType,
|
body: &E::CreationRequest,
|
||||||
object: &O,
|
query: &E::CreationQuery,
|
||||||
query: &Q
|
) -> Result<()> {
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
O: Serialize,
|
|
||||||
Q: Serialize
|
|
||||||
{
|
|
||||||
let url = self.collection_url(domain_type);
|
|
||||||
let request = self
|
let request = self
|
||||||
.http
|
.http
|
||||||
.post(url)
|
.post(self.collection_url(E::DOMAIN_TYPE))
|
||||||
.json(object)
|
.json(body)
|
||||||
.query(query)
|
.query(query)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.invoke_api(request).await
|
self.invoke_api(request).await
|
||||||
}
|
}
|
||||||
|
pub(crate) async fn read_domain_object<E: DomainExtension>(
|
||||||
pub(crate) async fn read<O, Q>(
|
|
||||||
&self,
|
&self,
|
||||||
domain_type: DomainType,
|
|
||||||
id: impl Display,
|
id: impl Display,
|
||||||
query: &Q,
|
query: &E::ReadQuery,
|
||||||
) -> Result<O>
|
) -> Result<DomainObject<E>> {
|
||||||
where
|
|
||||||
O: DeserializeOwned,
|
|
||||||
Q: Serialize
|
|
||||||
{
|
|
||||||
let url = self.object_url(domain_type, id);
|
|
||||||
let request = self
|
let request = self
|
||||||
.http
|
.http
|
||||||
.get(url)
|
.get(self.object_url(E::DOMAIN_TYPE, id))
|
||||||
.query(query)
|
.query(query)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.query_api(request).await
|
self.query_api(request).await
|
||||||
}
|
}
|
||||||
pub(crate) async fn update<O>(
|
pub(crate) async fn update_domain_object<E: DomainExtension>(
|
||||||
&self,
|
&self,
|
||||||
domain_type: DomainType,
|
|
||||||
id: impl Display,
|
id: impl Display,
|
||||||
object: &O,
|
request: &E::UpdateRequest,
|
||||||
) -> Result<()>
|
) -> Result<()> {
|
||||||
where
|
let url = self.object_url(E::DOMAIN_TYPE, id);
|
||||||
O: Serialize,
|
|
||||||
{
|
|
||||||
let url = self.object_url(domain_type, id);
|
|
||||||
let etag = self.get_etag(&url).await?;
|
let etag = self.get_etag(&url).await?;
|
||||||
|
|
||||||
let request = self
|
let request = self
|
||||||
.http
|
.http
|
||||||
.put(url)
|
.put(url)
|
||||||
.json(object)
|
.json(&request)
|
||||||
.header(reqwest::header::IF_MATCH, etag)
|
.header(reqwest::header::IF_MATCH, etag)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.invoke_api(request).await
|
self.invoke_api(request).await
|
||||||
}
|
}
|
||||||
pub(crate) async fn delete<Q>(
|
pub(crate) async fn delete_domain_object<E: DomainExtension>(
|
||||||
&self,
|
&self,
|
||||||
domain_type: DomainType,
|
|
||||||
id: impl Display,
|
id: impl Display,
|
||||||
query: &Q,
|
query: &E::DeleteQuery,
|
||||||
) -> Result<()>
|
) -> Result<()> {
|
||||||
where
|
|
||||||
Q: Serialize,
|
|
||||||
{
|
|
||||||
let url = self.object_url(domain_type, id);
|
|
||||||
let request = self
|
let request = self
|
||||||
.http
|
.http
|
||||||
.delete(url)
|
.delete(self.object_url(E::DOMAIN_TYPE, id))
|
||||||
.query(&query)
|
.query(&query)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -368,96 +343,71 @@ impl InnerClient {
|
|||||||
self.invoke_api(request).await
|
self.invoke_api(request).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn bulk_create<O, Q>(
|
pub(crate) async fn bulk_create_domain_objects<E: BulkCreateDomainExtension>(
|
||||||
&self,
|
&self,
|
||||||
domain_type: DomainType,
|
entries: &[E::CreationRequest],
|
||||||
entries: &[O],
|
query: &E::CreationQuery,
|
||||||
query: &Q,
|
) -> Result<()> {
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
O: Serialize,
|
|
||||||
Q: Serialize,
|
|
||||||
{
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct Request<'a, E: Serialize> {
|
struct Request<'a, D: BulkCreateDomainExtension> {
|
||||||
entries: &'a [E],
|
entries: &'a [D::CreationRequest],
|
||||||
}
|
}
|
||||||
let url = self.bulk_action_url(domain_type, BulkAction::Create);
|
|
||||||
let body = Request::<O> { entries };
|
|
||||||
|
|
||||||
let request = self
|
let request = self
|
||||||
.http
|
.http
|
||||||
.post(url)
|
.post(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Create))
|
||||||
.json(&body)
|
.json(&Request::<E> { entries })
|
||||||
.query(query)
|
.query(query)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.invoke_api(request).await
|
self.invoke_api(request).await
|
||||||
}
|
}
|
||||||
|
pub(crate) async fn bulk_read_domain_objects<E: BulkReadDomainExtension>(
|
||||||
pub(crate) async fn bulk_read<O, Q>(
|
|
||||||
&self,
|
&self,
|
||||||
domain_type: DomainType,
|
query: &E::BulkReadQuery,
|
||||||
query: &Q
|
) -> Result<Vec<DomainObject<E>>> {
|
||||||
) -> Result<Vec<DomainObject<O>>>
|
let request = self
|
||||||
where
|
.http
|
||||||
O: DeserializeOwned,
|
.get(self.collection_url(E::DOMAIN_TYPE))
|
||||||
Q: Serialize
|
|
||||||
{
|
|
||||||
let url = self.collection_url(domain_type);
|
|
||||||
let request = self.http
|
|
||||||
.get(url)
|
|
||||||
.query(query)
|
.query(query)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let response: DomainCollection<O> = self.query_api(request).await?;
|
let response: DomainCollection<E> = self.query_api(request).await?;
|
||||||
Ok(response.value)
|
Ok(response.value)
|
||||||
|
|
||||||
}
|
}
|
||||||
pub(crate) async fn bulk_update<O>(
|
pub(crate) async fn bulk_update_domain_objects<E: BulkUpdateDomainExtension>(
|
||||||
&self,
|
&self,
|
||||||
domain_type: DomainType,
|
entries: &[E::BulkUpdateRequest],
|
||||||
entries: &[O],
|
) -> Result<()> {
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
O: Serialize,
|
|
||||||
{
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct Request<'a, E: Serialize> {
|
struct Request<'a, D: BulkUpdateDomainExtension> {
|
||||||
entries: &'a [E],
|
entries: &'a [D::BulkUpdateRequest],
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = self.bulk_action_url(domain_type, BulkAction::Update);
|
|
||||||
let body = Request::<O> { entries };
|
|
||||||
|
|
||||||
let request = self
|
let request = self
|
||||||
.http
|
.http
|
||||||
.put(url)
|
.put(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Update))
|
||||||
.json(&body)
|
.json(&Request::<E> { entries })
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.invoke_api(request).await
|
self.invoke_api(request).await
|
||||||
}
|
}
|
||||||
pub(crate) async fn bulk_delete(
|
pub(crate) async fn bulk_delete_domain_objects<E: BulkDeleteDomainExtension>(
|
||||||
&self,
|
&self,
|
||||||
domain_type: DomainType,
|
entries: &[String],
|
||||||
entries: &[String]
|
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct Request<'a> {
|
struct Request<'a> {
|
||||||
entries: &'a [String],
|
entries: &'a [String],
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = self.bulk_action_url(domain_type, BulkAction::Delete);
|
|
||||||
let body = Request { entries };
|
|
||||||
|
|
||||||
let request = self
|
let request = self
|
||||||
.http
|
.http
|
||||||
.post(url)
|
.post(self.bulk_action_url(E::DOMAIN_TYPE, BulkAction::Delete))
|
||||||
.json(&body)
|
.json(&Request { entries })
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -496,3 +446,63 @@ impl <D> ApiClient<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<D: DomainExtension> From<&Client> for ApiClient<D> {
|
||||||
|
fn from(value: &Client) -> Self {
|
||||||
|
Self::new(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DomainExtension> ApiClient<D> {
|
||||||
|
pub async fn create(
|
||||||
|
&self,
|
||||||
|
request: &D::CreationRequest,
|
||||||
|
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> {
|
||||||
|
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 delete(&self, id: impl Display, query: &D::DeleteQuery) -> Result<()> {
|
||||||
|
self.inner.delete_domain_object::<D>(id, query).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: BulkCreateDomainExtension> ApiClient<D> {
|
||||||
|
pub async fn bulk_create(
|
||||||
|
&self,
|
||||||
|
request: &[D::CreationRequest],
|
||||||
|
query: &D::CreationQuery,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.inner
|
||||||
|
.bulk_create_domain_objects::<D>(request, query)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: BulkReadDomainExtension> ApiClient<D> {
|
||||||
|
pub async fn bulk_read(&self, query: &D::BulkReadQuery) -> 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: BulkUpdateDomainExtension> ApiClient<D> {
|
||||||
|
pub async fn bulk_update(&self, entries: &[D::BulkUpdateRequest]) -> Result<()> {
|
||||||
|
self.inner.bulk_update_domain_objects::<D>(entries).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: BulkDeleteDomainExtension> ApiClient<D> {
|
||||||
|
pub async fn bulk_delete(&self, ids: &[String]) -> Result<()> {
|
||||||
|
self.inner.bulk_delete_domain_objects::<D>(ids).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,5 +2,6 @@ pub mod api;
|
|||||||
mod client;
|
mod client;
|
||||||
mod error;
|
mod error;
|
||||||
|
|
||||||
pub use client::{ApiClient, Client, ClientBuilder};
|
pub(crate) use client::ApiClient;
|
||||||
|
pub use client::{Client, ClientBuilder};
|
||||||
pub use error::{Error, Result};
|
pub use error::{Error, Result};
|
||||||
|
|||||||
250
src/main.rs
250
src/main.rs
@ -8,13 +8,9 @@ const PASSWORD: &str = "C5t71DUPAu2D";
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let log_config = simplelog::ConfigBuilder::new()
|
|
||||||
.set_location_level(simplelog::LevelFilter::Error)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
simplelog::TermLogger::init(
|
simplelog::TermLogger::init(
|
||||||
simplelog::LevelFilter::Trace,
|
simplelog::LevelFilter::Trace,
|
||||||
log_config,
|
simplelog::Config::default(),
|
||||||
simplelog::TerminalMode::Stderr,
|
simplelog::TerminalMode::Stderr,
|
||||||
simplelog::ColorChoice::Auto,
|
simplelog::ColorChoice::Auto,
|
||||||
)
|
)
|
||||||
@ -29,12 +25,7 @@ async fn main() -> Result<()> {
|
|||||||
|
|
||||||
test_folders(client.clone()).await?;
|
test_folders(client.clone()).await?;
|
||||||
test_hosts(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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,12 +46,12 @@ async fn test_folders(client: Client) -> Result<()> {
|
|||||||
|
|
||||||
info!("creating testfolder");
|
info!("creating testfolder");
|
||||||
folderapi
|
folderapi
|
||||||
.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:?}");
|
||||||
@ -145,242 +136,9 @@ async fn test_hosts(client: Client) -> Result<()> {
|
|||||||
|
|
||||||
info!("deleting host");
|
info!("deleting host");
|
||||||
hostapi
|
hostapi
|
||||||
.delete(TESTHOST)
|
.delete(TESTHOST, &())
|
||||||
.await
|
.await
|
||||||
.inspect_err(|e| error!("failed to delete host: {e}"))?;
|
.inspect_err(|e| error!("failed to delete host: {e}"))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn test_hosttags(client: Client) -> Result<()> {
|
|
||||||
use checkmk_api::api::tags::*;
|
|
||||||
const TESTTAG: &str = "test-tag-group";
|
|
||||||
info!("testing hosttags");
|
|
||||||
|
|
||||||
let tagapi = client.tag_api();
|
|
||||||
let creq = ExtendedTagGroup::new(TESTTAG.to_string(), "Test Tag Group".to_string())
|
|
||||||
.with_topic("Testing".to_string())
|
|
||||||
.with_help("A test tag group".to_string())
|
|
||||||
.with_tag(Tag::new("test1".to_string(), "Test Tag 1".to_string()))
|
|
||||||
.with_tag(Tag::new("test2".to_string(), "Test Tag 2".to_string()));
|
|
||||||
|
|
||||||
let ureq = TagUpdateRequest::new("Updated Test Tag Group".to_string(), false)
|
|
||||||
.with_topic("Updated Testing".to_string())
|
|
||||||
.with_help("An updated test tag group".to_string())
|
|
||||||
.with_tag(Tag::new("test3".to_string(), "Test Tag 3".to_string()));
|
|
||||||
|
|
||||||
info!("creating test tag group");
|
|
||||||
tagapi
|
|
||||||
.create(&creq)
|
|
||||||
.await
|
|
||||||
.inspect_err(|e| error!("failed to create tag group: {e}"))?;
|
|
||||||
|
|
||||||
let tag_group = tagapi
|
|
||||||
.read(TESTTAG)
|
|
||||||
.await
|
|
||||||
.inspect_err(|e| error!("failed to read tag group: {e}"))?;
|
|
||||||
info!("tag group config: {tag_group:#?}");
|
|
||||||
|
|
||||||
info!("updating tag group");
|
|
||||||
tagapi
|
|
||||||
.update(TESTTAG, &ureq)
|
|
||||||
.await
|
|
||||||
.inspect_err(|e| error!("failed to update tag group: {e}"))?;
|
|
||||||
|
|
||||||
let tag_groups = tagapi
|
|
||||||
.bulk_read()
|
|
||||||
.await
|
|
||||||
.inspect_err(|e| error!("failed to read all tag groups: {e}"));
|
|
||||||
info!("all tag groups: {tag_groups:?}");
|
|
||||||
|
|
||||||
info!("deleting tag group");
|
|
||||||
tagapi
|
|
||||||
.delete(TESTTAG)
|
|
||||||
.await
|
|
||||||
.inspect_err(|e| error!("failed to delete tag group: {e}"))?;
|
|
||||||
|
|
||||||
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(())
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user