use serde::Deserialize;
use tracing::error;
use crate::{signals::Shutdown, target::TargetPidReceiver};
pub mod file_gen;
pub mod file_tree;
pub mod grpc;
pub mod http;
pub mod process_tree;
pub mod splunk_hec;
pub mod tcp;
pub mod udp;
pub mod unix_datagram;
pub mod unix_stream;
#[derive(Debug)]
pub enum Error {
Tcp(tcp::Error),
Udp(udp::Error),
Http(http::Error),
SplunkHec(splunk_hec::Error),
FileGen(file_gen::Error),
FileTree(file_tree::Error),
Grpc(grpc::Error),
UnixStream(unix_stream::Error),
UnixDatagram(unix_datagram::Error),
ProcessTree(process_tree::Error),
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub struct Config {
#[serde(flatten)]
pub general: General,
#[serde(flatten)]
pub inner: Inner,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub struct General {
pub id: Option<String>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum Inner {
Tcp(tcp::Config),
Udp(udp::Config),
Http(http::Config),
SplunkHec(splunk_hec::Config),
FileGen(file_gen::Config),
FileTree(file_tree::Config),
Grpc(grpc::Config),
UnixStream(unix_stream::Config),
UnixDatagram(unix_datagram::Config),
ProcessTree(process_tree::Config),
}
#[derive(Debug)]
pub enum Server {
Tcp(tcp::Tcp),
Udp(udp::Udp),
Http(http::Http),
SplunkHec(splunk_hec::SplunkHec),
FileGen(file_gen::FileGen),
FileTree(file_tree::FileTree),
Grpc(grpc::Grpc),
UnixStream(unix_stream::UnixStream),
UnixDatagram(unix_datagram::UnixDatagram),
ProcessTree(process_tree::ProcessTree),
}
impl Server {
pub fn new(config: Config, shutdown: Shutdown) -> Result<Self, Error> {
let srv = match config.inner {
Inner::Tcp(conf) => {
Self::Tcp(tcp::Tcp::new(config.general, &conf, shutdown).map_err(Error::Tcp)?)
}
Inner::Udp(conf) => {
Self::Udp(udp::Udp::new(config.general, &conf, shutdown).map_err(Error::Udp)?)
}
Inner::Http(conf) => {
Self::Http(http::Http::new(config.general, conf, shutdown).map_err(Error::Http)?)
}
Inner::SplunkHec(conf) => Self::SplunkHec(
splunk_hec::SplunkHec::new(config.general, conf, shutdown)
.map_err(Error::SplunkHec)?,
),
Inner::FileGen(conf) => Self::FileGen(
file_gen::FileGen::new(config.general, conf, shutdown).map_err(Error::FileGen)?,
),
Inner::FileTree(conf) => {
Self::FileTree(file_tree::FileTree::new(&conf, shutdown).map_err(Error::FileTree)?)
}
Inner::Grpc(conf) => {
Self::Grpc(grpc::Grpc::new(config.general, conf, shutdown).map_err(Error::Grpc)?)
}
Inner::UnixStream(conf) => Self::UnixStream(
unix_stream::UnixStream::new(config.general, conf, shutdown)
.map_err(Error::UnixStream)?,
),
Inner::UnixDatagram(conf) => Self::UnixDatagram(
unix_datagram::UnixDatagram::new(config.general, &conf, shutdown)
.map_err(Error::UnixDatagram)?,
),
Inner::ProcessTree(conf) => Self::ProcessTree(
process_tree::ProcessTree::new(&conf, shutdown).map_err(Error::ProcessTree)?,
),
};
Ok(srv)
}
pub async fn run(self, mut pid_snd: TargetPidReceiver) -> Result<(), Error> {
let _ = pid_snd.recv().await;
drop(pid_snd);
let res = match self {
Server::Tcp(inner) => inner.spin().await.map_err(Error::Tcp),
Server::Udp(inner) => inner.spin().await.map_err(Error::Udp),
Server::Http(inner) => inner.spin().await.map_err(Error::Http),
Server::SplunkHec(inner) => inner.spin().await.map_err(Error::SplunkHec),
Server::FileGen(inner) => inner.spin().await.map_err(Error::FileGen),
Server::FileTree(inner) => inner.spin().await.map_err(Error::FileTree),
Server::Grpc(inner) => inner.spin().await.map_err(Error::Grpc),
Server::UnixStream(inner) => inner.spin().await.map_err(Error::UnixStream),
Server::UnixDatagram(inner) => inner.spin().await.map_err(Error::UnixDatagram),
Server::ProcessTree(inner) => inner.spin().await.map_err(Error::ProcessTree),
};
if let Err(e) = &res {
error!("Generator error: {:?}", e);
}
res
}
}