Skip to main content

koi_common/
integration.rs

1//! Integration traits for cross-crate abstractions.
2//!
3//! These traits define contracts that domain crates implement
4//! and the binary crate wires together, without domain crates
5//! importing each other.
6//!
7//! Domain crates depend only on `koi-common`, never on each other.
8//! The binary crate (or `koi-embedded`) provides bridge implementations
9//! that wrap concrete domain cores and implement these traits.
10
11use std::collections::HashMap;
12use std::net::IpAddr;
13
14use chrono::{DateTime, Utc};
15use serde::{Deserialize, Serialize};
16
17use crate::types::ServiceRecord;
18
19// ── Status reporter ────────────────────────────────────────────────
20
21/// Trait for types that can report a capability status summary.
22///
23/// Each domain core implements this so the binary crate can
24/// build a unified status view without coupling domains.
25pub trait StatusReporter: Send + Sync {
26    /// Machine-readable capability name (e.g. "mdns", "dns", "health").
27    fn capability_name(&self) -> &'static str;
28
29    /// Whether the capability is currently operational.
30    fn is_running(&self) -> bool;
31
32    /// Optional human-readable status detail.
33    fn status_detail(&self) -> Option<String> {
34        None
35    }
36}
37
38// ── Summary types ──────────────────────────────────────────────────
39
40/// Summary of a certmesh member, projected through the trait boundary.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct MemberSummary {
43    pub hostname: String,
44    pub sans: Vec<String>,
45    pub cert_expires: Option<DateTime<Utc>>,
46    pub last_seen: Option<DateTime<Utc>>,
47    pub status: String,
48    pub proxy_entries: Vec<ProxyConfigSummary>,
49}
50
51/// Proxy configuration entry projected through the trait boundary.
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct ProxyConfigSummary {
54    pub name: String,
55    pub listen_port: u16,
56    pub backend: String,
57    pub allow_remote: bool,
58}
59
60/// Lightweight proxy entry used by health checks.
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct ProxyEntrySummary {
63    pub name: String,
64    pub listen_port: u16,
65    pub backend: String,
66}
67
68// ── Cross-domain traits ────────────────────────────────────────────
69
70/// Read-only snapshot of the certmesh roster.
71pub trait CertmeshSnapshot: Send + Sync {
72    /// Return summaries of all active members.
73    fn active_members(&self) -> Vec<MemberSummary>;
74}
75
76/// Read-only snapshot of mDNS network state.
77pub trait MdnsSnapshot: Send + Sync {
78    /// Map of hostname → IP derived from mDNS service records.
79    fn host_ips(&self) -> HashMap<String, IpAddr>;
80
81    /// All cached mDNS service records (for DNS alias building).
82    fn cached_records(&self) -> Vec<ServiceRecord>;
83}
84
85/// Resolve a local DNS name without importing the DNS crate.
86pub trait DnsProbe: Send + Sync {
87    /// Resolve a local name to IP addresses (A or AAAA).
88    fn resolve_local(&self, name: &str) -> Option<Vec<IpAddr>>;
89}
90
91/// Read-only snapshot of proxy entries.
92pub trait ProxySnapshot: Send + Sync {
93    /// Return all configured proxy entries.
94    fn entries(&self) -> Vec<ProxyEntrySummary>;
95}
96
97/// Write-back channel for DNS alias feedback to certmesh.
98///
99/// When the DNS resolver discovers mDNS aliases, it can push them
100/// to certmesh so that certificates include the correct SANs.
101pub trait AliasFeedback: Send + Sync {
102    /// Record that `hostname` should have `alias` as a SAN.
103    fn record_alias(&self, hostname: &str, alias: &str);
104}