use super::Client;
use super::utils::{
de_non_empty_object, de_option_empty_string_as_none, parse_json_response, se_as_json_string,
};
use super::{Error, OPENAPI_STYLE, OPENAPI_VERSION};
use bon::Builder;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use time::OffsetDateTime;
use u_sdk_common::helper::into_header_map;
use u_sdk_common::open_api_sign::{SignParams, get_openapi_request_header};
impl Client {
pub fn list_records(&self) -> ListRecordsBuilder<'_> {
ListRecords::builder(self)
}
pub fn get_record(&self) -> GetRecordBuilder<'_> {
GetRecord::builder(self)
}
pub fn create_record(&self) -> CreateRecordBuilder<'_> {
CreateRecord::builder(self)
}
pub fn delete_record(&self) -> DeleteRecordBuilder<'_> {
DeleteRecord::builder(self)
}
pub fn update_record(&self) -> UpdateRecordBuilder<'_> {
UpdateRecord::builder(self)
}
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Serialize, Builder)]
#[serde(rename_all = "PascalCase")]
pub struct ListRecords<'a> {
#[builder(start_fn)]
#[serde(skip_serializing)]
pub(crate) client: &'a Client,
site_id: i64,
record_name: Option<String>,
record_match_type: Option<RecordMatchType>,
page_number: Option<i32>,
page_size: Option<i32>,
source_type: Option<SourceType>,
biz_name: Option<BizName>,
proxied: Option<bool>,
record_type: Option<DnsRecordType>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum RecordMatchType {
Prefix, Suffix, Exact, Fuzzy, }
#[derive(Debug, Serialize, Deserialize)]
pub enum SourceType {
OSS, S3, LB, OP, Domain, }
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum BizName {
ImageVideo, Api, Web, }
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum DnsRecordType {
#[serde(rename = "A/AAAA")]
AOrAAAA, CNAME, MX, TXT, NS, SRV, CAA, CERT, SMIMEA, SSHFP, TLSA, URI, }
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct ListRecordsResponse {
pub request_id: String,
pub page_number: i32,
pub page_size: i32,
pub total_count: i32,
pub records: Vec<DnsRecord>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct DnsRecord {
#[serde(deserialize_with = "de_option_empty_string_as_none")]
pub biz_name: Option<BizName>,
pub data: DnsData,
#[serde(with = "time::serde::rfc3339")]
pub create_time: OffsetDateTime,
#[serde(with = "time::serde::rfc3339")]
pub update_time: OffsetDateTime,
pub proxied: bool,
pub record_id: i64,
#[serde(deserialize_with = "de_option_empty_string_as_none")]
pub record_source_type: Option<SourceType>,
pub record_name: String,
pub record_type: DnsRecordType,
pub site_id: i64,
pub site_name: String,
pub ttl: i32,
pub record_cname: String,
pub comment: String,
#[serde(default, deserialize_with = "de_non_empty_object")]
pub auth_conf: Option<AuthConf>,
#[serde(deserialize_with = "de_option_empty_string_as_none")]
pub host_policy: Option<HostPolicy>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct DnsData {
pub value: String,
pub priority: Option<i32>,
pub flag: Option<i32>,
pub tags: Option<HashMap<String, String>>,
pub weight: Option<i32>,
pub port: Option<i32>,
pub r#type: Option<i32>,
pub key_tag: Option<i32>,
pub algorithm: Option<i32>,
pub certificate: Option<String>,
pub usage: Option<i32>,
pub selector: Option<i32>,
pub matching_type: Option<i32>,
pub fingerprint: Option<String>,
pub tag: Option<String>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct AuthConf {
pub auth_type: Option<AuthType>,
pub access_key: Option<String>,
pub secret_key: Option<String>,
pub version: Option<String>,
pub region: Option<String>,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum AuthType {
Public, Private, PrivateSameAccount, PrivateCrossAccount, }
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum HostPolicy {
FollowHostname, FollowOriginDomain, }
impl ListRecords<'_> {
pub async fn send(&self) -> Result<ListRecordsResponse, Error> {
let client = self.client;
let creds = client.credentials_provider.load().await?;
let sign_params = SignParams {
req_method: "GET",
host: &client.host,
query_map: self,
x_acs_action: "ListRecords",
x_acs_version: OPENAPI_VERSION,
x_acs_security_token: creds.sts_security_token.as_deref(),
request_body: None,
style: &OPENAPI_STYLE,
};
let (common_headers, url_) =
get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
.map_err(|e| {
Error::Common(format!("failed to get openapi request header: {}", e))
})?;
let header_map = into_header_map(common_headers);
let resp = client
.http_client
.get(url_)
.headers(header_map)
.send()
.await?;
let data = parse_json_response(resp).await?;
Ok(data)
}
}
#[derive(Builder, Debug)]
pub struct GetRecord<'a> {
#[builder(start_fn)]
pub(crate) client: &'a Client,
pub(crate) record_id: i64,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct GetRecordResponse {
pub request_id: String,
pub record_model: DnsRecord,
}
impl GetRecord<'_> {
pub async fn send(&self) -> Result<GetRecordResponse, Error> {
let client = self.client;
let creds = client.credentials_provider.load().await?;
let sign_params = SignParams {
req_method: "GET",
host: &client.host,
query_map: HashMap::from([("RecordId", self.record_id)]),
x_acs_action: "GetRecord",
x_acs_version: OPENAPI_VERSION,
x_acs_security_token: creds.sts_security_token.as_deref(),
request_body: None,
style: &OPENAPI_STYLE,
};
let (common_headers, url_) =
get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
.map_err(|e| {
Error::Common(format!("failed to get openapi request header: {}", e))
})?;
let header_map = into_header_map(common_headers);
let resp = client
.http_client
.get(url_)
.headers(header_map)
.send()
.await?;
let data = parse_json_response(resp).await?;
Ok(data)
}
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct CreateRecord<'a> {
#[serde(skip_serializing)]
#[builder(start_fn)]
pub(crate) client: &'a Client,
site_id: i64,
record_name: &'a str,
proxied: Option<bool>,
r#type: DnsRecordType,
source_type: Option<SourceType>,
biz_name: Option<BizName>,
ttl: u32,
#[serde(serialize_with = "se_as_json_string")]
data: RecordData<'a>,
comment: Option<&'a str>,
auth_conf: Option<AuthConf>,
host_policy: Option<HostPolicy>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Serialize, Builder)]
#[serde(rename_all = "PascalCase")]
pub struct RecordData<'a> {
value: Option<&'a str>,
priority: Option<u16>,
flag: Option<u8>,
tag: Option<CaaTag>,
weight: Option<u16>,
port: Option<u16>,
r#type: Option<&'a str>,
key_tag: Option<u16>,
algorithm: Option<u8>,
certificate: Option<&'a str>,
usage: Option<u8>,
selector: Option<u8>,
matching_type: Option<u8>,
fingerprint: Option<&'a str>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum CaaTag {
Issue,
IssueWild,
Iodef,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct CreateRecordResponse {
pub request_id: String,
pub record_id: i64,
}
impl CreateRecord<'_> {
pub async fn send(&self) -> Result<CreateRecordResponse, Error> {
let client = self.client;
let creds = client.credentials_provider.load().await?;
let sign_params = SignParams {
req_method: "POST",
host: &client.host,
query_map: self,
x_acs_action: "CreateRecord",
x_acs_version: OPENAPI_VERSION,
x_acs_security_token: creds.sts_security_token.as_deref(),
request_body: None,
style: &OPENAPI_STYLE,
};
let (common_headers, url_) =
get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
.map_err(|e| {
Error::Common(format!("failed to get openapi request header: {}", e))
})?;
let header_map = into_header_map(common_headers);
let resp = client
.http_client
.post(url_)
.headers(header_map)
.send()
.await?;
let data = parse_json_response(resp).await?;
Ok(data)
}
}
#[derive(Builder, Debug)]
pub struct DeleteRecord<'a> {
#[builder(start_fn)]
pub(crate) client: &'a Client,
pub(crate) record_id: i64,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct DeleteRecordResponse {
pub request_id: String,
}
impl DeleteRecord<'_> {
pub async fn send(&self) -> Result<DeleteRecordResponse, Error> {
let client = self.client;
let creds = client.credentials_provider.load().await?;
let sign_params = SignParams {
req_method: "POST",
host: &client.host,
query_map: HashMap::from([("RecordId", self.record_id)]),
x_acs_action: "DeleteRecord",
x_acs_version: OPENAPI_VERSION,
x_acs_security_token: creds.sts_security_token.as_deref(),
request_body: None,
style: &OPENAPI_STYLE,
};
let (common_headers, url_) =
get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
.map_err(|e| {
Error::Common(format!("failed to get openapi request header: {}", e))
})?;
let header_map = into_header_map(common_headers);
let resp = client
.http_client
.post(url_)
.headers(header_map)
.send()
.await?;
let data = parse_json_response(resp).await?;
Ok(data)
}
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct UpdateRecord<'a> {
#[serde(skip_serializing)]
#[builder(start_fn)]
pub(crate) client: &'a Client,
record_id: i64,
ttl: Option<u32>,
proxied: Option<bool>,
r#type: Option<DnsRecordType>,
source_type: Option<SourceType>,
biz_name: Option<BizName>,
#[serde(serialize_with = "se_as_json_string")]
data: RecordData<'a>,
comment: Option<&'a str>,
auth_conf: Option<AuthConf>,
host_policy: Option<HostPolicy>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct UpdateRecordResponse {
pub request_id: String,
}
impl UpdateRecord<'_> {
pub async fn send(&self) -> Result<UpdateRecordResponse, Error> {
let client = self.client;
let creds = client.credentials_provider.load().await?;
let sign_params = SignParams {
req_method: "POST",
host: &client.host,
query_map: self,
x_acs_action: "UpdateRecord",
x_acs_version: OPENAPI_VERSION,
x_acs_security_token: creds.sts_security_token.as_deref(),
request_body: None,
style: &OPENAPI_STYLE,
};
let (common_headers, url_) =
get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
.map_err(|e| {
Error::Common(format!("failed to get openapi request header: {}", e))
})?;
let header_map = into_header_map(common_headers);
let resp = client
.http_client
.post(url_)
.headers(header_map)
.send()
.await?;
let data = parse_json_response(resp).await?;
Ok(data)
}
}