1use super::Client;
2use super::utils::{
3 de_non_empty_object, de_option_empty_string_as_none, parse_json_response, se_as_json_string,
4};
5use super::{Error, OPENAPI_STYLE, OPENAPI_VERSION};
6use bon::Builder;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use time::OffsetDateTime;
10use u_sdk_common::helper::into_header_map;
11use u_sdk_common::open_api_sign::{SignParams, get_openapi_request_header};
12
13impl Client {
14 pub fn list_records(&self) -> ListRecordsBuilder<'_> {
15 ListRecords::builder(self)
16 }
17
18 pub fn get_record(&self) -> GetRecordBuilder<'_> {
19 GetRecord::builder(self)
20 }
21
22 pub fn create_record(&self) -> CreateRecordBuilder<'_> {
23 CreateRecord::builder(self)
24 }
25
26 pub fn delete_record(&self) -> DeleteRecordBuilder<'_> {
27 DeleteRecord::builder(self)
28 }
29
30 pub fn update_record(&self) -> UpdateRecordBuilder<'_> {
31 UpdateRecord::builder(self)
32 }
33}
34
35#[serde_with::skip_serializing_none]
38#[derive(Debug, Serialize, Builder)]
39#[serde(rename_all = "PascalCase")]
40pub struct ListRecords<'a> {
41 #[builder(start_fn)]
42 #[serde(skip_serializing)]
43 pub(crate) client: &'a Client,
44
45 site_id: i64,
47
48 record_name: Option<String>,
50
51 record_match_type: Option<RecordMatchType>,
58
59 page_number: Option<i32>,
61
62 page_size: Option<i32>,
64
65 source_type: Option<SourceType>,
68
69 biz_name: Option<BizName>,
72
73 proxied: Option<bool>,
75
76 record_type: Option<DnsRecordType>,
78}
79
80#[derive(Debug, Serialize)]
82#[serde(rename_all = "lowercase")]
83pub enum RecordMatchType {
84 Prefix, Suffix, Exact, Fuzzy, }
89
90#[derive(Debug, Serialize, Deserialize)]
92pub enum SourceType {
93 OSS, S3, LB, OP, Domain, }
99
100#[derive(Debug, Serialize, Deserialize)]
102#[serde(rename_all = "snake_case")]
103pub enum BizName {
104 ImageVideo, Api, Web, }
108
109#[derive(Debug, Serialize, Deserialize)]
111#[serde(rename_all = "UPPERCASE")]
112pub enum DnsRecordType {
113 #[serde(rename = "A/AAAA")]
114 AOrAAAA, CNAME, MX, TXT, NS, SRV, CAA, CERT, SMIMEA, SSHFP, TLSA, URI, }
127
128#[derive(Debug, Deserialize)]
130#[serde(rename_all = "PascalCase")]
131pub struct ListRecordsResponse {
132 pub request_id: String,
134
135 pub page_number: i32,
137
138 pub page_size: i32,
140
141 pub total_count: i32,
143
144 pub records: Vec<DnsRecord>,
146}
147
148#[derive(Debug, Deserialize)]
150#[serde(rename_all = "PascalCase")]
151pub struct DnsRecord {
152 #[serde(deserialize_with = "de_option_empty_string_as_none")]
154 pub biz_name: Option<BizName>,
155
156 pub data: DnsData,
158
159 #[serde(with = "time::serde::rfc3339")]
161 pub create_time: OffsetDateTime,
162
163 #[serde(with = "time::serde::rfc3339")]
165 pub update_time: OffsetDateTime,
166
167 pub proxied: bool,
169
170 pub record_id: i64,
172
173 #[serde(deserialize_with = "de_option_empty_string_as_none")]
175 pub record_source_type: Option<SourceType>,
176
177 pub record_name: String,
179
180 pub record_type: DnsRecordType,
182
183 pub site_id: i64,
185
186 pub site_name: String,
188
189 pub ttl: i32,
191
192 pub record_cname: String,
194
195 pub comment: String,
197
198 #[serde(default, deserialize_with = "de_non_empty_object")]
202 pub auth_conf: Option<AuthConf>,
203
204 #[serde(deserialize_with = "de_option_empty_string_as_none")]
206 pub host_policy: Option<HostPolicy>,
207}
208
209#[derive(Debug, Serialize, Deserialize)]
211#[serde(rename_all = "PascalCase")]
212pub struct DnsData {
213 pub value: String,
215
216 pub priority: Option<i32>,
218
219 pub flag: Option<i32>,
221
222 pub tags: Option<HashMap<String, String>>,
224
225 pub weight: Option<i32>,
227
228 pub port: Option<i32>,
230
231 pub r#type: Option<i32>,
233
234 pub key_tag: Option<i32>,
236
237 pub algorithm: Option<i32>,
239
240 pub certificate: Option<String>,
242
243 pub usage: Option<i32>,
245
246 pub selector: Option<i32>,
248
249 pub matching_type: Option<i32>,
251
252 pub fingerprint: Option<String>,
254
255 pub tag: Option<String>,
257}
258
259#[derive(Debug, Deserialize, Serialize)]
261pub struct AuthConf {
262 pub auth_type: Option<AuthType>,
264
265 pub access_key: Option<String>,
267
268 pub secret_key: Option<String>,
270
271 pub version: Option<String>,
273
274 pub region: Option<String>,
276}
277
278#[derive(Debug, Deserialize, Serialize)]
280#[serde(rename_all = "snake_case")]
281pub enum AuthType {
282 Public, Private, PrivateSameAccount, PrivateCrossAccount, }
287
288#[derive(Debug, Deserialize, Serialize)]
290#[serde(rename_all = "snake_case")]
291pub enum HostPolicy {
292 FollowHostname, FollowOriginDomain, }
295
296impl ListRecords<'_> {
297 pub async fn send(&self) -> Result<ListRecordsResponse, Error> {
298 let client = self.client;
299 let creds = client.credentials_provider.load().await?;
300
301 let sign_params = SignParams {
302 req_method: "GET",
303 host: &client.host,
304 query_map: self,
305 x_acs_action: "ListRecords",
306 x_acs_version: OPENAPI_VERSION,
307 x_acs_security_token: creds.sts_security_token.as_deref(),
308 request_body: None,
309 style: &OPENAPI_STYLE,
310 };
311
312 let (common_headers, url_) =
313 get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
314 .map_err(|e| {
315 Error::Common(format!("failed to get openapi request header: {}", e))
316 })?;
317 let header_map = into_header_map(common_headers);
318
319 let resp = client
320 .http_client
321 .get(url_)
322 .headers(header_map)
323 .send()
324 .await?;
325
326 let data = parse_json_response(resp).await?;
327 Ok(data)
328 }
329}
330#[derive(Builder, Debug)]
335pub struct GetRecord<'a> {
336 #[builder(start_fn)]
337 pub(crate) client: &'a Client,
338 pub(crate) record_id: i64,
339}
340
341#[derive(Debug, Deserialize)]
342#[serde(rename_all = "PascalCase")]
343pub struct GetRecordResponse {
344 pub request_id: String,
345 pub record_model: DnsRecord,
346}
347
348impl GetRecord<'_> {
349 pub async fn send(&self) -> Result<GetRecordResponse, Error> {
350 let client = self.client;
351 let creds = client.credentials_provider.load().await?;
352
353 let sign_params = SignParams {
354 req_method: "GET",
355 host: &client.host,
356 query_map: HashMap::from([("RecordId", self.record_id)]),
357 x_acs_action: "GetRecord",
358 x_acs_version: OPENAPI_VERSION,
359 x_acs_security_token: creds.sts_security_token.as_deref(),
360 request_body: None,
361 style: &OPENAPI_STYLE,
362 };
363
364 let (common_headers, url_) =
365 get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
366 .map_err(|e| {
367 Error::Common(format!("failed to get openapi request header: {}", e))
368 })?;
369 let header_map = into_header_map(common_headers);
370
371 let resp = client
372 .http_client
373 .get(url_)
374 .headers(header_map)
375 .send()
376 .await?;
377
378 let data = parse_json_response(resp).await?;
379 Ok(data)
380 }
381}
382#[serde_with::skip_serializing_none]
387#[derive(Builder, Debug, Serialize)]
388#[serde(rename_all = "PascalCase")]
389pub struct CreateRecord<'a> {
390 #[serde(skip_serializing)]
391 #[builder(start_fn)]
392 pub(crate) client: &'a Client,
393
394 site_id: i64,
395 record_name: &'a str,
396
397 proxied: Option<bool>,
399
400 r#type: DnsRecordType,
402
403 source_type: Option<SourceType>,
405
406 biz_name: Option<BizName>,
408
409 ttl: u32,
410
411 #[serde(serialize_with = "se_as_json_string")]
412 data: RecordData<'a>,
413
414 comment: Option<&'a str>,
416
417 auth_conf: Option<AuthConf>,
419
420 host_policy: Option<HostPolicy>,
422}
423
424#[serde_with::skip_serializing_none]
425#[derive(Debug, Serialize, Builder)]
426#[serde(rename_all = "PascalCase")]
427pub struct RecordData<'a> {
428 value: Option<&'a str>,
430
431 priority: Option<u16>,
433
434 flag: Option<u8>,
436
437 tag: Option<CaaTag>,
439
440 weight: Option<u16>,
442
443 port: Option<u16>,
445
446 r#type: Option<&'a str>,
448
449 key_tag: Option<u16>,
451
452 algorithm: Option<u8>,
454
455 certificate: Option<&'a str>,
457
458 usage: Option<u8>,
460
461 selector: Option<u8>,
463
464 matching_type: Option<u8>,
466
467 fingerprint: Option<&'a str>,
469}
470
471#[derive(Debug, Serialize)]
472#[serde(rename_all = "lowercase")]
473pub enum CaaTag {
474 Issue,
475 IssueWild,
476 Iodef,
477}
478
479#[derive(Debug, Deserialize)]
480#[serde(rename_all = "PascalCase")]
481pub struct CreateRecordResponse {
482 pub request_id: String,
483 pub record_id: i64,
484}
485
486impl CreateRecord<'_> {
487 pub async fn send(&self) -> Result<CreateRecordResponse, Error> {
488 let client = self.client;
489 let creds = client.credentials_provider.load().await?;
490
491 let sign_params = SignParams {
492 req_method: "POST",
493 host: &client.host,
494 query_map: self,
495 x_acs_action: "CreateRecord",
496 x_acs_version: OPENAPI_VERSION,
497 x_acs_security_token: creds.sts_security_token.as_deref(),
498 request_body: None,
499 style: &OPENAPI_STYLE,
500 };
501
502 let (common_headers, url_) =
503 get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
504 .map_err(|e| {
505 Error::Common(format!("failed to get openapi request header: {}", e))
506 })?;
507 let header_map = into_header_map(common_headers);
508
509 let resp = client
510 .http_client
511 .post(url_)
512 .headers(header_map)
513 .send()
514 .await?;
515
516 let data = parse_json_response(resp).await?;
517 Ok(data)
518 }
519}
520#[derive(Builder, Debug)]
525pub struct DeleteRecord<'a> {
526 #[builder(start_fn)]
527 pub(crate) client: &'a Client,
528 pub(crate) record_id: i64,
529}
530
531#[derive(Debug, Deserialize)]
532#[serde(rename_all = "PascalCase")]
533pub struct DeleteRecordResponse {
534 pub request_id: String,
535}
536
537impl DeleteRecord<'_> {
538 pub async fn send(&self) -> Result<DeleteRecordResponse, Error> {
539 let client = self.client;
540 let creds = client.credentials_provider.load().await?;
541
542 let sign_params = SignParams {
543 req_method: "POST",
544 host: &client.host,
545 query_map: HashMap::from([("RecordId", self.record_id)]),
546 x_acs_action: "DeleteRecord",
547 x_acs_version: OPENAPI_VERSION,
548 x_acs_security_token: creds.sts_security_token.as_deref(),
549 request_body: None,
550 style: &OPENAPI_STYLE,
551 };
552
553 let (common_headers, url_) =
554 get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
555 .map_err(|e| {
556 Error::Common(format!("failed to get openapi request header: {}", e))
557 })?;
558 let header_map = into_header_map(common_headers);
559
560 let resp = client
561 .http_client
562 .post(url_)
563 .headers(header_map)
564 .send()
565 .await?;
566
567 let data = parse_json_response(resp).await?;
568 Ok(data)
569 }
570}
571#[serde_with::skip_serializing_none]
575#[derive(Builder, Debug, Serialize)]
576#[serde(rename_all = "PascalCase")]
577pub struct UpdateRecord<'a> {
578 #[serde(skip_serializing)]
579 #[builder(start_fn)]
580 pub(crate) client: &'a Client,
581
582 record_id: i64,
583
584 ttl: Option<u32>,
586
587 proxied: Option<bool>,
589
590 r#type: Option<DnsRecordType>,
592
593 source_type: Option<SourceType>,
595
596 biz_name: Option<BizName>,
598
599 #[serde(serialize_with = "se_as_json_string")]
600 data: RecordData<'a>,
601
602 comment: Option<&'a str>,
604
605 auth_conf: Option<AuthConf>,
607
608 host_policy: Option<HostPolicy>,
610}
611
612#[derive(Debug, Deserialize)]
613#[serde(rename_all = "PascalCase")]
614pub struct UpdateRecordResponse {
615 pub request_id: String,
616}
617
618impl UpdateRecord<'_> {
619 pub async fn send(&self) -> Result<UpdateRecordResponse, Error> {
620 let client = self.client;
621 let creds = client.credentials_provider.load().await?;
622
623 let sign_params = SignParams {
624 req_method: "POST",
625 host: &client.host,
626 query_map: self,
627 x_acs_action: "UpdateRecord",
628 x_acs_version: OPENAPI_VERSION,
629 x_acs_security_token: creds.sts_security_token.as_deref(),
630 request_body: None,
631 style: &OPENAPI_STYLE,
632 };
633
634 let (common_headers, url_) =
635 get_openapi_request_header(&creds.access_key_secret, &creds.access_key_id, sign_params)
636 .map_err(|e| {
637 Error::Common(format!("failed to get openapi request header: {}", e))
638 })?;
639 let header_map = into_header_map(common_headers);
640
641 let resp = client
642 .http_client
643 .post(url_)
644 .headers(header_map)
645 .send()
646 .await?;
647
648 let data = parse_json_response(resp).await?;
649 Ok(data)
650 }
651}
652