use std::net::{Ipv4Addr, Ipv6Addr};
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use super::EntityDescriptorConst;
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct DnsRecordSpecV1 {
pub external_id: Option<String>,
pub root_domain: String,
pub root_domain_external_id: Option<String>,
pub data: DnsRecordData,
}
impl DnsRecordSpecV1 {
pub fn kind(&self) -> DnsRecordKind {
self.data.kind_name()
}
pub fn full_domain(&self) -> String {
let name = self.data.common().name.trim().trim_end_matches('.');
if name.is_empty() || name == "@" {
self.root_domain.clone()
} else {
format!("{}.{}", name, self.root_domain)
}
}
}
impl EntityDescriptorConst for DnsRecordSpecV1 {
const NAMESPACE: &'static str = "wasmer.io";
const NAME: &'static str = "DnsRecord";
const VERSION: &'static str = "v1";
const KIND: &'static str = "wasmer.io/DnsRecord.v1";
type Spec = Self;
type State = ();
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Copy, Debug, schemars::JsonSchema)]
pub enum DnsRecordKind {
A,
Aaaa,
CName,
Txt,
Mx,
Ns,
Caa,
DName,
Ptr,
Soa,
}
impl DnsRecordKind {
pub fn as_str(&self) -> &str {
match self {
Self::A => "A",
Self::Aaaa => "AAAA",
Self::CName => "CNAME",
Self::Txt => "TXT",
Self::Mx => "MX",
Self::Ns => "NS",
Self::Caa => "CAA",
Self::DName => "DNAME",
Self::Ptr => "PTR",
Self::Soa => "SOA",
}
}
}
impl std::fmt::Display for DnsRecordKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub enum DnsRecordData {
#[serde(rename = "a")]
A(ARecord),
#[serde(rename = "aaaa")]
Aaaa(AaaaRecord),
#[serde(rename = "cname")]
CName(CNameRecord),
#[serde(rename = "txt")]
Txt(TxtRecord),
#[serde(rename = "mx")]
Mx(MxRecord),
#[serde(rename = "ns")]
Ns(NsRecord),
#[serde(rename = "caa")]
Caa(CaaRecord),
#[serde(rename = "dname")]
DName(DNameRecord),
#[serde(rename = "ptr")]
Ptr(PtrRecord),
#[serde(rename = "soa")]
Soa(SoaRecord),
}
impl DnsRecordData {
pub fn common(&self) -> &DnsRecordCommon {
match self {
DnsRecordData::A(x) => &x.common,
DnsRecordData::Aaaa(x) => &x.common,
DnsRecordData::CName(x) => &x.common,
DnsRecordData::Txt(x) => &x.common,
DnsRecordData::Mx(x) => &x.common,
DnsRecordData::Ns(x) => &x.common,
DnsRecordData::Caa(x) => &x.common,
DnsRecordData::DName(x) => &x.common,
DnsRecordData::Ptr(x) => &x.common,
DnsRecordData::Soa(x) => &x.common,
}
}
pub fn kind_name(&self) -> DnsRecordKind {
match self {
DnsRecordData::A(_) => DnsRecordKind::A,
DnsRecordData::Aaaa(_) => DnsRecordKind::Aaaa,
DnsRecordData::CName(_) => DnsRecordKind::CName,
DnsRecordData::Txt(_) => DnsRecordKind::Txt,
DnsRecordData::Mx(_) => DnsRecordKind::Mx,
DnsRecordData::Ns(_) => DnsRecordKind::Ns,
DnsRecordData::Caa(_) => DnsRecordKind::Caa,
DnsRecordData::DName(_) => DnsRecordKind::DName,
DnsRecordData::Ptr(_) => DnsRecordKind::Ptr,
DnsRecordData::Soa(_) => DnsRecordKind::Soa,
}
}
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct ARecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
#[schemars(with = "String")]
pub address: Ipv4Addr,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct AaaaRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub address: Ipv6Addr,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct CNameRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub cname: String,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct TxtRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub data: String,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct MxRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub mx: String,
pub preference: u16,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct NsRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub nameserver: String,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct CaaRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub value: String,
pub flags: i32,
pub tag: String,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct DNameRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub dname: String,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct PtrRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub ptr: String,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct SoaRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub mname: String,
pub rname: String,
pub serial: i64,
pub refresh: i64,
pub retry: i64,
pub expire: i64,
pub minimum: i64,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct SrvRecord {
#[serde(flatten)]
pub common: DnsRecordCommon,
pub service: String,
pub protocol: String,
pub priority: i32,
pub weight: i32,
pub port: i32,
pub target: String,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct DnsRecordCommon {
pub name: String,
pub ttl: Seconds,
#[serde(
default,
with = "time::serde::timestamp::option",
skip_serializing_if = "Option::is_none"
)]
#[schemars(with = "Option<u64>")]
pub created_at: Option<OffsetDateTime>,
#[serde(
default,
with = "time::serde::timestamp::option",
skip_serializing_if = "Option::is_none"
)]
#[schemars(with = "Option<u64>")]
pub updated_at: Option<OffsetDateTime>,
#[serde(
default,
with = "time::serde::timestamp::option",
skip_serializing_if = "Option::is_none"
)]
#[schemars(with = "Option<u64>")]
pub deleted_at: Option<OffsetDateTime>,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct Seconds(pub u32);