Some checks failed
continuous-integration/drone/push Build is failing
Signed-off-by: kjuulh <contact@kjuulh.io>
173 lines
5.0 KiB
Rust
173 lines
5.0 KiB
Rust
use std::path::Path;
|
|
|
|
use minijinja::{context, syntax::SyntaxConfig};
|
|
|
|
use crate::Component;
|
|
|
|
use super::cuddle_vars::{load_cuddle_file, CuddleVariable, CuddleVariables};
|
|
|
|
pub enum IngressType {
|
|
External,
|
|
Internal,
|
|
ExternalGrpc,
|
|
InternalGrpc,
|
|
}
|
|
|
|
pub struct Ingress {
|
|
variables: CuddleVariables,
|
|
}
|
|
|
|
impl Ingress {
|
|
pub async fn new(path: &Path) -> anyhow::Result<Self> {
|
|
let variables = load_cuddle_file(path).await?;
|
|
|
|
Ok(Self { variables })
|
|
}
|
|
|
|
fn render_ingress_types(
|
|
&self,
|
|
ingress_types: Vec<IngressType>,
|
|
) -> anyhow::Result<(String, String)> {
|
|
let mut templates = Vec::new();
|
|
|
|
let internal_template = r#"
|
|
{%- set service_name = vars.cuddle_vars.service %}
|
|
{%- set host_name = vars.cuddle_vars.service | replace("_", "-") | replace(".", "-") %}
|
|
<%- macro host() -%>
|
|
<% if connection_type is defined %><<connection_type>>.<% endif %>{{ host_name }}.{{ environment }}.<< base_host >>
|
|
<%- endmacro %>
|
|
|
|
<%- macro k8s_service() -%>
|
|
<%- if connection_type == "grpc" -%>
|
|
{{ service_name }}-grpc
|
|
<%- else -%>
|
|
{{ service_name }}
|
|
<%- endif -%>
|
|
<%- endmacro %>
|
|
|
|
---
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
annotations:
|
|
cert-manager.io/issuer: << issuer >>
|
|
traefik.ingress.kubernetes.io/router.entrypoints: web
|
|
traefik.ingress.kubernetes.io/router.tls: "true"
|
|
labels:
|
|
app: {{ service_name }}
|
|
cluster: {{ vars.cluster_vars.name }}
|
|
name: {{ service_name }}-<< name >>
|
|
namespace: {{ vars.cluster_vars.namespace }}
|
|
spec:
|
|
rules:
|
|
- host: << host() >>
|
|
http:
|
|
paths:
|
|
- backend:
|
|
service:
|
|
name: << k8s_service() >>
|
|
port:
|
|
name: << name >>
|
|
path: /
|
|
pathType: Prefix
|
|
tls:
|
|
- hosts:
|
|
- << host() >>
|
|
secretName: tls-{{ service_name }}-<< issuer >>-<< name >>-ingress-dns
|
|
"#;
|
|
|
|
let get_template = |name, base_host, connection_type| {
|
|
let mut env = minijinja::Environment::new();
|
|
env.set_syntax(
|
|
SyntaxConfig::builder()
|
|
.block_delimiters("<%", "%>")
|
|
.variable_delimiters("<<", ">>")
|
|
.comment_delimiters("<#", "#>")
|
|
.build()
|
|
.expect("to be able to build minijinja syntax"),
|
|
);
|
|
|
|
env.add_global("name", name);
|
|
env.add_global("base_host", base_host);
|
|
if let Some(connection_type) = connection_type {
|
|
env.add_global("connection_type", connection_type);
|
|
}
|
|
|
|
env.add_global("issuer", "kjuulh-app");
|
|
|
|
env.render_named_str("ingress.yaml", internal_template, context! {})
|
|
};
|
|
|
|
for ingress_type in ingress_types {
|
|
match ingress_type {
|
|
IngressType::External => {
|
|
templates.push(get_template("external-http", "kjuulh.app", None)?)
|
|
}
|
|
IngressType::Internal => {
|
|
templates.push(get_template("internal-http", "internal.kjuulh.app", None)?)
|
|
}
|
|
IngressType::ExternalGrpc => {
|
|
templates.push(get_template("external-grpc", "kjuulh.app", Some("grpc"))?)
|
|
}
|
|
IngressType::InternalGrpc => templates.push(get_template(
|
|
"internal-grpc",
|
|
"internal.kjuulh.app",
|
|
Some("grpc"),
|
|
)?),
|
|
}
|
|
}
|
|
|
|
Ok(("ingress.yaml".into(), templates.join("\n")))
|
|
}
|
|
}
|
|
|
|
impl Component for Ingress {
|
|
fn name(&self) -> String {
|
|
"cuddle/ingress".to_string()
|
|
}
|
|
|
|
fn render(
|
|
&self,
|
|
_environment: &str,
|
|
_value: &serde_yaml::Value,
|
|
) -> Option<anyhow::Result<(String, String)>> {
|
|
if let Some(ingress_types) = self
|
|
.variables
|
|
.0
|
|
.get("ingress")
|
|
.and_then(|v| match v {
|
|
CuddleVariable::Array(a) => Some(a),
|
|
_ => None,
|
|
})
|
|
.map(|o| {
|
|
let mut types = Vec::new();
|
|
|
|
for value in o {
|
|
match value {
|
|
CuddleVariable::Object(o) => {
|
|
if o.0.contains_key("external") {
|
|
types.push(IngressType::External)
|
|
} else if o.0.contains_key("internal") {
|
|
types.push(IngressType::Internal)
|
|
} else if o.0.contains_key("external_grpc") {
|
|
types.push(IngressType::ExternalGrpc)
|
|
} else if o.0.contains_key("internal_grpc") {
|
|
types.push(IngressType::InternalGrpc)
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
_ => continue,
|
|
}
|
|
}
|
|
|
|
types
|
|
})
|
|
{
|
|
return Some(self.render_ingress_types(ingress_types));
|
|
}
|
|
|
|
None
|
|
}
|
|
}
|