Skip to content

Commit

Permalink
Mount certs from secret in app services (#417)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianstanton authored Dec 12, 2023
1 parent 0a5b9a8 commit 3da9ed6
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 13 deletions.
2 changes: 1 addition & 1 deletion tembo-operator/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tembo-operator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "controller"
description = "Tembo Operator for Postgres"
version = "0.25.1"
version = "0.25.2"
edition = "2021"
default-run = "controller"
license = "Apache-2.0"
Expand Down
39 changes: 36 additions & 3 deletions tembo-operator/src/app_service/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use k8s_openapi::{
apps::v1::{Deployment, DeploymentSpec},
core::v1::{
Capabilities, Container, ContainerPort, EnvVar, EnvVarSource, HTTPGetAction, PodSpec,
PodTemplateSpec, Probe, SecretKeySelector, SecurityContext, Service, ServicePort, ServiceSpec,
PodTemplateSpec, Probe, SecretKeySelector, SecretVolumeSource, SecurityContext, Service,
ServicePort, ServiceSpec, Volume, VolumeMount,
},
},
apimachinery::pkg::{
Expand Down Expand Up @@ -355,6 +356,38 @@ fn generate_deployment(
// combine the secret env vars and those provided in spec by user
env_vars.extend(secret_envs);

// Create volume vec and add certs volume from secret
let mut volumes: Vec<Volume> = Vec::new();
let certs_volume = Volume {
name: "tembo-certs".to_string(),
secret: Some(SecretVolumeSource {
secret_name: Some(format!("{}-server1", coredb_name)),
..SecretVolumeSource::default()
}),
..Volume::default()
};
volumes.push(certs_volume);

// Create volume mounts vec and add certs volume mount
let mut volume_mounts: Vec<VolumeMount> = Vec::new();
let certs_volume_mount = VolumeMount {
name: "tembo-certs".to_string(),
mount_path: "/tembo/certs".to_string(),
read_only: Some(true),
..VolumeMount::default()
};
volume_mounts.push(certs_volume_mount);

// Add any user provided volumes / volume mounts
if let Some(storage) = appsvc.storage.clone() {
if let Some(vols) = storage.volumes {
volumes.extend(vols);
}
if let Some(vols) = storage.volume_mounts {
volume_mounts.extend(vols);
}
}

let pod_spec = PodSpec {
containers: vec![Container {
args: appsvc.args.clone(),
Expand All @@ -367,10 +400,10 @@ fn generate_deployment(
readiness_probe,
liveness_probe,
security_context: Some(security_context),
volume_mounts: appsvc.storage.clone().and_then(|s| s.volume_mounts),
volume_mounts: Some(volume_mounts),
..Container::default()
}],
volumes: appsvc.storage.clone().and_then(|s| s.volumes),
volumes: Some(volumes),
..PodSpec::default()
};

Expand Down
79 changes: 79 additions & 0 deletions tembo-operator/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3018,6 +3018,33 @@ mod test {
"value": "/certs/tls.crt"
},
],
"storage": {
"volumes": [
{
"name": "ferretdb-data",
"ephemeral": {
"volumeClaimTemplate": {
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "1Gi"
}
}
}
}
}
}
],
"volumeMounts": [
{
"name": "ferretdb-data",
"mountPath": "/state"
}
]
},
}
],
"postgresExporterEnabled": false
Expand Down Expand Up @@ -3047,6 +3074,38 @@ mod test {
assert_eq!(app_1.metadata.name.unwrap(), format!("{cdb_name}-postgrest"));
assert_eq!(app_2.metadata.name.unwrap(), format!("{cdb_name}-test-app-1"));

let selector_map = app_0
.spec
.as_ref()
.and_then(|s| s.selector.match_labels.as_ref())
.expect("Deployment should have a selector");
let selector = selector_map
.iter()
.map(|(k, v)| format!("{}={}", k, v))
.collect::<Vec<_>>()
.join(",");
let lp = ListParams::default().labels(&selector);
let pods: Api<Pod> = Api::namespaced(client.clone(), &namespace);
let pod_list = pods.list(&lp).await.unwrap();
assert_eq!(pod_list.items.len(), 1);
let app_0_pod = pod_list.items[0].clone();
let app_0_container = app_0_pod.spec.unwrap().containers[0].clone();

// Assert app_0 volume mounts include ferretdb-data and tembo-certs
let volume_mounts = app_0_container.volume_mounts.unwrap();
let mut found_ferretdb_data = false;
let mut found_tembo_certs = false;
for mount in volume_mounts {
if mount.mount_path == "/state" {
found_ferretdb_data = true;
}
if mount.mount_path == "/tembo/certs" {
found_tembo_certs = true;
}
}
assert!(found_ferretdb_data);
assert!(found_tembo_certs);

// Assert resources in first appService
// select the pod
let selector_map = app_1
Expand Down Expand Up @@ -3081,6 +3140,16 @@ mod test {
let app_1_resources = app_1_container.resources.unwrap();
assert_eq!(app_1_resources, expected);

// Assert /tembo/certs is included in volume mounts
let volume_mounts = app_1_container.volume_mounts.unwrap();
let mut found = false;
for mount in volume_mounts {
if mount.mount_path == "/tembo/certs" {
found = true;
}
}
assert!(found);

let ingresses: Result<Vec<IngressRoute>, errors::OperatorError> =
list_resources(client.clone(), cdb_name, &namespace, 1).await;
let ingress = ingresses.unwrap();
Expand Down Expand Up @@ -3157,6 +3226,16 @@ mod test {
let app_2_resources = app_2_container.resources.unwrap();
assert_eq!(app_2_resources, expected);

// Assert /tembo/certs is included in volume mounts
let volume_mounts = app_2_container.volume_mounts.unwrap();
let mut found = false;
for mount in volume_mounts {
if mount.mount_path == "/tembo/certs" {
found = true;
}
}
assert!(found);

// Delete the one without a service, but leave the postgrest appService
let coredb_json = serde_json::json!({
"apiVersion": API_VERSION,
Expand Down
10 changes: 2 additions & 8 deletions tembo-operator/yaml/sample-document.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ spec:
- name: FERRETDB_STATE_DIR
value: '-'
- name: FERRETDB_LISTEN_TLS_CERT_FILE
value: /certs/tls.crt
value: /tembo/certs/tls.crt
- name: FERRETDB_LISTEN_TLS_KEY_FILE
value: /certs/tls.key
value: /tembo/certs/tls.key
- name: FERRETDB_LISTEN_TLS
value: :27018
storage:
Expand All @@ -40,12 +40,6 @@ spec:
resources:
requests:
storage: 1Gi
- name: ferretdb-certs
secret:
secretName: sample-document-server1
volumeMounts:
- name: ferretdb-data
mountPath: /state
- name: ferretdb-certs
mountPath: /certs
readOnly: true

0 comments on commit 3da9ed6

Please sign in to comment.