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"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"k8s-openapi",
|
"k8s-openapi",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -124,9 +126,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.118"
|
version = "1.0.120"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4"
|
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
|
|
@ -5,3 +5,5 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
k8s-openapi = { version = "0.22.0", features = ["v1_30"] }
|
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 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 infra_rs;
|
||||||
mod manifests;
|
mod manifests;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let test = manifests::vaultwarden::render();
|
let test = manifests::render();
|
||||||
|
|
||||||
println!("{}", serde_json::to_string(&test).unwrap());
|
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 {
|
pub fn render() -> Vec<Value> {
|
||||||
deployment::new(Deployment {
|
let deployment = deployment::new(Deployment {
|
||||||
name: String::from("vaultwarden"),
|
name: String::from("vaultwarden"),
|
||||||
image: String::from("vaultwarden/server:testing"),
|
image: String::from("vaultwarden/server:testing"),
|
||||||
ports: vec![80],
|
ports: vec![80],
|
||||||
|
@ -18,5 +23,27 @@ pub fn render() -> api::Deployment {
|
||||||
..Default::default()
|
..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