diff --git a/src/config.rs b/src/config.rs index a7b1d3e..4dd95b1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -20,6 +20,8 @@ pub struct Config { /// Rusthead Docker image to use (defaults to "samply/rusthead:latest") #[serde(default = "default_image")] pub image: String, + /// Defaults to docker named volumes + pub volume_dir: Option, pub git_sync: Option, pub https_proxy_url: Option, pub ccp: Option, diff --git a/src/services/blaze.rs b/src/services/blaze.rs index 7fdec2e..d4c0967 100644 --- a/src/services/blaze.rs +++ b/src/services/blaze.rs @@ -3,6 +3,8 @@ use std::{marker::PhantomData, str::FromStr}; use askama::Template; use url::Url; +use crate::utils::filters; + use super::{Service, Traefik}; #[derive(Debug, Template)] diff --git a/src/services/dnpm_node.rs b/src/services/dnpm_node.rs index 720e738..1ca68bb 100644 --- a/src/services/dnpm_node.rs +++ b/src/services/dnpm_node.rs @@ -4,6 +4,7 @@ use serde::Deserialize; use crate::{ config::Config, services::{Service, Traefik}, + utils::filters, }; #[derive(Debug, Clone, Deserialize)] diff --git a/src/services/exporter.rs b/src/services/exporter.rs index 563f69b..d8fe871 100644 --- a/src/services/exporter.rs +++ b/src/services/exporter.rs @@ -9,6 +9,7 @@ use crate::{ datashield::DataShield, postgres::{PgConnectInfo, Postgres}, }, + utils::filters, }; #[derive(Debug, Template)] diff --git a/src/services/id_management.rs b/src/services/id_management.rs index 24b83f2..13941d9 100644 --- a/src/services/id_management.rs +++ b/src/services/id_management.rs @@ -4,7 +4,7 @@ use crate::{ config::Config, modules::CcpDefault, services::{OidcClient, OidcProvider, PrivateOidcClient, postgres::PgConnectInfo}, - utils::capitalize_first_letter, + utils::{capitalize_first_letter, filters}, }; use super::{ForwardProxy, Service, ToCompose, Traefik, postgres::Postgres}; diff --git a/src/services/mod.rs b/src/services/mod.rs index 60f958c..545f815 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -183,14 +183,15 @@ service_tuple!(T1, T2, T3); service_tuple!(T1, T2, T3, T4); pub trait ToCompose: Any { - fn render(&self) -> anyhow::Result; + fn render(&self, config: &'static Config) -> anyhow::Result; fn service_name(&self) -> String; } impl ToCompose for T { - fn render(&self) -> anyhow::Result { - Template::render(self) + fn render(&self, config: &'static Config) -> anyhow::Result { + let values = [("config", config as &dyn Any)]; + Template::render_with_values(self, &values as &dyn askama::Values) .with_context(|| format!("Failed to render {}", std::any::type_name::())) } @@ -356,7 +357,7 @@ impl ServiceMap { eprintln!("Generating service {service_name}"); fs::write( services_dir.join(format!("{}.yml", service.service_name())), - service.render()?, + service.render(self.config)?, )?; } Ok(()) diff --git a/src/services/postgres.rs b/src/services/postgres.rs index c736c6e..3d94262 100644 --- a/src/services/postgres.rs +++ b/src/services/postgres.rs @@ -2,6 +2,8 @@ use std::marker::PhantomData; use askama::Template; +use crate::utils::filters; + use super::Service; #[derive(Debug, Template)] diff --git a/src/services/transfair.rs b/src/services/transfair.rs index 0a8e91d..4f9470c 100644 --- a/src/services/transfair.rs +++ b/src/services/transfair.rs @@ -4,6 +4,8 @@ use askama::Template; use serde::Deserialize; use url::Url; +use crate::utils::filters; + use super::{Blaze, BlazeProvider, Service}; #[derive(Debug, Deserialize)] diff --git a/src/utils.rs b/src/utils.rs index 3baabce..3551867 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -26,10 +26,12 @@ pub fn secret_from_rng(rng: &mut impl rand::Rng) -> String { } pub mod filters { - use std::path::PathBuf; + use std::{fs, path::PathBuf}; use askama::Values; + use crate::config::Config; + #[askama::filter_fn] pub fn path(p: &PathBuf, _: &dyn Values) -> askama::Result { Ok(p.canonicalize() @@ -41,6 +43,36 @@ pub mod filters { .display() .to_string()) } + + #[askama::filter_fn] + pub fn make_volume(name: &str, ctx: &dyn Values) -> askama::Result { + let config = ctx + .get_value("config") + .unwrap() + .downcast_ref::() + .unwrap(); + if let Some(volume_dir) = &config.volume_dir { + let path = config.path.join(&volume_dir); + fs::create_dir_all(&path).map_err(|e| { + askama::Error::custom( + anyhow::Error::from(e) + .context(format!("Failed to create volume directory {volume_dir:?}")), + ) + })?; + let abs_path = path.canonicalize().map_err(|e| { + askama::Error::custom( + anyhow::Error::from(e) + .context(format!("Failed to canonicalize volume {volume_dir:?}")), + ) + })?; + Ok(format!( + "{name}:\n driver: local\n driver_opts:\n o: bind\n type: none\n device: {}", + abs_path.display() + )) + } else { + Ok(format!("{name}:")) + } + } } pub mod host { diff --git a/templates/blaze.yml b/templates/blaze.yml index ff568b6..49f1067 100644 --- a/templates/blaze.yml +++ b/templates/blaze.yml @@ -1,4 +1,5 @@ {% let name = Self::service_name() %} +{% let data_volume = format!("{}-data", name) %} services: {{ name }}: image: docker.verbis.dkfz.de/cache/samply/blaze:latest @@ -6,7 +7,7 @@ services: BASE_URL: {{ Self::get_url().to_string().trim_end_matches('/') }} ENFORCE_REFERENTIAL_INTEGRITY: "false" volumes: - - "{{ name }}-data:/app/data" + - "{{ data_volume }}:/app/data" {% if let Some(traefik_conf) = traefik_conf -%} labels: - "traefik.enable=true" @@ -18,4 +19,4 @@ services: {%- endif %} volumes: - {{ name }}-data: + {{ data_volume|make_volume }} diff --git a/templates/datashield.yml b/templates/datashield.yml index 45afc49..a5d9bae 100644 --- a/templates/datashield.yml +++ b/templates/datashield.yml @@ -1,4 +1,5 @@ {% let project = T::network_name() %} +{% let opal_metadata_volume = format!("{}-opal-metadata-db", project) %} services: {{ opal_host() }}: @@ -32,7 +33,7 @@ services: BEAM_SECRET: {{ tm_beam.secret }} BEAM_DATASHIELD_PROXY: request-manager volumes: - - "{{ project }}-opal-metadata-db:/srv" # Opal metadata + - "{{ opal_metadata_volume }}:/srv" # Opal metadata - "{{ opal_key_path|path }}:/certs/opal-key.pem" - "{{ opal_cert_path|path }}:/certs/opal-cert.pem" depends_on: @@ -44,4 +45,4 @@ services: - /srv volumes: - {{ project }}-opal-metadata-db: + {{ opal_metadata_volume|make_volume }} diff --git a/templates/dnpm_node.yml b/templates/dnpm_node.yml index acb81ee..9287e60 100644 --- a/templates/dnpm_node.yml +++ b/templates/dnpm_node.yml @@ -1,4 +1,8 @@ +{%- let mysql_volume = "dnpm-mysql" -%} +{%- let authup_volume = "dnpm-authup" -%} +{%- let backend_data_volume = "dnpm-backend-data" -%} + services: dnpm-mysql: image: mysql:9 @@ -11,12 +15,12 @@ services: MYSQL_ROOT_HOST: "%" MYSQL_ROOT_PASSWORD: {{ mysql_root_password }} volumes: - - dnpm-mysql:/var/lib/mysql + - {{ mysql_volume }}:/var/lib/mysql dnpm-authup: image: authup/authup:latest volumes: - - dnpm-authup:/usr/src/app/writable + - {{ authup_volume }}:/usr/src/app/writable depends_on: dnpm-mysql: condition: service_healthy @@ -64,7 +68,7 @@ services: - AUTHUP_URL=robot://system:{{ authup_secret }}@http://dnpm-authup:3000 - TZ=Europe/Berlin volumes: - - dnpm-backend-data:/dnpm_data + - {{ backend_data_volume }}:/dnpm_data configs: - source: dnpm-production.conf target: /dnpm_config/production.conf @@ -98,9 +102,9 @@ services: - "traefik.http.middlewares.dnpm-backend-peer.ipWhiteList.sourceRange=0.0.0.0/32" volumes: - dnpm-authup: - dnpm-mysql: - dnpm-backend-data: + {{ authup_volume|make_volume }} + {{ mysql_volume|make_volume }} + {{ backend_data_volume|make_volume }} configs: dnpm-production.conf: diff --git a/templates/exporter.yml b/templates/exporter.yml index e82738d..df70385 100644 --- a/templates/exporter.yml +++ b/templates/exporter.yml @@ -1,3 +1,6 @@ +{%- let project = project -%} +{%- let exporter_files_volume = format!("{}-files", Self::service_name()) -%} +{%- let reporter_files_volume = format!("{}-reporter-files", project) -%} services: {{ Self::service_name() }}: image: docker.verbis.dkfz.de/{{ project }}/dktk-exporter:latest @@ -23,7 +26,7 @@ services: - "traefik.http.middlewares.exporter_{{ project }}_strip.stripprefix.prefixes=/{{ project }}-exporter" - "traefik.http.routers.exporter_{{ project }}.middlewares=exporter_{{ project }}_strip" volumes: - - "{{ Self::service_name() }}-files:/app/exporter-files/output" + - "{{ exporter_files_volume }}:/app/exporter-files/output" depends_on: - {{ db.host }} @@ -39,7 +42,7 @@ services: LOG_FHIR_VALIDATION: "false" HTTP_SERVLET_REQUEST_SCHEME: "https" volumes: - - "{{ project }}-reporter-files:/app/reports" + - "{{ reporter_files_volume }}:/app/reports" labels: - "traefik.enable=true" - "traefik.http.routers.reporter_{{ project }}.rule=PathPrefix(`/{{ project }}-reporter`)" @@ -50,5 +53,5 @@ services: volumes: - {{ Self::service_name() }}-files: - {{ project }}-reporter-files: + {{ exporter_files_volume|make_volume }} + {{ reporter_files_volume|make_volume }} diff --git a/templates/id_management.yml b/templates/id_management.yml index 2634408..e1ea6b1 100644 --- a/templates/id_management.yml +++ b/templates/id_management.yml @@ -1,3 +1,4 @@ +{% let patientlist_data_volume = "patientlist-db-data" %} services: id-manager: @@ -93,4 +94,4 @@ services: condition: service_healthy volumes: - patientlist-db-data: + {{ patientlist_data_volume|make_volume }} diff --git a/templates/postgres.yml b/templates/postgres.yml index 56b87f2..1a1955f 100644 --- a/templates/postgres.yml +++ b/templates/postgres.yml @@ -1,3 +1,4 @@ +{% let data_volume = Self::service_name() %} services: {{ Self::service_name() }}: image: docker.verbis.dkfz.de/cache/postgres:15.6-alpine @@ -6,7 +7,7 @@ services: POSTGRES_DB: {{ realm }} POSTGRES_PASSWORD: {{ password }} volumes: - - "{{ Self::service_name() }}:/var/lib/postgresql/data" + - "{{ data_volume }}:/var/lib/postgresql/data" volumes: - {{ Self::service_name() }}: + {{ data_volume|make_volume }} diff --git a/templates/transfair.yml b/templates/transfair.yml index de4c748..6f39948 100644 --- a/templates/transfair.yml +++ b/templates/transfair.yml @@ -1,3 +1,6 @@ +{%- let data_volume = "transfair-data" -%} +{%- let input_blaze_data_volume = "transfair-input-blaze-data" -%} +{%- let request_blaze_data_volume = "transfair-request-blaze-data" -%} services: transfair: image: docker.verbis.dkfz.de/cache/samply/transfair:latest @@ -37,7 +40,7 @@ services: - TLS_CA_CERTIFICATES_DIR=/conf/trusted-ca-certs - TLS_DISABLE={{ conf.tls_disable }} volumes: - - transfair-data:/transfair + - {{ data_volume }}:/transfair - {{ trusted_ca_certs.display() }}:/conf/trusted-ca-certs:ro {%- if conf.fhir_input.is_none() %} @@ -51,7 +54,7 @@ services: CQL_EXPR_CACHE_SIZE: 8 ENFORCE_REFERENTIAL_INTEGRITY: "false" volumes: - - "transfair-input-blaze-data:/app/data" + - "{{ input_blaze_data_volume }}:/app/data" {%- endif %} {%- if conf.fhir_requests.is_none() %} @@ -65,14 +68,10 @@ services: CQL_EXPR_CACHE_SIZE: 8 ENFORCE_REFERENTIAL_INTEGRITY: "false" volumes: - - "transfair-request-blaze-data:/app/data" + - "{{ request_blaze_data_volume }}:/app/data" {%- endif %} volumes: -{%- if conf.fhir_input.is_none() %} - transfair-input-blaze-data: -{%- endif %} -{%- if conf.fhir_requests.is_none() %} - transfair-request-blaze-data: -{%- endif %} - transfair-data: \ No newline at end of file + {% if conf.fhir_input.is_none() %}{{ input_blaze_data_volume|make_volume }} + {% endif %}{% if conf.fhir_requests.is_none() %}{{ request_blaze_data_volume|make_volume }} + {% endif %}{{ data_volume|make_volume }} diff --git a/tests/configs/volume-dir.toml b/tests/configs/volume-dir.toml new file mode 100644 index 0000000..ff1610c --- /dev/null +++ b/tests/configs/volume-dir.toml @@ -0,0 +1,6 @@ +site_id = "dummy" +hostname = "dummy.local" +volume_dir = "./data" + +[ccp] +exporter = {} diff --git a/tests/snapshots/example.config/configs@services__dnpm-node.yml.snap b/tests/snapshots/example.config/configs@services__dnpm-node.yml.snap index 87d5058..b548249 100644 --- a/tests/snapshots/example.config/configs@services__dnpm-node.yml.snap +++ b/tests/snapshots/example.config/configs@services__dnpm-node.yml.snap @@ -4,7 +4,6 @@ expression: file info: services/dnpm-node.yml input_file: tests/configs/example.config.toml --- - services: dnpm-mysql: image: mysql:9 diff --git a/tests/snapshots/volume-dir/configs@.env.snap b/tests/snapshots/volume-dir/configs@.env.snap new file mode 100644 index 0000000..683bcd1 --- /dev/null +++ b/tests/snapshots/volume-dir/configs@.env.snap @@ -0,0 +1,11 @@ +--- +source: src/config.rs +expression: file +info: ".env" +input_file: tests/configs/volume-dir.toml +--- +# This file is auto generated please modify config.toml or config.local.toml instead! + +CCP_BEAM_PROXY_FOCUS_KEY="LP~Kg3u^X#" +CCP_EXPORTER_API_KEY="0RV9))l@tt" +CCP_EXPORTER_DB_PASSWORD="AbkbbWY1mA" diff --git a/tests/snapshots/volume-dir/configs@.gitignore.snap b/tests/snapshots/volume-dir/configs@.gitignore.snap new file mode 100644 index 0000000..bc84007 --- /dev/null +++ b/tests/snapshots/volume-dir/configs@.gitignore.snap @@ -0,0 +1,13 @@ +--- +source: src/config.rs +expression: file +info: ".gitignore" +input_file: tests/configs/volume-dir.toml +--- + +.env +config.local.toml +/pki +/trusted-ca-certs +/traefik-tls +docker-compose.override.yml diff --git a/tests/snapshots/volume-dir/configs@bridgehead.snap b/tests/snapshots/volume-dir/configs@bridgehead.snap new file mode 100644 index 0000000..f4ac03e --- /dev/null +++ b/tests/snapshots/volume-dir/configs@bridgehead.snap @@ -0,0 +1,146 @@ +--- +source: src/config.rs +expression: file +info: bridgehead +input_file: tests/configs/volume-dir.toml +--- +#!/usr/bin/env bash +set -e +set -o pipefail + +# Ensure the script is running in memory to avoid issues with self modification on update +[ "$LOADED" = 1 ] || LOADED=1 exec bash <(cat "$0") "$@" +cd [TMP_DIR] + + +main() { + case "$1" in + install) + [ "$(id -u)" -ne 0 ] && echo "Install command must be run as root." && exit 1 + useradd -M -g docker -N bridgehead &>/dev/null || echo "Using existing user bridgehead." + chown -R bridgehead:docker . + chmod -R g+sw . + sudo -u bridgehead git init -b main --shared=group + git config --global --add safe.directory [TMP_DIR] + git config --local user.email "bridgehead@samply.de" + git config --local user.name "Bridgehead" + if ! systemctl status docker &> /dev/null; then + echo "Systemd is not active or docker is not running via systemd. Skipping systemd setup." + set +e + sudo -u bridgehead ./bridgehead update + exit_code=$? + set -e + if [ "$exit_code" != "0" ] && [ "$exit_code" != "3" ]; then + echo "Failed to update bridgehead" + exit $exit_code + fi + else + install_systemd + fi + if [ -e [TMP_DIR]/pki/dummy.priv.pem ]; then + echo "Private key already exists. Skipping enrollment." + echo "If you want to re-enroll or changed the configuration and are now included in a new beam network run 'sudo [TMP_DIR]/bridgehead enroll'." + echo "Installation complete." + else + enroll + fi + ;; + logs) + shift + exec journalctl -u bridgehead -u bridgehead-update -a $@ + ;; + compose) + compose_files="$(ls services | awk '{print " -f services/" $0}')" + [ -e ./docker-compose.override.yml ] && compose_files+=" -f docker-compose.override.yml" + if [ ! -f [TMP_DIR]/pki/dummy.priv.pem ]; then + echo "Beam private key not found. Please run 'sudo [TMP_DIR]/bridgehead enroll' first." + exit 1 + fi + shift + exec docker compose -p bridgehead --env-file .env $compose_files -f docker-image.lock.yml $@ + ;; + enroll) + [ "$(id -u)" -ne 0 ] && echo "Enroll must be run as root." && exit 1 + enroll + ;; + update) + docker image prune -f + docker pull samply/rusthead:latest &>/dev/null || echo "Failed to pull latest rusthead image. Using latest local image." + # Mount the docker config if it exists to allow pulling from private registries if needed + docker_config=~/.docker/config.json + docker_config_mount="" + [ -f "$docker_config" ] && docker_config_mount="-v $docker_config:/root/.docker/config.json:ro" + docker run --rm \ + -v [TMP_DIR]:[TMP_DIR] \ + -v /var/run/docker.sock:/var/run/docker.sock \ + $docker_config_mount \ + -e BRIDGEHEAD_CONFIG_PATH=[TMP_DIR] \ + -u "$(id -u bridgehead):$(id -g bridgehead)" \ + samply/rusthead:latest update + ;; + *) + echo "Unknown bridgehead command '$@'" + exit 1 + ;; + esac +} +enroll() { + do_enroll() { + echo "Enrolling dummy.$1" + docker run --rm \ + -v [TMP_DIR]/pki:[TMP_DIR]/pki \ + docker.verbis.dkfz.de/cache/samply/beam-enroll:latest \ + --output-file [TMP_DIR]/pki/dummy.priv.pem \ + --proxy-id dummy.$1 + chmod 600 [TMP_DIR]/pki/dummy.priv.pem + chown bridgehead:docker [TMP_DIR]/pki/dummy.priv.pem + } + do_enroll broker.ccp-it.dktk.dkfz.de + echo "After getting the csr enrolled you may start the bridgehead service with 'systemctl start bridgehead'." +} + +install_systemd() { + cat < /etc/systemd/system/bridgehead.service +[Unit] +Description=Bridgehead Service +Requires=docker.service + +[Service] +ExecStart=[TMP_DIR]/bridgehead compose up --abort-on-container-exit +Restart=always +User=bridgehead +Group=docker + +[Install] +WantedBy=multi-user.target +EOF + cat < /etc/systemd/system/bridgehead-update.service +[Unit] +Description=Bridgehead Update Service +Requires=docker.service + +[Service] +ExecStart=[TMP_DIR]/bridgehead update +User=bridgehead +Group=docker +ExecStopPost=+/bin/bash -c 'if [ "\$EXIT_STATUS" = "3" ]; then systemctl restart bridgehead.service; fi' +EOF + cat < /etc/systemd/system/bridgehead-update.timer +[Unit] +Description=Daily Updates at 6am of Bridgehead + +[Timer] +OnCalendar=*-*-* 06:00:00 +Persistent=true + +[Install] +WantedBy=basic.target +EOF + systemctl daemon-reload + echo "Enabling autostart of bridgehead.service" + systemctl enable bridgehead.service + echo "Enabling auto-updates for bridgehead.service ..." + systemctl enable --now bridgehead-update.timer +} + +main "$@" diff --git a/tests/snapshots/volume-dir/configs@config.local.toml.snap b/tests/snapshots/volume-dir/configs@config.local.toml.snap new file mode 100644 index 0000000..ffff80a --- /dev/null +++ b/tests/snapshots/volume-dir/configs@config.local.toml.snap @@ -0,0 +1,10 @@ +--- +source: src/config.rs +expression: "toml::from_str::(&file).unwrap()" +info: config.local.toml +input_file: tests/configs/volume-dir.toml +--- +seed = 42 +[basic_auth_users.ccp-blaze] +hash = '' +pw = 'test' diff --git a/tests/snapshots/volume-dir/configs@services__ccp-beam-proxy.yml.snap b/tests/snapshots/volume-dir/configs@services__ccp-beam-proxy.yml.snap new file mode 100644 index 0000000..b10fa89 --- /dev/null +++ b/tests/snapshots/volume-dir/configs@services__ccp-beam-proxy.yml.snap @@ -0,0 +1,52 @@ +--- +source: src/config.rs +expression: file +info: services/ccp-beam-proxy.yml +input_file: tests/configs/volume-dir.toml +--- +services: + ccp-beam-proxy: + image: docker.verbis.dkfz.de/cache/samply/beam-proxy:develop + environment: + BROKER_URL: https://broker.ccp-it.dktk.dkfz.de/ + PROXY_ID: dummy.broker.ccp-it.dktk.dkfz.de + APP_focus_KEY: "${CCP_BEAM_PROXY_FOCUS_KEY}" + ROOTCERT_FILE: /conf/root.crt.pem + PRIVKEY_FILE: /run/secrets/proxy.pem + TLS_CA_CERTIFICATES_DIR: /conf/trusted-ca-certs + ALL_PROXY: http://forward-proxy:3128/ + volumes: + - [TMP_DIR]/trusted-ca-certs:/conf/trusted-ca-certs:ro + secrets: + - proxy.pem + configs: + - source: ccp.root.crt.pem + target: /conf/root.crt.pem + +configs: + ccp.root.crt.pem: + content: | + -----BEGIN CERTIFICATE----- + MIIDNTCCAh2gAwIBAgIUN7yzueIZzwpe8PaPEIMY8zoH+eMwDQYJKoZIhvcNAQEL + BQAwFjEUMBIGA1UEAxMLQnJva2VyLVJvb3QwHhcNMjMwNTIzMTAxNzIzWhcNMzMw + NTIwMTAxNzUzWjAWMRQwEgYDVQQDEwtCcm9rZXItUm9vdDCCASIwDQYJKoZIhvcN + AQEBBQADggEPADCCAQoCggEBAN5JAj+HydSGaxvA0AOcrXVTZ9FfsH0cMVBlQb72 + bGZgrRvkqtB011TNXZfsHl7rPxCY61DcsDJfFq3+8VHT+S9HE0qV1bEwP+oA3xc4 + Opq77av77cNNOqDC7h+jyPhHcUaE33iddmrH9Zn2ofWTSkKHHu3PAe5udCrc2QnD + 4PLRF6gqiEY1mcGknJrXj1ff/X0nRY/m6cnHNXz0Cvh8oPOtbdfGgfZjID2/fJNP + fNoNKqN+5oJAZ+ZZ9id9rBvKj1ivW3F2EoGjZF268SgZzc5QrM/D1OpSBQf5SF/V + qUPcQTgt9ry3YR+SZYazLkfKMEOWEa0WsqJVgXdQ6FyergcCAwEAAaN7MHkwDgYD + VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEa70kcseqU5 + bHx2zSt4bG21HokhMB8GA1UdIwQYMBaAFEa70kcseqU5bHx2zSt4bG21HokhMBYG + A1UdEQQPMA2CC0Jyb2tlci1Sb290MA0GCSqGSIb3DQEBCwUAA4IBAQCGmE7NXW4T + 6J4mV3b132cGEMD7grx5JeiXK5EHMlswUS+Odz0NcBNzhUHdG4WVMbrilHbI5Ua+ + 6jdKx5WwnqzjQvElP0MCw6sH/35gbokWgk1provOP99WOFRsQs+9Sm8M2XtMf9HZ + m3wABwU/O+dhZZ1OT1PjSZD0OKWKqH/KvlsoF5R6P888KpeYFiIWiUNS5z21Jm8A + ZcllJjiRJ60EmDwSUOQVJJSMOvtr6xTZDZLtAKSN8zN08lsNGzyrFwqjDwU0WTqp + scMXEGBsWQjlvxqDnXyljepR0oqRIjOvgrWaIgbxcnu98tK/OdBGwlAPKNUW7Crr + vO+eHxl9iqd4 + -----END CERTIFICATE----- + +secrets: + proxy.pem: + file: [TMP_DIR]/pki/dummy.priv.pem diff --git a/tests/snapshots/volume-dir/configs@services__ccp-blaze.yml.snap b/tests/snapshots/volume-dir/configs@services__ccp-blaze.yml.snap new file mode 100644 index 0000000..f754f30 --- /dev/null +++ b/tests/snapshots/volume-dir/configs@services__ccp-blaze.yml.snap @@ -0,0 +1,31 @@ +--- +source: src/config.rs +expression: file +info: services/ccp-blaze.yml +input_file: tests/configs/volume-dir.toml +--- + + +services: + ccp-blaze: + image: docker.verbis.dkfz.de/cache/samply/blaze:latest + environment: + BASE_URL: http://ccp-blaze:8080 + ENFORCE_REFERENTIAL_INTEGRITY: "false" + volumes: + - "ccp-blaze-data:/app/data" + labels: + - "traefik.enable=true" + - "traefik.http.routers.ccp-blaze.rule=PathPrefix(`/ccp-localdatamanagement`)" + - "traefik.http.middlewares.ccp-blaze_strip.stripprefix.prefixes=/ccp-localdatamanagement" + - "traefik.http.services.ccp-blaze.loadbalancer.server.port=8080" + - "traefik.http.routers.ccp-blaze.middlewares=ccp-blaze_strip,ccp-blaze" + - "traefik.http.routers.ccp-blaze.tls=true" + +volumes: + ccp-blaze-data: + driver: local + driver_opts: + o: bind + type: none + device: [TMP_DIR]/data diff --git a/tests/snapshots/volume-dir/configs@services__ccp-exporter-db.yml.snap b/tests/snapshots/volume-dir/configs@services__ccp-exporter-db.yml.snap new file mode 100644 index 0000000..63f4bc6 --- /dev/null +++ b/tests/snapshots/volume-dir/configs@services__ccp-exporter-db.yml.snap @@ -0,0 +1,24 @@ +--- +source: src/config.rs +expression: file +info: services/ccp-exporter-db.yml +input_file: tests/configs/volume-dir.toml +--- + +services: + ccp-exporter-db: + image: docker.verbis.dkfz.de/cache/postgres:15.6-alpine + environment: + POSTGRES_USER: ccp-exporter + POSTGRES_DB: ccp-exporter + POSTGRES_PASSWORD: ${CCP_EXPORTER_DB_PASSWORD} + volumes: + - "ccp-exporter-db:/var/lib/postgresql/data" + +volumes: + ccp-exporter-db: + driver: local + driver_opts: + o: bind + type: none + device: [TMP_DIR]/data diff --git a/tests/snapshots/volume-dir/configs@services__ccp-exporter.yml.snap b/tests/snapshots/volume-dir/configs@services__ccp-exporter.yml.snap new file mode 100644 index 0000000..0154fbb --- /dev/null +++ b/tests/snapshots/volume-dir/configs@services__ccp-exporter.yml.snap @@ -0,0 +1,67 @@ +--- +source: src/config.rs +expression: file +info: services/ccp-exporter.yml +input_file: tests/configs/volume-dir.toml +--- +services: + ccp-exporter: + image: docker.verbis.dkfz.de/ccp/dktk-exporter:latest + environment: + JAVA_OPTS: "-Xms1G -Xmx8G -XX:+UseG1GC" + LOG_LEVEL: "INFO" + EXPORTER_API_KEY: "${CCP_EXPORTER_API_KEY}" + CROSS_ORIGINS: "https://dummy.local" + EXPORTER_DB_USER: "ccp-exporter" + EXPORTER_DB_PASSWORD: "${CCP_EXPORTER_DB_PASSWORD}" + EXPORTER_DB_URL: "jdbc:postgresql://ccp-exporter-db:5432/ccp-exporter" + HTTP_RELATIVE_PATH: "/ccp-exporter" + BLAZE_URL: "http://ccp-blaze:8080/fhir" + HTTP_SERVLET_REQUEST_SCHEME: "https" + labels: + - "traefik.enable=true" + - "traefik.http.routers.exporter_ccp.rule=PathPrefix(`/ccp-exporter`)" + - "traefik.http.services.exporter_ccp.loadbalancer.server.port=8092" + - "traefik.http.routers.exporter_ccp.tls=true" + - "traefik.http.middlewares.exporter_ccp_strip.stripprefix.prefixes=/ccp-exporter" + - "traefik.http.routers.exporter_ccp.middlewares=exporter_ccp_strip" + volumes: + - "ccp-exporter-files:/app/exporter-files/output" + depends_on: + - ccp-exporter-db + + ccp-reporter: + image: docker.verbis.dkfz.de/ccp/dktk-reporter:latest + environment: + JAVA_OPTS: "-Xms1G -Xmx8G -XX:+UseG1GC" + LOG_LEVEL: "INFO" + CROSS_ORIGINS: "https://dummy.local" + HTTP_RELATIVE_PATH: "/ccp-reporter" + EXPORTER_API_KEY: "${CCP_EXPORTER_API_KEY}" + EXPORTER_URL: "http://ccp-exporter:8092" + LOG_FHIR_VALIDATION: "false" + HTTP_SERVLET_REQUEST_SCHEME: "https" + volumes: + - "ccp-reporter-files:/app/reports" + labels: + - "traefik.enable=true" + - "traefik.http.routers.reporter_ccp.rule=PathPrefix(`/ccp-reporter`)" + - "traefik.http.services.reporter_ccp.loadbalancer.server.port=8095" + - "traefik.http.routers.reporter_ccp.tls=true" + - "traefik.http.middlewares.reporter_ccp_strip.stripprefix.prefixes=/ccp-reporter" + - "traefik.http.routers.reporter_ccp.middlewares=reporter_ccp_strip" + + +volumes: + ccp-exporter-files: + driver: local + driver_opts: + o: bind + type: none + device: [TMP_DIR]/data + ccp-reporter-files: + driver: local + driver_opts: + o: bind + type: none + device: [TMP_DIR]/data diff --git a/tests/snapshots/volume-dir/configs@services__ccp-focus.yml.snap b/tests/snapshots/volume-dir/configs@services__ccp-focus.yml.snap new file mode 100644 index 0000000..5f37ea5 --- /dev/null +++ b/tests/snapshots/volume-dir/configs@services__ccp-focus.yml.snap @@ -0,0 +1,19 @@ +--- +source: src/config.rs +expression: file +info: services/ccp-focus.yml +input_file: tests/configs/volume-dir.toml +--- +services: + ccp-focus: + image: docker.verbis.dkfz.de/cache/samply/focus:main-dktk + environment: + BEAM_APP_ID_LONG: focus.dummy.broker.ccp-it.dktk.dkfz.de + BEAM_PROXY_URL: http://ccp-beam-proxy:8081/ + ENDPOINT_URL: http://ccp-blaze:8080/fhir/ + API_KEY: "${CCP_BEAM_PROXY_FOCUS_KEY}" + RETRY_COUNT: 128 + EPSILON: 0.28 + ENDPOINT_TYPE: blaze + EXPORTER_URL: "http://ccp-exporter:8080" + EXPORTER_API_KEY: "${CCP_EXPORTER_API_KEY}" diff --git a/tests/snapshots/volume-dir/configs@services__forward-proxy.yml.snap b/tests/snapshots/volume-dir/configs@services__forward-proxy.yml.snap new file mode 100644 index 0000000..b39997a --- /dev/null +++ b/tests/snapshots/volume-dir/configs@services__forward-proxy.yml.snap @@ -0,0 +1,18 @@ +--- +source: src/config.rs +expression: file +info: services/forward-proxy.yml +input_file: tests/configs/volume-dir.toml +--- +services: + forward-proxy: + image: docker.verbis.dkfz.de/cache/samply/bridgehead-forward-proxy:latest + + tmpfs: + - /var/log/squid + - /var/spool/squid + volumes: + - [TMP_DIR]/trusted-ca-certs:/docker/custom-certs/:ro + healthcheck: + # Wait 1s before marking this service healthy. Required for the oauth2-proxy to talk to the OIDC provider on startup which will fail if the forward proxy is not started yet. + test: ["CMD", "sleep", "1"] diff --git a/tests/snapshots/volume-dir/configs@services__traefik.yml.snap b/tests/snapshots/volume-dir/configs@services__traefik.yml.snap new file mode 100644 index 0000000..6e4fe75 --- /dev/null +++ b/tests/snapshots/volume-dir/configs@services__traefik.yml.snap @@ -0,0 +1,42 @@ +--- +source: src/config.rs +expression: file +info: services/traefik.yml +input_file: tests/configs/volume-dir.toml +--- +services: + traefik: + image: docker.verbis.dkfz.de/cache/traefik:latest + command: + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + - --providers.docker=true + - --providers.docker.exposedbydefault=false + - --providers.file.directory=/configuration/ + - --api.dashboard=false + - --accesslog=true + - --entrypoints.web.http.redirections.entrypoint.to=websecure + - --entrypoints.web.http.redirections.entrypoint.scheme=https + labels: + - "traefik.enable=true" + - "traefik.http.middlewares.ccp-blaze.basicauth.users=ccp-blaze:" + ports: + - 80:80 + - 443:443 + configs: + - source: certificates.yaml + target: /configuration/certificates.yaml + volumes: + - [TMP_DIR]/traefik-tls/fullchain.pem:/certs/fullchain.pem:ro + - [TMP_DIR]/traefik-tls/privkey.pem:/certs/privkey.pem:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + +configs: + certificates.yaml: + content: | + tls: + stores: + default: + defaultCertificate: + certFile: /certs/fullchain.pem + keyFile: /certs/privkey.pem