Move .env configuration to config.toml
This commit is contained in:
parent
4ba04706b5
commit
f78f735b2c
5 changed files with 128 additions and 40 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -118,7 +118,6 @@ version = "1.1.1-rc.2"
|
|||
dependencies = [
|
||||
"chrono",
|
||||
"confy",
|
||||
"dotenv",
|
||||
"ipnet",
|
||||
"log",
|
||||
"reqwest",
|
||||
|
@ -178,12 +177,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dotenv"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.33"
|
||||
|
|
|
@ -20,6 +20,5 @@ strum_macros = "^0.24.3"
|
|||
log = "^0.4.20"
|
||||
systemd-journal-logger = "^2.1.1"
|
||||
confy = "^0.5.1"
|
||||
dotenv = "^0.15.0"
|
||||
ipnet = "^2.9.0"
|
||||
url = "2.5.0"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::env::VarError;
|
||||
use std::error::Error;
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
|
@ -11,7 +10,7 @@ use serde_derive::{Deserialize, Serialize};
|
|||
use strum_macros::{Display, IntoStaticStr};
|
||||
use systemd_journal_logger::connected_to_journal;
|
||||
use url::ParseError;
|
||||
use crate::config::{ZoneConfig, ZoneEntry};
|
||||
use crate::config::{AppConfig, ZoneConfig, ZoneEntry};
|
||||
|
||||
const API_BASE: &str = "https://api.cloudflare.com/client/v4";
|
||||
|
||||
|
@ -34,8 +33,8 @@ pub(crate) struct CloudflareZone {
|
|||
}
|
||||
|
||||
impl CloudflareZone {
|
||||
pub(crate) fn new(zone: &ZoneConfig) -> Result<Self, VarError> {
|
||||
let key = env::var("CF_API_TOKEN")?;
|
||||
pub(crate) fn new(zone: &ZoneConfig, config: &AppConfig) -> Result<Self, VarError> {
|
||||
let key = config.cloudflare_api_token.clone();
|
||||
Ok(Self {
|
||||
name: zone.name.clone(),
|
||||
email: zone.email.clone(),
|
||||
|
|
|
@ -140,3 +140,47 @@ impl Default for ZoneConfig {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
pub(crate) struct AppConfig {
|
||||
#[serde(alias="cf_api_token")]
|
||||
pub(crate) cloudflare_api_token: String,
|
||||
pub(crate) check_interval_seconds: Option<u16>,
|
||||
pub(crate) uptime_url: Option<String>,
|
||||
}
|
||||
|
||||
impl AppConfig {
|
||||
pub(crate) fn load() -> Result<Self, Box<dyn Error>> {
|
||||
let cfg: Self = match confy::load(env!("CARGO_PKG_NAME"),"config") {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
match connected_to_journal() {
|
||||
true => error!("[ERROR] {e}"),
|
||||
false => eprintln!("[ERROR] {e}")
|
||||
}
|
||||
return Err(Box::new(e));
|
||||
}
|
||||
};
|
||||
|
||||
if cfg.cloudflare_api_token.is_empty() {
|
||||
let err_msg = "Cloudflare api token not specified. The app cannot work without this";
|
||||
match connected_to_journal() {
|
||||
true => error!("[ERROR] {err_msg}"),
|
||||
false => eprintln!("[ERROR] {err_msg}")
|
||||
}
|
||||
panic!("{err_msg}");
|
||||
}
|
||||
|
||||
Ok(cfg)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AppConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
cloudflare_api_token: "".to_owned(),
|
||||
check_interval_seconds: None,
|
||||
uptime_url: None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
109
src/main.rs
109
src/main.rs
|
@ -1,16 +1,15 @@
|
|||
/*use cloudflare_old::{Instance, CloudflareDnsType};*/
|
||||
use reqwest::blocking::get;
|
||||
use std::{env, thread::{sleep}};
|
||||
use std::{thread::{sleep}};
|
||||
use std::error::Error;
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::str::FromStr;
|
||||
use chrono::{Utc, Duration};
|
||||
use dotenv::dotenv;
|
||||
use log::{info, warn, error, LevelFilter};
|
||||
use reqwest::StatusCode;
|
||||
use systemd_journal_logger::{connected_to_journal, JournalLog};
|
||||
use crate::cloudflare::{CloudflareZone, DnsRecordType};
|
||||
use crate::config::{InterfaceConfig, ZoneConfig, ZoneEntry};
|
||||
use crate::config::{AppConfig, InterfaceConfig, ZoneConfig, ZoneEntry};
|
||||
|
||||
mod config;
|
||||
mod cloudflare;
|
||||
|
@ -233,10 +232,10 @@ fn compare_zones(old_zone: &ZoneConfig, new_zone: &ZoneConfig) -> Vec<String> {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
dotenv().ok();
|
||||
JournalLog::new().expect("Systemd-Logger crate error").install().expect("Systemd-Logger crate error");
|
||||
log::set_max_level(LevelFilter::Info);
|
||||
|
||||
let mut config = AppConfig::load().unwrap();
|
||||
let mut ifaces = InterfaceConfig::load().unwrap();
|
||||
let mut zone_cfgs = ZoneConfig::load().unwrap();
|
||||
|
||||
|
@ -248,32 +247,22 @@ fn main() {
|
|||
Err(e) => panic!("{}", e)
|
||||
};
|
||||
|
||||
let reload_interval = match env::var("CHECK_INTERVAL_SECONDS") {
|
||||
Ok(interval_string) => i64::from_str(&interval_string).unwrap_or_else(|e| {
|
||||
let warn_msg = format!("Expected integer number, got '{interval_string}'. Defaulting to 60");
|
||||
match connected_to_journal() {
|
||||
true => warn!("[WARN] {warn_msg}"),
|
||||
false => println!("[WARN] {warn_msg}"),
|
||||
};
|
||||
60
|
||||
}),
|
||||
Err(_) => {
|
||||
let warn_msg = "Reload interval env not set, defaulting to 60";
|
||||
match connected_to_journal() {
|
||||
true => warn!("[WARN] {warn_msg}"),
|
||||
false => println!("[WARN] {warn_msg}"),
|
||||
}
|
||||
60
|
||||
},
|
||||
};
|
||||
let reload_interval = config.check_interval_seconds.unwrap_or_else(|| {
|
||||
let warn_msg = "Reload interval option not set, defaulting to 60";
|
||||
match connected_to_journal() {
|
||||
true => warn!("[WARN] {warn_msg}"),
|
||||
false => println!("[WARN] {warn_msg}"),
|
||||
}
|
||||
60
|
||||
}) as i64;
|
||||
|
||||
loop {
|
||||
now = Utc::now();
|
||||
if now >= start + Duration::seconds(reload_interval) {
|
||||
start = now;
|
||||
|
||||
if let Ok(uptime_url) = env::var("UPTIME_URL") {
|
||||
get(uptime_url);
|
||||
if let Some(uptime_url) = &config.uptime_url {
|
||||
let _ = get(uptime_url);
|
||||
}
|
||||
|
||||
match InterfaceConfig::load() {
|
||||
|
@ -353,10 +342,9 @@ fn main() {
|
|||
|
||||
ifaces = new_cfg
|
||||
}
|
||||
|
||||
},
|
||||
Err(e) => {
|
||||
let err_msg = format!("Unable to load ínterfaces.toml with error: {}", e);
|
||||
let err_msg = format!("Unable to load ínterfaces.toml with error: {e}");
|
||||
match connected_to_journal() {
|
||||
true => error!("[ERROR] {err_msg}"),
|
||||
false => eprintln!("[ERROR] {err_msg}"),
|
||||
|
@ -496,7 +484,72 @@ fn main() {
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let err_msg = format!("Unable to load from zones.d with error: {}", e);
|
||||
let err_msg = format!("Unable to load from zones.d with error: {e}");
|
||||
match connected_to_journal() {
|
||||
true => error!("[ERROR] {err_msg}"),
|
||||
false => eprintln!("[ERROR] {err_msg}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match AppConfig::load() {
|
||||
Ok(new_cfg) => {
|
||||
if config != new_cfg {
|
||||
if config.cloudflare_api_token != new_cfg.cloudflare_api_token {
|
||||
let info_msg = "API token in config.toml changed";
|
||||
match connected_to_journal() {
|
||||
true => info!("[INFO] {info_msg}"),
|
||||
false => println!("[INFO] {info_msg}"),
|
||||
}
|
||||
}
|
||||
|
||||
if config.check_interval_seconds != new_cfg.check_interval_seconds {
|
||||
let info_msg = match config.check_interval_seconds {
|
||||
Some(old_interval) => {
|
||||
match new_cfg.check_interval_seconds {
|
||||
Some(new_interval) => format!("Check interval in config.toml changed from {old_interval}s to {new_interval}s"),
|
||||
None => format!("Check interval in config.toml changed from {old_interval}s to 60s"),
|
||||
}
|
||||
},
|
||||
None => {
|
||||
match new_cfg.check_interval_seconds {
|
||||
Some(new_interval) => format!("Check interval in config.toml changed from 60s to {new_interval}s"),
|
||||
None => "This is a unicorn error, congratulations.".to_owned(),
|
||||
}
|
||||
}
|
||||
};
|
||||
match connected_to_journal() {
|
||||
true => info!("[INFO] {info_msg}"),
|
||||
false => println!("[INFO] {info_msg}"),
|
||||
}
|
||||
}
|
||||
|
||||
if config.uptime_url != new_cfg.uptime_url {
|
||||
let info_msg = match &config.uptime_url {
|
||||
Some(old_url) => {
|
||||
match &new_cfg.uptime_url {
|
||||
Some(new_url) => format!("Uptime URL in config.toml changed from '{old_url}' to '{new_url}'"),
|
||||
None => "Uptime URL in config.toml was removed".to_owned(),
|
||||
}
|
||||
},
|
||||
None => {
|
||||
match &new_cfg.uptime_url {
|
||||
Some(new_url) => format!("Uptime URL '{new_url}' was added to config.toml"),
|
||||
None => "This is a unicorn error, congratulations.".to_owned(),
|
||||
}
|
||||
}
|
||||
};
|
||||
match connected_to_journal() {
|
||||
true => info!("[INFO] {info_msg}"),
|
||||
false => println!("[INFO] {info_msg}"),
|
||||
}
|
||||
}
|
||||
|
||||
config = new_cfg
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let err_msg = format!("Unable to load config.toml with error: {e}");
|
||||
match connected_to_journal() {
|
||||
true => error!("[ERROR] {err_msg}"),
|
||||
false => eprintln!("[ERROR] {err_msg}"),
|
||||
|
@ -506,7 +559,7 @@ fn main() {
|
|||
|
||||
ips.update();
|
||||
for zone in &zone_cfgs {
|
||||
let cf_zone = match CloudflareZone::new(zone) {
|
||||
let cf_zone = match CloudflareZone::new(zone, &config) {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("Cloudflare Token likely not set. Error: {}", e);
|
||||
|
|
Loading…
Reference in a new issue