chore: improve error handling
This commit is contained in:
parent
d715d3d408
commit
3e1152edfe
48
src/main.rs
48
src/main.rs
|
@ -56,12 +56,12 @@ async fn main() -> Result<()> {
|
||||||
|
|
||||||
let config_string = read_to_string("/etc/cloudflare-ddns-service/config.yaml")
|
let config_string = read_to_string("/etc/cloudflare-ddns-service/config.yaml")
|
||||||
.context("couldn't read config file!")?;
|
.context("couldn't read config file!")?;
|
||||||
let config: Config = from_str(&config_string)?;
|
let config: Config = from_str(&config_string).context("Failed to parse config file")?;
|
||||||
let cache_dir = PathBuf::from("/var/cache/cloudflare-ddns-service");
|
let cache_dir = PathBuf::from("/var/cache/cloudflare-ddns-service");
|
||||||
let cache_path = cache_dir.join("cache.yaml");
|
let cache_path = cache_dir.join("cache.yaml");
|
||||||
let mut cache = match read_to_string(&cache_path) {
|
let mut cache = match read_to_string(&cache_path).map(|str| from_str(&str)) {
|
||||||
Ok(cache) => from_str(&cache)?,
|
Ok(Ok(cache)) => cache,
|
||||||
Err(_) => {
|
_ => {
|
||||||
create_dir_all(cache_dir)?;
|
create_dir_all(cache_dir)?;
|
||||||
Cache::default()
|
Cache::default()
|
||||||
}
|
}
|
||||||
|
@ -75,10 +75,13 @@ async fn main() -> Result<()> {
|
||||||
},
|
},
|
||||||
HttpApiClientConfig::default(),
|
HttpApiClientConfig::default(),
|
||||||
Environment::Production,
|
Environment::Production,
|
||||||
)?;
|
)
|
||||||
let zone = get_zone(config.zone.clone(), &mut cf_client).await?;
|
.context("Failed to initiate cloudflare API client")?;
|
||||||
|
let zone = get_zone(config.zone.clone(), &mut cf_client)
|
||||||
|
.await
|
||||||
|
.context("Failed to get zone")?;
|
||||||
loop {
|
loop {
|
||||||
update(
|
if let Err(error) = update(
|
||||||
&config,
|
&config,
|
||||||
&mut cache,
|
&mut cache,
|
||||||
&cache_path,
|
&cache_path,
|
||||||
|
@ -86,7 +89,10 @@ async fn main() -> Result<()> {
|
||||||
&mut reqw_client,
|
&mut reqw_client,
|
||||||
&mut cf_client,
|
&mut cf_client,
|
||||||
)
|
)
|
||||||
.await?;
|
.await
|
||||||
|
{
|
||||||
|
log::error!("Failed to update record: {}", error);
|
||||||
|
}
|
||||||
interval.tick().await;
|
interval.tick().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +106,9 @@ async fn update(
|
||||||
cf_client: &mut CfClient,
|
cf_client: &mut CfClient,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if config.ipv4 {
|
if config.ipv4 {
|
||||||
let current = get_current_ipv4(reqw_client).await?;
|
let current = get_current_ipv4(reqw_client)
|
||||||
|
.await
|
||||||
|
.context("Failed to query current IPv4 address")?;
|
||||||
log::debug!("fetched current IP: {}", current.to_string());
|
log::debug!("fetched current IP: {}", current.to_string());
|
||||||
match cache.v4 {
|
match cache.v4 {
|
||||||
Some(old) if old == current => {
|
Some(old) if old == current => {
|
||||||
|
@ -119,14 +127,18 @@ async fn update(
|
||||||
DnsContent::A { content: current },
|
DnsContent::A { content: current },
|
||||||
cf_client,
|
cf_client,
|
||||||
)
|
)
|
||||||
.await?;
|
.await
|
||||||
|
.context("Failed to set DNS record")?;
|
||||||
cache.v4 = Some(current);
|
cache.v4 = Some(current);
|
||||||
write_cache(cache, cache_path)?;
|
write_cache(cache, cache_path)
|
||||||
|
.context("Failed to write current IPv4 address to cache")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.ipv6 {
|
if config.ipv6 {
|
||||||
let current = get_current_ipv6(reqw_client).await?;
|
let current = get_current_ipv6(reqw_client)
|
||||||
|
.await
|
||||||
|
.context("Failed to query current IPv4 address")?;
|
||||||
log::debug!("fetched current IP: {}", current.to_string());
|
log::debug!("fetched current IP: {}", current.to_string());
|
||||||
match cache.v6 {
|
match cache.v6 {
|
||||||
Some(old) if old == current => {
|
Some(old) if old == current => {
|
||||||
|
@ -145,9 +157,11 @@ async fn update(
|
||||||
DnsContent::AAAA { content: current },
|
DnsContent::AAAA { content: current },
|
||||||
cf_client,
|
cf_client,
|
||||||
)
|
)
|
||||||
.await?;
|
.await
|
||||||
|
.context("Failed to set DNS record")?;
|
||||||
cache.v6 = Some(current);
|
cache.v6 = Some(current);
|
||||||
write_cache(cache, cache_path)?;
|
write_cache(cache, cache_path)
|
||||||
|
.context("Failed to write current IPv4 address to cache")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +169,11 @@ async fn update(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_cache(cache: &mut Cache, cache_path: &PathBuf) -> Result<()> {
|
fn write_cache(cache: &mut Cache, cache_path: &PathBuf) -> Result<()> {
|
||||||
to_writer(File::create(cache_path)?, cache)?;
|
to_writer(
|
||||||
|
File::create(cache_path).context("Failed to open cache file for writing")?,
|
||||||
|
cache,
|
||||||
|
)
|
||||||
|
.context("Failed to serialize cache into file")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,22 +35,28 @@ pub async fn get_current_ipv4(client: &mut ReqwClient) -> Result<Ipv4Addr> {
|
||||||
Ok(client
|
Ok(client
|
||||||
.get("https://ipv4.icanhazip.com")
|
.get("https://ipv4.icanhazip.com")
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.await
|
||||||
|
.context("Failed to query current IPv4 from ipv4.icanhazip.com")?
|
||||||
.text()
|
.text()
|
||||||
.await?
|
.await
|
||||||
|
.context("Failed to read text body")?
|
||||||
.trim()
|
.trim()
|
||||||
.parse()?)
|
.parse()
|
||||||
|
.context("Failed to parse IPv4 address returned by ipv4.icanhazip.com")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_current_ipv6(client: &mut ReqwClient) -> Result<Ipv6Addr> {
|
pub async fn get_current_ipv6(client: &mut ReqwClient) -> Result<Ipv6Addr> {
|
||||||
Ok(client
|
Ok(client
|
||||||
.get("https://ipv6.icanhazip.com")
|
.get("https://ipv6.icanhazip.com")
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.await
|
||||||
|
.context("Failed to query current IPv6 from ipv6.icanhazip.com")?
|
||||||
.text()
|
.text()
|
||||||
.await?
|
.await
|
||||||
|
.context("Failed to read text body")?
|
||||||
.trim()
|
.trim()
|
||||||
.parse()?)
|
.parse()
|
||||||
|
.context("Failed to parse IPv6 address returned by ipv6.icanhazip.com")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_zone(domain: String, cf_client: &mut CfClient) -> Result<String> {
|
pub async fn get_zone(domain: String, cf_client: &mut CfClient) -> Result<String> {
|
||||||
|
@ -66,7 +72,8 @@ pub async fn get_zone(domain: String, cf_client: &mut CfClient) -> Result<String
|
||||||
search_match: None,
|
search_match: None,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.await?
|
.await
|
||||||
|
.context("Failed to query zone from cf_client")?
|
||||||
.result[0]
|
.result[0]
|
||||||
.id
|
.id
|
||||||
.clone())
|
.clone())
|
||||||
|
@ -95,9 +102,7 @@ pub async fn get_record(
|
||||||
.context("Couldn't fetch record")?
|
.context("Couldn't fetch record")?
|
||||||
.result
|
.result
|
||||||
.iter()
|
.iter()
|
||||||
.find(|record| {
|
.find(|record| std::mem::discriminant(&record.content) == std::mem::discriminant(&r#type))
|
||||||
std::mem::discriminant(&record.content) == std::mem::discriminant(&r#type)
|
|
||||||
})
|
|
||||||
.context("No matching record found")?
|
.context("No matching record found")?
|
||||||
.id
|
.id
|
||||||
.clone())
|
.clone())
|
||||||
|
|
Loading…
Reference in a new issue