dnslib/dto/
record_request.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use chrono::Duration;
use hickory_proto::rr::rdata::{A, AAAA, CNAME, TXT};
use hickory_proto::rr::{Name, Record, RecordType};
use serde::{Deserialize, Serialize};
use std::str::FromStr;

///
/// Record Request contains information about DNS record
///
/// # Fields
/// * domain - `String` contains domain name for record etc (setupit.org. experiment.school. etc.)
/// * name_labels - `String` subdomain for record (git.setupit.org. test.experiment.school. etc.)
/// * rdata - `RData` data of record
///
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct RecordRequest {
    pub domain: String,
    pub name_labels: String,
    pub new_name_labels: Option<String>,
    pub zone: Option<String>,
    pub rdata: RData,
}

///
/// Rdata contains data of record
///
/// # Fields
/// * rdata_type - `String` record type (A, AAAA, MX, CNAME, etc)
/// * rdata_content - `String` (34.102.136.180, 2a00:1450:4010:c02::66)
/// * preference - `Option<String>` priority for MX (1 ,2 ,3 etc.)
///
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct RData {
    pub rdata_type: String,
    pub rdata_content: Option<String>,
    pub preference: Option<u16>,
    pub txt: Option<Vec<String>>,
}

impl RecordRequest {
    pub fn from_str(&self) -> RecordType {
        let rr_type = match self.rdata.rdata_type.as_str() {
            "A" => RecordType::A,
            "AAAA" => RecordType::AAAA,
            "MX" => RecordType::MX,
            "CNAME" => RecordType::CNAME,
            "TXT" => RecordType::TXT,
            _ => RecordType::Unknown(0),
        };
        rr_type
    }
    pub fn to_record(&self) -> Record {
        let rr_type = match self.rdata.rdata_type.as_str() {
            "A" => RecordType::A,
            "AAAA" => RecordType::AAAA,
            "MX" => RecordType::MX,
            "CNAME" => RecordType::CNAME,
            "TXT" => RecordType::TXT,
            _ => RecordType::Unknown(0),
        };
        let mut record = Record::with(
            Name::from_str(self.name_labels.clone().as_str()).unwrap(),
            rr_type,
            Duration::hours(5).num_seconds() as u32,
        );

        match rr_type {
            RecordType::A => {
                record.set_data(Some(hickory_proto::rr::RData::A(
                    A::from_str(self.rdata.rdata_content.clone().unwrap().as_str()).unwrap(),
                )));
            }
            RecordType::AAAA => {
                record.set_data(Some(hickory_proto::rr::RData::AAAA(
                    AAAA::from_str(self.rdata.rdata_content.clone().unwrap().as_str()).unwrap(),
                )));
            }
            RecordType::MX => {
                record.set_data(Some(hickory_proto::rr::RData::MX(
                    hickory_proto::rr::rdata::MX::new(
                        self.rdata.preference.unwrap(),
                        Name::from_str(self.name_labels.clone().as_str()).unwrap(),
                    ),
                )));
            }
            RecordType::CNAME => {
                record.set_data(Some(hickory_proto::rr::RData::CNAME(CNAME(
                    Name::from_str(self.rdata.rdata_content.clone().unwrap().as_str()).unwrap(),
                ))));
            }
            RecordType::TXT => {
                record.set_data(Some(hickory_proto::rr::RData::TXT(TXT::new(
                    self.rdata.txt.clone().unwrap(),
                ))));
            }
            _ => {}
        }
        record
    }
}