use std::{path::Path, time::Duration};
use anyhow::Context;
use crate::secret_string::SecretString;
#[derive(serde::Deserialize, Clone, Debug)]
#[serde(tag = "version")]
pub enum ConfigFile {
#[serde(rename = "1")]
V1(ConfigFileV1),
}
impl ConfigFile {
#[must_use]
pub fn v1(&self) -> &ConfigFileV1 {
let ConfigFile::V1(config_file) = self;
config_file
}
}
impl ConfigFile {
pub fn from_yaml(yaml: &str) -> serde_yaml::Result<Self> {
serde_yaml::from_str::<Self>(yaml)
}
pub fn from_yaml_reader<Rdr: std::io::Read>(reader: Rdr) -> serde_yaml::Result<Self> {
serde_yaml::from_reader::<Rdr, Self>(reader)
}
pub fn load_from_yaml(path: &Path) -> anyhow::Result<Self> {
if !path.is_file() {
return Err(anyhow::Error::msg("Path not a file"));
}
let file_content = std::fs::read(path).with_context(|| "Could not load config file")?;
let file_content =
std::str::from_utf8(&file_content).with_context(|| "Config file is not utf8")?;
Self::from_yaml(file_content).with_context(|| "Could not parse config file")
}
}
#[derive(serde::Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ConfigFileV1 {
pub routers: Vec<Router>,
}
#[derive(serde::Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Router {
pub username: String,
pub password: SecretString,
pub http_endpoint: url::Url,
pub name: Option<String>,
#[serde(default)]
pub cert_validation: crate::mikrotik_api::CertValidation,
#[serde(with = "humantime_serde", default)]
pub connect_timeout: Option<Duration>,
#[serde(with = "humantime_serde", default)]
pub total_timeout: Option<Duration>,
#[serde(default)]
pub prometheus_exporter: ExporterConfig,
}
#[derive(serde::Deserialize, Clone, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct ExporterConfig {
#[serde(default)]
pub enabled: bool,
}