Skip to content

Commit

Permalink
Ensure app works without notifications, or gitops configured. Fix def…
Browse files Browse the repository at this point in the history
…aults so helm values.yaml with minimal config functions.
  • Loading branch information
slackspace-io committed Apr 6, 2024
1 parent 8270a39 commit 7538cd1
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 117 deletions.
31 changes: 0 additions & 31 deletions charts/slackwatch/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,3 @@ config:
#default schedule is every 2 hours
schedule: "0 0 */2 * *"
data_dir: "/app/slackwatch/data"

notifications:
ntfy:
url: "http://ntfy-server.default:80" # Assumes an 'ntfy-server' available in the 'default' namespace
topic: "slackwatch-test"
token: "slackwatch-ntfy-token"
priority: 1
reminder: "24h"
# ... other notification provider settings

gitops:
- name: "test-repo" # Placeholder name
repository_url: "https://github.com/your-org/test-repo.git"
branch: "main"
access_token_env_name: "TEST_REPO_ACCESS_TOKEN"
commit_message: "Automated commit by slackwatch"
commit_email: "[email protected]"
# ... other GitOps settings

# Custom environment variables for the Slackwatch application
#customEnv:
# # Example of a direct value environment variable
# # EXAMPLE_ENV_VAR: "example_value"
#
# # Environment variables that should be populated from secrets
# # Users can comment out or remove if not needed
# TEST_REPO_ACCESS_TOKEN:
# fromSecret:
# enabled: true
# secretName: "TEST_REPO_ACCESS_TOKEN"
# key: "tokensupersecret"
19 changes: 14 additions & 5 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ use serde_derive::Deserialize;
#[derive(Debug, Deserialize, Clone)]
#[allow(unused)]
pub struct Settings {
pub notifications: Notifications,
#[serde(default)]
pub system: System,
pub gitops: Vec<GitopsConfig>,
pub notifications: Option<Notifications>,
pub gitops: Option<Vec<GitopsConfig>>,
}

impl Default for System {
fn default() -> Self {
System {
schedule: "0 0 6-20/2 * * *".to_string(),
data_dir: "/app/slackwatch/data".to_string(),
}
}
}

#[derive(Debug, Deserialize, Clone)]
Expand All @@ -31,7 +41,7 @@ pub struct GitopsConfig {
#[derive(Debug, Deserialize, Clone)]
#[allow(unused)]
pub struct Notifications {
pub ntfy: Ntfy,
pub ntfy: Option<Ntfy>,
}

#[derive(Debug, Deserialize, Clone)]
Expand All @@ -57,7 +67,7 @@ impl Settings {
.build()?;
//print config
println!("{:?}", s);
s.try_deserialize()
s.try_deserialize::<Settings>().or_else(|e| Err(e))
}
//add clone
}
Expand Down Expand Up @@ -105,7 +115,6 @@ mod tests {
//remove conflicting env var ones for now
assert_eq!(settings.system.data_dir, "/tmp/data");
assert_eq!(settings.gitops[0].name, "example-repo");
assert_eq!(settings.notifications.ntfy.url, "http://ntfy.example.com");
}

