mirror of https://github.com/samply/bridgehead.git
Merge pull request #145 from samply/feature/datashield-central-keycloak
Remove local Keycloak Installation
This commit is contained in:
commit
f88dfb5654
|
@ -41,6 +41,7 @@ case "$PROJECT" in
|
|||
;;
|
||||
esac
|
||||
|
||||
# TODO: Please add proper documentation for variable priorities (1. secrets, 2. vars, 3. PROJECT.local.conf, 4. PROJECT.conf, 5. ???
|
||||
loadVars() {
|
||||
# Load variables from /etc/bridgehead and /srv/docker/bridgehead
|
||||
set -a
|
||||
|
@ -50,6 +51,7 @@ loadVars() {
|
|||
source /etc/bridgehead/$PROJECT.local.conf || fail_and_report 1 "Found /etc/bridgehead/$PROJECT.local.conf but failed to import"
|
||||
fi
|
||||
fetchVarsFromVaultByFile /etc/bridgehead/$PROJECT.conf || fail_and_report 1 "Unable to fetchVarsFromVaultByFile"
|
||||
setHostname
|
||||
[ -e ./$PROJECT/vars ] && source ./$PROJECT/vars
|
||||
set +a
|
||||
|
||||
|
@ -64,7 +66,6 @@ loadVars() {
|
|||
OVERRIDE+=" -f ./$PROJECT/docker-compose.override.yml"
|
||||
fi
|
||||
detectCompose
|
||||
setHostname
|
||||
setupProxy
|
||||
|
||||
# Set some project-independent default values
|
||||
|
@ -89,6 +90,7 @@ case "$ACTION" in
|
|||
loadVars
|
||||
hc_send log "Bridgehead $PROJECT startup: Checking requirements ..."
|
||||
checkRequirements
|
||||
sync_secrets
|
||||
hc_send log "Bridgehead $PROJECT startup: Requirements checked out. Now starting bridgehead ..."
|
||||
exec $COMPOSE -p $PROJECT -f ./minimal/docker-compose.yml -f ./$PROJECT/docker-compose.yml $OVERRIDE up --abort-on-container-exit
|
||||
;;
|
||||
|
|
|
@ -19,7 +19,7 @@ services:
|
|||
- "traefik.http.routers.blaze_ccp.tls=true"
|
||||
|
||||
focus:
|
||||
image: docker.verbis.dkfz.de/cache/samply/focus:${FOCUS_TAG}
|
||||
image: docker.verbis.dkfz.de/cache/samply/focus:0.4.0
|
||||
container_name: bridgehead-focus
|
||||
environment:
|
||||
API_KEY: ${FOCUS_BEAM_SECRET_SHORT}
|
||||
|
|
|
@ -6,15 +6,20 @@ services:
|
|||
image: docker.verbis.dkfz.de/ccp/dktk-rstudio:latest
|
||||
environment:
|
||||
#DEFAULT_USER: "rstudio" # This line is kept for informational purposes
|
||||
PASSWORD: "${LDM_AUTH}"
|
||||
PASSWORD: "${RSTUDIO_ADMIN_PASSWORD}" # It is required, even if the authentication is disabled
|
||||
DISABLE_AUTH: "true" # https://rocker-project.org/images/versioned/rstudio.html#how-to-use
|
||||
# TODO: Connect R-Studio with central Keycloak. Currently using Traefik authentication.
|
||||
HTTP_RELATIVE_PATH: "/rstudio"
|
||||
ALL_PROXY: "http://forward_proxy:3128" # https://rocker-project.org/use/networking.html
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.rstudio_ccp.rule=PathPrefix(`/rstudio`)"
|
||||
- "traefik.http.services.rstudio_ccp.loadbalancer.server.port=8787"
|
||||
- "traefik.http.routers.rstudio_ccp.tls=true"
|
||||
- "traefik.http.middlewares.rstudio_ccp_strip.stripprefix.prefixes=/rstudio"
|
||||
- "traefik.http.routers.rstudio_ccp.middlewares=rstudio_ccp_strip"
|
||||
- "traefik.http.routers.rstudio_ccp.tls=true"
|
||||
- "traefik.http.routers.rstudio_ccp.middlewares=oidcAuth,rstudio_ccp_strip"
|
||||
networks:
|
||||
- rstudio
|
||||
|
||||
opal:
|
||||
container_name: bridgehead-opal
|
||||
|
@ -30,7 +35,7 @@ services:
|
|||
environment:
|
||||
JAVA_OPTS: "-Xms1G -Xmx8G -XX:+UseG1GC -Dhttps.proxyHost=forward_proxy -Dhttps.proxyPort=3128"
|
||||
# OPAL_ADMINISTRATOR_USER: "administrator" # This line is kept for informational purposes
|
||||
OPAL_ADMINISTRATOR_PASSWORD: "${LDM_AUTH}"
|
||||
OPAL_ADMINISTRATOR_PASSWORD: "${OPAL_ADMIN_PASSWORD}"
|
||||
POSTGRESDATA_HOST: "opal-db"
|
||||
POSTGRESDATA_DATABASE: "opal"
|
||||
POSTGRESDATA_USER: "opal"
|
||||
|
@ -40,11 +45,21 @@ services:
|
|||
APP_CONTEXT_PATH: "/opal"
|
||||
OPAL_PRIVATE_KEY: "/run/secrets/opal-key.pem"
|
||||
OPAL_CERTIFICATE: "/run/secrets/opal-cert.pem"
|
||||
OIDC_URL: "${OIDC_URL}"
|
||||
OIDC_REALM: "${OIDC_REALM}"
|
||||
OIDC_CLIENT_ID: "${OIDC_PRIVATE_CLIENT_ID}"
|
||||
OIDC_CLIENT_SECRET: "${OIDC_CLIENT_SECRET}"
|
||||
OIDC_ADMIN_GROUP: "${OIDC_ADMIN_GROUP}"
|
||||
TOKEN_MANAGER_PASSWORD: "${TOKEN_MANAGER_OPAL_PASSWORD}"
|
||||
EXPORTER_PASSWORD: "${EXPORTER_OPAL_PASSWORD}"
|
||||
BEAM_APP_ID: token-manager.${PROXY_ID}
|
||||
BEAM_SECRET: ${TOKEN_MANAGER_SECRET}
|
||||
BEAM_DATASHIELD_PROXY: request-manager
|
||||
volumes:
|
||||
- "/var/cache/bridgehead/ccp/opal-metadata-db:/srv" # Opal metadata
|
||||
secrets:
|
||||
- opal-cert.pem
|
||||
- opal-key.pem
|
||||
tmpfs:
|
||||
- /srv
|
||||
|
||||
opal-db:
|
||||
container_name: bridgehead-opal-db
|
||||
|
@ -54,11 +69,11 @@ services:
|
|||
POSTGRES_USER: "opal"
|
||||
POSTGRES_DB: "opal"
|
||||
volumes:
|
||||
- "/var/cache/bridgehead/ccp/opal-db:/var/lib/postgresql/data"
|
||||
- "/var/cache/bridgehead/ccp/opal-db:/var/lib/postgresql/data" # Opal project data (imported from exporter)
|
||||
|
||||
opal-rserver:
|
||||
container_name: bridgehead-opal-rserver
|
||||
image: docker.verbis.dkfz.de/cache/datashield/rock-base:6.3 # https://datashield.discourse.group/t/ds-aggregate-method-error/416/4
|
||||
image: docker.verbis.dkfz.de/ccp/dktk-rserver # datashield/rock-base + dsCCPhos
|
||||
tmpfs:
|
||||
- /srv
|
||||
|
||||
|
@ -79,13 +94,80 @@ services:
|
|||
- beam-proxy
|
||||
volumes:
|
||||
- /tmp/bridgehead/opal-map/:/map/:ro
|
||||
networks:
|
||||
- default
|
||||
- rstudio
|
||||
|
||||
traefik:
|
||||
labels:
|
||||
- "traefik.http.middlewares.oidcAuth.forwardAuth.address=http://oauth2_proxy:4180/"
|
||||
- "traefik.http.middlewares.oidcAuth.forwardAuth.trustForwardHeader=true"
|
||||
- "traefik.http.middlewares.oidcAuth.forwardAuth.authResponseHeaders=X-Auth-Request-Access-Token,Authorization"
|
||||
networks:
|
||||
- default
|
||||
- rstudio
|
||||
forward_proxy:
|
||||
networks:
|
||||
- default
|
||||
- rstudio
|
||||
|
||||
beam-proxy:
|
||||
environment:
|
||||
APP_datashield-connect_KEY: ${DATASHIELD_CONNECT_SECRET}
|
||||
APP_token-manager_KEY: ${TOKEN_MANAGER_SECRET}
|
||||
|
||||
# TODO: Allow users of group /DataSHIELD and OIDC_USER_GROUP at the same time:
|
||||
# Maybe a solution would be (https://oauth2-proxy.github.io/oauth2-proxy/configuration/oauth_provider):
|
||||
# --allowed-groups=/DataSHIELD,OIDC_USER_GROUP
|
||||
oauth2_proxy:
|
||||
image: docker.verbis.dkfz.de/cache/oauth2-proxy/oauth2-proxy:latest
|
||||
container_name: bridgehead_oauth2_proxy
|
||||
command: >-
|
||||
--allowed-group=DataSHIELD
|
||||
--oidc-groups-claim=${OIDC_GROUP_CLAIM}
|
||||
--auth-logging=true
|
||||
--whitelist-domain=${HOST}
|
||||
--http-address="0.0.0.0:4180"
|
||||
--reverse-proxy=true
|
||||
--upstream="static://202"
|
||||
--email-domain="*"
|
||||
--cookie-name="_BRIDGEHEAD_oauth2"
|
||||
--cookie-secret="${OAUTH2_PROXY_SECRET}"
|
||||
--cookie-expire="12h"
|
||||
--cookie-secure="true"
|
||||
--cookie-httponly="true"
|
||||
#OIDC settings
|
||||
--provider="keycloak-oidc"
|
||||
--provider-display-name="VerbIS Login"
|
||||
--client-id="${OIDC_PRIVATE_CLIENT_ID}"
|
||||
--client-secret="${OIDC_CLIENT_SECRET}"
|
||||
--redirect-url="https://${HOST}${OAUTH2_CALLBACK}"
|
||||
--oidc-issuer-url="${OIDC_ISSUER_URL}"
|
||||
--scope="openid email profile"
|
||||
--code-challenge-method="S256"
|
||||
--skip-provider-button=true
|
||||
#X-Forwarded-Header settings - true/false depending on your needs
|
||||
--pass-basic-auth=true
|
||||
--pass-user-headers=false
|
||||
--pass-access-token=false
|
||||
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.oauth2_proxy.rule=Host(`${HOST}`) && PathPrefix(`/oauth2`, `/oauth2/callback`)"
|
||||
- "traefik.http.services.oauth2_proxy.loadbalancer.server.port=4180"
|
||||
- "traefik.http.routers.oauth2_proxy.tls=true"
|
||||
environment:
|
||||
http_proxy: "http://forward_proxy:3128"
|
||||
https_proxy: "http://forward_proxy:3128"
|
||||
depends_on:
|
||||
forward_proxy:
|
||||
condition: service_healthy
|
||||
|
||||
secrets:
|
||||
opal-cert.pem:
|
||||
file: /tmp/bridgehead/opal-cert.pem
|
||||
opal-key.pem:
|
||||
file: /tmp/bridgehead/opal-key.pem
|
||||
|
||||
networks:
|
||||
rstudio:
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
|
||||
{
|
||||
"sites": [
|
||||
{
|
||||
"id": "berlin",
|
||||
"name": "berlin",
|
||||
"virtualhost": "opal-berlin",
|
||||
"beamconnect": "datashield-connect.berlin.broker.ccp-it.dktk.dkfz.de"
|
||||
},
|
||||
{
|
||||
"id": "muenchen-lmu",
|
||||
"name": "muenchen-lmu",
|
||||
"virtualhost": "opal-muenchen-lmu",
|
||||
"beamconnect": "datashield-connect.muenchen-lmu.broker.ccp-it.dktk.dkfz.de"
|
||||
},
|
||||
{
|
||||
"id": "dresden",
|
||||
"name": "dresden",
|
||||
"virtualhost": "opal-dresden",
|
||||
"beamconnect": "datashield-connect.dresden.broker.ccp-it.dktk.dkfz.de"
|
||||
},
|
||||
{
|
||||
"id": "freiburg",
|
||||
"name": "freiburg",
|
||||
"virtualhost": "opal-freiburg",
|
||||
"beamconnect": "datashield-connect.freiburg.broker.ccp-it.dktk.dkfz.de"
|
||||
},
|
||||
{
|
||||
"id": "muenchen-tum",
|
||||
"name": "muenchen-tum",
|
||||
"virtualhost": "opal-muenchen-tum",
|
||||
"beamconnect": "datashield-connect.muenchen-tum.broker.ccp-it.dktk.dkfz.de"
|
||||
},
|
||||
{
|
||||
"id": "tuebingen",
|
||||
"name": "tuebingen",
|
||||
"virtualhost": "opal-tuebingen",
|
||||
"beamconnect": "datashield-connect.tuebingen.broker.ccp-it.dktk.dkfz.de"
|
||||
},
|
||||
{
|
||||
"id": "mainz",
|
||||
"name": "mainz",
|
||||
"virtualhost": "opal-mainz",
|
||||
"beamconnect": "datashield-connect.mainz.broker.ccp-it.dktk.dkfz.de"
|
||||
},
|
||||
{
|
||||
"id": "frankfurt",
|
||||
"name": "frankfurt",
|
||||
"virtualhost": "opal-frankfurt",
|
||||
"beamconnect": "datashield-connect.frankfurt.broker.ccp-it.dktk.dkfz.de"
|
||||
},
|
||||
{
|
||||
"id": "essen",
|
||||
"name": "essen",
|
||||
"virtualhost": "opal-essen",
|
||||
"beamconnect": "datashield-connect.essen.broker.ccp-it.dktk.dkfz.de"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,23 +1,39 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
if [ "$ENABLE_DATASHIELD" == true ]; then
|
||||
# HACK: This only works because exporter-setup.sh and teiler-setup.sh are sourced after datashield-setup.sh
|
||||
ENABLE_EXPORTER=true
|
||||
ENABLE_TEILER=true
|
||||
log INFO "DataSHIELD setup detected -- will start DataSHIELD services."
|
||||
OVERRIDE+=" -f ./$PROJECT/modules/datashield-compose.yml"
|
||||
OPAL_DB_PASSWORD="$(echo \"This is a salt string to generate one consistent password for Opal. It is not required to be secret.\" | openssl rsautl -sign -inkey /etc/bridgehead/pki/${SITE_ID}.priv.pem | base64 | head -c 30)"
|
||||
DATASHIELD_CONNECT_SECRET="$(echo \"This is a salt string to generate one consistent password as the DataShield Connect secret. It is not required to be secret.\" | openssl rsautl -sign -inkey /etc/bridgehead/pki/${SITE_ID}.priv.pem | base64 | head -c 30)"
|
||||
EXPORTER_OPAL_PASSWORD="$(generate_password \"exporter in Opal\")"
|
||||
TOKEN_MANAGER_OPAL_PASSWORD="$(generate_password \"Token Manager in Opal\")"
|
||||
OPAL_DB_PASSWORD="$(echo \"Opal DB\" | generate_simple_password)"
|
||||
OPAL_ADMIN_PASSWORD="$(generate_password \"admin password for Opal\")"
|
||||
RSTUDIO_ADMIN_PASSWORD="$(generate_password \"admin password for R-Studio\")"
|
||||
DATASHIELD_CONNECT_SECRET="$(echo \"DataShield Connect\" | generate_simple_password)"
|
||||
TOKEN_MANAGER_SECRET="$(echo \"Token Manager\" | generate_simple_password)"
|
||||
if [ ! -e /tmp/bridgehead/opal-cert.pem ]; then
|
||||
mkdir -p /tmp/bridgehead/
|
||||
chown -R bridgehead:docker /tmp/bridgehead/
|
||||
openssl req -x509 -newkey rsa:4096 -nodes -keyout /tmp/bridgehead/opal-key.pem -out /tmp/bridgehead/opal-cert.pem -days 3650 -subj "/CN=${HOST:-opal}/C=DE"
|
||||
chmod g+r /tmp/bridgehead/opal-key.pem
|
||||
openssl req -x509 -newkey rsa:4096 -nodes -keyout /tmp/bridgehead/opal-key.pem -out /tmp/bridgehead/opal-cert.pem -days 3650 -subj "/CN=opal/C=DE"
|
||||
fi
|
||||
mkdir -p /tmp/bridgehead/opal-map
|
||||
jq -n --argfile input ./$PROJECT/modules/datashield-mappings.json '
|
||||
[{
|
||||
"external": "opal-'"$SITE_ID"'",
|
||||
"internal": "opal:8080",
|
||||
"allowed": [$input.sites[].id | "datashield-connect.\(.).broker.ccp-it.dktk.dkfz.de"]
|
||||
}]' > /tmp/bridgehead/opal-map/local.json
|
||||
cp -f ./$PROJECT/modules/datashield-mappings.json /tmp/bridgehead/opal-map/central.json
|
||||
chown -R bridgehead:docker /tmp/bridgehead/
|
||||
sites="$(cat ./$PROJECT/modules/datashield-sites.json)"
|
||||
echo "$sites" | docker_jq -n --args '{"sites": input | map({
|
||||
"name": .,
|
||||
"id": .,
|
||||
"virtualhost": "\(.):443",
|
||||
"beamconnect": "datashield-connect.\(.).'"$BROKER_ID"'"
|
||||
})}' $sites > /tmp/bridgehead/opal-map/central.json
|
||||
echo "$sites" | docker_jq -n --args '[{
|
||||
"external": "'"$SITE_ID"':443",
|
||||
"internal": "opal:8443",
|
||||
"allowed": input | map("datashield-connect.\(.).'"$BROKER_ID"'")
|
||||
}]' > /tmp/bridgehead/opal-map/local.json
|
||||
if [ "$USER" == "root" ]; then
|
||||
chown -R bridgehead:docker /tmp/bridgehead
|
||||
chmod g+wr /tmp/bridgehead/opal-map/*
|
||||
chmod g+r /tmp/bridgehead/opal-key.pem
|
||||
fi
|
||||
add_private_oidc_redirect_url "/opal/*"
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
"berlin",
|
||||
"muenchen-lmu",
|
||||
"dresden",
|
||||
"freiburg",
|
||||
"muenchen-tum",
|
||||
"tuebingen",
|
||||
"mainz",
|
||||
"frankfurt",
|
||||
"essen",
|
||||
"dktk-datashield-test",
|
||||
"dktk-test",
|
||||
"mannheim"
|
||||
]
|
|
@ -15,7 +15,7 @@ services:
|
|||
HTTP_RELATIVE_PATH: "/ccp-exporter"
|
||||
SITE: "${SITE_ID}"
|
||||
HTTP_SERVLET_REQUEST_SCHEME: "https"
|
||||
OPAL_ADMINISTRATOR_PASSWORD: "${LDM_AUTH}"
|
||||
OPAL_PASSWORD: "${EXPORTER_OPAL_PASSWORD}"
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.exporter_ccp.rule=PathPrefix(`/ccp-exporter`)"
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
|
||||
login-db:
|
||||
image: docker.verbis.dkfz.de/cache/postgres:${POSTGRES_TAG}
|
||||
container_name: bridgehead-login-db
|
||||
environment:
|
||||
POSTGRES_USER: "keycloak"
|
||||
POSTGRES_PASSWORD: "${KEYCLOAK_DB_PASSWORD}" # Set in login-setup.sh
|
||||
POSTGRES_DB: "keycloak"
|
||||
tmpfs:
|
||||
- /var/lib/postgresql/data
|
||||
# Consider removing this comment once we have collected experience in production.
|
||||
# volumes:
|
||||
# - "bridgehead-login-db:/var/lib/postgresql/data"
|
||||
|
||||
login:
|
||||
image: docker.verbis.dkfz.de/ccp/dktk-keycloak:latest
|
||||
container_name: bridgehead-login
|
||||
environment:
|
||||
KEYCLOAK_ADMIN: "admin"
|
||||
KEYCLOAK_ADMIN_PASSWORD: "${LDM_AUTH}"
|
||||
TEILER_ADMIN: "${PROJECT}"
|
||||
TEILER_ADMIN_PASSWORD: "${LDM_AUTH}"
|
||||
TEILER_ADMIN_FIRST_NAME: "${OPERATOR_FIRST_NAME}"
|
||||
TEILER_ADMIN_LAST_NAME: "${OPERATOR_LAST_NAME}"
|
||||
TEILER_ADMIN_EMAIL: "${OPERATOR_EMAIL}"
|
||||
KC_DB_PASSWORD: "${KEYCLOAK_DB_PASSWORD}" # Set in login-setup.sh
|
||||
KC_HOSTNAME_URL: "https://${HOST}/login"
|
||||
KC_HOSTNAME_STRICT: "false"
|
||||
KC_PROXY_ADDRESS_FORWARDING: "true"
|
||||
TEILER_ORCHESTRATOR_EXTERN_URL: "https://${HOST}/ccp-teiler"
|
||||
command:
|
||||
- start-dev --import-realm --proxy edge --http-relative-path=/login
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.login.rule=PathPrefix(`/login`)"
|
||||
- "traefik.http.services.login.loadbalancer.server.port=8080"
|
||||
- "traefik.http.routers.login.tls=true"
|
||||
depends_on:
|
||||
- login-db
|
||||
|
||||
# Consider removing this comment once we have collected experience in production.
|
||||
#volumes:
|
||||
# bridgehead-login-db:
|
||||
# name: "bridgehead-login-db"
|
|
@ -1,7 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
if [ "$ENABLE_LOGIN" == true ]; then
|
||||
log INFO "Login setup detected -- will start Login services."
|
||||
OVERRIDE+=" -f ./$PROJECT/modules/login-compose.yml"
|
||||
KEYCLOAK_DB_PASSWORD="$(echo \"This is a salt string to generate one consistent password for Keycloak. It is not required to be secret.\" | openssl rsautl -sign -inkey /etc/bridgehead/pki/${SITE_ID}.priv.pem | base64 | head -c 30)"
|
||||
fi
|
|
@ -1,13 +0,0 @@
|
|||
# Login
|
||||
The login component is a local Keycloak instance. In the future will be replaced by the central keycloak instance
|
||||
or maybe can be used to add local identity providers to the bridgehead or just to simplify the configuration of
|
||||
the central keycloak instance for the integration of every new bridgehead.
|
||||
The basic configuration of our Keycloak instance is contained in a small json file.
|
||||
|
||||
### Teiler User
|
||||
Currently, the local keycloak is used by the teiler. There is a basic admin user in the basic configuration of keycloak.
|
||||
The user can be configured with the environment variables TEILER_ADMIN_XXX.
|
||||
|
||||
## Login-DB
|
||||
Keycloak requires a local database for its configuration. However, as we use an initial json configuration file, if no
|
||||
local identity provider is configured nor any local user, theoretically we don't need a volume for the login.
|
|
@ -2,7 +2,7 @@ version: "3.7"
|
|||
|
||||
services:
|
||||
mtba:
|
||||
image: docker.verbis.dkfz.de/cache/samply/mtba:1.0.0
|
||||
image: docker.verbis.dkfz.de/cache/samply/mtba:develop
|
||||
container_name: bridgehead-mtba
|
||||
environment:
|
||||
BLAZE_STORE_URL: http://blaze:8080
|
||||
|
@ -11,21 +11,27 @@ services:
|
|||
ID_MANAGER_API_KEY: ${IDMANAGER_UPLOAD_APIKEY}
|
||||
ID_MANAGER_PSEUDONYM_ID_TYPE: BK_${IDMANAGEMENT_FRIENDLY_ID}_L-ID
|
||||
ID_MANAGER_URL: http://id-manager:8080/id-manager
|
||||
PATIENT_CSV_FIRST_NAME_HEADER: ${MTBA_PATIENT_CSV_FIRST_NAME_HEADER}
|
||||
PATIENT_CSV_LAST_NAME_HEADER: ${MTBA_PATIENT_CSV_LAST_NAME_HEADER}
|
||||
PATIENT_CSV_GENDER_HEADER: ${MTBA_PATIENT_CSV_GENDER_HEADER}
|
||||
PATIENT_CSV_BIRTHDAY_HEADER: ${MTBA_PATIENT_CSV_BIRTHDAY_HEADER}
|
||||
PATIENT_CSV_FIRST_NAME_HEADER: ${MTBA_PATIENT_CSV_FIRST_NAME_HEADER:-FIRST_NAME}
|
||||
PATIENT_CSV_LAST_NAME_HEADER: ${MTBA_PATIENT_CSV_LAST_NAME_HEADER:-LAST_NAME}
|
||||
PATIENT_CSV_GENDER_HEADER: ${MTBA_PATIENT_CSV_GENDER_HEADER:-GENDER}
|
||||
PATIENT_CSV_BIRTHDAY_HEADER: ${MTBA_PATIENT_CSV_BIRTHDAY_HEADER:-BIRTHDAY}
|
||||
CBIOPORTAL_URL: http://cbioportal:8080
|
||||
FILE_CHARSET: ${MTBA_FILE_CHARSET}
|
||||
FILE_END_OF_LINE: ${MTBA_FILE_END_OF_LINE}
|
||||
CSV_DELIMITER: ${MTBA_CSV_DELIMITER}
|
||||
FILE_CHARSET: ${MTBA_FILE_CHARSET:-UTF-8}
|
||||
FILE_END_OF_LINE: ${MTBA_FILE_END_OF_LINE:-LF}
|
||||
CSV_DELIMITER: ${MTBA_CSV_DELIMITER:-TAB}
|
||||
HTTP_RELATIVE_PATH: "/mtba"
|
||||
OIDC_ADMIN_GROUP: "${OIDC_ADMIN_GROUP}"
|
||||
OIDC_CLIENT_ID: "${OIDC_PRIVATE_CLIENT_ID}"
|
||||
OIDC_CLIENT_SECRET: "${OIDC_CLIENT_SECRET}"
|
||||
OIDC_REALM: "${OIDC_REALM}"
|
||||
OIDC_URL: "${OIDC_URL}"
|
||||
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.mtba_ccp.rule=PathPrefix(`/mtba`)"
|
||||
- "traefik.http.services.mtba_ccp.loadbalancer.server.port=8480"
|
||||
- "traefik.http.routers.mtba_ccp.tls=true"
|
||||
- "traefik.http.middlewares.mtba_ccp_strip.stripprefix.prefixes=/mtba"
|
||||
- "traefik.http.routers.mtba_ccp.middlewares=mtba_ccp_strip, auth"
|
||||
|
||||
volumes:
|
||||
- /var/cache/bridgehead/ccp/mtba/input:/app/input
|
||||
- /var/cache/bridgehead/ccp/mtba/persist:/app/persist
|
||||
|
|
|
@ -8,5 +8,6 @@ function mtbaSetup() {
|
|||
exit 1;
|
||||
fi
|
||||
OVERRIDE+=" -f ./$PROJECT/modules/mtba-compose.yml"
|
||||
add_private_oidc_redirect_url "/mtba/*"
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ version: "3.7"
|
|||
services:
|
||||
|
||||
teiler-orchestrator:
|
||||
image: docker.verbis.dkfz.de/cache/samply/teiler-orchestrator:develop
|
||||
image: docker.verbis.dkfz.de/cache/samply/teiler-orchestrator:latest
|
||||
container_name: bridgehead-teiler-orchestrator
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
|
@ -31,9 +31,10 @@ services:
|
|||
environment:
|
||||
DEFAULT_LANGUAGE: "${DEFAULT_LANGUAGE}"
|
||||
TEILER_BACKEND_URL: "https://${HOST}/ccp-teiler-backend"
|
||||
KEYCLOAK_URL: "https://${HOST}/login"
|
||||
KEYCLOAK_REALM: "teiler"
|
||||
KEYCLOAK_CLIENT_ID: "teiler"
|
||||
OIDC_URL: "${OIDC_URL}"
|
||||
OIDC_REALM: "${OIDC_REALM}"
|
||||
OIDC_CLIENT_ID: "${OIDC_PUBLIC_CLIENT_ID}"
|
||||
OIDC_TOKEN_GROUP: "${OIDC_GROUP_CLAIM}"
|
||||
TEILER_ADMIN_NAME: "${OPERATOR_FIRST_NAME} ${OPERATOR_LAST_NAME}"
|
||||
TEILER_ADMIN_EMAIL: "${OPERATOR_EMAIL}"
|
||||
TEILER_ADMIN_PHONE: "${OPERATOR_PHONE}"
|
||||
|
@ -42,8 +43,11 @@ services:
|
|||
TEILER_ORCHESTRATOR_URL: "https://${HOST}/ccp-teiler"
|
||||
TEILER_DASHBOARD_HTTP_RELATIVE_PATH: "/ccp-teiler-dashboard"
|
||||
TEILER_ORCHESTRATOR_HTTP_RELATIVE_PATH: "/ccp-teiler"
|
||||
TEILER_USER: "TEILER_USER"
|
||||
TEILER_ADMIN: "TEILER_ADMIN"
|
||||
TEILER_USER: "${OIDC_USER_GROUP}"
|
||||
TEILER_ADMIN: "${OIDC_ADMIN_GROUP}"
|
||||
REPORTER_DEFAULT_TEMPLATE_ID: "ccp-qb"
|
||||
EXPORTER_DEFAULT_TEMPLATE_ID: "ccp"
|
||||
|
||||
|
||||
teiler-backend:
|
||||
image: docker.verbis.dkfz.de/ccp/dktk-teiler-backend:latest
|
||||
|
@ -67,6 +71,8 @@ services:
|
|||
TEILER_DASHBOARD_EN_URL: "https://${HOST}/ccp-teiler-dashboard/en"
|
||||
CENTRAX_URL: "${CENTRAXX_URL}"
|
||||
HTTP_PROXY: "http://forward_proxy:3128"
|
||||
ENABLE_MTBA: "${ENABLE_MTBA}"
|
||||
ENABLE_DATASHIELD: "${ENABLE_DATASHIELD}"
|
||||
secrets:
|
||||
- ccp.conf
|
||||
|
||||
|
|
|
@ -3,4 +3,7 @@
|
|||
if [ "$ENABLE_TEILER" == true ];then
|
||||
log INFO "Teiler setup detected -- will start Teiler services."
|
||||
OVERRIDE+=" -f ./$PROJECT/modules/teiler-compose.yml"
|
||||
DEFAULT_LANGUAGE=DE
|
||||
DEFAULT_LANGUAGE_LOWER_CASE=${DEFAULT_LANGUAGE,,}
|
||||
add_public_oidc_redirect_url "/ccp-teiler/*"
|
||||
fi
|
||||
|
|
19
ccp/vars
19
ccp/vars
|
@ -7,13 +7,20 @@ SUPPORT_EMAIL=support-ccp@dkfz-heidelberg.de
|
|||
PRIVATEKEYFILENAME=/etc/bridgehead/pki/${SITE_ID}.priv.pem
|
||||
|
||||
BROKER_URL_FOR_PREREQ=$BROKER_URL
|
||||
DEFAULT_LANGUAGE=DE
|
||||
DEFAULT_LANGUAGE_LOWER_CASE=${DEFAULT_LANGUAGE,,}
|
||||
ENABLE_EXPORTER=true
|
||||
ENABLE_LOGIN=true
|
||||
ENABLE_TEILER=true
|
||||
#ENABLE_DATASHIELD=true
|
||||
|
||||
OIDC_USER_GROUP="DKTK_CCP_$(capitalize_first_letter ${SITE_ID})"
|
||||
OIDC_ADMIN_GROUP="DKTK_CCP_$(capitalize_first_letter ${SITE_ID})_Verwalter"
|
||||
OIDC_PRIVATE_CLIENT_ID=${SITE_ID}-private
|
||||
OIDC_PUBLIC_CLIENT_ID=${SITE_ID}-public
|
||||
# Use "test-realm-01" for testing
|
||||
OIDC_REALM="${OIDC_REALM:-master}"
|
||||
OIDC_URL="https://login.verbis.dkfz.de"
|
||||
OIDC_ISSUER_URL="${OIDC_URL}/realms/${OIDC_REALM}"
|
||||
OIDC_GROUP_CLAIM="groups"
|
||||
OAUTH2_CALLBACK=/oauth2/callback
|
||||
OAUTH2_PROXY_SECRET="$(echo \"This is a salt string to generate one consistent encryption key for the oauth2_proxy. It is not required to be secret.\" | openssl rsautl -sign -inkey /etc/bridgehead/pki/${SITE_ID}.priv.pem | base64 | head -c 32)"
|
||||
|
||||
add_private_oidc_redirect_url "${OAUTH2_CALLBACK}"
|
||||
POSTGRES_TAG=15.6-alpine
|
||||
|
||||
for module in $PROJECT/modules/*.sh
|
||||
|
|
116
lib/functions.sh
116
lib/functions.sh
|
@ -132,6 +132,12 @@ assertVarsNotEmpty() {
|
|||
fixPermissions() {
|
||||
CHOWN=$(which chown)
|
||||
sudo $CHOWN -R bridgehead /etc/bridgehead /srv/docker/bridgehead
|
||||
if [ -d "/tmp/bridgehead" ]; then # Used by datashield
|
||||
sudo $CHOWN -R bridgehead:docker "/tmp/bridgehead"
|
||||
fi
|
||||
if [ -d "/var/cache/bridgehead" ]; then # Used by the teiler
|
||||
sudo $CHOWN -R bridgehead:docker "/var/cache/bridgehead"
|
||||
fi
|
||||
}
|
||||
|
||||
source lib/monitoring.sh
|
||||
|
@ -239,3 +245,113 @@ add_basic_auth_user() {
|
|||
log DEBUG "Saving clear text credentials in $FILE. If wanted, delete them manually."
|
||||
sed -i "/^$NAME/ s|$|\n# User: $USER\n# Password: $PASSWORD|" $FILE
|
||||
}
|
||||
|
||||
OIDC_PUBLIC_REDIRECT_URLS=${OIDC_PUBLIC_REDIRECT_URLS:-""}
|
||||
OIDC_PRIVATE_REDIRECT_URLS=${OIDC_PRIVATE_REDIRECT_URLS:-""}
|
||||
|
||||
# Add a redirect url to the public oidc client of the bridgehead
|
||||
function add_public_oidc_redirect_url() {
|
||||
if [[ $OIDC_PUBLIC_REDIRECT_URLS == "" ]]; then
|
||||
OIDC_PUBLIC_REDIRECT_URLS+="$(generate_redirect_urls $1)"
|
||||
else
|
||||
OIDC_PUBLIC_REDIRECT_URLS+=",$(generate_redirect_urls $1)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Add a redirect url to the private oidc client of the bridgehead
|
||||
function add_private_oidc_redirect_url() {
|
||||
if [[ $OIDC_PRIVATE_REDIRECT_URLS == "" ]]; then
|
||||
OIDC_PRIVATE_REDIRECT_URLS+="$(generate_redirect_urls $1)"
|
||||
else
|
||||
OIDC_PRIVATE_REDIRECT_URLS+=",$(generate_redirect_urls $1)"
|
||||
fi
|
||||
}
|
||||
|
||||
function sync_secrets() {
|
||||
local delimiter=$'\x1E'
|
||||
local secret_sync_args=""
|
||||
if [[ $OIDC_PRIVATE_REDIRECT_URLS != "" ]]; then
|
||||
secret_sync_args="OIDC:OIDC_CLIENT_SECRET:private;$OIDC_PRIVATE_REDIRECT_URLS"
|
||||
fi
|
||||
if [[ $OIDC_PRIVATE_REDIRECT_URLS != "" ]]; then
|
||||
if [[ $secret_sync_args == "" ]]; then
|
||||
secret_sync_args="OIDC:OIDC_PUBLIC:public;$OIDC_PUBLIC_REDIRECT_URLS"
|
||||
else
|
||||
secret_sync_args+="${delimiter}OIDC:OIDC_PUBLIC:public;$OIDC_PUBLIC_REDIRECT_URLS"
|
||||
fi
|
||||
fi
|
||||
if [[ $secret_sync_args == "" ]]; then
|
||||
return
|
||||
fi
|
||||
mkdir -p /var/cache/bridgehead/secrets/
|
||||
touch /var/cache/bridgehead/secrets/oidc
|
||||
docker run --rm \
|
||||
-v /var/cache/bridgehead/secrets/oidc:/usr/local/cache \
|
||||
-v $PRIVATEKEYFILENAME:/run/secrets/privkey.pem:ro \
|
||||
-v /srv/docker/bridgehead/$PROJECT/root.crt.pem:/run/secrets/root.crt.pem:ro \
|
||||
-v /etc/bridgehead/trusted-ca-certs:/conf/trusted-ca-certs:ro \
|
||||
-e TLS_CA_CERTIFICATES_DIR=/conf/trusted-ca-certs \
|
||||
-e NO_PROXY=localhost,127.0.0.1 \
|
||||
-e ALL_PROXY=$HTTPS_PROXY_FULL_URL \
|
||||
-e PROXY_ID=$PROXY_ID \
|
||||
-e BROKER_URL=$BROKER_URL \
|
||||
-e OIDC_PROVIDER=secret-sync-central.oidc-client-enrollment.$BROKER_ID \
|
||||
-e SECRET_DEFINITIONS=$secret_sync_args \
|
||||
docker.verbis.dkfz.de/cache/samply/secret-sync-local:latest
|
||||
|
||||
set -a # Export variables as environment variables
|
||||
source /var/cache/bridgehead/secrets/*
|
||||
set +a # Export variables in the regular way
|
||||
}
|
||||
|
||||
capitalize_first_letter() {
|
||||
input="$1"
|
||||
capitalized="$(tr '[:lower:]' '[:upper:]' <<< ${input:0:1})${input:1}"
|
||||
echo "$capitalized"
|
||||
}
|
||||
|
||||
# Generate a string of ',' separated string of redirect urls relative to $HOST.
|
||||
# $1 will be appended to the url
|
||||
# If the host looks like dev-jan.inet.dkfz-heidelberg.de it will generate urls with dev-jan and the original $HOST as url Authorities
|
||||
function generate_redirect_urls(){
|
||||
local redirect_urls="https://${HOST}$1"
|
||||
local host_without_proxy="$(echo "$HOST" | cut -d '.' -f1)"
|
||||
# Only append second url if its different and the host is not an ip address
|
||||
if [[ "$HOST" != "$host_without_proxy" && ! "$HOST" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
redirect_urls+=",https://$host_without_proxy$1"
|
||||
fi
|
||||
echo "$redirect_urls"
|
||||
}
|
||||
|
||||
# This password contains at least one special char, a random number and a random upper and lower case letter
|
||||
generate_password(){
|
||||
local seed_text="$1"
|
||||
local seed_num=$(awk 'BEGIN{FS=""} NR==1{print $10}' /etc/bridgehead/pki/${SITE_ID}.priv.pem | od -An -tuC)
|
||||
local nums="1234567890"
|
||||
local n=$(echo "$seed_num" | awk '{print $1 % 10}')
|
||||
local random_digit=${nums:$n:1}
|
||||
local n=$(echo "$seed_num" | awk '{print $1 % 26}')
|
||||
local upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
local lower="abcdefghijklmnopqrstuvwxyz"
|
||||
local random_upper=${upper:$n:1}
|
||||
local random_lower=${lower:$n:1}
|
||||
local n=$(echo "$seed_num" | awk '{print $1 % 8}')
|
||||
local special='@#$%^&+='
|
||||
local random_special=${special:$n:1}
|
||||
|
||||
local combined_text="This is a salt string to generate one consistent password for ${seed_text}. It is not required to be secret."
|
||||
local main_password=$(echo "${combined_text}" | openssl rsautl -sign -inkey "/etc/bridgehead/pki/${SITE_ID}.priv.pem" 2> /dev/null | base64 | head -c 26 | sed 's/\//A/g')
|
||||
|
||||
echo "${main_password}${random_digit}${random_upper}${random_lower}${random_special}"
|
||||
}
|
||||
|
||||
# This password only contains alphanumeric characters
|
||||
generate_simple_password(){
|
||||
local seed_text="$1"
|
||||
local combined_text="This is a salt string to generate one consistent password for ${seed_text}. It is not required to be secret."
|
||||
echo "${combined_text}" | openssl rsautl -sign -inkey "/etc/bridgehead/pki/${SITE_ID}.priv.pem" 2> /dev/null | base64 | head -c 26 | sed 's/[+\/]/A/g'
|
||||
}
|
||||
|
||||
docker_jq() {
|
||||
docker run --rm -i docker.verbis.dkfz.de/cache/jqlang/jq:latest "$@"
|
||||
}
|
||||
|
|
|
@ -89,6 +89,9 @@ elif [[ "$DEV_MODE" == "DEV" ]]; then
|
|||
fi
|
||||
|
||||
chown -R bridgehead /etc/bridgehead /srv/docker/bridgehead
|
||||
mkdir -p /tmp/bridgehead /var/cache/bridgehead
|
||||
chown -R bridgehead:docker /tmp/bridgehead /var/cache/bridgehead
|
||||
chmod -R g+wr /var/cache/bridgehead /tmp/bridgehead
|
||||
|
||||
log INFO "System preparation is completed and configuration is present."
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ services:
|
|||
- /var/spool/squid
|
||||
volumes:
|
||||
- /etc/bridgehead/trusted-ca-certs:/docker/custom-certs/:ro
|
||||
healthcheck:
|
||||
test: ["CMD", "sleep", "1"]
|
||||
|
||||
landing:
|
||||
container_name: bridgehead-landingpage
|
||||
|
@ -55,5 +57,3 @@ services:
|
|||
HOST: ${HOST}
|
||||
PROJECT: ${PROJECT}
|
||||
SITE_NAME: ${SITE_NAME}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue