| mod app_state; |
| mod composite_query; |
| mod dbus_client; |
| mod events; |
| mod grpc; |
| mod handlers; |
| #[cfg(feature = "loas3")] |
| mod loas3; |
| mod sensor_database; |
| use crate::grpc::telemetry_server::{load_server_config, BmcTelemetryService}; |
| use crate::grpc::third_party_voyager::machine_telemetry_server::MachineTelemetryServer; |
| |
| use crate::app_state::AppState; |
| use crate::handlers::chassis::chassis_service; |
| use crate::handlers::service_root::service_root; |
| use crate::handlers::xpath::xpath_service; |
| #[cfg(feature = "loas3")] |
| use crate::loas3::loas3::run_secure_server; |
| use axum::{routing::get, Router}; |
| use clap::{arg, Command}; |
| use handlers::chassis::ChassisState; |
| use sensor_database::sensor_database::sensor_database_main::create_sensor_database; |
| use std::sync::Arc; |
| |
| fn cli() -> Command { |
| Command::new("my_server") |
| .about("Starts a server with the specified configuration") |
| .arg( |
| arg!(-c --config <CONFIG> "Streaming telemetry server config textproto file") |
| .default_value("server_config.textproto") |
| .value_parser(clap::value_parser!(String)), |
| ) |
| .arg( |
| arg!(-r --redfish "Run HTTP Redfish server instead of gRPC telemetry server") |
| .required(false) |
| .default_value("false") |
| .action(clap::ArgAction::SetTrue), |
| ) |
| .arg( |
| arg!(-i --insecure "Disables SSL certificate verification") |
| .required(false) |
| .default_value("false") |
| .action(clap::ArgAction::SetTrue), |
| ) |
| .arg( |
| arg!(-k --key <KEY> "Server's private key file name") |
| .required_if_eq("insecure", "false") |
| .value_parser(clap::value_parser!(String)), |
| ) |
| .arg( |
| arg!(-c --cert <CERT> "Server's certificate file name") |
| .required_if_eq("insecure", "false") |
| .value_parser(clap::value_parser!(String)), |
| ) |
| .arg( |
| arg!(-a --cacert <CACERT> "CA certificate chain file name") |
| .required_if_eq("insecure", "false") |
| .value_parser(clap::value_parser!(String)), |
| ) |
| .arg( |
| arg!(-p --policy <POLICY> "Client authentication policy file name") |
| .required_if_eq("insecure", "false") |
| .value_parser(clap::value_parser!(String)), |
| ) |
| .arg( |
| arg!(-s --crls <CRLS> "Certificate Revocation List file name") |
| .required(false) |
| .value_parser(clap::value_parser!(String)), |
| ) |
| .arg( |
| arg!(-P --port <PORT> "Server's listening port number") |
| .required(true) |
| .value_parser(clap::value_parser!(u16)), |
| ) |
| } |
| |
| async fn run_insecure_server( |
| port: u16, |
| app: Router, |
| grpc: MachineTelemetryServer<BmcTelemetryService>, |
| run_redfish: bool, |
| ) -> Result<(), Box<dyn std::error::Error>> { |
| if run_redfish { |
| let addr = format!("127.0.0.1:{port}"); |
| let listener = tokio::net::TcpListener::bind(addr).await.unwrap(); |
| println!("listening on {}", listener.local_addr().unwrap()); |
| axum::serve(listener, app).await.unwrap(); |
| } else { |
| let addr = format!("[::1]:{port}").parse()?; |
| tonic::transport::Server::builder() |
| .add_service(grpc) |
| .serve(addr) |
| .await?; |
| } |
| |
| Ok(()) |
| } |
| |
| #[tokio::main] |
| async fn main() -> Result<(), Box<dyn std::error::Error>> { |
| // env_logger::init(); |
| |
| let matches = cli().get_matches(); |
| |
| let port = matches |
| .get_one::<u16>("port") |
| .expect("required argument") |
| .to_owned(); |
| |
| let chassis_state = ChassisState::default(); |
| let sensor_database = create_sensor_database(1_000, 10_000).await?; |
| let state = Arc::new(AppState { |
| chassis_state, |
| sensor_database, |
| }); |
| |
| let app = Router::new() |
| .route("/redfish/v1", get(service_root)) |
| .nest("/redfish/v1", xpath_service()) |
| .nest("/redfish/v1", chassis_service()) |
| .with_state(state.clone()); |
| |
| let server_config = matches.get_one::<String>("config").unwrap(); |
| let server_config = load_server_config(server_config).unwrap(); |
| // The server_config will not be read at data path, means when data streaming started, the |
| // application will not try to access it anymore |
| let server_config = Arc::new(tokio::sync::RwLock::new(server_config)); |
| let grpc = MachineTelemetryServer::new(BmcTelemetryService { |
| state, |
| server_config, |
| }); |
| |
| if matches.get_flag("insecure") { |
| println!("Running in insecure mode on port {}...", port); |
| run_insecure_server(port, app, grpc, matches.get_flag("redfish")).await |
| } else { |
| #[cfg(feature = "loas3")] |
| { |
| let key = matches.get_one::<String>("key").unwrap(); |
| let cert = matches.get_one::<String>("cert").unwrap(); |
| let cacert = matches.get_one::<String>("cacert").unwrap(); |
| let policy = matches.get_one::<String>("policy").unwrap(); |
| let crls = matches.get_one::<String>("crls").map(|s| s.as_str()); |
| |
| println!("Starting secure server on port {}...", port); |
| println!("Using key file: {}", key); |
| println!("Using certificate file: {}", cert); |
| println!("Using CA certificate file: {}", cacert); |
| println!("Using policy file: {}", policy); |
| run_secure_server( |
| port, |
| key, |
| cert, |
| cacert, |
| policy, |
| crls, |
| app, |
| grpc, |
| matches.get_flag("redfish"), |
| ) |
| .await?; |
| } |
| Ok(()) |
| } |
| } |