config: add a wrapper for ZoneConfig, use Derivative to impl Default for DnsConfig

zone: make Zone a model of ZoneData

zone: rename ZoneData back to Zone
This commit is contained in:
Luna Yao
2026-04-06 11:54:01 +02:00
parent 743d8e4810
commit 97edee20f9
+55 -36
View File
@@ -1,8 +1,10 @@
use crate::common::config::ConfigLoader; use crate::common::config::ConfigLoader;
use crate::common::global_ctx::GlobalCtx; use crate::common::global_ctx::GlobalCtx;
use crate::dns::utils::{parse, NameServerAddr, NameServerAddrGroup}; use crate::dns::utils::{parse, NameServerAddr, NameServerAddrGroup};
use crate::dns::zone::Zone;
use crate::proto::dns::{GetExportConfigResponse, ZoneData}; use crate::proto::dns::{GetExportConfigResponse, ZoneData};
use derive_more::{Deref, DerefMut}; use derivative::Derivative;
use derive_more::{Deref, DerefMut, Into};
use gethostname::gethostname; use gethostname::gethostname;
use hickory_proto::rr::{LowerName, Name}; use hickory_proto::rr::{LowerName, Name};
use hickory_proto::xfer::Protocol; use hickory_proto::xfer::Protocol;
@@ -17,14 +19,15 @@ use uuid::Uuid;
pub const DNS_DEFAULT_ADDRESS: NameServerAddr = NameServerAddr { pub const DNS_DEFAULT_ADDRESS: NameServerAddr = NameServerAddr {
protocol: Protocol::Udp, protocol: Protocol::Udp,
addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(100, 100, 100, 101), 53)) addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(100, 100, 100, 101), 53)),
}; };
pub static DNS_DEFAULT_TLD: LazyLock<LowerName> = pub static DNS_DEFAULT_TLD: LazyLock<LowerName> =
LazyLock::new(|| LowerName::from_str("et.net.").unwrap()); LazyLock::new(|| LowerName::from_str("et.net.").unwrap());
pub static DNS_SERVER_RPC_ADDR: LazyLock<Url> = pub static DNS_SERVER_RPC_ADDR: LazyLock<Url> =
LazyLock::new(|| Url::parse("tcp://127.0.0.1:49813").unwrap()); LazyLock::new(|| Url::parse("tcp://127.0.0.1:49813").unwrap());
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] #[derive(Derivative, Debug, Clone, Deserialize, Serialize, PartialEq)]
#[derivative(Default)]
#[serde(default)] #[serde(default)]
pub struct DnsConfig { pub struct DnsConfig {
#[serde(rename = "zone")] #[serde(rename = "zone")]
@@ -32,7 +35,9 @@ pub struct DnsConfig {
#[serde(flatten)] #[serde(flatten)]
pub policies: HashMap<LowerName, DnsPolicyConfig>, pub policies: HashMap<LowerName, DnsPolicyConfig>,
name: LowerName, name: LowerName,
#[derivative(Default(value = "DNS_DEFAULT_TLD.clone()"))]
pub domain: LowerName, pub domain: LowerName,
#[derivative(Default(value = "vec![DNS_DEFAULT_ADDRESS].into()"))]
#[serde(deserialize_with = "DnsConfig::validate_addresses")] #[serde(deserialize_with = "DnsConfig::validate_addresses")]
pub addresses: NameServerAddrGroup, pub addresses: NameServerAddrGroup,
pub listeners: NameServerAddrGroup, pub listeners: NameServerAddrGroup,
@@ -119,33 +124,27 @@ impl DnsGlobalCtxExt for GlobalCtx {
} }
} }
impl Default for DnsConfig { #[derive(Derivative, Debug, Clone, Deserialize, Serialize, Default, Deref, DerefMut, Into)]
fn default() -> Self { #[derivative(PartialEq)]
Self { #[serde(try_from = "ZoneConfigInner", into = "ZoneConfigInner")]
zones: Vec::new(), pub struct ZoneConfig {
policies: HashMap::new(), #[into]
name: LowerName::default(), #[derivative(PartialEq = "ignore")]
domain: DNS_DEFAULT_TLD.clone(), data: ZoneData,
addresses: vec![DNS_DEFAULT_ADDRESS].into(), #[into]
listeners: vec![].into(), #[deref]
} #[deref_mut]
} inner: ZoneConfigInner,
} }
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)] impl TryFrom<ZoneConfigInner> for ZoneConfig {
pub struct ZoneConfig { type Error = anyhow::Error;
#[serde(default = "Uuid::new_v4")]
#[serde(skip_serializing)] fn try_from(value: ZoneConfigInner) -> Result<Self, Self::Error> {
id: Uuid, let data = ZoneData::from(value.clone());
pub origin: LowerName, let _ = Zone::try_from(&data)?;
#[serde(default)] Ok(Self { data, inner: value })
pub ttl: u32, }
#[serde(default)]
pub records: Vec<String>,
#[serde(default)]
pub forwarders: NameServerAddrGroup,
#[serde(flatten)]
pub policy: ZonePolicyConfig,
} }
impl ZoneConfig { impl ZoneConfig {
@@ -168,24 +167,44 @@ impl ZoneConfig {
export: Some(DnsExportPolicy::default()), export: Some(DnsExportPolicy::default()),
}; };
(!records.is_empty()).then_some(Self { if records.is_empty() {
id: id.unwrap_or(Uuid::new_v4()), return None;
}
let config = ZoneConfigInner {
id: id.unwrap_or_else(Uuid::new_v4),
origin, origin,
records, records,
policy, policy,
..Default::default() ..Default::default()
}) };
config.try_into().ok()
} }
} }
impl From<ZoneConfig> for ZoneData { #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)]
fn from(value: ZoneConfig) -> Self { pub struct ZoneConfigInner {
#[serde(default = "Uuid::new_v4")]
#[serde(skip_serializing)]
id: Uuid,
pub origin: LowerName,
#[serde(default)]
pub ttl: u32,
#[serde(default)]
pub records: Vec<String>,
#[serde(default)]
pub forwarders: NameServerAddrGroup,
#[serde(flatten)]
pub policy: ZonePolicyConfig,
}
impl From<ZoneConfigInner> for ZoneData {
fn from(value: ZoneConfigInner) -> Self {
Self { Self {
id: Some(value.id.into()), id: Some(value.id.into()),
origin: value.origin.to_string(), origin: value.origin.to_string(),
ttl: value.ttl, records: value.records,
records: value.records.clone(),
forwarders: value.forwarders.into(), forwarders: value.forwarders.into(),
} }
} }