Services and ingresses
Seriously, if I catch you using this, I will bite >:(
This commit is contained in:
parent
938f558962
commit
30d241ea4e
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -29,6 +29,8 @@ name = "infra-rs"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"k8s-openapi",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -124,9 +126,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.118"
|
||||
version = "1.0.120"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4"
|
||||
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
|
|
@ -5,3 +5,5 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
k8s-openapi = { version = "0.22.0", features = ["v1_30"] }
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
serde_json = "1.0.120"
|
||||
|
|
69
src/infra_rs/ingress.rs
Normal file
69
src/infra_rs/ingress.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
use k8s_openapi::{
|
||||
api::{
|
||||
core::v1::Service,
|
||||
networking::v1::{
|
||||
self as api, HTTPIngressPath, HTTPIngressRuleValue, IngressBackend, IngressRule,
|
||||
IngressServiceBackend, IngressSpec, IngressTLS, ServiceBackendPort,
|
||||
},
|
||||
},
|
||||
apimachinery::pkg::apis::meta::v1::ObjectMeta,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Ingress {
|
||||
pub name: String,
|
||||
pub hostname: String,
|
||||
pub tls_secret: Option<String>,
|
||||
}
|
||||
|
||||
pub fn new(ingress: Ingress, service: &Service) -> api::Ingress {
|
||||
api::Ingress {
|
||||
metadata: ObjectMeta {
|
||||
name: Some(ingress.name.clone()),
|
||||
..Default::default()
|
||||
},
|
||||
spec: Some(IngressSpec {
|
||||
rules: Some(vec![IngressRule {
|
||||
host: Some(ingress.hostname.clone()),
|
||||
http: Some(HTTPIngressRuleValue {
|
||||
paths: vec![HTTPIngressPath {
|
||||
path: Some(String::from("/")),
|
||||
path_type: String::from("Prefix"),
|
||||
backend: IngressBackend {
|
||||
service: Some(IngressServiceBackend {
|
||||
name: service.metadata.clone().name.unwrap(),
|
||||
port: Some(ServiceBackendPort {
|
||||
number: Some(
|
||||
service
|
||||
.spec
|
||||
.clone()
|
||||
.unwrap()
|
||||
.ports
|
||||
.unwrap()
|
||||
.first()
|
||||
.unwrap()
|
||||
.port,
|
||||
),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}],
|
||||
}),
|
||||
}]),
|
||||
tls: if let Some(tls_secret) = ingress.tls_secret {
|
||||
Some(vec![IngressTLS {
|
||||
hosts: Some(vec![ingress.hostname]),
|
||||
secret_name: Some(tls_secret),
|
||||
}])
|
||||
} else {
|
||||
None
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
|
@ -1 +1,22 @@
|
|||
use serde::{self, Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
pub mod deployment;
|
||||
pub mod ingress;
|
||||
pub mod service;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum Resource {
|
||||
Deployment(k8s_openapi::api::apps::v1::Deployment),
|
||||
Ingress(k8s_openapi::api::networking::v1::Ingress),
|
||||
Service(k8s_openapi::api::core::v1::Service),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ResourceList {
|
||||
#[serde(rename = "apiVersion")]
|
||||
pub api_version: String,
|
||||
pub kind: String,
|
||||
pub items: Vec<Value>,
|
||||
}
|
||||
|
|
75
src/infra_rs/service.rs
Normal file
75
src/infra_rs/service.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use k8s_openapi::{
|
||||
api::{
|
||||
apps::v1::Deployment,
|
||||
core::v1::{self as api, ServicePort, ServiceSpec},
|
||||
},
|
||||
apimachinery::pkg::apis::meta::v1::ObjectMeta,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Service {
|
||||
pub name: String,
|
||||
pub port: i32,
|
||||
}
|
||||
|
||||
pub fn new(service: Service) -> api::Service {
|
||||
api::Service {
|
||||
metadata: ObjectMeta {
|
||||
name: Some(service.name.clone()),
|
||||
namespace: Some(service.name.clone()),
|
||||
..Default::default()
|
||||
},
|
||||
spec: Some(ServiceSpec {
|
||||
ports: Some(vec![ServicePort {
|
||||
name: Some(format!("{}-{}", service.name, service.port)),
|
||||
port: service.port,
|
||||
..Default::default()
|
||||
}]),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(deployment: &Deployment) -> api::Service {
|
||||
let d = deployment.clone();
|
||||
let containers = d.spec.unwrap().template.clone().spec.unwrap().containers;
|
||||
let ports: Vec<ServicePort> = containers
|
||||
.into_iter()
|
||||
.map(|c| {
|
||||
c.ports.unwrap().into_iter().map(|p| ServicePort {
|
||||
port: p.container_port,
|
||||
name: Some(format!(
|
||||
"{}-{}",
|
||||
d.metadata.name.clone().unwrap(),
|
||||
p.container_port
|
||||
)),
|
||||
..Default::default()
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
api::Service {
|
||||
metadata: ObjectMeta {
|
||||
name: Some(d.metadata.name.clone().unwrap()),
|
||||
namespace: Some(d.metadata.name.clone().unwrap()),
|
||||
labels: Some(BTreeMap::from([(
|
||||
String::from("app"),
|
||||
d.metadata.name.clone().unwrap(),
|
||||
)])),
|
||||
..Default::default()
|
||||
},
|
||||
spec: Some(ServiceSpec {
|
||||
ports: Some(ports),
|
||||
selector: Some(BTreeMap::from([(
|
||||
String::from("app"),
|
||||
d.metadata.name.clone().unwrap(),
|
||||
)])),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
use k8s_openapi::serde_json;
|
||||
use serde_json;
|
||||
|
||||
mod infra_rs;
|
||||
mod manifests;
|
||||
|
||||
fn main() {
|
||||
let test = manifests::vaultwarden::render();
|
||||
let test = manifests::render();
|
||||
|
||||
println!("{}", serde_json::to_string(&test).unwrap());
|
||||
}
|
||||
|
|
|
@ -1 +1,13 @@
|
|||
pub mod vaultwarden;
|
||||
use crate::infra_rs::ResourceList;
|
||||
|
||||
mod vaultwarden;
|
||||
|
||||
pub fn render() -> ResourceList {
|
||||
let resources = vec![vaultwarden::render()].into_iter().flatten().collect();
|
||||
|
||||
ResourceList {
|
||||
items: resources,
|
||||
api_version: String::from("v1"),
|
||||
kind: String::from("List"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
use k8s_openapi::api::apps::v1 as api;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::infra_rs::deployment::{self, Deployment, DeploymentEnv};
|
||||
use crate::infra_rs::{
|
||||
deployment::{self, Deployment, DeploymentEnv},
|
||||
ingress::{self, Ingress},
|
||||
service::{self, Service},
|
||||
Resource,
|
||||
};
|
||||
|
||||
pub fn render() -> api::Deployment {
|
||||
deployment::new(Deployment {
|
||||
pub fn render() -> Vec<Value> {
|
||||
let deployment = deployment::new(Deployment {
|
||||
name: String::from("vaultwarden"),
|
||||
image: String::from("vaultwarden/server:testing"),
|
||||
ports: vec![80],
|
||||
|
@ -18,5 +23,27 @@ pub fn render() -> api::Deployment {
|
|||
..Default::default()
|
||||
},
|
||||
],
|
||||
})
|
||||
});
|
||||
|
||||
let service = service::from(&deployment);
|
||||
|
||||
let ingress = ingress::new(
|
||||
Ingress {
|
||||
name: String::from("vaultwarden"),
|
||||
hostname: String::from("pw.gmem.ca"),
|
||||
tls_secret: Some(String::from("gmem-ca-wildcard")),
|
||||
},
|
||||
&service,
|
||||
);
|
||||
|
||||
let resources = vec![
|
||||
Resource::Deployment(deployment),
|
||||
Resource::Service(service),
|
||||
Resource::Ingress(ingress),
|
||||
];
|
||||
|
||||
resources
|
||||
.into_iter()
|
||||
.map(|res| serde_json::to_value(res).unwrap())
|
||||
.collect()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue