Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ lum_config = "0.2.3"
lum_libs = { version = "0.2.4", features = ["serde"] }
lum_log = "0.2.5"
reqwest = "0.12.19"
serde_yaml_ng = "0.10.0"
thiserror = "2.0.12"
tokio = { version = "1.45.1", features = ["full"] }
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ If your provider is not supported, you can implement your own provider by defini
## Configuration

Documentation coming soon™

See `docs/example-config.yaml` for configuration reference. *dnrs* creates this if no configuration is available at first start.
54 changes: 54 additions & 0 deletions docs/example-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
resolver:
ipv4:
url: https://ip.cancom.io
type: Raw
ipv6:
url: https://ipv6.cancom.io
type: Raw
providers:
- Nitrado:
name: Nitrado1
api_key: your_api_key
api_base_url: https://api.nitrado.net
dns:
- Nitrado:
provider_name: Nitrado1
domains:
- domain: example.com
records:
- !Manual
domain: ipv4
value: !A 127.0.0.1
ttl: 3600
- !Manual
domain: ipv6
value: !AAAA ::1
ttl: 3600
- !Manual
domain: forward
value: !CNAME example.com
ttl: 3600
- !Manual
domain: '@'
value: !MX
priority: 10
target: mail.example.com
ttl: 3600
- !Manual
domain: '@'
value: !TXT v=spf1 include:example.com ~all
ttl: 3600
- !Manual
domain: '@'
value: !Custom
- RecordType
- Value
ttl: 3600
- !Automatic
domain: auto-ipv4
ttl: 300
resolve_type: IPv4
- !Automatic
domain: auto-ipv6
ttl: 300
resolve_type: IPv6
37 changes: 8 additions & 29 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,27 @@ pub mod dns;
pub mod provider;
pub mod resolver;

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(crate = "lum_libs::serde")]
#[serde(default)]
pub struct FileConfig {
resolver: resolver::FileConfig,
providers: Vec<provider::FileConfig>,
dns: Vec<dns::FileConfig>,
}

