neon-operator/src/minio.rs

184 lines
6.1 KiB
Rust

use k8s_openapi::api::apps::v1::{Deployment, DeploymentSpec};
use k8s_openapi::api::core::v1::{
Container, ContainerPort, EnvVar, PodSpec, PodTemplateSpec, Service, ServicePort, ServiceSpec,
};
use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector;
use kube::api::{ListParams, ObjectMeta, Patch, PatchParams};
use kube::{Api, Client, Error};
use std::collections::BTreeMap;
use tracing::{info, instrument};
const NAME: &str = "minio";
pub async fn create_deployment(client: Client, namespace: &str) -> Result<(), Error> {
let minio_container = Container {
name: NAME.to_string(),
env: Some(vec![
EnvVar {
name: "MINIO_ROOT_USER".to_string(),
value: Some("minio".to_string()),
..Default::default()
},
EnvVar {
name: "MINIO_ROOT_PASSWORD".to_string(),
value: Some("password".to_string()),
..Default::default()
},
]),
image: Some("quay.io/minio/minio:RELEASE.2022-10-20T00-55-09Z".to_string()),
ports: Some(vec![
ContainerPort {
container_port: 9000,
..Default::default()
},
ContainerPort {
container_port: 9001,
..Default::default()
},
]),
args: Some(
vec![
"server",
"/data",
"--address",
":9000",
"--console-address",
":9001",
]
.iter()
.map(|s| s.to_string())
.collect::<Vec<String>>(),
),
liveness_probe: Some(k8s_openapi::api::core::v1::Probe {
http_get: Some(k8s_openapi::api::core::v1::HTTPGetAction {
path: Some("/minio/health/live".to_string()),
port: k8s_openapi::apimachinery::pkg::util::intstr::IntOrString::Int(9000),
..Default::default()
}),
initial_delay_seconds: Some(10),
period_seconds: Some(30),
..Default::default()
}),
readiness_probe: Some(k8s_openapi::api::core::v1::Probe {
http_get: Some(k8s_openapi::api::core::v1::HTTPGetAction {
path: Some("/minio/health/ready".to_string()),
port: k8s_openapi::apimachinery::pkg::util::intstr::IntOrString::Int(9000),
..Default::default()
}),
initial_delay_seconds: Some(10),
period_seconds: Some(30),
..Default::default()
}),
..Default::default()
};
let mc_container = Container {
name: "mc".to_string(),
env: Some(vec![
EnvVar {
name: "MINIO_ROOT_USER".to_string(),
value: Some("minio".to_string()),
..Default::default()
},
EnvVar {
name: "MINIO_ROOT_PASSWORD".to_string(),
value: Some("password".to_string()),
..Default::default()
},
]),
image: Some("minio/mc".to_string()),
command: Some(vec!["bash".to_string(), "-c".to_string()]),
args: Some(vec!["until (/usr/bin/mc alias set minio http://localhost:9000 $$MINIO_ROOT_USER $$MINIO_ROOT_PASSWORD) do
echo 'Waiting to start minio...' && sleep 1;
done;
/usr/bin/mc mb --ignore-existing minio/neon --region=eu-north-1;
sleep inf;".to_string()]),
..Default::default()
};
let deployment = Deployment {
metadata: ObjectMeta {
name: Some(NAME.to_string()),
namespace: Some(namespace.to_string()),
labels: Some(BTreeMap::from([("app".to_string(), NAME.to_string())])),
..Default::default()
},
spec: Some(DeploymentSpec {
replicas: Some(1),
selector: LabelSelector {
match_labels: Some(BTreeMap::from([("app".to_string(), NAME.to_string())])),
..Default::default()
},
template: PodTemplateSpec {
metadata: Some(ObjectMeta {
labels: Some(BTreeMap::from([("app".to_string(), NAME.to_string())])),
..Default::default()
}),
spec: Some(PodSpec {
containers: vec![minio_container, mc_container],
..Default::default()
}),
..Default::default()
},
..Default::default()
}),
..Default::default()
};
let deployment_api = Api::<Deployment>::namespaced(client, namespace);
deployment_api
.patch(
NAME,
&PatchParams::apply("neon-operator"),
&Patch::Apply(deployment),
)
.await?;
Ok(())
}
pub async fn create_service(client: Client, namespace: &str) -> Result<(), Error> {
let service = Service {
metadata: ObjectMeta {
name: Some(NAME.to_string()),
namespace: Some(namespace.to_string()),
labels: Some(BTreeMap::from([("app".to_string(), NAME.to_string())])),
..Default::default()
},
spec: Some(ServiceSpec {
selector: Some(BTreeMap::from([("app".to_string(), NAME.to_string())])),
ports: Some(vec![ServicePort {
port: 9000,
..Default::default()
}]),
..Default::default()
}),
..Default::default()
};
info!("Reconciling service");
Api::<Service>::namespaced(client, namespace)
.patch(
NAME,
&PatchParams::apply("neon-operator"),
&Patch::Apply(service),
)
.await?;
Ok(())
}
#[instrument(err, skip(client))]
pub async fn deployment_exists(client: Client, namespace: &str) -> Result<bool, Error> {
let deployment_api: Api<Deployment> = Api::namespaced(client, namespace);
let lp = ListParams {
label_selector: Some(format!("app={}", NAME)),
..Default::default()
};
let list_result = deployment_api.list(&lp).await?;
Ok(list_result.items.len() > 0)
}