blob: 8b1dc2d0a066fbf78728d086543318f8a7af3c23 [file] [log] [blame]
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
mod app_state;
mod composite_query;
mod dbus_client;
mod grpc;
mod handlers;
#[cfg(feature = "mtls")]
mod mtls;
mod telemetry_source_manager;
use crate::grpc::telemetry_server::{load_server_config, BmcTelemetryService};
use crate::grpc::third_party_voyager::machine_telemetry_server::MachineTelemetryServer;
use crate::app_state::AppState;
#[cfg(feature = "mtls")]
use crate::mtls::mtls::run_secure_server;
use clap::{arg, Command};
use handlers::chassis::ChassisState;
use std::sync::Arc;
use telemetry_source_manager::telemetry_source_manager_api::create_telemetry_source_manager;
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!(-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)),
)
.arg(
arg!(-e --emconfig <EMCONFIG> "EntityManager cofnig files separated by comma")
.required(true)
.value_parser(clap::value_parser!(String)),
)
}
async fn run_insecure_server(
port: u16,
grpc: MachineTelemetryServer<BmcTelemetryService>,
) -> Result<(), Box<dyn std::error::Error>> {
let addr = format!("[::]:{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 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 em_config = matches.get_one::<String>("emconfig").unwrap();
let em_config: Vec<String> = em_config.split(',').map(|s| s.trim().to_string()).collect();
let chassis_state = ChassisState::default();
let telemetry_source_manager =
create_telemetry_source_manager(1_000, 10_000, server_config.clone(), em_config).await?;
let state = Arc::new(AppState {
chassis_state,
telemetry_source_manager,
});
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, grpc).await
} else {
#[cfg(feature = "mtls")]
{
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, grpc).await?;
}
Ok(())
}
}