use crate::opaque_error::OpaqueError; use std::env; use tokio::net::TcpListener; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; mod kube_cache; mod mc_server; mod opaque_error; mod packets; mod proxy; mod types; #[tokio::main] async fn main() { // ---- Tracing setup ---- let fmt_layer = tracing_subscriber::fmt::layer() .with_target(false) .with_level(true); let filter_layer = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")); tracing_subscriber::registry() .with(fmt_layer) .with(filter_layer) .with(tracing_error::ErrorLayer::default()) .init(); tracing::info!("mc-ingress"); let revision: &'static str = env!("COMMIT_HASH"); tracing::info!(revision); let cancel_token = tokio_util::sync::CancellationToken::new(); let (api, api_task) = kube_cache::McApi::create(cancel_token.clone()) .await .unwrap(); tracing::info!("initialized kube api"); let config: Config = Default::default(); let listener = TcpListener::bind(config.bind_addr.clone()).await.unwrap(); tracing::info!(bind_addr = config.bind_addr, "started tcp server"); let mut sigterm = match tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) { Ok(x) => x, Err(e) => { tracing::error!(error = ?e, "could not initilaize SIGTERM handling channel!"); return; } }; let mut conn_task = proxy::start_proxy(listener, api, config, cancel_token.clone()); tokio::select! { _ = api_task => { tracing::error!("the MinecraftApi tokio:spawn'ed task ran to completion, which should not happen!"); } _ = &mut conn_task => { tracing::error!("the connection handling tokio:spawn'ed task ran to completion, which should not happen!"); } _ = sigterm.recv() => { tracing::info!("SIGTERM received"); cancel_token.cancel(); let res = conn_task.await; tracing::info!(proxy_task_result = ?res, "shutdown complete"); } } } #[derive(Clone)] struct Config { pub filter_conn: String, pub bind_addr: String, } impl Default for Config { fn default() -> Self { let filter_conn = match env::var("FILTER_CONN") { Ok(x) => x, Err(_) => "(addr == \"10.100.0.1\")".to_string(), }; let bind_addr = match env::var("BIND_ADDR") { Ok(x) => x, Err(_) => "0.0.0.0:25565".to_string(), }; Self { filter_conn, bind_addr, } } }