use async_trait::async_trait;
use serde::Serialize;
use super::{DnsError, DnsProvider, TxtHandle};
pub struct ChallTestSrvDns {
base_url: String,
http: reqwest::Client,
}
impl ChallTestSrvDns {
pub fn new(base_url: impl Into<String>) -> Self {
Self { base_url: base_url.into(), http: reqwest::Client::new() }
}
}
#[derive(Serialize)]
struct SetTxt<'a> {
host: &'a str,
value: &'a str,
}
#[derive(Serialize)]
struct ClearTxt<'a> {
host: &'a str,
}
#[async_trait]
impl DnsProvider for ChallTestSrvDns {
async fn add_txt(&self, name: &str, value: &str) -> Result<TxtHandle, DnsError> {
let host = fqdn(name);
self.http
.post(format!("{}/set-txt", self.base_url))
.json(&SetTxt { host: &host, value })
.send()
.await
.map_err(|e| DnsError::Api(e.to_string()))?
.error_for_status()
.map_err(|e| DnsError::Api(e.to_string()))?;
Ok(TxtHandle {
name: name.to_string(),
value: value.to_string(),
provider_ref: String::new(),
})
}
async fn remove_txt(&self, handle: &TxtHandle) -> Result<(), DnsError> {
let host = fqdn(&handle.name);
self.http
.post(format!("{}/clear-txt", self.base_url))
.json(&ClearTxt { host: &host })
.send()
.await
.map_err(|e| DnsError::Api(e.to_string()))?
.error_for_status()
.map_err(|e| DnsError::Api(e.to_string()))?;
Ok(())
}
}
fn fqdn(name: &str) -> String {
if name.ends_with('.') {
name.to_string()
} else {
format!("{name}.")
}
}