feat: add dns.rs
This commit is contained in:
42
src/acme.rs
42
src/acme.rs
@@ -4,11 +4,10 @@ use std::collections::BTreeMap;
|
||||
use acme_lib::{Directory, create_p256_key, create_p384_key, create_rsa_key};
|
||||
use acme_lib::persist::FilePersist;
|
||||
use rust_util::XResult;
|
||||
use aliyun_openapi_core_rust_sdk::RPClient;
|
||||
use crate::util::parse_dns_record;
|
||||
use crate::network::{get_resolver, resolve_first_ipv4};
|
||||
use crate::ali_dns::{add_txt_dns_record, build_dns_client, delete_dns_record, list_dns, simple_parse_aliyun_supplier};
|
||||
use crate::config::{AcmeChallenge, AcmeMode};
|
||||
use crate::dns::{DnsClient, DnsClientFactory, DnsRecord};
|
||||
use crate::x509::{X509PublicKeyAlgo, X509EcPublicKeyAlgo};
|
||||
|
||||
|
||||
@@ -64,9 +63,9 @@ pub fn request_acme_certificate(acme_request: AcmeRequest, dns_cleaned_domains:
|
||||
let dir = opt_result!(Directory::from_url(persist, url), "Create directory from url failed: {}");
|
||||
let acc = opt_result!(dir.account(acme_request.contract_email), "Directory set account failed: {}");
|
||||
let mut ord_new = opt_result!( acc.new_order(acme_request.primary_name, acme_request.alt_names), "Create order failed: {}");
|
||||
let ali_yun_client: Option<RPClient> = match acme_request.credential_supplier {
|
||||
Some(credential_supplier) => Some(build_dns_client(
|
||||
&opt_result!(simple_parse_aliyun_supplier(credential_supplier), "Parse credential supplier failed: {}"))),
|
||||
let mut dns_client: Option<Box<dyn DnsClient>> = match acme_request.credential_supplier {
|
||||
Some(credential_supplier) => Some(
|
||||
opt_result!(DnsClientFactory::build(credential_supplier), "Build dns client failed: {}")),
|
||||
None => None,
|
||||
};
|
||||
|
||||
@@ -107,18 +106,16 @@ pub fn request_acme_certificate(acme_request: AcmeRequest, dns_cleaned_domains:
|
||||
if !dns_cleaned_domains.contains(&rr_and_domain.1) {
|
||||
information!("Clearing domain: {}", &rr_and_domain.1);
|
||||
dns_cleaned_domains.push(rr_and_domain.1.clone());
|
||||
ali_yun_client.as_ref().map(|client| {
|
||||
match list_dns(client, &rr_and_domain.1) {
|
||||
dns_client.as_mut().map(|client| {
|
||||
match client.list_dns(&rr_and_domain.1) {
|
||||
Err(e) => warning!("List dns for: {}, failed: {}", &rr_and_domain.1, e),
|
||||
Ok(Err(e)) => warning!("List dns for: {}, failed: {:?}", &rr_and_domain.1, e),
|
||||
Ok(Ok(s)) => {
|
||||
for r in &s.domain_records.record {
|
||||
Ok(records) => {
|
||||
for r in &records {
|
||||
let rr = &r.rr;
|
||||
if rr == "_acme-challenge" || rr.starts_with("_acme-challenge.") {
|
||||
match delete_dns_record(client, &r.record_id) {
|
||||
Err(e) => warning!("Delete dns: {}.{}, failed: {}", r.rr, r.domain_name, e),
|
||||
Ok(Err(e)) => warning!("Delete dns: {}.{}, failed: {:?}", r.rr, r.domain_name, e),
|
||||
Ok(Ok(_)) => success!("Delete dns: {}.{}", r.rr, r.domain_name),
|
||||
match client.delete_dns_record(&r.id) {
|
||||
Err(e) => warning!("Delete dns: {}.{}, failed: {}", r.rr, r.domain, e),
|
||||
Ok(_) => success!("Delete dns: {}.{}", r.rr, r.domain),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,13 +124,18 @@ pub fn request_acme_certificate(acme_request: AcmeRequest, dns_cleaned_domains:
|
||||
});
|
||||
}
|
||||
|
||||
match &ali_yun_client {
|
||||
match &mut dns_client {
|
||||
Some(client) => {
|
||||
let add_txt_dns_result = opt_result!(add_txt_dns_record(client, &rr_and_domain.1, &rr_and_domain.0, &proof), "Add DNS TXT record failed: {}");
|
||||
match add_txt_dns_result {
|
||||
Ok(s) => success!("Add dns txt record successes: {}", s.record_id),
|
||||
Err(e) => return simple_error!("Add dns txt record failed: {:?}", e),
|
||||
}
|
||||
let dns_record = DnsRecord {
|
||||
id: String::new(),
|
||||
domain: rr_and_domain.1,
|
||||
rr: rr_and_domain.0,
|
||||
r#type: "TXT".into(),
|
||||
ttl: -1,
|
||||
value: proof,
|
||||
};
|
||||
let _ = opt_result!(client.add_dns_record(&dns_record), "Add DNS TXT record failed: {}");
|
||||
success!("Add dns txt record successes: {}.{} -> {}", dns_record.rr, dns_record.domain, dns_record.value);
|
||||
}
|
||||
None => if acme_request.allow_interact {
|
||||
let mut line = String::new();
|
||||
|
||||
@@ -1,10 +1,53 @@
|
||||
use rust_util::XResult;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use aliyun_openapi_core_rust_sdk::RPClient;
|
||||
use crate::dns::DnsClient;
|
||||
|
||||
static ALI_DNS_ENDPOINT: &str = "https://alidns.aliyuncs.com";
|
||||
static ALI_DNS_API_VERSION: &str = "2015-01-09";
|
||||
|
||||
pub struct AlibabaCloudDnsClient {
|
||||
client: RPClient,
|
||||
}
|
||||
|
||||
impl AlibabaCloudDnsClient {
|
||||
pub fn build(supplier: &str) -> XResult<AlibabaCloudDnsClient> {
|
||||
let access_credential = simple_parse_aliyun_supplier(supplier)?;
|
||||
Ok(AlibabaCloudDnsClient {
|
||||
client: build_dns_client(&access_credential)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl DnsClient for AlibabaCloudDnsClient {
|
||||
fn list_dns(&mut self, domain: &str) -> XResult<Vec<crate::dns::DnsRecord>> {
|
||||
let list_dns_response = opt_result!(list_dns(&self.client, domain)?, "List dns records failed: {:?}");
|
||||
let mut dns_records = vec![];
|
||||
list_dns_response.domain_records.record.into_iter().for_each(|record| {
|
||||
dns_records.push(crate::dns::DnsRecord {
|
||||
id: record.record_id,
|
||||
domain: record.domain_name,
|
||||
rr: record.rr,
|
||||
r#type: record.r#type,
|
||||
ttl: record.ttl,
|
||||
value: record.value,
|
||||
});
|
||||
});
|
||||
Ok(dns_records)
|
||||
}
|
||||
|
||||
fn delete_dns_record(&mut self, record_id: &str) -> XResult<()> {
|
||||
opt_result!(delete_dns_record(&self.client, record_id)?, "Delete dns record failed: {:?}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_dns_record(&mut self, dns_record: &crate::dns::DnsRecord) -> XResult<()> {
|
||||
let _ = opt_result!(add_dns_record(&self.client, &dns_record.domain, &dns_record.rr, &dns_record.r#type, &dns_record.value),
|
||||
"Add dns record failed: {}");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AccessCredential {
|
||||
access_key_id: String,
|
||||
@@ -111,9 +154,9 @@ pub fn delete_dns_record(client: &RPClient, record_id: &str) -> XResult<Result<C
|
||||
parse_result("DeleteDomainRecord", &delete_domain_record_response)
|
||||
}
|
||||
|
||||
pub fn add_txt_dns_record(client: &RPClient, domain: &str, rr: &str, value: &str) -> XResult<Result<CommonSuccessResponse, CommonErrorResponse>> {
|
||||
add_dns_record(client, domain, rr, "TXT", value)
|
||||
}
|
||||
// pub fn add_txt_dns_record(client: &RPClient, domain: &str, rr: &str, value: &str) -> XResult<Result<CommonSuccessResponse, CommonErrorResponse>> {
|
||||
// add_dns_record(client, domain, rr, "TXT", value)
|
||||
// }
|
||||
|
||||
// domain -> "example.com"
|
||||
// rr -> "@", "_acme-challenge"
|
||||
|
||||
30
src/dns.rs
Normal file
30
src/dns.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use rust_util::XResult;
|
||||
use crate::ali_dns::AlibabaCloudDnsClient;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct DnsRecord {
|
||||
pub id: String,
|
||||
pub domain: String,
|
||||
pub rr: String,
|
||||
pub r#type: String,
|
||||
pub ttl: i32,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
pub trait DnsClient {
|
||||
fn list_dns(&mut self, domain: &str) -> XResult<Vec<DnsRecord>>;
|
||||
|
||||
fn delete_dns_record(&mut self, record_id: &str) -> XResult<()>;
|
||||
|
||||
fn add_dns_record(&mut self, dns_record: &DnsRecord) -> XResult<()>;
|
||||
}
|
||||
|
||||
pub struct DnsClientFactory {}
|
||||
|
||||
impl DnsClientFactory {
|
||||
pub fn build(supplier: &str) -> XResult<Box<dyn DnsClient>> {
|
||||
Ok(Box::new(AlibabaCloudDnsClient::build(supplier)?))
|
||||
//simple_error!("Build dns client failed: {}", supplier)
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ mod x509;
|
||||
mod network;
|
||||
mod statics;
|
||||
mod dingtalk;
|
||||
mod dns;
|
||||
mod ali_dns;
|
||||
// mod simple_thread_pool;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user