feat: Impl TlsRoute for K8sAnywhereTopology
This commit is contained in:
@@ -152,6 +152,12 @@ pub struct InterpretError {
|
||||
msg: String,
|
||||
}
|
||||
|
||||
impl From<InterpretError> for String {
|
||||
fn from(e: InterpretError) -> String {
|
||||
format!("InterpretError : {}", e.msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for InterpretError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(&self.msg)
|
||||
|
||||
@@ -34,13 +34,14 @@ use crate::{
|
||||
service_monitor::ServiceMonitor,
|
||||
},
|
||||
},
|
||||
network::TlsPassthroughScore,
|
||||
prometheus::{
|
||||
k8s_prometheus_alerting_score::K8sPrometheusCRDAlertingScore,
|
||||
prometheus::PrometheusMonitoring, rhob_alerting_score::RHOBAlertingScore,
|
||||
},
|
||||
},
|
||||
score::Score,
|
||||
topology::ingress::Ingress,
|
||||
topology::{TlsRoute, TlsRouter, ingress::Ingress},
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -102,6 +103,29 @@ impl K8sclient for K8sAnywhereTopology {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl TlsRouter for K8sAnywhereTopology {
|
||||
async fn install_route(&self, route: TlsRoute) -> Result<(), String> {
|
||||
if let Some(distro) = self.k8s_distribution.get() {
|
||||
match distro {
|
||||
KubernetesDistribution::OpenshiftFamily => {
|
||||
TlsPassthroughScore { route }
|
||||
.interpret(&Inventory::empty(), self)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
KubernetesDistribution::K3sFamily | KubernetesDistribution::Default => Err(
|
||||
format!("Distribution not supported yet for Tlsrouter {distro:?}"),
|
||||
),
|
||||
}
|
||||
} else {
|
||||
Err(format!(
|
||||
"Could not find a k8s distribution, TlsRouter in K8sAnywhereTopology requires it"
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Grafana for K8sAnywhereTopology {
|
||||
async fn ensure_grafana_operator(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use async_trait::async_trait;
|
||||
use cidr::Ipv4Cidr;
|
||||
use derive_new::new;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::{IpAddress, LogicalHost};
|
||||
|
||||
@@ -47,8 +48,6 @@ impl Router for UnmanagedRouter {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
||||
/// Desired state config for a TLS passthrough route.
|
||||
/// Forwards external TLS (port 443) → backend service:target_port (no termination at router).
|
||||
/// Inspired by CNPG multisite: exposes `-rw`/`-ro` services publicly via OKD Route/HAProxy/K8s
|
||||
@@ -63,6 +62,7 @@ impl Router for UnmanagedRouter {
|
||||
/// target_port: 5432,
|
||||
/// };
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct TlsRoute {
|
||||
/// Public hostname clients connect to (TLS SNI, port 443 implicit).
|
||||
/// Router matches this for passthrough forwarding.
|
||||
@@ -95,24 +95,4 @@ pub trait TlsRouter: Send + Sync {
|
||||
/// Example: OKD Route{ host, to: backend:target_port, tls: {passthrough} };
|
||||
/// HAProxy frontend→backend \"postgres-upstream\".
|
||||
async fn install_route(&self, config: TlsRoute) -> Result<(), String>;
|
||||
|
||||
/// Installed route's public hostname.
|
||||
fn hostname(&self) -> String;
|
||||
|
||||
/// Installed route's backend identifier.
|
||||
fn backend(&self) -> String;
|
||||
|
||||
/// Installed route's backend port.
|
||||
fn target_port(&self) -> u16;
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for dyn TlsRouter {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!(
|
||||
"TlsRouter[hostname={}, backend={}:{}]",
|
||||
self.hostname(),
|
||||
self.backend(),
|
||||
self.target_port()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,13 @@ use crate::topology::{K8sclient, Topology};
|
||||
/// # Usage
|
||||
/// ```
|
||||
/// use harmony::modules::network::TlsPassthroughScore;
|
||||
/// use harmony::topology::router::TlsRoute;
|
||||
/// let score = TlsPassthroughScore {
|
||||
/// route: TlsRoute {
|
||||
/// backend: "postgres-cluster-rw".to_string(),
|
||||
/// hostname: "postgres-rw.example.com".to_string(),
|
||||
/// target_port: 5432,
|
||||
/// },
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
@@ -37,28 +40,20 @@ use crate::topology::{K8sclient, Topology};
|
||||
/// to use through this high level TlsPassthroughScore.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct TlsPassthroughScore {
|
||||
/// 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,
|
||||
pub route: TlsRoute,
|
||||
}
|
||||
|
||||
impl<T: Topology + K8sclient + TlsRouter + Send + Sync> Score<T> for TlsPassthroughScore {
|
||||
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(TlsPassthroughInterpret { tls_route })
|
||||
Box::new(TlsPassthroughInterpret {
|
||||
tls_route: self.route.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
format!(
|
||||
"TlsRouterScore({}:{} → {})",
|
||||
self.backend, self.target_port, self.hostname
|
||||
self.route.backend, self.route.target_port, self.route.hostname
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user