#[test]
Expand Down
43 changes: 37 additions & 6 deletions src/gitops/gitops.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::config::Settings;
use crate::config::{GitopsConfig, Ntfy, Settings};
use crate::models::models::Workload;
use futures::FutureExt;
use git2::{
Expand All @@ -12,6 +12,23 @@ use std::path::Path;
use k8s_openapi::api::apps::v1::{Deployment, StatefulSet};
use crate::notifications::ntfy::notify_commit;



fn load_settings() ->Result<Vec<GitopsConfig>, String> {
//get settings
let settings = Settings::new().unwrap_or_else(|err| {
log::error!("Failed to load settings: {}", err);
panic!("Failed to load settings: {}", err);
});
if let Some(gitops_config) = settings.gitops {
return Ok(gitops_config.clone());
} else {
return Err("No Gitops Config Found".to_string());
}

}


fn delete_local_repo() -> Result<(), std::io::Error> {
let local_path = Path::new("/tmp/repos/");
//delete if exists
Expand Down Expand Up @@ -192,12 +209,25 @@ fn push_changes(repo: &Repository, access_token: &str) -> Result<(), git2::Error
}

pub async fn run_git_operations(workload: Workload) -> Result<(), Box<dyn Error>> {
match load_settings() {
Ok(settings) => {
log::info!("Settings: {:?}", settings);
return Ok(run_git_operations_internal(settings, workload).await?);
}
Err(e) => {
log::info!("Failed to load settings: {}", e);
//Create error
return Ok(());
// Handle the error, e.g., by returning or panicking
}
}

let settings = Settings::new().unwrap_or_else(|err| {
log::error!("Failed to load settings: {}", err);
panic!("Failed to load settings: {}", err);
});
for gitops_config in settings.gitops {
async fn run_git_operations_internal(
settings: Vec<GitopsConfig>,
workload: Workload,
) -> Result<(), Box<dyn Error>> {

for gitops_config in settings {
log::info!("Gitops config: {:?}", gitops_config);
log::info!("Workload: {:?}", workload);
if gitops_config.name.as_str() != workload.git_ops_repo.clone().unwrap_or_default().as_str()
Expand Down Expand Up @@ -233,3 +263,4 @@ pub async fn run_git_operations(workload: Workload) -> Result<(), Box<dyn Error>

Ok(())
}
}
193 changes: 118 additions & 75 deletions src/notifications/ntfy.rs
Original file line number Diff line number Diff line change
@@ -1,90 +1,133 @@
use crate::config::Settings;
use dioxus::html::set;
use dioxus::prelude::client;
use dioxus::prelude::server_fn::response::Res;
use crate::config::{Ntfy, Settings};
use crate::models::models::Workload;
use ntfy::payload::{Action, ActionType};
use ntfy::{Auth, Dispatcher, NtfyError, Payload, Priority};
use wasm_bindgen_futures::js_sys::Atomics::load;
use wasm_bindgen_futures::js_sys::Set;


pub async fn notify_commit(workload: &Workload) -> Result<(), NtfyError> {
//get settings
let settings = Settings::new().unwrap();
let token = settings.notifications.ntfy.token;
let topic = settings.notifications.ntfy.topic;
let url = settings.notifications.ntfy.url;

let dispatcher = Dispatcher::builder(&url)
.credentials(Auth::new("", &token)) // Add optional credentials
.build()?; // Build dispatcher

//let action = Action::new(
// ActionType::Http,
// "Acknowledge",
// Url::parse(&url)?,
//);

//make message for payload about new container update
let message = format!(
"Deployment {} has been updated to version {}",
workload.name, workload.latest_version
);

let payload = Payload::new(&topic)
.message(message) // Add optional message
.title(&workload.name) // Add optiona title
.tags(["Update"]) // Add optional tags
.priority(Priority::Default) // Edit priority
//.actions([action]) // Add optional actions
//.click(Url::parse("https://example.com")?) // Add optional clickable url
//.attach(Url::parse("https://example.com/file.jpg")?) // Add optional url attachment
//.delay(Local::now() + Duration::minutes(1)) // Add optional delay
.markdown(true); // Use markdown

match dispatcher.send(&payload).await {
Ok(_) => log::info!("Payload sent successfully."),
Err(e) => log::error!("Failed to send payload: {}", e),
match load_settings() {
Ok(settings) => {
let url = settings.url;
let topic = settings.topic;
let token = settings.token;


let dispatcher = Dispatcher::builder(&url)
.credentials(Auth::new("", &token)) // Add optional credentials
.build()?; // Build dispatcher

//let action = Action::new(
// ActionType::Http,
// "Acknowledge",
// Url::parse(&url)?,
//);

//make message for payload about new container update
let message = format!(
"Deployment {} has been updated to version {}",
workload.name, workload.latest_version
);

let payload = Payload::new(&topic)
.message(message) // Add optional message
.title(&workload.name) // Add optiona title
.tags(["Update"]) // Add optional tags
.priority(Priority::Default) // Edit priority
//.actions([action]) // Add optional actions
//.click(Url::parse("https://example.com")?) // Add optional clickable url
//.attach(Url::parse("https://example.com/file.jpg")?) // Add optional url attachment
//.delay(Local::now() + Duration::minutes(1)) // Add optional delay
.markdown(true); // Use markdown

match dispatcher.send(&payload).await {
Ok(_) => log::info!("Payload sent successfully."),
Err(e) => log::error!("Failed to send payload: {}", e),
}
log::info!("Notification sent");
Ok(())// Proceed with using settings
},
Err(e) => {
log::info!("Failed to load settings: {}", e);
Ok(())
// Handle the error, e.g., by returning or panicking
}
}
log::info!("Notification sent");
Ok(())


}

fn load_settings() ->Result<Ntfy, String> {
//get settings
let settings = Settings::new().unwrap_or_else(|err| {
log::error!("Failed to load settings: {}", err);
panic!("Failed to load settings: {}", err);
});
if let Some(notifications) = settings.notifications {
if let Some(ntfy_config) = notifications.ntfy {
return Ok(ntfy_config.clone());
} else {
return Err("No Ntfy Config Found".to_string());
}
} else {
return Err("No Notifications Config Found".to_string());
}

}

pub async fn send_notification(workload: &Workload) -> Result<(), NtfyError> {
//get settings
let settings = Settings::new().unwrap();
let token = settings.notifications.ntfy.token;
let topic = settings.notifications.ntfy.topic;
let url = settings.notifications.ntfy.url;

let dispatcher = Dispatcher::builder(&url)
.credentials(Auth::new("", &token)) // Add optional credentials
.build()?; // Build dispatcher

//let action = Action::new(
// ActionType::Http,
// "Acknowledge",
// Url::parse(&url)?,
//);

//make message for payload about new container update
let message = format!(
"Update Available: {} From {} to {}",
workload.name, workload.current_version, workload.latest_version
);

let payload = Payload::new(&topic)
.message(message) // Add optional message
.title(&workload.name) // Add optiona title
.tags(["Update"]) // Add optional tags
.priority(Priority::High) // Edit priority
//.actions([action]) // Add optional actions
//.click(Url::parse("https://example.com")?) // Add optional clickable url
//.attach(Url::parse("https://example.com/file.jpg")?) // Add optional url attachment
//.delay(Local::now() + Duration::minutes(1)) // Add optional delay
.markdown(true); // Use markdown

match dispatcher.send(&payload).await {
Ok(_) => log::info!("Payload sent successfully."),
Err(e) => log::error!("Failed to send payload: {}", e),
match load_settings() {
Ok(settings) => {
let url = settings.url;
let topic = settings.topic;
let token = settings.token;

let dispatcher = Dispatcher::builder(&url)
.credentials(Auth::new("", &token)) // Add optional credentials
.build()?; // Build dispatcher

//let action = Action::new(
// ActionType::Http,
// "Acknowledge",
// Url::parse(&url)?,
//);

//make message for payload about new container update
let message = format!(
"Update Available: {} From {} to {}",
workload.name, workload.current_version, workload.latest_version
);

let payload = Payload::new(&topic)
.message(message) // Add optional message
.title(&workload.name) // Add optiona title
.tags(["Update"]) // Add optional tags
.priority(Priority::High) // Edit priority
//.actions([action]) // Add optional actions
//.click(Url::parse("https://example.com")?) // Add optional clickable url
//.attach(Url::parse("https://example.com/file.jpg")?) // Add optional url attachment
//.delay(Local::now() + Duration::minutes(1)) // Add optional delay
.markdown(true); // Use markdown

match dispatcher.send(&payload).await {
Ok(_) => log::info!("Payload sent successfully."),
Err(e) => log::error!("Failed to send payload: {}", e),
}
log::info!("Notification sent");
Ok(()) // Proceed with using settings
},
Err(e) => {
log::info!("Failed to load settings: {}", e);
Ok(()) // Handle the error, e.g., by returning or panicking
// Handle the error, e.g., by returning or panicking
}
}
log::info!("Notification sent");
Ok(())


}

0 comments on commit 7538cd1

Please sign in to comment.