use std::fmt;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use super::{Fleet, FleetPage, Item};
use crate::{
Error, Result, Scope,
http::{Method, Raw},
pagination::paginated,
request::endpoint,
};
#[derive(Clone, Deserialize, Serialize)]
#[non_exhaustive]
pub struct AgentPolicy {
pub id: String,
pub name: String,
pub namespace: String,
pub revision: u64,
#[serde(default)]
pub description: Option<String>,
#[serde(default)]
pub status: Option<String>,
#[serde(default)]
pub agents: Option<u64>,
#[serde(default)]
pub package_policies: Vec<Value>,
#[serde(flatten)]
pub extra: Map<String, Value>,
}
impl AgentPolicy {
pub fn edit(&self) -> Result<AgentPolicyEdit> {
let timeout = self
.extra
.get("inactivity_timeout")
.and_then(Value::as_u64)
.ok_or_else(|| {
Error::InvalidRequest(
"agent policy edit requires a retrieved inactivity_timeout".into(),
)
})?;
Ok(AgentPolicyEdit {
id: self.id.clone(),
policy: NewAgentPolicy::new(&self.name, &self.namespace).inactivity_timeout(timeout),
})
}
}
impl fmt::Debug for AgentPolicy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AgentPolicy")
.field("id", &self.id)
.field("name", &self.name)
.field("namespace", &self.namespace)
.field("revision", &self.revision)
.field("status", &self.status)
.field("agents", &self.agents)
.field("package_policies", &self.package_policies.len())
.finish_non_exhaustive()
}
}
#[derive(Clone, Debug, Serialize)]
pub struct NewAgentPolicy {
name: String,
namespace: String,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
monitoring_enabled: Option<Vec<String>>,
#[allow(clippy::option_option)]
#[serde(skip_serializing_if = "Option::is_none")]
data_output_id: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
inactivity_timeout: Option<u64>,
}
impl NewAgentPolicy {
pub fn new(name: impl Into<String>, namespace: impl Into<String>) -> Self {
Self {
name: name.into(),
namespace: namespace.into(),
description: None,
monitoring_enabled: None,
data_output_id: None,
inactivity_timeout: None,
}
}
pub fn description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
pub fn monitoring_enabled<I: IntoIterator<Item = S>, S: Into<String>>(
mut self,
kinds: I,
) -> Self {
self.monitoring_enabled = Some(kinds.into_iter().map(Into::into).collect());
self
}
pub fn data_output_id(mut self, id: impl Into<String>) -> Self {
self.data_output_id = Some(Some(id.into()));
self
}
pub fn clear_data_output_id(mut self) -> Self {
self.data_output_id = Some(None);
self
}
pub fn inactivity_timeout(mut self, seconds: u64) -> Self {
self.inactivity_timeout = Some(seconds);
self
}
}
#[derive(Clone, Debug, Serialize)]
pub struct AgentPolicyEdit {
#[serde(skip)]
id: String,
#[serde(flatten)]
policy: NewAgentPolicy,
}
impl AgentPolicyEdit {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.policy.name = name.into();
self
}
pub fn namespace(mut self, namespace: impl Into<String>) -> Self {
self.policy.namespace = namespace.into();
self
}
pub fn description(mut self, description: impl Into<String>) -> Self {
self.policy = self.policy.description(description);
self
}
pub fn monitoring_enabled<I: IntoIterator<Item = S>, S: Into<String>>(
mut self,
kinds: I,
) -> Self {
self.policy = self.policy.monitoring_enabled(kinds);
self
}
pub fn data_output_id(mut self, id: impl Into<String>) -> Self {
self.policy = self.policy.data_output_id(id);
self
}
pub fn clear_data_output_id(mut self) -> Self {
self.policy = self.policy.clear_data_output_id();
self
}
pub fn inactivity_timeout(mut self, seconds: u64) -> Self {
self.policy = self.policy.inactivity_timeout(seconds);
self
}
}
impl<'a> Fleet<'a> {
pub fn find_agent_policies(&self) -> FindAgentPolicies<'a> {
FindAgentPolicies(
self.0
.request(
Method::GET,
Scope::Space,
&["api", "fleet", "agent_policies"],
)
.param("full", true),
)
}
pub fn get_agent_policy(&self, id: &str) -> GetAgentPolicy<'a> {
GetAgentPolicy(self.0.request(
Method::GET,
Scope::Space,
&["api", "fleet", "agent_policies", id],
))
}
pub fn create_agent_policy<B: Serialize + ?Sized>(&self, policy: &B) -> CreateAgentPolicy<'a> {
CreateAgentPolicy(
self.0
.request(
Method::POST,
Scope::Space,
&["api", "fleet", "agent_policies"],
)
.json(policy),
)
}
pub fn update_agent_policy<B: Serialize + ?Sized>(
&self,
id: &str,
policy: &B,
) -> UpdateAgentPolicy<'a> {
UpdateAgentPolicy(
self.0
.request(
Method::PUT,
Scope::Space,
&["api", "fleet", "agent_policies", id],
)
.json(policy)
.check_body_id(id, false),
)
}
pub fn edit_agent_policy(&self, edit: &AgentPolicyEdit) -> UpdateAgentPolicy<'a> {
self.update_agent_policy(&edit.id, edit)
}
pub fn delete_agent_policy(&self, id: &str) -> DeleteAgentPolicy<'a> {
DeleteAgentPolicy(
self.0
.request(
Method::POST,
Scope::Space,
&["api", "fleet", "agent_policies", "delete"],
)
.nonempty("agentPolicyId", id)
.field("agentPolicyId", id),
)
}
pub fn copy_agent_policy(&self, id: &str, name: &str) -> CopyAgentPolicy<'a> {
CopyAgentPolicy(
self.0
.request(
Method::POST,
Scope::Space,
&["api", "fleet", "agent_policies", id, "copy"],
)
.field("name", name),
)
}
pub fn download_agent_policy(&self, id: &str) -> DownloadAgentPolicy<'a> {
DownloadAgentPolicy(self.0.request(
Method::GET,
Scope::Space,
&["api", "fleet", "agent_policies", id, "download"],
))
}
}
endpoint! {
FindAgentPolicies => FleetPage<AgentPolicy>
}
impl FindAgentPolicies<'_> {
pub fn full(self, full: bool) -> Self {
Self(self.0.param("full", full))
}
pub fn with_agent_count(self, enabled: bool) -> Self {
Self(self.0.param("withAgentCount", enabled))
}
}
endpoint! {
GetAgentPolicy => Item<AgentPolicy>
}
endpoint! {
CreateAgentPolicy => Item<AgentPolicy>
}
impl CreateAgentPolicy<'_> {
pub fn sys_monitoring(self, enabled: bool) -> Self {
Self(self.0.param("sys_monitoring", enabled))
}
}
endpoint! {
UpdateAgentPolicy => Item<AgentPolicy>
}
endpoint! {
DeleteAgentPolicy => Value
}
impl DeleteAgentPolicy<'_> {
pub fn force(self, force: bool) -> Self {
Self(self.0.field("force", force))
}
}
endpoint! {
CopyAgentPolicy => Item<AgentPolicy>
}
impl CopyAgentPolicy<'_> {
pub fn description(self, description: &str) -> Self {
Self(self.0.field("description", description))
}
}
endpoint! {
DownloadAgentPolicy => Raw
}
impl DownloadAgentPolicy<'_> {
pub fn standalone(self, enabled: bool) -> Self {
Self(self.0.param("standalone", enabled))
}
pub fn kubernetes(self, enabled: bool) -> Self {
Self(self.0.param("kubernetes", enabled))
}
}
page_setters!(FindAgentPolicies);
sort_setters!(FindAgentPolicies);
paginated!(FindAgentPolicies => FleetPage<AgentPolicy>);