siphon_server/dns_provider.rs
1//! DNS provider abstraction for tunnel DNS management
2//!
3//! This trait allows for different DNS backends (Cloudflare, mock for testing, etc.)
4
5use async_trait::async_trait;
6use thiserror::Error;
7
8/// Origin CA certificate and private key
9#[derive(Debug, Clone)]
10pub struct OriginCertificate {
11 /// PEM-encoded certificate
12 pub certificate: String,
13 /// PEM-encoded private key
14 pub private_key: String,
15 /// Certificate expiration date
16 pub expires_on: String,
17}
18
19/// Errors from DNS provider operations
20#[derive(Debug, Error)]
21pub enum DnsError {
22 #[error("HTTP request failed: {0}")]
23 Request(String),
24
25 #[error("API error: {0}")]
26 Api(String),
27}
28
29/// Trait for DNS and certificate management providers
30///
31/// This abstraction allows the server to work with different DNS backends,
32/// such as Cloudflare for production or a mock implementation for testing.
33#[async_trait]
34#[allow(dead_code)]
35pub trait DnsProvider: Send + Sync {
36 /// Create a DNS record for a subdomain
37 ///
38 /// # Arguments
39 /// * `subdomain` - The subdomain to create (e.g., "myapp")
40 /// * `proxied` - Whether to proxy through the provider (true for HTTP, false for TCP)
41 ///
42 /// # Returns
43 /// The DNS record ID for later deletion
44 async fn create_record(&self, subdomain: &str, proxied: bool) -> Result<String, DnsError>;
45
46 /// Delete a DNS record by its ID
47 async fn delete_record(&self, record_id: &str) -> Result<(), DnsError>;
48
49 /// Create an origin certificate for HTTPS
50 ///
51 /// # Arguments
52 /// * `validity_days` - Certificate validity in days
53 ///
54 /// # Returns
55 /// An OriginCertificate if the provider supports it, None otherwise
56 async fn create_origin_certificate(
57 &self,
58 validity_days: u32,
59 ) -> Result<Option<OriginCertificate>, DnsError>;
60
61 /// Clean up old origin certificates for this domain
62 ///
63 /// # Returns
64 /// The number of certificates revoked
65 async fn cleanup_old_origin_certificates(&self) -> Result<u32, DnsError>;
66}