nazrin/nzr-api/src/config.rs
2024-08-15 19:25:24 -07:00

166 lines
4.7 KiB
Rust

use std::path::PathBuf;
use figment::{
providers::{Env, Format, Json, Toml},
Figment, Metadata, Provider,
};
use hickory_proto::rr::Name;
use serde::{Deserialize, Serialize};
/// libvirt storage pool configuration
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StorageConfig {
/// The primary storage pool, allocated to all VMs.
pub primary_pool: String,
/// The secondary storage pool, allocated to any VMs that require slower storage.
pub secondary_pool: String,
/// Pool containing cloud-init base images.
pub base_image_pool: String,
}
/// Provides the basic SOA (Start-of-Authority) for the internal DNS zone.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SOAConfig {
pub nzr_domain: Name,
pub contact: Name,
pub refresh: i32,
pub retry: i32,
pub expire: i32,
}
/// DNS server configuration.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DNSConfig {
pub listen_addr: String,
pub port: u16,
pub default_zone: Name,
pub soa: SOAConfig,
}
/// DHCP server configuration.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DHCPConfig {
pub listen_addr: String,
pub port: u16,
}
/// Cloud-init configuration, used by omyacid.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CloudConfig {
pub listen_addr: String,
pub port: u16,
pub http_addr: Option<String>,
pub admin_user: String,
}
impl CloudConfig {
pub fn http_addr(&self) -> String {
if let Some(http_addr) = &self.http_addr {
if http_addr.ends_with('/') {
http_addr.clone()
} else {
format!("{}/", http_addr)
}
} else {
format!("http://{}:{}/", self.listen_addr, self.port)
}
}
}
/// Server<->Client RPC configuration.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RPCConfig {
pub socket_path: PathBuf,
pub admin_group: Option<String>,
}
/// The root configuration struct.
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
pub rpc: RPCConfig,
pub log_level: String,
/// Where database information should be stored.
pub db_uri: String,
pub qemu_img_path: Option<PathBuf>,
/// The libvirt URI to use for connections; e.g. `qemu:///system`.
pub libvirt_uri: String,
pub storage: StorageConfig,
pub dns: DNSConfig,
pub dhcp: DHCPConfig,
pub cloud: CloudConfig,
}
impl Default for Config {
fn default() -> Self {
Self {
log_level: "WARN".to_owned(),
qemu_img_path: None,
rpc: RPCConfig {
socket_path: PathBuf::from("/var/run/nazrin/nzrd.sock"),
admin_group: None,
},
db_uri: "sqlite:/var/lib/nazrin/main_sql.db".to_owned(),
libvirt_uri: match std::env::var("LIBVIRT_URI") {
Ok(v) => v,
Err(_) => String::from("qemu:///system"),
},
storage: StorageConfig {
primary_pool: "pri".to_owned(),
secondary_pool: "data".to_owned(),
base_image_pool: "images".to_owned(),
},
dns: DNSConfig {
listen_addr: "127.0.0.1".to_owned(),
port: 5353,
default_zone: Name::from_utf8("servers.local").unwrap(),
soa: SOAConfig {
nzr_domain: Name::from_utf8("nzr.local").unwrap(),
contact: Name::from_utf8("admin.nzr.local").unwrap(),
refresh: 86400,
retry: 7200,
expire: 3_600_000,
},
},
dhcp: DHCPConfig {
listen_addr: "127.0.0.1".to_owned(),
port: 67,
},
cloud: CloudConfig {
listen_addr: "0.0.0.0".to_owned(),
port: 80,
http_addr: None,
admin_user: "admin".to_owned(),
},
}
}
}
impl Provider for Config {
fn metadata(&self) -> figment::Metadata {
Metadata::named("Nazrin config")
}
fn data(
&self,
) -> Result<figment::value::Map<figment::Profile, figment::value::Dict>, figment::Error> {
figment::providers::Serialized::defaults(Config::default()).data()
}
fn profile(&self) -> Option<figment::Profile> {
None
}
}
impl Config {
pub fn figment() -> Figment {
let mut fig = Figment::from(Config::default()).merge(Toml::file("/etc/nazrin.conf"));
#[allow(deprecated)]
if let Some(mut home) = std::env::home_dir() {
home.push(".nazrin.conf");
fig = fig.merge(Json::file(home));
}
fig.merge(Env::prefixed("NZR_"))
}
}