diff --git a/Cargo.lock b/Cargo.lock index 01a2a0a..b59d9c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,6 +181,7 @@ dependencies = [ "serde", "serde_json", "simple_logger", + "strfmt", "tokio", ] @@ -791,6 +792,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "strfmt" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b278b244ef7aa5852b277f52dd0c6cac3a109919e1f6d699adde63251227a30f" + [[package]] name = "syn" version = "1.0.82" diff --git a/Cargo.toml b/Cargo.toml index af284de..98b18ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,5 @@ tokio = { version = "1", features = ["full"] } serde = { version = "1.0.132", features = ["derive"]} serde_json = "1.0" log = { version = "0.4", features = ["std", "serde"] } -simple_logger = "1.16.0" \ No newline at end of file +simple_logger = "1.16.0" +strfmt = "0.1.6" \ No newline at end of file diff --git a/src/go_daddy_ddns/mod.rs b/src/go_daddy_ddns/mod.rs index 6e6933f..33aec2c 100644 --- a/src/go_daddy_ddns/mod.rs +++ b/src/go_daddy_ddns/mod.rs @@ -1,53 +1,17 @@ +use std::collections::HashMap; use std::fs::read_to_string; use std::path::Path; + use log::{debug, info}; +use strfmt::strfmt; -use serde::{Deserialize, Serialize}; - +use crate::go_daddy_ddns::dns_record::{DNSRecord, DNSRecordsHolder}; use crate::ip_handler::get_ip_to_publish; +mod dns_record; + const RECORDS_FILE_NAME: &'static str = "records.json"; -#[derive(Debug, Deserialize)] -struct DNSRecordsHolder { - records: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -struct DNSRecord { - name: String, - record_type: String, - data: Option, - ttl: u32, -} - -#[derive(Debug, Serialize, Deserialize)] -struct DNSRecordCreateTypeName { - data: String, - - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(default)] - port: Option, // SRV Only. - - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(default)] - priority: Option, // MX and SRV only. - - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(default)] - protocol: Option, // SRV only. - - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(default)] - service: Option, // SRV only. - - ttl: u32, - - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(default)] - weight: Option, // SRV only. -} - /// Updates the DNS records if the IP has changed and returns the result of the execution. /// /// # Arguments @@ -62,7 +26,7 @@ pub async fn exec(domain: &str, key: &str, secret: &str) -> Result<(), Box Result<(), Box Vec { /// /// # Arguments /// -/// * `record` - A &DNSRecord holding the record to update. +/// * `record` - A DNSRecord holding the record to update. /// /// * `value` - A &str holding the current WAN ip. /// @@ -101,7 +65,7 @@ fn get_records() -> Vec { /// /// * `secret` - A &str holding the GoDaddy developer secret. async fn update_record( - record: &DNSRecord, + record: DNSRecord, value: &str, domain: &str, key: &str, @@ -110,23 +74,35 @@ async fn update_record( let url = format!( "https://api.godaddy.com/v1/domains/{domain}/records/{record_type}/{name}", domain = domain, - record_type = record.record_type, - name = record.name + record_type = record.record_type.unwrap(), + name = record.name.unwrap() ); let data = match &record.data { - Some(x) => String::from(x), + Some(x) => { + if record.interpolate.is_some() && record.interpolate.unwrap() == true { + let mut vars = HashMap::new(); + vars.insert("ip".to_string(), value); + + strfmt(x, &vars).expect("Error interpolating {ip} from data.") + } else { + String::from(x) + } + } None => String::from(value), }; - let body = vec![DNSRecordCreateTypeName { - data, - port: None, - priority: None, - protocol: None, - service: None, + let body = vec![DNSRecord { + name: None, + record_type: None, + data: Some(data), + port: record.port, + priority: record.priority, + protocol: record.protocol, + service: record.service, ttl: record.ttl, - weight: None, + interpolate: None, + weight: record.weight, }]; let header = format!("sso-key {}:{}", key, secret);