diff --git a/Cargo.lock b/Cargo.lock index caae4d4..92ad6d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "anyhow" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" + [[package]] name = "atty" version = "0.2.14" @@ -248,6 +254,7 @@ dependencies = [ name = "gandi-rust-dns-updater" version = "0.1.0" dependencies = [ + "anyhow", "directories", "futures", "json", diff --git a/Cargo.toml b/Cargo.toml index 36de4c3..27f1d6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,5 @@ serde = { version = "1.0", features = ["derive"] } directories = "4.0.1" structopt = "0.3.25" tokio = { version = "1.14.0", features = ["full"] } -futures = "0.3.17" \ No newline at end of file +futures = "0.3.17" +anyhow = "1.0" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9b476e2..510ff47 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ -use std::collections::HashMap; use crate::config::Config; -use reqwest::{header, Client, ClientBuilder}; -use std::error::Error; -use structopt::StructOpt; -use tokio; +use anyhow; use futures; +use reqwest::{header, Client, ClientBuilder, StatusCode}; +use std::collections::HashMap; +use structopt::StructOpt; +use tokio::{self, task::JoinHandle}; mod config; mod opts; @@ -13,10 +13,13 @@ fn gandi_api_get(fqdn: &str) -> String { } fn gandi_api_url(fqdn: &str, rrset_name: &str, rrset_type: &str) -> String { - return format!(" https://api.gandi.net/v5/livedns/domains/{}/records/{}/{}", fqdn, rrset_name, rrset_type); + return format!( + " https://api.gandi.net/v5/livedns/domains/{}/records/{}/{}", + fqdn, rrset_name, rrset_type + ); } -fn api_client(api_key: &str) -> Result> { +fn api_client(api_key: &str) -> anyhow::Result { let client_builder = ClientBuilder::new(); let key = format!("Apikey {}", api_key); @@ -31,7 +34,7 @@ fn api_client(api_key: &str) -> Result> { } #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> anyhow::Result<()> { let opts = opts::Opts::from_args(); let conf_path = config::config_path(&opts); println!("Loading config from {:#?}", conf_path); @@ -43,26 +46,40 @@ async fn main() -> Result<(), Box> { let ipv4 = String::from("173.89.215.91"); let ipv6 = String::from("2603:6011:be07:302:79f4:50dd:6abe:be38"); - let mut results = Vec::new(); + let mut results: Vec> = Vec::new(); for entry in &conf.entry { for entry_type in Config::types(entry) { let fqdn = Config::fqdn(&entry, &conf); let url = gandi_api_url(fqdn, entry.name.as_str(), entry_type); - let ip = if entry_type.eq("A") { ipv4.as_str() } else { ipv6.as_str() }; + let ip = if entry_type.eq("A") { + ipv4.as_str() + } else { + ipv6.as_str() + }; let mut map = HashMap::new(); map.insert("rrset_values", ip); let req = client.put(url).json(&map); let task = tokio::task::spawn(async move { - let response = req.send().await?; - return (response.status(), response.text().await?); + match req.send().await { + Ok(response) => ( + response.status(), + response + .text() + .await + .unwrap_or_else(|error| error.to_string()), + ), + Err(error) => ( + StatusCode::IM_A_TEAPOT, error.to_string() + ), + } }); results.push(task); } } - + let results = futures::future::try_join_all(results).await?; - + for (status, body) in results { println!("{} - {}", status, body); }