edge_schema/schema/
dns.rs

1use std::net::{Ipv4Addr, Ipv6Addr};
2
3use serde::{Deserialize, Serialize};
4use time::OffsetDateTime;
5
6use super::EntityDescriptorConst;
7
8#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
9pub struct DnsRecordSpecV1 {
10    pub external_id: Option<String>,
11    /// Root domain as text.
12    pub root_domain: String,
13    /// Root domain as entity reference.
14    pub root_domain_external_id: Option<String>,
15    pub data: DnsRecordData,
16}
17
18impl DnsRecordSpecV1 {
19    pub fn kind(&self) -> DnsRecordKind {
20        self.data.kind_name()
21    }
22
23    pub fn full_domain(&self) -> String {
24        let name = self.data.common().name.trim().trim_end_matches('.');
25
26        if name.is_empty() || name == "@" {
27            self.root_domain.clone()
28        } else {
29            format!("{}.{}", name, self.root_domain)
30        }
31    }
32}
33
34impl EntityDescriptorConst for DnsRecordSpecV1 {
35    const NAMESPACE: &'static str = "wasmer.io";
36    const NAME: &'static str = "DnsRecord";
37    const VERSION: &'static str = "v1";
38    const KIND: &'static str = "wasmer.io/DnsRecord.v1";
39
40    type Spec = Self;
41    type State = ();
42}
43
44#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Copy, Debug, schemars::JsonSchema)]
45pub enum DnsRecordKind {
46    A,
47    Aaaa,
48    CName,
49    Txt,
50    Mx,
51    Ns,
52    Caa,
53    DName,
54    Ptr,
55    Soa,
56}
57
58impl DnsRecordKind {
59    pub fn as_str(&self) -> &str {
60        match self {
61            Self::A => "A",
62            Self::Aaaa => "AAAA",
63            Self::CName => "CNAME",
64            Self::Txt => "TXT",
65            Self::Mx => "MX",
66            Self::Ns => "NS",
67            Self::Caa => "CAA",
68            Self::DName => "DNAME",
69            Self::Ptr => "PTR",
70            Self::Soa => "SOA",
71        }
72    }
73}
74
75impl std::fmt::Display for DnsRecordKind {
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77        write!(f, "{}", self.as_str())
78    }
79}
80
81#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
82pub enum DnsRecordData {
83    #[serde(rename = "a")]
84    A(ARecord),
85    #[serde(rename = "aaaa")]
86    Aaaa(AaaaRecord),
87    #[serde(rename = "cname")]
88    CName(CNameRecord),
89    #[serde(rename = "txt")]
90    Txt(TxtRecord),
91    #[serde(rename = "mx")]
92    Mx(MxRecord),
93    #[serde(rename = "ns")]
94    Ns(NsRecord),
95    #[serde(rename = "caa")]
96    Caa(CaaRecord),
97    #[serde(rename = "dname")]
98    DName(DNameRecord),
99    #[serde(rename = "ptr")]
100    Ptr(PtrRecord),
101    #[serde(rename = "soa")]
102    Soa(SoaRecord),
103}
104
105impl DnsRecordData {
106    pub fn common(&self) -> &DnsRecordCommon {
107        match self {
108            DnsRecordData::A(x) => &x.common,
109            DnsRecordData::Aaaa(x) => &x.common,
110            DnsRecordData::CName(x) => &x.common,
111            DnsRecordData::Txt(x) => &x.common,
112            DnsRecordData::Mx(x) => &x.common,
113            DnsRecordData::Ns(x) => &x.common,
114            DnsRecordData::Caa(x) => &x.common,
115            DnsRecordData::DName(x) => &x.common,
116            DnsRecordData::Ptr(x) => &x.common,
117            DnsRecordData::Soa(x) => &x.common,
118        }
119    }
120
121    pub fn kind_name(&self) -> DnsRecordKind {
122        match self {
123            DnsRecordData::A(_) => DnsRecordKind::A,
124            DnsRecordData::Aaaa(_) => DnsRecordKind::Aaaa,
125            DnsRecordData::CName(_) => DnsRecordKind::CName,
126            DnsRecordData::Txt(_) => DnsRecordKind::Txt,
127            DnsRecordData::Mx(_) => DnsRecordKind::Mx,
128            DnsRecordData::Ns(_) => DnsRecordKind::Ns,
129            DnsRecordData::Caa(_) => DnsRecordKind::Caa,
130            DnsRecordData::DName(_) => DnsRecordKind::DName,
131            DnsRecordData::Ptr(_) => DnsRecordKind::Ptr,
132            DnsRecordData::Soa(_) => DnsRecordKind::Soa,
133        }
134    }
135}
136
137#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
138pub struct ARecord {
139    #[serde(flatten)]
140    pub common: DnsRecordCommon,
141    #[schemars(with = "String")]
142    pub address: Ipv4Addr,
143}
144
145#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
146pub struct AaaaRecord {
147    #[serde(flatten)]
148    pub common: DnsRecordCommon,
149    pub address: Ipv6Addr,
150}
151
152#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
153pub struct CNameRecord {
154    #[serde(flatten)]
155    pub common: DnsRecordCommon,
156    pub cname: String,
157}
158
159#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
160pub struct TxtRecord {
161    #[serde(flatten)]
162    pub common: DnsRecordCommon,
163    pub data: String,
164}
165
166#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
167pub struct MxRecord {
168    #[serde(flatten)]
169    pub common: DnsRecordCommon,
170    pub mx: String,
171    pub preference: u16,
172}
173
174#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
175pub struct NsRecord {
176    #[serde(flatten)]
177    pub common: DnsRecordCommon,
178    pub nameserver: String,
179}
180
181#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
182pub struct CaaRecord {
183    #[serde(flatten)]
184    pub common: DnsRecordCommon,
185    pub value: String,
186    pub flags: i32,
187    pub tag: String,
188}
189
190#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
191pub struct DNameRecord {
192    #[serde(flatten)]
193    pub common: DnsRecordCommon,
194    pub dname: String,
195}
196
197#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
198pub struct PtrRecord {
199    #[serde(flatten)]
200    pub common: DnsRecordCommon,
201    pub ptr: String,
202}
203
204#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
205pub struct SoaRecord {
206    #[serde(flatten)]
207    pub common: DnsRecordCommon,
208    pub mname: String,
209    pub rname: String,
210    pub serial: i64,
211    pub refresh: i64,
212    pub retry: i64,
213    pub expire: i64,
214    pub minimum: i64,
215}
216
217#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
218pub struct SrvRecord {
219    #[serde(flatten)]
220    pub common: DnsRecordCommon,
221
222    pub service: String,
223    pub protocol: String,
224    pub priority: i32,
225    pub weight: i32,
226    pub port: i32,
227    pub target: String,
228}
229
230#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
231pub struct DnsRecordCommon {
232    pub name: String,
233    pub ttl: Seconds,
234    #[serde(
235        default,
236        with = "time::serde::timestamp::option",
237        skip_serializing_if = "Option::is_none"
238    )]
239    #[schemars(with = "Option<u64>")]
240    pub created_at: Option<OffsetDateTime>,
241    #[serde(
242        default,
243        with = "time::serde::timestamp::option",
244        skip_serializing_if = "Option::is_none"
245    )]
246    #[schemars(with = "Option<u64>")]
247    pub updated_at: Option<OffsetDateTime>,
248    #[serde(
249        default,
250        with = "time::serde::timestamp::option",
251        skip_serializing_if = "Option::is_none"
252    )]
253    #[schemars(with = "Option<u64>")]
254    pub deleted_at: Option<OffsetDateTime>,
255}
256
257#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
258pub struct Seconds(pub u32);