/*
* Copyright (C) 2025 Jonni Liljamo <jonni@liljamo.com>
*
* This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for
* more information.
*/
use std::sync::Arc;
use axum::{
Router,
response::Html,
routing::{get, post},
};
use clap::Parser;
use reqwest::StatusCode;
use tokio::net::TcpListener;
use tower_http::trace::TraceLayer;
use tracing::info;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
mod config;
use config::Config;
mod state;
use state::State;
mod routes;
mod service;
const LICENSE_HTML: &str = include_str!("../static/license.html");
#[derive(Parser)]
#[command(version)]
struct Args {
/// Config file location.
#[arg(short, long, default_value = "./canwa.toml")]
config: String,
/// Don't run the main program, useful for config validation.
#[arg(long)]
dry_run: bool,
}
#[tokio::main]
async fn main() {
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
format!(
"{}=debug,tower_http=debug,axum::rejection=trace",
env!("CARGO_CRATE_NAME")
)
.into()
}),
)
.with(tracing_subscriber::fmt::layer())
.init();
let args: Args = Args::parse();
let config: Config = Config::from_path(&args.config).await.unwrap();
let state: Arc<State> = Arc::new(State::from_config(&config).unwrap());
if args.dry_run {
std::process::exit(0);
}
let router = Router::new()
.route("/", get(|| async { "canwa" }))
.route(
"/license",
get(|| async { (StatusCode::OK, Html::from(LICENSE_HTML)) }),
)
.route(
"/message",
post({
let shared_state = Arc::clone(&state);
move |headers, body| routes::message::message(shared_state, headers, body)
}),
)
.route(
"/alertmanager/v4",
post({
let shared_state = Arc::clone(&state);
move |headers, body| {
routes::alertmanager::alertmanager_v4(shared_state, headers, body)
}
}),
)
.layer(TraceLayer::new_for_http())
.with_state(state);
let addr = format!("{}:{}", config.interface, config.port);
info!(msg="serving http", %addr);
let listener = TcpListener::bind(addr).await.unwrap();
axum::serve(listener, router).await.unwrap();
}