From ae7643193a5557c4e8eb7806cd0bdea80c4a7895 Mon Sep 17 00:00:00 2001 From: Vincent Stuyck Date: Sun, 11 Jan 2026 17:15:20 +0100 Subject: [PATCH] add tags to api --- src/api/groups.rs | 8 +-- src/api/mod.rs | 3 + src/api/tags.rs | 161 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 src/api/tags.rs diff --git a/src/api/groups.rs b/src/api/groups.rs index 8762b64..72f4791 100644 --- a/src/api/groups.rs +++ b/src/api/groups.rs @@ -17,7 +17,7 @@ pub struct Group { } impl Group { - fn new(name: String, alias: String) -> Self { + pub fn new(name: String, alias: String) -> Self { Self { name, alias } } } @@ -29,7 +29,7 @@ pub struct GroupAlias { } impl GroupAlias { - fn new(alias: String) -> Self { + pub fn new(alias: String) -> Self { Self { alias } } } @@ -42,7 +42,7 @@ pub struct BulkGroupUpdate { } impl BulkGroupUpdate { - fn new(name: String, alias: String) -> Self { + pub fn new(name: String, alias: String) -> Self { Self { name, attributes: GroupAlias::new(alias) @@ -65,7 +65,7 @@ macro_rules! domain_group { } impl $id { - fn new(name: String, alias: String) -> Self { + pub fn new(name: String, alias: String) -> Self { Self(Group::new(name, alias)) } } diff --git a/src/api/mod.rs b/src/api/mod.rs index 482cbb1..231f33b 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -2,6 +2,7 @@ pub mod folders; pub mod hosts; pub mod groups; pub(crate) mod rules; +pub mod tags; use std::fmt; @@ -16,6 +17,7 @@ pub enum DomainType { ContactGroupConfig, HostGroupConfig, ServiceGroupConfig, + HostTagGroup } impl fmt::Display for DomainType { @@ -27,6 +29,7 @@ impl fmt::Display for DomainType { DomainType::ContactGroupConfig => write!(f, "contact_group_config"), DomainType::HostGroupConfig => write!(f, "host_group_config"), DomainType::ServiceGroupConfig => write!(f, "service_group_config"), + DomainType::HostTagGroup => write!(f, "host_tag_group"), } } } diff --git a/src/api/tags.rs b/src/api/tags.rs new file mode 100644 index 0000000..20b59ea --- /dev/null +++ b/src/api/tags.rs @@ -0,0 +1,161 @@ +use serde::{Deserialize, Serialize}; +#[cfg(feature = "schemars")] +use schemars::JsonSchema; + +use crate::api::{BulkReadDomainExtension, DomainExtension, DomainType}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "schemars", derive(JsonSchema))] +pub struct ExtendedTagGroup { + pub id: String, + pub title: String, + #[serde(flatten, default)] + pub inner: TagGroup +} + +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "schemars", derive(JsonSchema))] +pub struct TagGroup { + #[serde(default, skip_serializing_if = "String::is_empty")] + pub topic: String, + #[serde(default, skip_serializing_if = "String::is_empty")] + pub help: String, + pub tags: Vec +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "schemars", derive(JsonSchema))] +pub struct Tag { + pub id: Option, + pub title: String, + pub aux_tags: Vec +} + +impl ExtendedTagGroup { + pub fn new(id: String, title: String) -> Self { + Self { id, title, inner: Default::default() } + } + + pub fn set_topic(&mut self, topic: String) { + self.inner.topic = topic; + } + pub fn with_topic(mut self, topic: String) -> Self { + self.set_topic(topic); + self + } + pub fn set_help(&mut self, help: String) { + self.inner.help = help; + } + pub fn with_help(mut self, help: String) -> Self { + self.set_help(help); + self + } + pub fn add_tag(&mut self, tag: Tag) { + self.inner.tags.push(tag); + } + pub fn with_tag(mut self, tag: Tag) -> Self { + self.add_tag(tag); + self + } +} + +impl Tag { + pub fn new(id: String, title: String) -> Self { + Self { + id: Some(id), + title, + aux_tags: Vec::new() + } + } + pub fn new_default(title: String) -> Self { + Self { + id: None, + title, + aux_tags: Vec::new() + } + } + + pub fn add_aux_tag(&mut self, tag: String) { + self.aux_tags.push(tag); + } + pub fn with_aux_tag(mut self, tag: String) -> Self { + self.add_aux_tag(tag); + self + } +} + +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "schemars", derive(JsonSchema))] +pub struct TagUpdateRequest { + title: String, + #[serde(flatten, default)] + inner: TagGroup, + repair: bool +} + +impl TagUpdateRequest { + pub fn new(title: String, repair: bool) -> Self { + Self { title, repair, inner: Default::default() } + } + + pub fn set_topic(&mut self, topic: String) { + self.inner.topic = topic; + } + pub fn with_topic(mut self, topic: String) -> Self { + self.set_topic(topic); + self + } + pub fn set_help(&mut self, help: String) { + self.inner.help = help; + } + pub fn with_help(mut self, help: String) -> Self { + self.set_help(help); + self + } + pub fn add_tag(&mut self, tag: Tag) { + self.inner.tags.push(tag); + } + pub fn with_tag(mut self, tag: Tag) -> Self { + self.add_tag(tag); + self + } +} + +#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)] +#[cfg_attr(feature = "schemars", derive(JsonSchema))] +pub struct TagDeleteQuery { + repair: bool, + mode: TagDeleteMode +} + +impl TagDeleteQuery { + pub fn new(repair: bool, mode: TagDeleteMode) -> Self { + Self { repair, mode } + } +} + +#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)] +#[cfg_attr(feature = "schemars", derive(JsonSchema))] +pub enum TagDeleteMode { + Abort, + #[default] Delete, + Remove, + Null +} + +impl DomainExtension for TagGroup { + const DOMAIN_TYPE: super::DomainType = DomainType::HostTagGroup; + + type CreationRequest = ExtendedTagGroup; + type CreationQuery = (); + type ReadQuery = (); + type UpdateRequest = TagUpdateRequest; + type DeleteQuery = (); +} + +// TODO: id and title are in the "DomainObject". +// should be added to during query? +// maybe add "with_title_and_id" to DomainExtension, defaulting to no-op? +impl BulkReadDomainExtension for TagGroup { + type BulkReadQuery = (); +}