feat: OKD route CRD and OKD specific route score
All checks were successful
Run Check Script / check (pull_request) Successful in 1m30s
All checks were successful
Run Check Script / check (pull_request) Successful in 1m30s
This commit is contained in:
@@ -13,13 +13,30 @@ use crate::topology::{K8sclient, Topology};
|
|||||||
/// Exposes backend services via TLS passthrough (L4 TCP/SNI forwarding).
|
/// Exposes backend services via TLS passthrough (L4 TCP/SNI forwarding).
|
||||||
/// Agnostic to underlying router impl (OKD Route, HAProxy, Envoy, etc.).
|
/// Agnostic to underlying router impl (OKD Route, HAProxy, Envoy, etc.).
|
||||||
///
|
///
|
||||||
|
/// TlsPassthroughScore relies on the TlsRouter Capability for its entire functionnality,
|
||||||
|
/// the implementation depends entirely on how the Topology implements it.
|
||||||
|
///
|
||||||
/// # Usage
|
/// # Usage
|
||||||
/// ```
|
/// ```
|
||||||
/// use harmony::modules::network::TlsRouterScore;
|
/// use harmony::modules::network::TlsPassthroughScore;
|
||||||
/// let score = TlsRouterScore::new("postgres-cluster-rw", "pg-rw.example.com", 5432);
|
/// let score = TlsPassthroughScore {
|
||||||
|
/// backend: "postgres-cluster-rw".to_string(),
|
||||||
|
/// hostname: "postgres-rw.example.com".to_string(),
|
||||||
|
/// target_port: 5432,
|
||||||
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Hint
|
||||||
|
///
|
||||||
|
/// **This TlsPassthroughScore should be used whenever possible.** It is effectively
|
||||||
|
/// an abstraction over the concept of tls passthrough, and it will allow much more flexible
|
||||||
|
/// usage over multiple types of Topology than using a lower level module such as
|
||||||
|
/// OKDTlsPassthroughScore.
|
||||||
|
///
|
||||||
|
/// On the other hand, some implementation specific options might not be available or practical
|
||||||
|
/// to use through this high level TlsPassthroughScore.
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct TlsRouterScore {
|
pub struct TlsPassthroughScore {
|
||||||
/// Backend identifier (k8s Service, HAProxy upstream, IP/FQDN, etc.).
|
/// Backend identifier (k8s Service, HAProxy upstream, IP/FQDN, etc.).
|
||||||
pub backend: String,
|
pub backend: String,
|
||||||
/// Public hostname clients connect to (TLS SNI, port 443 implicit).
|
/// Public hostname clients connect to (TLS SNI, port 443 implicit).
|
||||||
@@ -28,34 +45,32 @@ pub struct TlsRouterScore {
|
|||||||
pub target_port: u16,
|
pub target_port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TlsRouterScore {
|
impl<T: Topology + K8sclient + TlsRouter + Send + Sync> Score<T> for TlsPassthroughScore {
|
||||||
fn default() -> Self {
|
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||||
Self {
|
let tls_route = TlsRoute {
|
||||||
backend: "default-backend".to_string(),
|
hostname: self.hostname.clone(),
|
||||||
hostname: "tls.default.public".to_string(),
|
backend: self.backend.clone(),
|
||||||
target_port: 5432,
|
target_port: self.target_port,
|
||||||
}
|
};
|
||||||
|
Box::new(TlsPassthroughInterpret { tls_route })
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl TlsRouterScore {
|
fn name(&self) -> String {
|
||||||
pub fn new(backend: &str, hostname: &str, target_port: u16) -> Self {
|
format!(
|
||||||
Self {
|
"TlsRouterScore({}:{} → {})",
|
||||||
backend: backend.to_string(),
|
self.backend, self.target_port, self.hostname
|
||||||
hostname: hostname.to_string(),
|
)
|
||||||
target_port,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Custom interpret: provisions the TLS passthrough route on the topology.
|
/// Custom interpret: provisions the TLS passthrough route on the topology.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct TlsRouterInterpret {
|
struct TlsPassthroughInterpret {
|
||||||
tls_route: TlsRoute,
|
tls_route: TlsRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: Topology + K8sclient + TlsRouter + Send + Sync> Interpret<T> for TlsRouterInterpret {
|
impl<T: Topology + K8sclient + TlsRouter + Send + Sync> Interpret<T> for TlsPassthroughInterpret {
|
||||||
fn get_name(&self) -> InterpretName {
|
fn get_name(&self) -> InterpretName {
|
||||||
InterpretName::Custom("TlsRouterInterpret")
|
InterpretName::Custom("TlsRouterInterpret")
|
||||||
}
|
}
|
||||||
@@ -79,21 +94,3 @@ impl<T: Topology + K8sclient + TlsRouter + Send + Sync> Interpret<T> for TlsRout
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
pub mod nmstate;
|
pub mod nmstate;
|
||||||
|
pub mod route;
|
||||||
|
|||||||
285
harmony/src/modules/okd/crd/route.rs
Normal file
285
harmony/src/modules/okd/crd/route.rs
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
use k8s_openapi::apimachinery::pkg::apis::meta::v1::{ListMeta, ObjectMeta, Time};
|
||||||
|
use k8s_openapi::apimachinery::pkg::util::intstr::IntOrString;
|
||||||
|
use k8s_openapi::{NamespaceResourceScope, Resource};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LocalObjectReference {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Route {
|
||||||
|
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
// pub api_version: Option<String>,
|
||||||
|
//
|
||||||
|
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
// pub kind: Option<String>,
|
||||||
|
pub metadata: ObjectMeta,
|
||||||
|
|
||||||
|
pub spec: RouteSpec,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub status: Option<RouteStatus>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Resource for Route {
|
||||||
|
const API_VERSION: &'static str = "route.openshift.io/v1";
|
||||||
|
const GROUP: &'static str = "route.openshift.io";
|
||||||
|
const VERSION: &'static str = "v1";
|
||||||
|
const KIND: &'static str = "Route";
|
||||||
|
const URL_PATH_SEGMENT: &'static str = "routes";
|
||||||
|
type Scope = NamespaceResourceScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl k8s_openapi::Metadata for Route {
|
||||||
|
type Ty = ObjectMeta;
|
||||||
|
|
||||||
|
fn metadata(&self) -> &Self::Ty {
|
||||||
|
&self.metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata_mut(&mut self) -> &mut Self::Ty {
|
||||||
|
&mut self.metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Route {
|
||||||
|
fn default() -> Self {
|
||||||
|
Route {
|
||||||
|
metadata: ObjectMeta::default(),
|
||||||
|
spec: RouteSpec::default(),
|
||||||
|
status: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteList {
|
||||||
|
pub metadata: ListMeta,
|
||||||
|
pub items: Vec<Route>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RouteList {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
metadata: ListMeta::default(),
|
||||||
|
items: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Resource for RouteList {
|
||||||
|
const API_VERSION: &'static str = "route.openshift.io/v1";
|
||||||
|
const GROUP: &'static str = "route.openshift.io";
|
||||||
|
const VERSION: &'static str = "v1";
|
||||||
|
const KIND: &'static str = "RouteList";
|
||||||
|
const URL_PATH_SEGMENT: &'static str = "routes";
|
||||||
|
type Scope = NamespaceResourceScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl k8s_openapi::Metadata for RouteList {
|
||||||
|
type Ty = ListMeta;
|
||||||
|
|
||||||
|
fn metadata(&self) -> &Self::Ty {
|
||||||
|
&self.metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata_mut(&mut self) -> &mut Self::Ty {
|
||||||
|
&mut self.metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteSpec {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub alternate_backends: Option<Vec<RouteTargetReference>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub host: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub http_headers: Option<RouteHTTPHeaders>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub path: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub port: Option<RoutePort>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub subdomain: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tls: Option<TLSConfig>,
|
||||||
|
|
||||||
|
pub to: RouteTargetReference,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub wildcard_policy: Option<String>,
|
||||||
|
}
|
||||||
|
impl Default for RouteSpec {
|
||||||
|
fn default() -> RouteSpec {
|
||||||
|
RouteSpec {
|
||||||
|
alternate_backends: None,
|
||||||
|
host: None,
|
||||||
|
http_headers: None,
|
||||||
|
path: None,
|
||||||
|
port: None,
|
||||||
|
subdomain: None,
|
||||||
|
tls: None,
|
||||||
|
to: RouteTargetReference::default(),
|
||||||
|
wildcard_policy: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteTargetReference {
|
||||||
|
pub kind: String,
|
||||||
|
pub name: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub weight: Option<i32>,
|
||||||
|
}
|
||||||
|
impl Default for RouteTargetReference {
|
||||||
|
fn default() -> RouteTargetReference {
|
||||||
|
RouteTargetReference {
|
||||||
|
kind: String::default(),
|
||||||
|
name: String::default(),
|
||||||
|
weight: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RoutePort {
|
||||||
|
pub target_port: IntOrString,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct TLSConfig {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub ca_certificate: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub certificate: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub destination_ca_certificate: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub external_certificate: Option<LocalObjectReference>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub insecure_edge_termination_policy: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub key: Option<String>,
|
||||||
|
|
||||||
|
pub termination: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TLSConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
ca_certificate: None,
|
||||||
|
certificate: None,
|
||||||
|
destination_ca_certificate: None,
|
||||||
|
external_certificate: None,
|
||||||
|
insecure_edge_termination_policy: None,
|
||||||
|
key: None,
|
||||||
|
termination: "edge".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteStatus {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub ingress: Option<Vec<RouteIngress>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteIngress {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub host: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub router_canonical_hostname: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub router_name: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub wildcard_policy: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub conditions: Option<Vec<RouteIngressCondition>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteIngressCondition {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub last_transition_time: Option<Time>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub message: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub reason: Option<String>,
|
||||||
|
|
||||||
|
pub status: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub condition_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteHTTPHeader {
|
||||||
|
pub name: String,
|
||||||
|
pub action: RouteHTTPHeaderActionUnion,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteHTTPHeaderActionUnion {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub set: Option<RouteSetHTTPHeader>,
|
||||||
|
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub action_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteSetHTTPHeader {
|
||||||
|
pub value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug, Default)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteHTTPHeaderActions {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub request: Option<Vec<RouteHTTPHeader>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub response: Option<Vec<RouteHTTPHeader>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RouteHTTPHeaders {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub actions: Option<RouteHTTPHeaderActions>,
|
||||||
|
}
|
||||||
136
harmony/src/modules/okd/route.rs
Normal file
136
harmony/src/modules/okd/route.rs
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
// TODO
|
||||||
|
// Write OKDRouteScore : This is the real one which will apply the k8s resource and expose all
|
||||||
|
// relevant option to Harmony's various use cases
|
||||||
|
//
|
||||||
|
// Write OKDTlsPassthroughScore : This one will use an OKDRouteScore under the hood and simply fill
|
||||||
|
// in all settings to make this route a TlsPassthrough
|
||||||
|
//
|
||||||
|
// These scores are meant to be used by an OKD based topology to provide Capabilities like
|
||||||
|
// TlsRouter
|
||||||
|
//
|
||||||
|
// The first use case to serve here is the postgresql multisite setup, so exposing only the
|
||||||
|
// settings relevant to this use case is enough at first, following YAGNI.
|
||||||
|
//
|
||||||
|
// These scores are not intended to be used directly by a user, unless the user knows that he will
|
||||||
|
// always be dealing only with okd/openshift compatible topologies and is ready to manage the
|
||||||
|
// additional maintenance burden that comes with a lower level functionnality.
|
||||||
|
|
||||||
|
use k8s_openapi::apimachinery::pkg::util::intstr::IntOrString;
|
||||||
|
use kube::api::ObjectMeta;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::modules::k8s::resource::K8sResourceScore;
|
||||||
|
use crate::modules::okd::crd::route::{
|
||||||
|
Route, RoutePort, RouteSpec, RouteTargetReference, TLSConfig,
|
||||||
|
};
|
||||||
|
use crate::score::Score;
|
||||||
|
use crate::topology::{K8sclient, Topology};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize)]
|
||||||
|
struct OKDRoutePort {
|
||||||
|
#[serde(rename = "targetPort")]
|
||||||
|
target_port: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize)]
|
||||||
|
struct OKDTLSConfig {
|
||||||
|
#[serde(rename = "termination")]
|
||||||
|
termination: String,
|
||||||
|
#[serde(rename = "insecureEdgeTerminationPolicy")]
|
||||||
|
insecure_edge_termination_policy: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct OKDRouteScore {
|
||||||
|
pub name: String,
|
||||||
|
pub namespace: String,
|
||||||
|
pub spec: RouteSpec,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OKDRouteScore {
|
||||||
|
pub fn new(name: &str, namespace: &str, spec: RouteSpec) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.to_string(),
|
||||||
|
namespace: namespace.to_string(),
|
||||||
|
spec,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Topology + K8sclient> Score<T> for OKDRouteScore {
|
||||||
|
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
|
||||||
|
let route = Route {
|
||||||
|
metadata: ObjectMeta {
|
||||||
|
name: Some(self.name.clone()),
|
||||||
|
namespace: Some(self.namespace.clone()),
|
||||||
|
..ObjectMeta::default()
|
||||||
|
},
|
||||||
|
spec: self.spec.clone(),
|
||||||
|
status: None,
|
||||||
|
};
|
||||||
|
K8sResourceScore::single(route, Some(self.namespace.clone())).create_interpret()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> String {
|
||||||
|
format!("OKDRouteScore({})", self.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct OKDTlsPassthroughScore {
|
||||||
|
pub name: String,
|
||||||
|
pub namespace: String,
|
||||||
|
pub backend: String,
|
||||||
|
pub hostname: String,
|
||||||
|
pub target_port: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OKDTlsPassthroughScore {
|
||||||
|
pub fn new(
|
||||||
|
name: &str,
|
||||||
|
namespace: &str,
|
||||||
|
backend: &str,
|
||||||
|
hostname: &str,
|
||||||
|
target_port: &str,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.to_string(),
|
||||||
|
namespace: namespace.to_string(),
|
||||||
|
backend: backend.to_string(),
|
||||||
|
hostname: hostname.to_string(),
|
||||||
|
target_port: target_port.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Topology + K8sclient> Score<T> for OKDTlsPassthroughScore {
|
||||||
|
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
|
||||||
|
let passthrough_spec = RouteSpec {
|
||||||
|
host: Some(self.hostname.clone()),
|
||||||
|
wildcard_policy: Some("None".to_string()),
|
||||||
|
to: RouteTargetReference {
|
||||||
|
kind: "Service".to_string(),
|
||||||
|
name: self.backend.clone(),
|
||||||
|
weight: Some(100),
|
||||||
|
},
|
||||||
|
port: Some(RoutePort {
|
||||||
|
target_port: IntOrString::String(self.target_port.clone()),
|
||||||
|
}),
|
||||||
|
tls: Some(TLSConfig {
|
||||||
|
termination: "passthrough".to_string(),
|
||||||
|
insecure_edge_termination_policy: Some("None".to_string()),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let route_score = OKDRouteScore::new(&self.name, &self.namespace, passthrough_spec);
|
||||||
|
route_score.create_interpret()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"OKDTlsPassthroughScore({}:{}/{} → {})",
|
||||||
|
self.backend, self.target_port, self.namespace, self.hostname
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user