db/heromodels/src/models/heroledger/dnsrecord.rs
2025-08-05 12:53:24 +02:00

302 lines
6.8 KiB
Rust

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<DNSRecord>,
pub administrators: Vec<u32>,
pub status: DNSZoneStatus,
pub metadata: HashMap<String, String>,
pub soarecord: Vec<SOARecord>,
}
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<DNSRecord>) -> 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<u32>) -> 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<String, String>) -> 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<SOARecord>) -> Self {
self.soarecord = soarecord;
self
}
/// Build the final DNS zone instance
pub fn build(self) -> Self {
self
}
}