forked from github-starred/komodo
* start 1.19.1 * deploy 1.19.1-dev-1 * Global Auto Update rustdoc * support stack additional files * deploy 1.19.1-dev-2 * Fe support additional file language detection * fix tsc * Fix: Example code blocks got interpreted as rust code, leading to compilation errors (#743) * Enhanced Server Stats Dashboard with Performance Optimizations (#746) * Improve the layout of server mini stats in the dashboard. - Server stats and tags made siblings for clearer responsibilities - Changed margin to padding - Unreachable indicator made into an overlay of the stats * feat: optimize dashboard server stats with lazy loading and smart server availability checks - Add enabled prop to ServerStatsMini for conditional data fetching - Implement server availability check (only fetch stats for Ok servers, not NotOk/Disabled) - Prevent 500 errors by avoiding API calls to offline servers - Increase polling interval from 10s to 15s and add 5s stale time - Add useMemo for expensive calculations to reduce re-renders - Add conditional overlay rendering for unreachable servers - Only render stats when showServerStats preference is enabled * fix: show disabled servers with overlay instead of hiding component - Maintain consistent layout by showing disabled state overlay - Prevent UX inconsistency where disabled servers disappeared entirely * fix: show button height * feat: add enhance card animations * cleanup * gen types * deploy 1.19.1-dev-3 * add .ini * deploy 1.19.1-dev-4 * simple configure action args as JSON * server enabled actually defaults false * SendAlert via Action / CLI * fix clippy if let string * deploy 1.19.1-dev-5 * improve cli ergonomics * gen types and fix responses formatting * Add RunStackService API implementing `docker compose run` (#732) * Add RunStackService API implementing `docker compose run` * Add working Procedure configuration * Remove `km execute run` alias. Remove redundant ``#[serde(default)]` on `Option`. * Refactor command from `String` to `Vec<String>` * Implement proper shell escaping * bump deps * Update configuration.md - fix typo: "affect" -> "effect" (#747) * clean up SendAlert doc * deploy 1.19.1-dev-6 * env file args won't double pass env file * deploy 1.19.1-dev-7 * Add Enter Key Support for Dialog Confirmations (#750) * start 1.19.1 * deploy 1.19.1-dev-1 * Implement usePromptHotkeys for enhanced dialog interactions and UX * Refactor usePromptHotkeys to enhance confirm button detection and improve UX * Remove forceConfirmDialog prop from ActionWithDialog and related logic for cleaner implementation * Add dialog descriptions to ConfirmUpdate and ActionWithDialog for better clarity and resolve warnings * fix * Restore forceConfirmDialog prop to ActionWithDialog for enhanced confirmation handling * cleanup * Remove conditional className logic from ConfirmButton --------- Co-authored-by: mbecker20 <max@mogh.tech> * Support complex file depency action resolution * get FE compile * deploy 1.19.1-dev-8 * implement additional file dependency configuration * deploy 1.19.1-dev-9 * UI default file dependency None * default additional file requires is None * deploy 1.19.1-dev-10 * rename additional_files => config_files for clarity * deploy 1.19.1-dev-11 * fix skip serializing if None * deploy 1.19.1-dev-12 * stack file dependency toml parsing aliases * fmt * Add: Server Version Mismatch Warnings & Alert System (#748) * start 1.19.1 * deploy 1.19.1-dev-1 * feat: implement version mismatch warnings in server UI - Replace orange warning colors with yellow for better visibility - Add version mismatch detection that shows warnings instead of OK status Implement responsive "VERSION MISMATCH" badge layout - Update server dashboard to include warning counts - Add backend version comparison logic for GetServersSummary * feat: add warning count to server summary and update backup documentation link * feat: add server version mismatch alert handling and update server summary invalidation logic * fix: correct version mismatch alert config and disabled server display - Use send_version_mismatch_alerts instead of send_unreachable_alerts - Show 'Unknown' instead of 'Disabled' for disabled server versions - Remove commented VersionAlert and Alerts UI components - Update version to 1.19.0 * cleanup * Update TypeScript types after merge * cleanup * cleanup * cleanup * Add "ServerVersionMismatch" to alert types * Adjust color classes for warning states and revert server update invalidation logic --------- Co-authored-by: mbecker20 <max@mogh.tech> * backend for build multi registry push support * deploy 1.19.1-dev-13 * build multi registry configuration * deploy 1.19.1-dev-14 * fix invalid tokens JSON * DeployStackIfChanged restarts also update stack.info.deployed_contents * update deployed services comments * deploy 1.19.1-dev-15 * Enhance server monitoring with load average data and new server monitoring table (#761) * add monitoring page * initial table * moving monitoring table to servers * add cpu load average * typeshare doesnt allow tuples * fix GetHistoricalServerStats * add loadAvg to the server monitoring table * improve styling * add load average chart * multiple colors for average loads chart * make load average chart line and non-stacked * cleanup * use server thresholds * cleanup * Change "Dependents:" to "Services:" in config file service dependency selector * deploy 1.19.1-dev-16 * 1.19.1 --------- Co-authored-by: mbecker20 <max@mogh.tech> Co-authored-by: Marcel Pfennig <82059270+MP-Tool@users.noreply.github.com> Co-authored-by: Brian Bradley <brian.bradley.p@gmail.com> Co-authored-by: Ravi Wolter-Krishan <rkn@gedikas.net> Co-authored-by: jack <45038833+jackra1n@users.noreply.github.com>
150 lines
3.8 KiB
Rust
150 lines
3.8 KiB
Rust
use anyhow::{Context, anyhow};
|
|
use formatting::format_serror;
|
|
use futures::{TryStreamExt, stream::FuturesUnordered};
|
|
use komodo_client::{
|
|
api::execute::{SendAlert, TestAlerter},
|
|
entities::{
|
|
alert::{Alert, AlertData, AlertDataVariant, SeverityLevel},
|
|
alerter::Alerter,
|
|
komodo_timestamp,
|
|
permission::PermissionLevel,
|
|
},
|
|
};
|
|
use reqwest::StatusCode;
|
|
use resolver_api::Resolve;
|
|
use serror::AddStatusCodeError;
|
|
|
|
use crate::{
|
|
alert::send_alert_to_alerter, helpers::update::update_update,
|
|
permission::get_check_permissions, resource::list_full_for_user,
|
|
};
|
|
|
|
use super::ExecuteArgs;
|
|
|
|
impl Resolve<ExecuteArgs> for TestAlerter {
|
|
#[instrument(name = "TestAlerter", skip(user, update), fields(user_id = user.id, update_id = update.id))]
|
|
async fn resolve(
|
|
self,
|
|
ExecuteArgs { user, update }: &ExecuteArgs,
|
|
) -> Result<Self::Response, Self::Error> {
|
|
let alerter = get_check_permissions::<Alerter>(
|
|
&self.alerter,
|
|
user,
|
|
PermissionLevel::Execute.into(),
|
|
)
|
|
.await?;
|
|
|
|
let mut update = update.clone();
|
|
|
|
if !alerter.config.enabled {
|
|
update.push_error_log(
|
|
"Test Alerter",
|
|
String::from(
|
|
"Alerter is disabled. Enable the Alerter to send alerts.",
|
|
),
|
|
);
|
|
update.finalize();
|
|
update_update(update.clone()).await?;
|
|
return Ok(update);
|
|
}
|
|
|
|
let ts = komodo_timestamp();
|
|
|
|
let alert = Alert {
|
|
id: Default::default(),
|
|
ts,
|
|
resolved: true,
|
|
level: SeverityLevel::Ok,
|
|
target: update.target.clone(),
|
|
data: AlertData::Test {
|
|
id: alerter.id.clone(),
|
|
name: alerter.name.clone(),
|
|
},
|
|
resolved_ts: Some(ts),
|
|
};
|
|
|
|
if let Err(e) = send_alert_to_alerter(&alerter, &alert).await {
|
|
update.push_error_log("Test Alerter", format_serror(&e.into()));
|
|
} else {
|
|
update.push_simple_log("Test Alerter", String::from("Alert sent successfully. It should be visible at your alerting destination."));
|
|
};
|
|
|
|
update.finalize();
|
|
update_update(update.clone()).await?;
|
|
|
|
Ok(update)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<ExecuteArgs> for SendAlert {
|
|
#[instrument(name = "SendAlert", skip(user, update), fields(user_id = user.id, update_id = update.id))]
|
|
async fn resolve(
|
|
self,
|
|
ExecuteArgs { user, update }: &ExecuteArgs,
|
|
) -> Result<Self::Response, Self::Error> {
|
|
let alerters = list_full_for_user::<Alerter>(
|
|
Default::default(),
|
|
user,
|
|
PermissionLevel::Execute.into(),
|
|
&[],
|
|
)
|
|
.await?
|
|
.into_iter()
|
|
.filter(|a| {
|
|
a.config.enabled
|
|
&& (self.alerters.is_empty()
|
|
|| self.alerters.contains(&a.name)
|
|
|| self.alerters.contains(&a.id))
|
|
&& (a.config.alert_types.is_empty()
|
|
|| a.config.alert_types.contains(&AlertDataVariant::Custom))
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
if alerters.is_empty() {
|
|
return Err(anyhow!(
|
|
"Could not find any valid alerters to send to, this required Execute permissions on the Alerter"
|
|
).status_code(StatusCode::BAD_REQUEST));
|
|
}
|
|
|
|
let mut update = update.clone();
|
|
|
|
let ts = komodo_timestamp();
|
|
|
|
let alert = Alert {
|
|
id: Default::default(),
|
|
ts,
|
|
resolved: true,
|
|
level: self.level,
|
|
target: update.target.clone(),
|
|
data: AlertData::Custom {
|
|
message: self.message,
|
|
details: self.details,
|
|
},
|
|
resolved_ts: Some(ts),
|
|
};
|
|
|
|
update.push_simple_log(
|
|
"Send alert",
|
|
serde_json::to_string_pretty(&alert)
|
|
.context("Failed to serialize alert to JSON")?,
|
|
);
|
|
|
|
if let Err(e) = alerters
|
|
.iter()
|
|
.map(|alerter| send_alert_to_alerter(alerter, &alert))
|
|
.collect::<FuturesUnordered<_>>()
|
|
.try_collect::<Vec<_>>()
|
|
.await
|
|
{
|
|
update.push_error_log("Send Error", format_serror(&e.into()));
|
|
};
|
|
|
|
update.finalize();
|
|
update_update(update.clone()).await?;
|
|
|
|
Ok(update)
|
|
}
|
|
}
|