wip: TlsRoute score first version
Some checks failed
Run Check Script / check (pull_request) Failing after 1m11s

This commit is contained in:
2025-12-13 22:32:27 -05:00
parent 2254641f3d
commit 142300802d
5 changed files with 104 additions and 2 deletions

View File

@@ -75,8 +75,6 @@ pub struct TlsRoute {
pub target_port: u16,
}
#[async_trait]
/// Installs and queries TLS passthrough routes (L4 TCP/SNI forwarding, no TLS termination).
/// Agnostic to impl: OKD Route, AWS NLB+HAProxy, k3s Envoy Gateway, Apache ProxyPass.
/// Used by PostgreSQL capability to expose CNPG clusters multisite (site1 → site2 replication).
@@ -91,6 +89,7 @@ pub struct TlsRoute {
/// topology.install_route(route).await; // OKD Route, HAProxy reload, etc.
/// }
/// ```
#[async_trait]
pub trait TlsRouter: Send + Sync {
/// Provisions the route (idempotent where possible).
/// Example: OKD Route{ host, to: backend:target_port, tls: {passthrough} };

View File

@@ -11,6 +11,7 @@ pub mod k8s;
pub mod lamp;
pub mod load_balancer;
pub mod monitoring;
pub mod network;
pub mod okd;
pub mod opnsense;
pub mod postgresql;

View File

@@ -0,0 +1,2 @@
mod tls_router;
pub use tls_router::*;

View File

@@ -0,0 +1,99 @@
use async_trait::async_trait;
use harmony_types::id::Id;
use serde::Serialize;
use crate::data::Version;
use crate::domain::topology::router::{TlsRoute, TlsRouter};
use crate::interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome};
use crate::inventory::Inventory;
use crate::score::Score;
use crate::topology::{K8sclient, Topology};
/// Score for provisioning a TLS passthrough route.
/// Exposes backend services via TLS passthrough (L4 TCP/SNI forwarding).
/// Agnostic to underlying router impl (OKD Route, HAProxy, Envoy, etc.).
///
/// # Usage
/// ```
/// use harmony::modules::network::TlsRouterScore;
/// let score = TlsRouterScore::new("postgres-cluster-rw", "pg-rw.example.com", 5432);
/// ```
#[derive(Debug, Clone, Serialize)]
pub struct TlsRouterScore {
/// Backend identifier (k8s Service, HAProxy upstream, IP/FQDN, etc.).
pub backend: String,
/// Public hostname clients connect to (TLS SNI, port 443 implicit).
pub hostname: String,
/// Backend TCP port.
pub target_port: u16,
}
impl Default for TlsRouterScore {
fn default() -> Self {
Self {
backend: "default-backend".to_string(),
hostname: "tls.default.public".to_string(),
target_port: 5432,
}
}
}
impl TlsRouterScore {
pub fn new(backend: &str, hostname: &str, target_port: u16) -> Self {
Self {
backend: backend.to_string(),
hostname: hostname.to_string(),
target_port,
}
}
}
/// Custom interpret: provisions the TLS passthrough route on the topology.
#[derive(Debug, Clone)]
struct TlsRouterInterpret {
tls_route: TlsRoute,
}
#[async_trait]
impl<T: Topology + K8sclient + TlsRouter + Send + Sync> Interpret<T> for TlsRouterInterpret {
fn get_name(&self) -> InterpretName {
InterpretName::Custom("TlsRouterInterpret")
}
fn get_version(&self) -> Version {
todo!()
}
fn get_status(&self) -> InterpretStatus {
todo!()
}
fn get_children(&self) -> Vec<Id> {
todo!()
}
async fn execute(&self, _inventory: &Inventory, topo: &T) -> Result<Outcome, InterpretError> {
topo.install_route(self.tls_route.clone())
.await
.map_err(|e| InterpretError::new(e.to_string()))?;
Ok(Outcome::success(format!(
"TLS route installed: {}{}:{}",
self.tls_route.hostname, self.tls_route.backend, self.tls_route.target_port
)))
}
}
impl<T: Topology + K8sclient + TlsRouter + Send + Sync> Score<T> for TlsRouterScore {
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
let tls_route = TlsRoute {
hostname: self.hostname.clone(),
backend: self.backend.clone(),
target_port: self.target_port,
};
Box::new(TlsRouterInterpret { tls_route })
}
fn name(&self) -> String {
format!(
"TlsRouterScore({}:{ }{})",
self.backend, self.target_port, self.hostname
)
}
}

View File

@@ -12,6 +12,7 @@ pub mod dns;
pub mod installation;
pub mod ipxe;
pub mod load_balancer;
pub mod route;
pub mod templates;
pub mod upgrade;
pub use bootstrap_01_prepare::*;