use heromodels_core::{Model, BaseModelData, IndexKey}; use heromodels_derive::model; use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// Defines the supported DNS record types #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum NameType { A, AAAA, CNAME, MX, TXT, SRV, PTR, NS, } impl Default for NameType { fn default() -> Self { NameType::A } } /// Category of the DNS record #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum NameCat { IPv4, IPv6, Mycelium, } impl Default for NameCat { fn default() -> Self { NameCat::IPv4 } } /// Status of a DNS zone #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum DNSZoneStatus { Active, Suspended, Archived, } impl Default for DNSZoneStatus { fn default() -> Self { DNSZoneStatus::Active } } /// Represents a DNS record configuration #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct DNSRecord { pub subdomain: String, pub record_type: NameType, pub value: String, pub priority: u32, pub ttl: u32, pub is_active: bool, pub cat: NameCat, pub is_wildcard: bool, } impl DNSRecord { pub fn new() -> Self { Self { subdomain: String::new(), record_type: NameType::default(), value: String::new(), priority: 0, ttl: 3600, is_active: true, cat: NameCat::default(), is_wildcard: false, } } pub fn subdomain(mut self, subdomain: impl ToString) -> Self { self.subdomain = subdomain.to_string(); self } pub fn record_type(mut self, record_type: NameType) -> Self { self.record_type = record_type; self } pub fn value(mut self, value: impl ToString) -> Self { self.value = value.to_string(); self } pub fn priority(mut self, priority: u32) -> Self { self.priority = priority; self } pub fn ttl(mut self, ttl: u32) -> Self { self.ttl = ttl; self } pub fn is_active(mut self, is_active: bool) -> Self { self.is_active = is_active; self } pub fn cat(mut self, cat: NameCat) -> Self { self.cat = cat; self } pub fn is_wildcard(mut self, is_wildcard: bool) -> Self { self.is_wildcard = is_wildcard; self } pub fn build(self) -> Self { self } } /// SOA (Start of Authority) record for a DNS zone #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct SOARecord { pub zone_id: u32, pub primary_ns: String, pub admin_email: String, pub serial: u64, pub refresh: u32, pub retry: u32, pub expire: u32, pub minimum_ttl: u32, pub is_active: bool, } impl SOARecord { pub fn new() -> Self { Self { zone_id: 0, primary_ns: String::new(), admin_email: String::new(), serial: 0, refresh: 3600, retry: 600, expire: 604800, minimum_ttl: 3600, is_active: true, } } pub fn zone_id(mut self, zone_id: u32) -> Self { self.zone_id = zone_id; self } pub fn primary_ns(mut self, primary_ns: impl ToString) -> Self { self.primary_ns = primary_ns.to_string(); self } pub fn admin_email(mut self, admin_email: impl ToString) -> Self { self.admin_email = admin_email.to_string(); self } pub fn serial(mut self, serial: u64) -> Self { self.serial = serial; self } pub fn refresh(mut self, refresh: u32) -> Self { self.refresh = refresh; self } pub fn retry(mut self, retry: u32) -> Self { self.retry = retry; self } pub fn expire(mut self, expire: u32) -> Self { self.expire = expire; self } pub fn minimum_ttl(mut self, minimum_ttl: u32) -> Self { self.minimum_ttl = minimum_ttl; self } pub fn is_active(mut self, is_active: bool) -> Self { self.is_active = is_active; self } pub fn build(self) -> Self { self } } /// Represents a DNS zone with its configuration and records #[model] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] pub struct DNSZone { /// Base model data pub base_data: BaseModelData, #[index] pub domain: String, pub dnsrecords: Vec, pub administrators: Vec, pub status: DNSZoneStatus, pub metadata: HashMap, pub soarecord: Vec, } impl DNSZone { /// Create a new DNS zone instance pub fn new(id: u32) -> Self { let mut base_data = BaseModelData::new(); base_data.update_id(id); Self { base_data, domain: String::new(), dnsrecords: Vec::new(), administrators: Vec::new(), status: DNSZoneStatus::default(), metadata: HashMap::new(), soarecord: Vec::new(), } } /// Set the domain name (fluent) pub fn domain(mut self, domain: impl ToString) -> Self { self.domain = domain.to_string(); self } /// Add a DNS record (fluent) pub fn add_dnsrecord(mut self, record: DNSRecord) -> Self { self.dnsrecords.push(record); self } /// Set all DNS records (fluent) pub fn dnsrecords(mut self, dnsrecords: Vec) -> Self { self.dnsrecords = dnsrecords; self } /// Add an administrator (fluent) pub fn add_administrator(mut self, admin_id: u32) -> Self { self.administrators.push(admin_id); self } /// Set all administrators (fluent) pub fn administrators(mut self, administrators: Vec) -> Self { self.administrators = administrators; self } /// Set the zone status (fluent) pub fn status(mut self, status: DNSZoneStatus) -> Self { self.status = status; self } /// Add metadata entry (fluent) pub fn add_metadata(mut self, key: impl ToString, value: impl ToString) -> Self { self.metadata.insert(key.to_string(), value.to_string()); self } /// Set all metadata (fluent) pub fn metadata(mut self, metadata: HashMap) -> Self { self.metadata = metadata; self } /// Add an SOA record (fluent) pub fn add_soarecord(mut self, soa: SOARecord) -> Self { self.soarecord.push(soa); self } /// Set all SOA records (fluent) pub fn soarecord(mut self, soarecord: Vec) -> Self { self.soarecord = soarecord; self } /// Build the final DNS zone instance pub fn build(self) -> Self { self } }