A cloudflare backed DDNS service written in Rust
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
4.0 KiB

use yaml_rust::{Yaml, YamlLoader};
use std::error::Error;
use std::fmt;
pub struct ServerConfig {
pub host: String,
pub port: i64,
pub workers: i64,
}
pub struct CloudflareDomainConfig {
pub domain: String,
pub zone_id: String,
}
pub struct CloudflareConfig {
pub domains: Vec<CloudflareDomainConfig>,
pub key: String,
}
pub struct DDNSDomain {
pub domain: String,
pub subdomains: Vec<String>,
}
pub struct DDNSConfig {
pub domains: Vec<DDNSDomain>
}
pub struct Config {
pub server: ServerConfig,
pub cloudflare: CloudflareConfig,
pub ddns: DDNSConfig,
}
fn get_default_config() -> Config {
Config {
server: ServerConfig {
host: String::from("localhost"),
port: 8080,
workers: 4
},
cloudflare: CloudflareConfig {
key: String::from("IAmNotAKey"),
domains: vec![
CloudflareDomainConfig {
domain: String::from("IAmNotADomain.com"),
zone_id: String::from("IAmNotAZoneID")
}
]
},
ddns: DDNSConfig {
domains: vec![
DDNSDomain {
domain: String::from("IAmNotADomain.com"),
subdomains: vec![
String::from("ddns")
]
}
]
}
}
}
#[derive(Debug)]
pub struct ConfigError;
impl Error for ConfigError {}
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Configuration Error")
}
}
fn create_server_config_from_yaml(yaml: &Yaml) -> Result<ServerConfig, ConfigError> {
Result::Ok(ServerConfig {
host: String::from(yaml["host"].as_str().unwrap()),
port: yaml["port"].as_i64().unwrap(),
workers: yaml["workers"].as_i64().unwrap(),
})
}
fn create_cloudflare_domain_config_from_yaml(yaml: &Yaml) -> Result<CloudflareDomainConfig, ConfigError> {
Result::Ok(CloudflareDomainConfig {
domain: String::from(yaml["domain"].as_str().unwrap()),
zone_id: String::from(yaml["zone_id"].as_str().unwrap()),
})
}
fn create_cloudflare_config_from_yaml(yaml: &Yaml) -> Result<CloudflareConfig, ConfigError> {
Result::Ok(CloudflareConfig {
key: String::from(yaml["key"].as_str().unwrap()),
domains: yaml["domains"].as_vec().unwrap().into_iter().map(|y| create_cloudflare_domain_config_from_yaml(&y).unwrap()).collect(),
})
}
fn create_ddns_domain_config_from_yaml(yaml: &Yaml) -> Result<DDNSDomain, ConfigError> {
Result::Ok(DDNSDomain {
domain: String::from(yaml["domain"].as_str().unwrap()),
subdomains: yaml["subdomains"].as_vec().unwrap().into_iter().map(|y| String::from(y.as_str().unwrap())).collect(),
})
}
fn create_ddns_config_from_yaml(yaml: &Yaml) -> Result<DDNSConfig, ConfigError> {
Result::Ok(DDNSConfig {
domains: yaml["domains"].as_vec().unwrap().into_iter().map(|y| create_ddns_domain_config_from_yaml(&y).unwrap()).collect()
})
}
fn create_config_from_yaml(config_yaml: Vec<Yaml>) -> Result<Config, ConfigError> {
let config = &config_yaml[0];
let server_config = match create_server_config_from_yaml(&config["server"]) {
Ok(v) => v,
Err(e) => return Result::Err(e)
};
let cloudflare_config = match create_cloudflare_config_from_yaml(&config["cloudflare"]) {
Ok(v) => v,
Err(e) => return Result::Err(e)
};
let ddns_config = match create_ddns_config_from_yaml(&config["ddns"]) {
Ok(v) => v,
Err(e) => return Result::Err(e)
};
Result::Ok(Config {
server: server_config,
cloudflare: cloudflare_config,
ddns: ddns_config,
})
}
pub fn load_config(path: &str) -> Result<Config, ConfigError> {
let yaml_load = YamlLoader::load_from_str(path);
match yaml_load {
Ok(config_yaml) => create_config_from_yaml(config_yaml),
Err(_e) => Result::Err(ConfigError{})
}
}