104 lines
2.4 KiB
Rust
104 lines
2.4 KiB
Rust
use std::net::SocketAddr;
|
|
use askama::Template;
|
|
use axum::{
|
|
extract::State,
|
|
routing::post,
|
|
http::StatusCode,
|
|
response::{IntoResponse, Response},
|
|
Json, Router,
|
|
};
|
|
use serde::Deserialize;
|
|
|
|
mod jabber;
|
|
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
struct Payload {
|
|
alerts: Vec<Alert>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Template)]
|
|
#[template(path="alert.txt", escape="none")]
|
|
struct Alert {
|
|
status: String,
|
|
labels: AlertLabels,
|
|
annotations: AlertAnnotations,
|
|
#[serde(rename = "generatorURL")]
|
|
generator_url: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
struct AlertLabels {
|
|
alertname: Option<String>,
|
|
host: Option<String>,
|
|
instance: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
struct AlertAnnotations {
|
|
message: Option<String>,
|
|
description: Option<String>,
|
|
}
|
|
|
|
async fn alerts(
|
|
State(jabber): State<jabber::Handle>,
|
|
Json(payload): Json<Payload>,
|
|
) -> Response {
|
|
let mut error_message = None;
|
|
|
|
for alert in payload.alerts {
|
|
match alert.render() {
|
|
Ok(message) => {
|
|
jabber.send_message(message).await;
|
|
}
|
|
Err(e) => {
|
|
error_message = Some(format!("{}", e));
|
|
}
|
|
}
|
|
}
|
|
|
|
match error_message {
|
|
None =>
|
|
StatusCode::OK.into_response(),
|
|
Some(error_message) =>
|
|
(StatusCode::INTERNAL_SERVER_ERROR,
|
|
error_message
|
|
).into_response()
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct Config {
|
|
listen_port: u16,
|
|
jid: String,
|
|
password: String,
|
|
muc: String,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
// initialize tracing
|
|
tracing_subscriber::fmt::init();
|
|
|
|
let config: Config = serde_json::from_str(
|
|
&std::fs::read_to_string(
|
|
std::env::args().nth(1)
|
|
.expect("Call with config.json")
|
|
).expect("read config")
|
|
).expect("parse config");
|
|
let jabber = jabber::run(config.jid, config.password, config.muc).await;
|
|
|
|
// build our application with a route
|
|
let app = Router::new()
|
|
.route("/alert", post(alerts))
|
|
.with_state(jabber);
|
|
|
|
let addr = SocketAddr::from(([127, 0, 0, 1], config.listen_port));
|
|
tracing::debug!("listening on {}", addr);
|
|
let server = axum::Server::bind(&addr)
|
|
.serve(app.into_make_service());
|
|
systemd::daemon::notify(false, [(systemd::daemon::STATE_READY, "1")].iter())
|
|
.unwrap();
|
|
server.await
|
|
.unwrap();
|
|
}
|