pub mod dns;
pub mod parameters;
pub mod response;
pub mod zone;
use crate::parameters::DnsRecordType;
use crate::zone::Zone;
use serde::Serialize;
use std::env;
use validator::{Validate, ValidationErrors};
pub const API_PREFIX: &str = "https://api.cloudflare.com/client/v4/";
pub struct Cloudflare {
auth_key: String,
}
impl Cloudflare {
pub fn default(api_key: Option<String>) -> Cloudflare {
match api_key {
Some(value) => Cloudflare { auth_key: value },
None => {
let api_key =
env::var("CLOUDFLARE_API_KEY").expect("CLOUDFLARE_API_KEY was not found");
Cloudflare { auth_key: api_key }
}
}
}
fn make_request(&self, url: String, httpverb: parameters::HttpVerb) -> ureq::Request {
let mut request = if httpverb == parameters::HttpVerb::GET {
ureq::get(&url)
} else if httpverb == parameters::HttpVerb::DELETE {
ureq::delete(&url)
} else {
ureq::post(&url)
};
request
.set("Authorization", &format!("Bearer {}", &self.auth_key))
.set("Content-Type", "application/json");
request
}
pub fn list(self, zone: Zone) -> crate::response::CFResponse {
let mut url = format!("{}zones?", API_PREFIX);
url.push_str(&format!("match={}", zone.search.to_string()));
if let Some(i) = zone.per_page {
url.push_str(&(format!("&per_page={:?}", i)));
}
if let Some(i) = zone.name {
url.push_str(&(format!("&name={}", i)));
}
if let Some(i) = zone.status {
url.push_str(&(format!("&status={}", i)));
}
if let Some(i) = zone.direction {
url.push_str(&(format!("&direction={}", i)));
}
if let Some(i) = zone.order {
url.push_str(&(format!("&order={}", i)));
}
if let Some(i) = zone.account_name {
url.push_str(&(format!("&account.name={}", i)));
}
if let Some(i) = zone.page {
url.push_str(&(format!("&page={}", i)));
}
if let Some(i) = zone.account_id {
url.push_str(&(format!("&account.id={}", i)));
}
println!("{:?}", url);
let response = self.make_request(url, parameters::HttpVerb::GET).call();
println!("{:?}", response);
response
.into_json_deserialize::<crate::response::CFResponse>()
.unwrap()
}
pub fn list_dns_record(
&self,
dns_type: DnsRecordType,
domain_name: &str,
zone: &str,
) -> crate::response::CFResponse {
let mut url = format!("{}zones/{}/dns_records?", API_PREFIX, zone);
url.push_str(&format!("type={}", dns_type.to_string()));
url.push_str(&(format!("&name={}", domain_name)));
let response = self.make_request(url, parameters::HttpVerb::GET).call();
response
.into_json_deserialize::<crate::response::CFResponse>()
.unwrap()
}
pub fn create_dns_record<T: Validate + Serialize>(
&self,
record: T,
zone: &str,
) -> Result<crate::response::CFCreateResponse, ValidationErrors> {
let url = format!("{}zones/{}/dns_records", API_PREFIX, zone);
record.validate()?;
let response = self
.make_request(url, parameters::HttpVerb::POST)
.send_json(ureq::json!(record));
Ok(response
.into_json_deserialize::<crate::response::CFCreateResponse>()
.unwrap())
}
pub fn delete_dns_record(
&self,
zone: &str,
dns_record: &str,
) -> crate::response::CFDeleteResponse {
let url = format!("{}zones/{}/dns_records/{}", API_PREFIX, zone, dns_record);
let response = self.make_request(url, parameters::HttpVerb::DELETE).call();
response
.into_json_deserialize::<crate::response::CFDeleteResponse>()
.unwrap()
}
}