Skip to main content

dnslib/core/dns/
service.rs

1//! Vendor-neutral DNS service contracts.
2//!
3//! Vendor adapters implement these traits so the CLI and MCP layers can depend
4//! on DNS capabilities instead of concrete vendor clients.
5
6use std::future::Future;
7
8use serde_json::Value;
9
10use crate::control_plane::config::VendorKind;
11use crate::core::dns::capabilities::VendorCapabilities;
12use crate::core::dns::logs::LogsRead;
13use crate::core::dns::records::RecordData;
14use crate::core::dns::responses::ListRecordsResponse;
15use crate::core::error::Result;
16
17#[derive(Debug, Clone, Copy, Default)]
18pub struct ListRecordsOptions {
19    pub use_local_ip: bool,
20    /// Fetch all records in the zone so the caller can filter for a domain and its subdomains.
21    pub all_subdomains: bool,
22}
23
24pub trait DnsVendor {
25    fn kind(&self) -> VendorKind;
26
27    fn capabilities(&self) -> VendorCapabilities;
28}
29
30pub trait ZoneRead {
31    fn list_zones(
32        &self,
33        page: u32,
34        per_page: u32,
35    ) -> impl Future<Output = Result<Value>> + Send + '_;
36
37    fn list_records<'a>(
38        &'a self,
39        domain: &'a str,
40        zone: Option<&'a str>,
41        options: ListRecordsOptions,
42    ) -> impl Future<Output = Result<ListRecordsResponse>> + Send + 'a;
43}
44
45pub trait ZoneWrite {
46    fn create_zone<'a>(
47        &'a self,
48        zone: &'a str,
49        zone_type: &'a str,
50    ) -> impl Future<Output = Result<Value>> + Send + 'a;
51
52    fn delete_zone<'a>(&'a self, zone: &'a str) -> impl Future<Output = Result<Value>> + Send + 'a;
53
54    fn enable_zone<'a>(&'a self, zone: &'a str) -> impl Future<Output = Result<Value>> + Send + 'a;
55
56    fn disable_zone<'a>(&'a self, zone: &'a str)
57    -> impl Future<Output = Result<Value>> + Send + 'a;
58}
59
60pub trait RecordWrite {
61    fn add_record<'a>(
62        &'a self,
63        zone: &'a str,
64        domain: &'a str,
65        ttl: u32,
66        record: &'a RecordData,
67    ) -> impl Future<Output = Result<Value>> + Send + 'a;
68
69    fn delete_record<'a>(
70        &'a self,
71        zone: &'a str,
72        domain: &'a str,
73        type_params: &'a [(&'a str, String)],
74    ) -> impl Future<Output = Result<Value>> + Send + 'a;
75}
76
77pub trait CacheRead {
78    fn list_cache<'a>(&'a self, domain: &'a str)
79    -> impl Future<Output = Result<Value>> + Send + 'a;
80}
81
82pub trait CacheWrite {
83    fn delete_cache_zone<'a>(
84        &'a self,
85        domain: &'a str,
86    ) -> impl Future<Output = Result<Value>> + Send + 'a;
87
88    fn flush_cache(&self) -> impl Future<Output = Result<Value>> + Send + '_;
89}
90
91pub trait StatsRead {
92    fn get_stats<'a>(
93        &'a self,
94        stats_type: &'a str,
95    ) -> impl Future<Output = Result<Value>> + Send + 'a;
96}
97
98pub trait AccessListRead {
99    fn list_blocked(&self) -> impl Future<Output = Result<Value>> + Send + '_;
100
101    fn list_allowed(&self) -> impl Future<Output = Result<Value>> + Send + '_;
102}
103
104pub trait AccessListWrite {
105    fn add_blocked<'a>(
106        &'a self,
107        domain: &'a str,
108    ) -> impl Future<Output = Result<Value>> + Send + 'a;
109
110    fn delete_blocked<'a>(
111        &'a self,
112        domain: &'a str,
113    ) -> impl Future<Output = Result<Value>> + Send + 'a;
114
115    fn add_allowed<'a>(
116        &'a self,
117        domain: &'a str,
118    ) -> impl Future<Output = Result<Value>> + Send + 'a;
119
120    fn delete_allowed<'a>(
121        &'a self,
122        domain: &'a str,
123    ) -> impl Future<Output = Result<Value>> + Send + 'a;
124}
125
126pub trait ZoneImport {
127    fn import_zone_file<'a>(
128        &'a self,
129        zone: &'a str,
130        file_name: String,
131        file_bytes: Vec<u8>,
132        overwrite: bool,
133        overwrite_zone: bool,
134        overwrite_soa_serial: bool,
135    ) -> impl Future<Output = Result<Value>> + Send + 'a;
136}
137
138pub trait ZoneExport {
139    fn export_zone_file<'a>(
140        &'a self,
141        zone: &'a str,
142    ) -> impl Future<Output = Result<String>> + Send + 'a;
143}
144
145pub trait SettingsRead {
146    fn get_settings(&self) -> impl Future<Output = Result<Value>> + Send + '_;
147}
148
149pub trait DnsRead:
150    DnsVendor + ZoneRead + CacheRead + StatsRead + AccessListRead + SettingsRead + ZoneExport + LogsRead
151{
152}
153
154impl<T> DnsRead for T where
155    T: DnsVendor
156        + ZoneRead
157        + CacheRead
158        + StatsRead
159        + AccessListRead
160        + SettingsRead
161        + ZoneExport
162        + LogsRead
163{
164}
165
166pub trait DnsWrite: ZoneWrite + RecordWrite + CacheWrite + AccessListWrite + ZoneImport {}
167
168impl<T> DnsWrite for T where T: ZoneWrite + RecordWrite + CacheWrite + AccessListWrite + ZoneImport {}
169
170pub trait DnsService: DnsRead + DnsWrite + Send + Sync {}
171
172impl<T> DnsService for T where T: DnsRead + DnsWrite + Send + Sync {}