forked from NationTech/harmony
170 lines
4.1 KiB
Rust
170 lines
4.1 KiB
Rust
use std::sync::Arc;
|
|
|
|
use async_trait::async_trait;
|
|
use log::debug;
|
|
use serde::Serialize;
|
|
use strum::{Display, EnumString};
|
|
|
|
use crate::{
|
|
data::{Id, Version},
|
|
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
|
inventory::Inventory,
|
|
modules::monitoring::ntfy::helm::ntfy_helm_chart::ntfy_helm_chart_score,
|
|
score::Score,
|
|
topology::{HelmCommand, K8sclient, Topology, k8s::K8sClient},
|
|
};
|
|
|
|
#[derive(Debug, Clone, Serialize)]
|
|
pub struct NtfyScore {
|
|
pub namespace: String,
|
|
}
|
|
|
|
impl<T: Topology + HelmCommand + K8sclient> Score<T> for NtfyScore {
|
|
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
|
Box::new(NtfyInterpret {
|
|
score: self.clone(),
|
|
})
|
|
}
|
|
|
|
fn name(&self) -> String {
|
|
format!("Ntfy")
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct NtfyInterpret {
|
|
pub score: NtfyScore,
|
|
}
|
|
|
|
#[derive(Debug, EnumString, Display)]
|
|
enum NtfyAccessMode {
|
|
#[strum(serialize = "read-write", serialize = "rw", to_string = "read-write")]
|
|
ReadWrite,
|
|
#[strum(
|
|
serialize = "read-only",
|
|
serialize = "ro",
|
|
serialize = "read",
|
|
to_string = "read-only"
|
|
)]
|
|
ReadOnly,
|
|
#[strum(
|
|
serialize = "write-only",
|
|
serialize = "wo",
|
|
serialize = "write",
|
|
to_string = "write-only"
|
|
)]
|
|
WriteOnly,
|
|
#[strum(serialize = "none", to_string = "deny")]
|
|
Deny,
|
|
}
|
|
|
|
#[derive(Debug, EnumString, Display)]
|
|
enum NtfyRole {
|
|
#[strum(serialize = "user", to_string = "user")]
|
|
User,
|
|
#[strum(serialize = "admin", to_string = "admin")]
|
|
Admin,
|
|
}
|
|
|
|
impl NtfyInterpret {
|
|
async fn add_user(
|
|
&self,
|
|
k8s_client: Arc<K8sClient>,
|
|
username: &str,
|
|
password: &str,
|
|
role: Option<NtfyRole>,
|
|
) -> Result<(), String> {
|
|
let role = match role {
|
|
Some(r) => r,
|
|
None => NtfyRole::User,
|
|
};
|
|
|
|
k8s_client
|
|
.exec_app(
|
|
"ntfy".to_string(),
|
|
Some(&self.score.namespace),
|
|
vec![
|
|
"sh",
|
|
"-c",
|
|
format!("NTFY_PASSWORD={password} ntfy user add --role={role} {username}")
|
|
.as_str(),
|
|
],
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn set_access(
|
|
&self,
|
|
k8s_client: Arc<K8sClient>,
|
|
username: &str,
|
|
topic: &str,
|
|
mode: NtfyAccessMode,
|
|
) -> Result<(), String> {
|
|
k8s_client
|
|
.exec_app(
|
|
"ntfy".to_string(),
|
|
Some(&self.score.namespace),
|
|
vec![
|
|
"sh",
|
|
"-c",
|
|
format!("ntfy access {username} {topic} {mode}").as_str(),
|
|
],
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// We need a ntfy interpret to wrap the HelmChartScore in order to run the score, and then bootstrap the config inside ntfy
|
|
#[async_trait]
|
|
impl<T: Topology + HelmCommand + K8sclient> Interpret<T> for NtfyInterpret {
|
|
async fn execute(
|
|
&self,
|
|
inventory: &Inventory,
|
|
topology: &T,
|
|
) -> Result<Outcome, InterpretError> {
|
|
ntfy_helm_chart_score(self.score.namespace.clone())
|
|
.create_interpret()
|
|
.execute(inventory, topology)
|
|
.await?;
|
|
|
|
debug!("installed ntfy helm chart");
|
|
let client = topology
|
|
.k8s_client()
|
|
.await
|
|
.expect("couldn't get k8s client");
|
|
|
|
client
|
|
.wait_until_deployment_ready(
|
|
"ntfy".to_string(),
|
|
Some(&self.score.namespace.as_str()),
|
|
None,
|
|
)
|
|
.await?;
|
|
debug!("created k8s client");
|
|
|
|
self.add_user(client, "harmony", "harmony", Some(NtfyRole::Admin))
|
|
.await?;
|
|
|
|
debug!("exec into pod done");
|
|
|
|
Ok(Outcome::success("installed ntfy".to_string()))
|
|
}
|
|
|
|
fn get_name(&self) -> InterpretName {
|
|
todo!()
|
|
}
|
|
fn get_version(&self) -> Version {
|
|
todo!()
|
|
}
|
|
fn get_status(&self) -> InterpretStatus {
|
|
todo!()
|
|
}
|
|
fn get_children(&self) -> Vec<Id> {
|
|
todo!()
|
|
}
|
|
}
|