All checks were successful
Run Check Script / check (pull_request) Successful in 1m1s
176 lines
5.1 KiB
Rust
176 lines
5.1 KiB
Rust
use async_trait::async_trait;
|
|
use harmony_macros::ingress_path;
|
|
use harmony_types::id::Id;
|
|
use k8s_openapi::api::networking::v1::Ingress;
|
|
use log::{debug, trace};
|
|
use serde::Serialize;
|
|
use serde_json::json;
|
|
|
|
use crate::{
|
|
data::Version,
|
|
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
|
inventory::Inventory,
|
|
score::Score,
|
|
topology::{K8sclient, Topology},
|
|
};
|
|
|
|
use super::resource::{K8sResourceInterpret, K8sResourceScore};
|
|
|
|
#[derive(Debug, Clone, Serialize)]
|
|
pub enum PathType {
|
|
ImplementationSpecific,
|
|
Exact,
|
|
Prefix,
|
|
}
|
|
|
|
impl PathType {
|
|
fn as_str(&self) -> &'static str {
|
|
match self {
|
|
PathType::ImplementationSpecific => "ImplementationSpecific",
|
|
PathType::Exact => "Exact",
|
|
PathType::Prefix => "Prefix",
|
|
}
|
|
}
|
|
}
|
|
|
|
type IngressPath = String;
|
|
|
|
#[derive(Debug, Clone, Serialize)]
|
|
pub struct K8sIngressScore {
|
|
pub name: fqdn::FQDN,
|
|
pub host: fqdn::FQDN,
|
|
pub backend_service: fqdn::FQDN,
|
|
pub port: u16,
|
|
pub path: Option<IngressPath>,
|
|
pub path_type: Option<PathType>,
|
|
pub namespace: Option<fqdn::FQDN>,
|
|
pub ingress_class_name: Option<String>,
|
|
}
|
|
|
|
impl<T: Topology + K8sclient> Score<T> for K8sIngressScore {
|
|
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
|
let path = match self.path.clone() {
|
|
Some(p) => p,
|
|
None => ingress_path!("/"),
|
|
};
|
|
|
|
let path_type = match self.path_type.clone() {
|
|
Some(p) => p,
|
|
None => PathType::Prefix,
|
|
};
|
|
|
|
let ingress_class = match self.ingress_class_name.clone() {
|
|
Some(ingress_class_name) => ingress_class_name,
|
|
None => "\"default\"".to_string(),
|
|
};
|
|
|
|
let ingress = json!(
|
|
{
|
|
"metadata": {
|
|
"name": self.name.to_string(),
|
|
},
|
|
"spec": {
|
|
"ingressClassName": ingress_class.as_str(),
|
|
"rules": [
|
|
{ "host": self.host.to_string(),
|
|
"http": {
|
|
"paths": [
|
|
{
|
|
"path": path,
|
|
"pathType": path_type.as_str(),
|
|
"backend": {
|
|
"service": {
|
|
"name": self.backend_service.to_string(),
|
|
"port": {
|
|
"number": self.port,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
);
|
|
|
|
trace!("Building ingresss object from Value {ingress:#}");
|
|
let ingress: Ingress = serde_json::from_value(ingress).unwrap();
|
|
debug!(
|
|
"Successfully built Ingress for host {:?}",
|
|
ingress.metadata.name
|
|
);
|
|
|
|
Box::new(K8sIngressInterpret {
|
|
ingress,
|
|
service: self.name.to_string(),
|
|
namespace: self.namespace.clone().map(|f| f.to_string()),
|
|
host: self.host.clone(),
|
|
})
|
|
}
|
|
|
|
fn name(&self) -> String {
|
|
format!("{} K8sIngressScore", self.name)
|
|
}
|
|
}
|
|
|
|
#[derive(std::fmt::Debug)]
|
|
struct K8sIngressInterpret {
|
|
ingress: Ingress,
|
|
service: String,
|
|
namespace: Option<String>,
|
|
host: fqdn::FQDN,
|
|
}
|
|
|
|
#[async_trait]
|
|
impl<T: Topology + K8sclient> Interpret<T> for K8sIngressInterpret {
|
|
async fn execute(
|
|
&self,
|
|
inventory: &Inventory,
|
|
topology: &T,
|
|
) -> Result<Outcome, InterpretError> {
|
|
let result = K8sResourceInterpret {
|
|
score: K8sResourceScore::single(self.ingress.clone(), self.namespace.clone()),
|
|
}
|
|
.execute(inventory, topology)
|
|
.await;
|
|
|
|
match result {
|
|
Ok(outcome) => match outcome.status {
|
|
InterpretStatus::SUCCESS => {
|
|
let details = match &self.namespace {
|
|
Some(namespace) => {
|
|
vec![format!(
|
|
"{} ({namespace}): http://{}",
|
|
self.service, self.host
|
|
)]
|
|
}
|
|
None => vec![format!("{}: {}", self.service, self.host)],
|
|
};
|
|
|
|
Ok(Outcome::success_with_details(outcome.message, details))
|
|
}
|
|
_ => Ok(outcome),
|
|
},
|
|
Err(e) => Err(e),
|
|
}
|
|
}
|
|
|
|
fn get_name(&self) -> InterpretName {
|
|
InterpretName::K8sIngress
|
|
}
|
|
|
|
fn get_version(&self) -> Version {
|
|
Version::from("0.0.1").unwrap()
|
|
}
|
|
|
|
fn get_status(&self) -> InterpretStatus {
|
|
todo!()
|
|
}
|
|
|
|
fn get_children(&self) -> Vec<Id> {
|
|
vec![]
|
|
}
|
|
}
|