nazrin/nzrd/src/main.rs

101 lines
3.3 KiB
Rust

mod cloud;
mod cmd;
mod ctrl;
mod ctx;
mod dns;
mod img;
mod prelude;
mod rpc;
#[cfg(test)]
mod test;
mod virt;
use crate::ctrl::{net::Subnet, Storable};
use log::LevelFilter;
use log::*;
use nzr_api::config;
use std::str::FromStr;
use tokio::net::UdpSocket;
use trust_dns_server::ServerFuture;
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let cfg: config::Config = config::Config::figment().extract()?;
let ctx = ctx::Context::new(cfg)?;
syslog::init_unix(
syslog::Facility::LOG_DAEMON,
LevelFilter::from_str(ctx.config.log_level.as_str())?,
)?;
info!("Hydrating initial zones...");
for subnet in Subnet::all(ctx.db.clone())? {
match subnet {
Ok(subnet) => {
// A records
if let Err(err) = ctx.zones.new_zone(&subnet).await {
error!("Couldn't create zone for {}: {}", &subnet.ifname, err);
continue;
}
match subnet.leases() {
Ok(leases) => {
for lease in leases {
match lease {
Ok(lease) => {
if let Err(err) = ctx
.zones
.new_record(
&subnet.ifname.to_string(),
&lease.inst_name,
lease.ipv4_addr.addr,
)
.await
{
error!(
"Failed to set up lease for {} in {}: {}",
&lease.inst_name, &subnet.ifname, err
);
}
}
Err(err) => {
warn!(
"Lease iterator error while hydrating {}: {}",
&subnet.ifname, err
);
}
}
}
}
Err(err) => {
error!("Couldn't get leases for {}: {}", &subnet.ifname, err);
continue;
}
}
}
Err(err) => {
warn!("Error while iterating subnets: {}", err);
}
}
}
// DNS init
let mut dns_listener = ServerFuture::new(ctx.zones.catalog());
let dns_socket = UdpSocket::bind(ctx.config.dns.listen_addr.as_str()).await?;
dns_listener.register_socket(dns_socket);
tokio::select! {
res = rpc::serve(ctx.clone(), ctx.zones.clone()) => {
if let Err(err) = res {
error!("Error from RPC: {}", err);
}
},
res = dns_listener.block_until_done() => {
if let Err(err) = res {
error!("Error from DNS: {}", err);
}
}
}
Ok(())
}