1#![allow(non_camel_case_types, non_upper_case_globals)]
2use anyhow::Result;
9use hickory_proto::rr::{
10 Name,
11 RData,
12 Record,
13 rdata::{A, NS, SOA},
14};
15use hickory_server::{
21 net::runtime::TokioRuntimeProvider,
22 store::in_memory::InMemoryZoneHandler,
23 zone_handler::{AxfrPolicy, ZoneType},
24};
25
26pub fn EditorLandZone() -> Result<Vec<Record>> {
30 let mut Records = Vec::new();
31
32 let Origin = Name::from_ascii("editor.land.").unwrap();
33
34 let TTL = 300u32;
35
36 let Serial = 2025010100u32;
37
38 let Refresh:i32 = 86400;
39
40 let Retry:i32 = 7200;
41
42 let Expire:i32 = 604800;
43
44 let Minimum:u32 = 3600;
45
46 let SOARecord = SOA::new(
47 Name::from_ascii("ns1.editor.land.").unwrap(),
48 Name::from_ascii("hostmaster.editor.land.").unwrap(),
49 Serial,
50 Refresh,
51 Retry,
52 Expire,
53 Minimum,
54 );
55
56 Records.push(Record::from_rdata(Origin.clone(), TTL, RData::SOA(SOARecord)));
57
58 let NSName = Name::from_ascii("ns1.editor.land.").unwrap();
59
60 Records.push(Record::from_rdata(Origin.clone(), TTL, RData::NS(NS(NSName))));
61
62 Records.push(Record::from_rdata(
63 Name::from_ascii("ns1.editor.land.").unwrap(),
64 TTL,
65 RData::A(A::new(127, 0, 0, 1)),
66 ));
67
68 let Subdomains = vec!["editor", "www", "localhost", "sidecar", "cocoon"];
69
70 for (Index, Subdomain) in Subdomains.iter().enumerate() {
71 let SubdomainName = Name::from_ascii(format!("{}.editor.land.", Subdomain)).unwrap();
72
73 let IP = A::new(127, 0, (Index / 255) as u8, (Index % 255) as u8);
74
75 Records.push(Record::from_rdata(SubdomainName, TTL, RData::A(IP)));
76 }
77
78 Records.push(Record::from_rdata(Origin, TTL, RData::A(A::new(127, 0, 0, 1))));
79
80 Ok(Records)
81}
82
83pub fn EditorLandAuthority() -> Result<InMemoryZoneHandler<TokioRuntimeProvider>> {
85 let Origin = Name::from_ascii("editor.land.").unwrap();
86
87 let Authority =
88 InMemoryZoneHandler::<TokioRuntimeProvider>::empty(Origin, ZoneType::Primary, AxfrPolicy::Deny, None);
89
90 let _Records = EditorLandZone()?;
91
92 Ok(Authority)
93}
94
95pub fn CustomAuthority(Origin:&Name, _Records:Vec<Record>) -> Result<InMemoryZoneHandler<TokioRuntimeProvider>> {
97 let Authority =
98 InMemoryZoneHandler::<TokioRuntimeProvider>::empty(Origin.clone(), ZoneType::Primary, AxfrPolicy::Deny, None);
99
100 Ok(Authority)
101}
102
103#[cfg(test)]
104mod tests {
105
106 use hickory_server::zone_handler::ZoneHandler;
107
108 use super::*;
109
110 #[test]
111 fn TestZoneCreation() {
112 let Zone = EditorLandZone().expect("Failed to create zone");
113
114 assert!(!Zone.is_empty());
115 }
116
117 #[test]
118 fn TestZoneHasLoopbackRecords() {
119 let Zone = EditorLandZone().expect("Failed to create zone");
120
121 for Record in &Zone {
122 if let RData::A(IP) = Record.data() {
123 assert_eq!(IP.octets()[0], 127, "A record must resolve to 127.x.x.x");
124 }
125 }
126 }
127}