impl Default for FileConfig {
fn default() -> Self {
FileConfig {
resolver: resolver::FileConfig::default(),
providers: vec![provider::FileConfig::default()],
dns: vec![dns::FileConfig::default()],
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(crate = "lum_libs::serde")]
#[serde(default)]
pub struct Config {
pub resolver: resolver::FileConfig,
pub providers: Vec<provider::FileConfig>,
pub dns: Vec<dns::FileConfig>,
pub resolver: resolver::Config,
pub providers: Vec<provider::Config>,
pub dns: Vec<dns::Config>,
}

impl Default for Config {
fn default() -> Self {
let file_config = FileConfig::default();

Config {
resolver: file_config.resolver,
providers: file_config.providers,
dns: file_config.dns,
resolver: resolver::Config::default(),
providers: vec![provider::Config::default()],
dns: vec![dns::Config::default()],
}
}
}

impl MergeFrom<FileConfig> for Config {
fn merge_from(self, other: FileConfig) -> Self {
impl MergeFrom<Self> for Config {
fn merge_from(self, other: Self) -> Self {
Self {
resolver: other.resolver,
providers: other.providers,
Expand Down
6 changes: 3 additions & 3 deletions src/config/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ pub enum ResolveType {

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(crate = "lum_libs::serde")]
pub struct FileConfig {
pub struct Config {
#[serde(flatten)]
pub dns: Type,
}

impl Default for FileConfig {
impl Default for Config {
fn default() -> Self {
FileConfig {
Config {
dns: Type::Nitrado(nitrado::DnsConfig::default()),
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/config/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ pub enum Provider {

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(crate = "lum_libs::serde")]
pub struct FileConfig {
pub struct Config {
#[serde(flatten)]
pub provider: Provider,
}

impl Default for FileConfig {
impl Default for Config {
fn default() -> Self {
FileConfig {
Config {
provider: Provider::Nitrado(nitrado::ProviderConfig::default()),
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/config/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ pub struct IpResolver {

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(crate = "lum_libs::serde")]
pub struct FileConfig {
pub struct Config {
pub ipv4: IpResolver,
pub ipv6: IpResolver,
}

impl Default for FileConfig {
impl Default for Config {
fn default() -> Self {
FileConfig {
Config {
ipv4: IpResolver {
url: "https://ip.cancom.io".to_string(),
type_: IpResolverType::Raw,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod provider;
pub mod resolver;
pub mod types;

pub use config::{Config, FileConfig};
pub use config::Config;
pub use logger::setup_logger;

pub const PROGRAM_NAME: &str = env!("CARGO_PKG_NAME");
Expand Down
44 changes: 38 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::fmt::{self, Debug};
use std::fs::{self, File};

use dnrs::{Config, FileConfig, RuntimeError, run, setup_logger};
use lum_config::{
ConfigPathError, EnvironmentConfigParseError, FileConfigParseError, FileHandler, merge,
};
use dnrs::{Config, RuntimeError, run, setup_logger};
use lum_config::{ConfigPathError, EnvironmentConfigParseError, FileConfigParseError, merge};
use lum_log::info;
use lum_log::{error, log::SetLoggerError};
use thiserror::Error;

Expand Down Expand Up @@ -52,6 +52,15 @@ enum Error {
#[error("Failed to load file config: {0}")]
FileHandler(#[from] ConfigPathError),

#[error("YAML config error: {0}")]
YamlConfig(#[from] serde_yaml_ng::Error),

#[error("IO error: {0}")]
Io(#[from] std::io::Error),

#[error("Unable to determine config directory")]
NoConfigDirectory,

#[error("Runtime error: {0}")]
Runtime(#[from] RuntimeError),
}
Expand All @@ -67,10 +76,33 @@ impl Debug for Error {
async fn main() -> Result<(), Error> {
setup_logger()?;

let file_config: FileConfig = FileHandler::new(APP_NAME, None, None)?.load_config()?;
let config_path = dirs::config_dir()
.ok_or(Error::NoConfigDirectory)?
.join(APP_NAME)
.join("config.yaml");

let mut loaded_config: Option<Config> = None;
if config_path.exists() {
let file = File::open(&config_path)?;
loaded_config = Some(serde_yaml_ng::from_reader(file)?);
}
let config_existed = loaded_config.is_some();

let config = Config::default();
let config = merge(config, file_config);
let config = match loaded_config {
Some(loaded_config) => merge(config, loaded_config),
None => config,
};

if let Some(parent) = config_path.parent() {
fs::create_dir_all(parent)?;
}
let file = File::create(&config_path)?;
serde_yaml_ng::to_writer(file, &config)?;

if !config_existed {
info!("Created default config file at: {}", config_path.display());
}

run(config).await?;
Ok(())
Expand Down
20 changes: 19 additions & 1 deletion src/provider/nitrado.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use thiserror::Error;
use crate::{
config::dns::{AutomaticRecordConfig, RecordConfig, ResolveType},
provider::{self, Feature, Provider},
types::dns::{self, Record, RecordValue},
types::dns::{self, MxRecord, Record, RecordValue},
};

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -72,6 +72,24 @@ impl Default for DnsConfig {
value: RecordValue::CNAME("example.com".to_string()),
ttl: Some(3600),
}),
RecordConfig::Manual(dns::Record {
domain: "@".to_string(),
value: RecordValue::MX(MxRecord {
priority: 10,
target: "mail.example.com".to_string(),
}),
ttl: Some(3600),
}),
RecordConfig::Manual(dns::Record {
domain: "@".to_string(),
value: RecordValue::TXT("v=spf1 include:example.com ~all".to_string()),
ttl: Some(3600),
}),
RecordConfig::Manual(dns::Record {
domain: "@".to_string(),
value: RecordValue::Custom("RecordType".to_string(), "Value".to_string()),
ttl: Some(3600),
}),
RecordConfig::Automatic(AutomaticRecordConfig {
domain: "auto-ipv4".to_string(),
ttl: Some(300),
Expand Down
Loading