feat: Impl TlsRoute for K8sAnywhereTopology
This commit is contained in:
@@ -152,6 +152,12 @@ pub struct InterpretError {
|
|||||||
msg: String,
|
msg: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<InterpretError> for String {
|
||||||
|
fn from(e: InterpretError) -> String {
|
||||||
|
format!("InterpretError : {}", e.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for InterpretError {
|
impl std::fmt::Display for InterpretError {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_str(&self.msg)
|
f.write_str(&self.msg)
|
||||||
|
|||||||
@@ -34,13 +34,14 @@ use crate::{
|
|||||||
service_monitor::ServiceMonitor,
|
service_monitor::ServiceMonitor,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
network::TlsPassthroughScore,
|
||||||
prometheus::{
|
prometheus::{
|
||||||
k8s_prometheus_alerting_score::K8sPrometheusCRDAlertingScore,
|
k8s_prometheus_alerting_score::K8sPrometheusCRDAlertingScore,
|
||||||
prometheus::PrometheusMonitoring, rhob_alerting_score::RHOBAlertingScore,
|
prometheus::PrometheusMonitoring, rhob_alerting_score::RHOBAlertingScore,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
score::Score,
|
score::Score,
|
||||||
topology::ingress::Ingress,
|
topology::{TlsRoute, TlsRouter, ingress::Ingress},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
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]
|
#[async_trait]
|
||||||
impl Grafana for K8sAnywhereTopology {
|
impl Grafana for K8sAnywhereTopology {
|
||||||
async fn ensure_grafana_operator(
|
async fn ensure_grafana_operator(
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use cidr::Ipv4Cidr;
|
use cidr::Ipv4Cidr;
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::{IpAddress, LogicalHost};
|
use super::{IpAddress, LogicalHost};
|
||||||
|
|
||||||
@@ -47,8 +48,6 @@ impl Router for UnmanagedRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
|
|
||||||
/// Desired state config for a TLS passthrough route.
|
/// Desired state config for a TLS passthrough route.
|
||||||
/// Forwards external TLS (port 443) → backend service:target_port (no termination at router).
|
/// 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
|
/// 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,
|
/// target_port: 5432,
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
|
#[derive(Clone, Debug, Serialize)]
|
||||||
pub struct TlsRoute {
|
pub struct TlsRoute {
|
||||||
/// Public hostname clients connect to (TLS SNI, port 443 implicit).
|
/// Public hostname clients connect to (TLS SNI, port 443 implicit).
|
||||||
/// Router matches this for passthrough forwarding.
|
/// 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} };
|
/// Example: OKD Route{ host, to: backend:target_port, tls: {passthrough} };
|
||||||
/// HAProxy frontend→backend \"postgres-upstream\".
|
/// HAProxy frontend→backend \"postgres-upstream\".
|
||||||
async fn install_route(&self, config: TlsRoute) -> Result<(), String>;
|
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
|
/// # Usage
|
||||||
/// ```
|
/// ```
|
||||||
/// use harmony::modules::network::TlsPassthroughScore;
|
/// use harmony::modules::network::TlsPassthroughScore;
|
||||||
|
/// use harmony::topology::router::TlsRoute;
|
||||||
/// let score = TlsPassthroughScore {
|
/// let score = TlsPassthroughScore {
|
||||||
|
/// route: TlsRoute {
|
||||||
/// backend: "postgres-cluster-rw".to_string(),
|
/// backend: "postgres-cluster-rw".to_string(),
|
||||||
/// hostname: "postgres-rw.example.com".to_string(),
|
/// hostname: "postgres-rw.example.com".to_string(),
|
||||||
/// target_port: 5432,
|
/// target_port: 5432,
|
||||||
|
/// },
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
@@ -37,28 +40,20 @@ use crate::topology::{K8sclient, Topology};
|
|||||||
/// to use through this high level TlsPassthroughScore.
|
/// to use through this high level TlsPassthroughScore.
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct TlsPassthroughScore {
|
pub struct TlsPassthroughScore {
|
||||||
/// Backend identifier (k8s Service, HAProxy upstream, IP/FQDN, etc.).
|
pub route: TlsRoute,
|
||||||
pub backend: String,
|
|
||||||
/// Public hostname clients connect to (TLS SNI, port 443 implicit).
|
|
||||||
pub hostname: String,
|
|
||||||
/// Backend TCP port.
|
|
||||||
pub target_port: u16,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Topology + K8sclient + TlsRouter + Send + Sync> Score<T> for TlsPassthroughScore {
|
impl<T: Topology + K8sclient + TlsRouter + Send + Sync> Score<T> for TlsPassthroughScore {
|
||||||
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||||
let tls_route = TlsRoute {
|
Box::new(TlsPassthroughInterpret {
|
||||||
hostname: self.hostname.clone(),
|
tls_route: self.route.clone(),
|
||||||
backend: self.backend.clone(),
|
})
|
||||||
target_port: self.target_port,
|
|
||||||
};
|
|
||||||
Box::new(TlsPassthroughInterpret { tls_route })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
format!(
|
format!(
|
||||||
"TlsRouterScore({}:{} → {})",
|
"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