Compare commits

...

2 Commits

Author SHA1 Message Date
Vincent Stuyck
96402420c1 add bones for change activations 2026-01-11 22:33:03 +01:00
Vincent Stuyck
ae7643193a add tags to api 2026-01-11 17:15:20 +01:00
5 changed files with 222 additions and 8 deletions

44
src/api/activations.rs Normal file
View File

@ -0,0 +1,44 @@
use serde::{Deserialize, Serialize};
use crate::{ApiClient, Client, Result};
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct ChangeActivation;
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct PendingChange;
impl From<&Client> for ApiClient<ChangeActivation> {
fn from(value: &Client) -> Self {
Self::new(value)
}
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct ActivateChangeRequest {
redirect: bool,
sites: Vec<String>,
force_foreign_changes: bool
}
impl ApiClient<ChangeActivation> {
pub async fn activate(&self) -> Result<()> {
todo!()
}
pub async fn await_activation(&self, activation_id: &str) -> Result<()> {
todo!()
}
pub async fn read_current_activations(&self) -> Result<Vec<ChangeActivation>> {
todo!()
}
pub async fn bulk_read_pending_changes(&self) -> Result<Vec<PendingChange>> {
todo!()
}
pub async fn read_activation_status(&self, activation_id: &str) -> Result<ChangeActivation> {
todo!()
}
}

View File

@ -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))
}
}

View File

@ -1,7 +1,9 @@
pub mod activations;
pub mod folders;
pub mod hosts;
pub mod groups;
pub(crate) mod rules;
pub mod tags;
use std::fmt;
@ -16,6 +18,7 @@ pub enum DomainType {
ContactGroupConfig,
HostGroupConfig,
ServiceGroupConfig,
HostTagGroup
}
impl fmt::Display for DomainType {
@ -27,6 +30,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"),
}
}
}

160
src/api/tags.rs Normal file
View File

@ -0,0 +1,160 @@
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<Tag>
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct Tag {
pub id: Option<String>,
pub title: String,
pub aux_tags: Vec<String>
}
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: Option<TagDeleteMode>
}
impl TagDeleteQuery {
pub fn new(repair: bool, mode: Option<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,
}
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 = ();
}

View File

@ -433,20 +433,26 @@ impl Display for BulkAction {
}
}
pub struct ApiClient<D: DomainExtension> {
pub struct ApiClient<D> {
pub(crate) inner: Arc<InnerClient>,
_marker: PhantomData<D>,
}
impl<D: DomainExtension> From<&Client> for ApiClient<D> {
fn from(value: &Client) -> Self {
impl <D> ApiClient<D> {
pub(crate) fn new(inner: &Client) -> Self {
Self {
inner: value.0.clone(),
inner: inner.0.clone(),
_marker: Default::default(),
}
}
}
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,