mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-22 06:47:56 +01:00
Splitting config
This commit is contained in:
parent
28d90f1078
commit
b02afe5575
@ -56,6 +56,7 @@ ptr_meta = "0.1"
|
||||
rkyv_typename = "0.7"
|
||||
rkyv_dyn = "0.7"
|
||||
inventory = "0.1"
|
||||
linkme = "0.2.10"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
|
||||
# Password hashing for internal users
|
||||
@ -77,7 +78,6 @@ capnp-rpc = "0.14.1"
|
||||
rsasl = { git = "https://github.com/dequbed/rsasl.git", branch = "main", default_features = false, features = ["unstable_custom_mechanism", "provider", "registry_static", "plain"] }
|
||||
desfire = "0.2.0-alpha1"
|
||||
hex = { version = "0.4.3", features = ["serde"] }
|
||||
linkme = "0.2.10"
|
||||
|
||||
futures-signals = "0.3.22"
|
||||
async-oneshot = "0.5"
|
||||
|
59
bffhd/capnp/config.rs
Normal file
59
bffhd/capnp/config.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use std::fmt::Formatter;
|
||||
use std::net::ToSocketAddrs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use crate::config::deser_option;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
/// API Socket Configuration block.
|
||||
///
|
||||
/// One configuration block can result in several sockets if the given `address` resolves to more
|
||||
/// than one SocketAddr. BFFH will attempt to bind to all of them.
|
||||
pub struct Listen {
|
||||
pub address: String,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Option::is_none", deserialize_with = "deser_option")]
|
||||
pub port: Option<u16>,
|
||||
}
|
||||
|
||||
impl Listen {
|
||||
pub fn to_tuple(&self) -> (&str, u16) {
|
||||
(self.address.as_str(), self.port.unwrap_or(DEFAULT_PORT))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Listen {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}:{}", &self.address, self.port.unwrap_or(DEFAULT_PORT))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSocketAddrs for Listen {
|
||||
type Iter = <(String, u16) as ToSocketAddrs>::Iter;
|
||||
|
||||
fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
|
||||
if let Some(port) = self.port {
|
||||
(self.address.as_str(), port).to_socket_addrs()
|
||||
} else {
|
||||
(self.address.as_str(), DEFAULT_PORT).to_socket_addrs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct TlsListen {
|
||||
pub certfile: PathBuf,
|
||||
pub keyfile: PathBuf,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub ciphers: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub tls_min_version: Option<String>,
|
||||
#[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")]
|
||||
pub protocols: Vec<String>,
|
||||
}
|
||||
|
||||
// The default port in the non-assignable i.e. free-use area
|
||||
pub const DEFAULT_PORT: u16 = 59661;
|
@ -1,6 +1,3 @@
|
||||
use crate::config::Listen;
|
||||
|
||||
|
||||
use async_net::TcpListener;
|
||||
|
||||
|
||||
@ -18,13 +15,12 @@ use std::io;
|
||||
|
||||
use std::net::SocketAddr;
|
||||
|
||||
|
||||
use crate::authentication::AuthenticationHandle;
|
||||
|
||||
|
||||
|
||||
use crate::session::SessionManager;
|
||||
|
||||
mod config;
|
||||
pub use config::{Listen, TlsListen};
|
||||
|
||||
mod authenticationsystem;
|
||||
mod connection;
|
||||
mod machine;
|
||||
|
8
bffhd/config/dhall.rs
Normal file
8
bffhd/config/dhall.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use std::path::Path;
|
||||
use crate::Config;
|
||||
|
||||
pub fn read_config_file(path: impl AsRef<Path>) -> Result<Config, serde_dhall::Error> {
|
||||
serde_dhall::from_file(path)
|
||||
.parse()
|
||||
.map_err(Into::into)
|
||||
}
|
@ -6,17 +6,23 @@ use serde::{Serialize, Deserialize};
|
||||
|
||||
use std::fmt::Formatter;
|
||||
use std::net::{ToSocketAddrs};
|
||||
use serde_dhall::{SimpleType};
|
||||
|
||||
|
||||
mod dhall;
|
||||
pub use dhall::read_config_file as read;
|
||||
|
||||
use crate::authorization::permissions::{PrivilegesBuf};
|
||||
use crate::authorization::roles::Role;
|
||||
use crate::capnp::{Listen, TlsListen};
|
||||
use crate::logging::LogConfig;
|
||||
|
||||
type Result<T> = std::result::Result<T, serde_dhall::Error>;
|
||||
pub fn load(path: impl AsRef<Path>, args: &clap::ArgMatches) -> anyhow::Result<Config> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn read(path: &Path) -> Result<Config> {
|
||||
serde_dhall::from_file(path)
|
||||
.parse()
|
||||
.map_err(Into::into)
|
||||
pub struct ConfigBlock {
|
||||
static_type: SimpleType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@ -78,7 +84,7 @@ pub struct Config {
|
||||
pub verbosity: isize,
|
||||
|
||||
#[serde(default, skip)]
|
||||
pub log_format: String,
|
||||
pub logging: LogConfig,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@ -105,49 +111,6 @@ pub(crate) fn deser_option<'de, D, T>(d: D) -> std::result::Result<Option<T>, D:
|
||||
Ok(T::deserialize(d).ok())
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Listen {
|
||||
address: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none", deserialize_with = "deser_option")]
|
||||
port: Option<u16>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct TlsListen {
|
||||
pub certfile: PathBuf,
|
||||
pub keyfile: PathBuf,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub ciphers: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub tls_min_version: Option<String>,
|
||||
#[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")]
|
||||
pub protocols: Vec<String>,
|
||||
}
|
||||
|
||||
impl Listen {
|
||||
pub fn to_tuple(&self) -> (&str, u16) {
|
||||
(self.address.as_str(), self.port.unwrap_or(DEFAULT_PORT))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Listen {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}:{}", &self.address, self.port.unwrap_or(DEFAULT_PORT))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSocketAddrs for Listen {
|
||||
type Iter = <(String, u16) as ToSocketAddrs>::Iter;
|
||||
|
||||
fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
|
||||
if let Some(port) = self.port {
|
||||
(self.address.as_str(), port).to_socket_addrs()
|
||||
} else {
|
||||
(self.address.as_str(), DEFAULT_PORT).to_socket_addrs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
@ -194,10 +157,7 @@ impl Default for Config {
|
||||
|
||||
tlskeylog: None,
|
||||
verbosity: 0,
|
||||
log_format: "Full".to_string(),
|
||||
logging: LogConfig::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The default port in the non-assignable i.e. free-use area
|
||||
pub const DEFAULT_PORT: u16 = 59661;
|
@ -40,7 +40,6 @@ mod session;
|
||||
|
||||
|
||||
|
||||
|
||||
use std::sync::{Arc};
|
||||
|
||||
use anyhow::Context;
|
||||
@ -79,7 +78,7 @@ pub static RESOURCES: OnceCell<ResourcesHandle> = OnceCell::new();
|
||||
|
||||
impl Diflouroborane {
|
||||
pub fn new(config: Config) -> anyhow::Result<Self> {
|
||||
logging::init(&config);
|
||||
logging::init(&config.logging);
|
||||
tracing::info!(version=RELEASE_STRING, "Starting");
|
||||
|
||||
let span = tracing::info_span!("setup");
|
||||
|
@ -1,16 +1,46 @@
|
||||
use tracing_subscriber::{EnvFilter};
|
||||
use crate::Config;
|
||||
|
||||
pub fn init(config: &Config) {
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LogConfig {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
/// Log filter string in the tracing format `target[span{field=value}]=level`.
|
||||
/// lvalue is optional and multiple filters can be combined with comma.
|
||||
/// e.g. `warn,diflouroborane::actors=debug` will only print `WARN` and `ERROR` unless the
|
||||
/// message is logged in a span below `diflouroborane::actors` (i.e. by an actor task) in
|
||||
/// which case `DEBUG` and `INFO` will also be printed.
|
||||
pub filter: Option<String>,
|
||||
|
||||
pub format: String,
|
||||
}
|
||||
|
||||
impl Default for LogConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
filter: None,
|
||||
format: "full".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(config: &LogConfig) {
|
||||
let filter = if let Some(ref filter) = config.filter {
|
||||
EnvFilter::new(filter.as_str())
|
||||
} else {
|
||||
EnvFilter::from_env("BFFH_LOG")
|
||||
};
|
||||
|
||||
let builder = tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env());
|
||||
let format = config.log_format.to_lowercase();
|
||||
.with_env_filter(filter);
|
||||
|
||||
let format = config.format.to_lowercase();
|
||||
match format.as_str() {
|
||||
"compact" => builder.compact().init(),
|
||||
"pretty" => builder.pretty().init(),
|
||||
"full" => builder.init(),
|
||||
_ => builder.init(),
|
||||
}
|
||||
|
||||
tracing::info!(format = format.as_str(), "Logging initialized")
|
||||
}
|
@ -9,7 +9,10 @@ use rkyv_dyn::{DynDeserializer, DynError, DynSerializer};
|
||||
|
||||
|
||||
use crate::utils::oid::ObjectIdentifier;
|
||||
|
||||
// Not using linkme because dynamically loaded modules
|
||||
use inventory;
|
||||
|
||||
use rkyv::ser::{ScratchSpace, Serializer};
|
||||
use serde::de::Error as SerdeError;
|
||||
use serde::ser::SerializeMap;
|
||||
|
@ -8,6 +8,7 @@ use futures_rustls::TlsAcceptor;
|
||||
use rustls::{Certificate, PrivateKey, ServerConfig, SupportedCipherSuite};
|
||||
use rustls::version::{TLS12, TLS13};
|
||||
use tracing::{Level};
|
||||
use crate::capnp::TlsListen;
|
||||
use crate::config;
|
||||
|
||||
use crate::keylog::KeyLogFile;
|
||||
@ -61,7 +62,7 @@ impl TlsConfig {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_tls_acceptor(&self, config: &config::TlsListen) -> anyhow::Result<TlsAcceptor> {
|
||||
pub fn make_tls_acceptor(&self, config: &TlsListen) -> anyhow::Result<TlsAcceptor> {
|
||||
let span = tracing::debug_span!("tls");
|
||||
let _guard = span.enter();
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clap::{Arg, Command};
|
||||
use clap::{Arg, Command, Parser};
|
||||
use diflouroborane::{config, Diflouroborane};
|
||||
|
||||
|
||||
@ -91,16 +91,23 @@ fn main() -> anyhow::Result<()> {
|
||||
// invalidate the generated TOML
|
||||
let stdout = io::stdout();
|
||||
let mut handle = stdout.lock();
|
||||
handle.write_all(&encoded.as_bytes()).unwrap();
|
||||
handle.write_all(encoded.as_bytes()).unwrap();
|
||||
|
||||
// Early return to exit.
|
||||
return Ok(());
|
||||
} else if matches.is_present("check config") {
|
||||
match config::read(&PathBuf::from_str(configpath).unwrap()) {
|
||||
Ok(c) => {
|
||||
println!("{:#?}", c);
|
||||
println!("config is valid");
|
||||
std::process::exit(0);
|
||||
let formatted = format!("{:#?}", c);
|
||||
|
||||
// Direct writing to fd 1 is faster but also prevents any print-formatting that could
|
||||
// invalidate the generated TOML
|
||||
let stdout = io::stdout();
|
||||
let mut handle = stdout.lock();
|
||||
handle.write_all(formatted.as_bytes()).unwrap();
|
||||
|
||||
// Early return to exit.
|
||||
return Ok(());
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("{}", e);
|
||||
@ -140,7 +147,7 @@ fn main() -> anyhow::Result<()> {
|
||||
if config.verbosity == 0 && matches.is_present("quiet") {
|
||||
config.verbosity = -1;
|
||||
}
|
||||
config.log_format = matches.value_of("log format").unwrap_or("Full").to_string();
|
||||
config.logging.format = matches.value_of("log format").unwrap_or("full").to_string();
|
||||
|
||||
let mut bffh = Diflouroborane::new(config)?;
|
||||
bffh.run()?;
|
||||
|
Loading…
Reference in New Issue
Block a user