2024-05-25 10:51:02 -04:00
|
|
|
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()]),
|
2024-05-26 13:02:55 -04:00
|
|
|
args: Some(vec!["until (/usr/bin/mc alias set minio http://localhost:9000 $$MINIO_ROOT_USER $$MINIO_ROOT_PASSWORD) do
|
2024-05-25 10:51:02 -04:00
|
|
|
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)
|
|
|
|
}
|