mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-26 00:24:55 +01:00
158 lines
5.3 KiB
Rust
158 lines
5.3 KiB
Rust
use std::{
|
|
io,
|
|
io::Write,
|
|
path::PathBuf,
|
|
};
|
|
use clap::{App, Arg, crate_version, crate_description, crate_name};
|
|
use std::str::FromStr;
|
|
use diflouroborane::{error::Error};
|
|
use diflouroborane::db::{Databases, Dump};
|
|
use std::net::ToSocketAddrs;
|
|
|
|
mod config;
|
|
|
|
fn main() -> Result<(), Error> {
|
|
tracing_subscriber::fmt::init();
|
|
// Argument parsing
|
|
// values for the name, description and version are pulled from `Cargo.toml`.
|
|
let matches = App::new(crate_name!())
|
|
.about(crate_description!())
|
|
.version(crate_version!())
|
|
.arg(Arg::with_name("config")
|
|
.help("Path to the config file to use")
|
|
.long("config")
|
|
.short("c")
|
|
.takes_value(true
|
|
))
|
|
.arg(Arg::with_name("print default")
|
|
.help("Print a default config to stdout instead of running")
|
|
.long("print-default")
|
|
)
|
|
.arg(Arg::with_name("check config")
|
|
.help("Check config for validity")
|
|
.long("check")
|
|
)
|
|
.arg(Arg::with_name("dump")
|
|
.help("Dump all internal databases")
|
|
.long("dump")
|
|
.conflicts_with("load")
|
|
)
|
|
.arg(Arg::with_name("load")
|
|
.help("Load values into the internal databases")
|
|
.long("load")
|
|
.conflicts_with("dump")
|
|
)
|
|
.get_matches();
|
|
|
|
// Check for the --print-default option first because we don't need to do anything else in that
|
|
// case.
|
|
if matches.is_present("print default") {
|
|
let config = config::Config::default();
|
|
let encoded = serde_dhall::serialize(&config).to_string().unwrap();
|
|
|
|
// 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(&encoded.as_bytes()).unwrap();
|
|
|
|
// Early return to exit.
|
|
return Ok(());
|
|
} else if matches.is_present("check config") {
|
|
let configpath = matches.value_of("config").unwrap_or("/etc/diflouroborane.dhall");
|
|
match config::read(&PathBuf::from_str(configpath).unwrap()) {
|
|
Ok(_) => {
|
|
//TODO: print a normalized version of the supplied config
|
|
println!("config is valid");
|
|
std::process::exit(0);
|
|
}
|
|
Err(e) => {
|
|
eprintln!("{}", e);
|
|
std::process::exit(-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// If no `config` option is given use a preset default.
|
|
let configpath = matches.value_of("config").unwrap_or("/etc/diflouroborane.dhall");
|
|
let config = config::read(&PathBuf::from_str(configpath).unwrap())
|
|
.expect("Failed to parse config");
|
|
println!("{:#?}", config);
|
|
|
|
let mut sockaddrs = Vec::new();
|
|
for listen in config.listens {
|
|
match listen.to_socket_addrs() {
|
|
Ok(addrs) => {
|
|
sockaddrs.extend(addrs)
|
|
},
|
|
Err(e) => {
|
|
tracing::error!("Invalid listen \"{}\" {}", listen, e);
|
|
}
|
|
}
|
|
}
|
|
|
|
println!("Final listens: {:?}", sockaddrs);
|
|
|
|
let dbs = Databases::create(config.db_path)?;
|
|
|
|
if matches.is_present("dump") {
|
|
let dump = Dump::new(&dbs)?;
|
|
let encoded = serde_json::to_vec(&dump).unwrap();
|
|
|
|
// 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(&encoded).unwrap();
|
|
}
|
|
/*
|
|
} else if matches.is_present("load") {
|
|
let db = db::Databases::new(&log, &config)?;
|
|
let mut dir = PathBuf::from(matches.value_of_os("load").unwrap());
|
|
|
|
dir.push("users.toml");
|
|
let map = db::user::load_file(&dir)?;
|
|
for (uid,user) in map.iter() {
|
|
db.userdb.put_user(uid, user)?;
|
|
}
|
|
tracing::debug!("Loaded users: {:?}", map);
|
|
dir.pop();
|
|
|
|
Ok(())
|
|
} else {
|
|
let ex = smol::Executor::new();
|
|
let db = db::Databases::new(&log, &config)?;
|
|
|
|
let machines = machine::load(&config)?;
|
|
let (actor_map, actors) = actor::load(&log, &config)?;
|
|
let (init_map, initiators) = initiator::load(&log, &config, db.userdb.clone(), db.access.clone())?;
|
|
|
|
let mut network = network::Network::new(machines, actor_map, init_map);
|
|
|
|
for (a,b) in config.actor_connections.iter() {
|
|
if let Err(e) = network.connect_actor(a,b) {
|
|
tracing::error!("{}", e);
|
|
}
|
|
tracing::info!("[Actor] Connected {} to {}", a, b);
|
|
}
|
|
|
|
for (a,b) in config.init_connections.iter() {
|
|
if let Err(e) = network.connect_init(a,b) {
|
|
tracing::error!("{}", e);
|
|
}
|
|
tracing::info!("[Initi] Connected {} to {}", a, b);
|
|
}
|
|
|
|
for actor in actors.into_iter() {
|
|
ex.spawn(actor).detach();
|
|
}
|
|
for init in initiators.into_iter() {
|
|
ex.spawn(init).detach();
|
|
}
|
|
|
|
server::serve_api_connections(log.clone(), config, db, network, ex)
|
|
}
|
|
*/
|
|
|
|
Ok(())
|
|
} |