feat: add ingress score (#32)
Co-authored-by: tahahawa <tahahawa@gmail.com> Reviewed-on: #32 Reviewed-by: wjro <wrolleman@nationtech.io>
This commit is contained in:
@@ -39,3 +39,11 @@ lazy_static = "1.5.0"
|
||||
dockerfile_builder = "0.1.5"
|
||||
temp-file = "0.1.9"
|
||||
convert_case.workspace = true
|
||||
fqdn = { version = "0.4.6", features = [
|
||||
"domain-label-cannot-start-or-end-with-hyphen",
|
||||
"domain-label-length-limited-to-63",
|
||||
"domain-name-without-special-chars",
|
||||
"domain-name-length-limited-to-255",
|
||||
"punycode",
|
||||
"serde",
|
||||
] }
|
||||
|
||||
98
harmony/src/modules/k8s/ingress.rs
Normal file
98
harmony/src/modules/k8s/ingress.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
use harmony_macros::ingress_path;
|
||||
use k8s_openapi::api::networking::v1::Ingress;
|
||||
use serde::Serialize;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
interpret::Interpret,
|
||||
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>,
|
||||
}
|
||||
|
||||
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 = json!(
|
||||
{
|
||||
"metadata": {
|
||||
"name": self.name
|
||||
},
|
||||
"spec": {
|
||||
"rules": [
|
||||
{ "host": self.host,
|
||||
"http": {
|
||||
"paths": [
|
||||
{
|
||||
"path": path,
|
||||
"pathType": path_type.as_str(),
|
||||
"backend": [
|
||||
{
|
||||
"service": self.backend_service,
|
||||
"port": self.port
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let ingress: Ingress = serde_json::from_value(ingress).unwrap();
|
||||
Box::new(K8sResourceInterpret {
|
||||
score: K8sResourceScore::single(
|
||||
ingress.clone(),
|
||||
self.namespace
|
||||
.clone()
|
||||
.map(|f| f.as_c_str().to_str().unwrap().to_string()),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
format!("{} K8sIngressScore", self.name)
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod deployment;
|
||||
pub mod ingress;
|
||||
pub mod namespace;
|
||||
pub mod resource;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use convert_case::{Case, Casing};
|
||||
use dockerfile_builder::instruction::{CMD, COPY, ENV, EXPOSE, FROM, RUN, WORKDIR};
|
||||
use dockerfile_builder::{Dockerfile, instruction_builder::EnvBuilder};
|
||||
use fqdn::fqdn;
|
||||
use harmony_macros::ingress_path;
|
||||
use non_blank_string_rs::NonBlankString;
|
||||
use serde_json::json;
|
||||
use std::collections::HashMap;
|
||||
@@ -13,6 +15,7 @@ use log::{debug, info};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::config::{REGISTRY_PROJECT, REGISTRY_URL};
|
||||
use crate::modules::k8s::ingress::K8sIngressScore;
|
||||
use crate::topology::HelmCommand;
|
||||
use crate::{
|
||||
data::{Id, Version},
|
||||
@@ -132,6 +135,29 @@ impl<T: Topology + K8sclient + HelmCommand> Interpret<T> for LAMPInterpret {
|
||||
|
||||
info!("LAMP deployment_score {deployment_score:?}");
|
||||
|
||||
let lamp_ingress = K8sIngressScore {
|
||||
name: fqdn!("lamp-ingress"),
|
||||
host: fqdn!("test"),
|
||||
backend_service: fqdn!(
|
||||
<LAMPScore as Score<T>>::name(&self.score)
|
||||
.to_case(Case::Kebab)
|
||||
.as_str()
|
||||
),
|
||||
port: 8080,
|
||||
path: Some(ingress_path!("/")),
|
||||
path_type: None,
|
||||
namespace: self
|
||||
.get_namespace()
|
||||
.map(|nbs| fqdn!(nbs.to_string().as_str())),
|
||||
};
|
||||
|
||||
lamp_ingress
|
||||
.create_interpret()
|
||||
.execute(inventory, topology)
|
||||
.await?;
|
||||
|
||||
info!("LAMP lamp_ingress {lamp_ingress:?}");
|
||||
|
||||
Ok(Outcome::success(
|
||||
"Successfully deployed LAMP Stack!".to_string(),
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user