diff --git a/.env b/.env index 19ca5b6..72d4e80 100644 --- a/.env +++ b/.env @@ -7,10 +7,13 @@ # # Host # -SERVER_SCHEME=https -HOST_URL=http://172.17.0.1 +SERVER_SCHEME=http +HOST_IP_ADDRESS= +HOST_NAME=${HOST_IP_ADDRESS:-localhost} +HOST_URL=${SERVER_SCHEME}://${HOST_NAME} TIMEZONE=UTC - +GITPOD_ENV=false +ENABLE_SSO=false # # OpenMRS # @@ -29,7 +32,7 @@ SPA_CONFIG_URLS=/openmrs/spa/configs/ozone-frontend-config.json SPA_DEFAULT_LOCALE=en # OpenMRS frontend and backend Docker image tag -O3_DOCKER_IMAGE_TAG= +O3_DOCKER_IMAGE_TAG=3.1.1 # # MySQL @@ -57,6 +60,8 @@ ODOO_CONFIG_PATH= ODOO_INITIALIZER_CONFIG_FILE_PATH= ODOO_DATABASE=odoo +ODOO_SERVER_ENV_CONFIG= + # # ERPNext # @@ -70,6 +75,21 @@ ERPNEXT_DB_NAME=erpnext SITE=senaite SENAITE_ADMIN_USER=admin SENAITE_ADMIN_PASSWORD=password +SENAITE_DB_NAME=senaite +SENAITE_DB_USER=senaite +SENAITE_DB_PASSWORD=password +SENAITE_DB_HOST=postgresql + +# +# Keycloak +# +KEYCLOAK_DB_USER=keycloak +KEYCLOAK_DB_PASSWORD=keycloak +KEYCLOAK_DB=keycloak +KEYCLOAK_DB_SCHEMA=keycloak +KEYCLOAK_USER=admin +KEYCLOAK_PASSWORD=password +KEYCLOAK_INTERNAL_HOST_URL=http://keycloak:8080 # # Common EIP clients config @@ -116,6 +136,7 @@ OPENMRS_PROPERTIES_PATH= OPENMRS_CORE_PATH= OPENMRS_MODULES_PATH= OPENMRS_CONFIG_PATH= +OPENMRS_TOMCAT_CONFIG_PATH= OPENMRS_PERSON_IMAGES_PATH= OPENMRS_COMPLEX_OBS_PATH= SPA_PATH= @@ -124,6 +145,7 @@ OPENMRS_OWAS_PATH= ODOO_CONFIG_PATH= ODOO_EXTRA_ADDONS= SENAITE_CONFIG_PATH= +KEYCLOAK_CONFIG_PATH= OPENMRS_FRONTEND_BINARY_PATH= OPENMRS_FRONTEND_CONFIG_PATH= EIP_OPENMRS_SENAITE_CONFIG_PATH= @@ -147,11 +169,40 @@ ODOO_CONFIG_CHECKSUMS_PATH= # # Public Hostnames # -O3_HOSTNAME=emr-172-17-0-1.traefik.me -ODOO_HOSTNAME=erp-172-17-0-1.traefik.me -SENAITE_HOSTNAME=lims-172-17-0-1.traefik.me -ERPNEXT_HOSTNAME=erpnext-172-17-0-1.traefik.me -FHIR_ODOO_HOSTNAME=fhir-erp-172-17-0-1.traefik.me +O3_HOSTNAME=${HOST_NAME} +ODOO_HOSTNAME=${HOST_NAME}:8069 +SENAITE_HOSTNAME=${HOST_NAME}:8081 +ERPNEXT_HOSTNAME=${HOST_NAME}:8082 +SUPERSET_HOSTNAME=${HOST_NAME}:8088 +FHIR_ODOO_HOSTNAME=${HOST_NAME}:8083 +KEYCLOAK_HOSTNAME=${HOST_NAME}:8084 + +# +# Sample SSO Client Secrets used in the demo script +# +SUPERSET_CLIENT_UUID=891b980a-9edb-4c72-a63d-1f8e488d6ad4 +SUPERSET_CLIENT_SECRET=znZK8dvk7hLOpwfU + +SENAITE_CLIENT_UUID=3b8672bf-b239-46e5-b0b6-8ba71a4bf5ac +SENAITE_CLIENT_SECRET=Vdi1xIgJiUcrF4dx + +OPENMRS_CLIENT_UUID=14b6083d-2d3c-4fb1-a75d-0f5af17be198 +OPENMRS_CLIENT_SECRET=AYmNV4AEHA0Tlxwa + +ODOO_CLIENT_UUID=70a0e2fd-2bb2-4417-9fc6-22cdca1bb5be +ODOO_CLIENT_SECRET=z3epa8rE66tUIZz6 + +KEYCLOAK_ADMIN_SA_CLIENT_SECRET=5HuMNB6gwHd0fY2L +EIP_CLIENT_SECRET=h9PQzv6zWnVl1yxnhdfZulnW7FPqPlci + +# +# EIP OAuth2 +# +OAUTH_ENABLED=${ENABLE_SSO} +OAUTH_CLIENT_ID=eip +OAUTH_CLIENT_SECRET=${EIP_CLIENT_SECRET} +OAUTH_CLIENT_SCOPE=openid +OAUTH_ACCESS_TOKEN_URL=http://keycloak:8080/realms/ozone/protocol/openid-connect/token # # Backup diff --git a/bundled-docker/frontend/Dockerfile b/bundled-docker/frontend/Dockerfile index 113b706..d917848 100644 --- a/bundled-docker/frontend/Dockerfile +++ b/bundled-docker/frontend/Dockerfile @@ -1,6 +1,8 @@ FROM openmrs/openmrs-reference-application-3-frontend:nightly + ADD distro/binaries/openmrs/frontend /usr/share/nginx/html ADD distro/configs/openmrs/frontend_config /usr/share/nginx/html/configs + RUN mkdir -p /app WORKDIR /app COPY bundled-docker/frontend/startup.sh /app diff --git a/bundled-docker/frontend/startup.sh b/bundled-docker/frontend/startup.sh index 7f60d42..1e63ad6 100755 --- a/bundled-docker/frontend/startup.sh +++ b/bundled-docker/frontend/startup.sh @@ -3,6 +3,6 @@ set -e for f in /usr/share/nginx/html/configs/*.json; do echo "processing===> $f"; - envsubst < $f | sponge $f; + envsubst < "$f" | sponge "$f"; done /usr/local/bin/startup.sh diff --git a/bundled-docker/keycloak/Dockerfile b/bundled-docker/keycloak/Dockerfile new file mode 100644 index 0000000..37e68bd --- /dev/null +++ b/bundled-docker/keycloak/Dockerfile @@ -0,0 +1,3 @@ +FROM docker.io/bitnami/keycloak:22.0.5 +ADD configs/keycloak/realms /keycloak-files/realm-config +ADD configs/keycloak/themes/carbon /opt/bitnami/keycloak/themes/carbon diff --git a/bundled-docker/openmrs/Dockerfile b/bundled-docker/openmrs/Dockerfile index 4a5357f..c74ee34 100644 --- a/bundled-docker/openmrs/Dockerfile +++ b/bundled-docker/openmrs/Dockerfile @@ -1,3 +1,8 @@ -FROM openmrs/openmrs-reference-application-3-backend:nightly -ADD binaries/openmrs/modules /openmrs/distribution/openmrs_modules -ADD configs/openmrs/initializer_config /openmrs/distribution/openmrs_config \ No newline at end of file +FROM openmrs/openmrs-core:2.6.7 + +# Add modules & configurations for the ozone distribution +ADD distro/binaries/openmrs/modules /openmrs/distribution/openmrs_modules +ADD distro/configs/openmrs/initializer_config /openmrs/distribution/openmrs_config +ADD distro/configs/openmrs/properties/fhirproxy.properties /openmrs/data/fhirproxy/config.properties +ADD distro/configs/openmrs/properties/oauth2.properties /openmrs/data/oauth2.properties +ADD bundled-docker/openmrs/tomcat/server.xml /usr/local/tomcat/conf/server.xml diff --git a/bundled-docker/pom.xml b/bundled-docker/pom.xml index 7871686..cfc4f71 100644 --- a/bundled-docker/pom.xml +++ b/bundled-docker/pom.xml @@ -76,7 +76,15 @@ postgresql/** proxy/** senaite/** + keycloak/** + + + + ../ + docker-compose-bundled.yml.template + docker-compose-bundled-sso.yml.template + openmrs/** @@ -105,4 +113,4 @@ - \ No newline at end of file + diff --git a/bundled-docker/postgresql/Dockerfile b/bundled-docker/postgresql/Dockerfile index 96e4c04..e401f99 100644 --- a/bundled-docker/postgresql/Dockerfile +++ b/bundled-docker/postgresql/Dockerfile @@ -1,3 +1,6 @@ FROM postgres:13 + ADD data/postgresql/create_db.sh /docker-entrypoint-initdb.d/create_db.sh -ADD data/postgresql/odoo /docker-entrypoint-initdb.d/db/odoo \ No newline at end of file +ADD data/postgresql/odoo /docker-entrypoint-initdb.d/db/odoo +ADD data/postgresql/senaite /docker-entrypoint-initdb.d/db/senaite +ADD data/postgresql/keycloak /docker-entrypoint-initdb.d/db/keycloak diff --git a/bundled-docker/proxy/default.conf.template b/bundled-docker/proxy/default.conf.template index 82d9ec4..98e5c35 100644 --- a/bundled-docker/proxy/default.conf.template +++ b/bundled-docker/proxy/default.conf.template @@ -151,3 +151,14 @@ server { proxy_pass http://$senaite; } } + +server { + listen 8084; + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Forward-Proto http; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + set $keycloak keycloak:8080; + proxy_pass http://$keycloak; + } +} diff --git a/bundled-docker/senaite/Dockerfile b/bundled-docker/senaite/Dockerfile index ba8f7e9..5496135 100644 --- a/bundled-docker/senaite/Dockerfile +++ b/bundled-docker/senaite/Dockerfile @@ -1,2 +1,3 @@ -FROM mekomsolutions/senaite -ADD configs/senaite/initializer_config /data/importdata/senaite \ No newline at end of file +FROM mekomsolutions/senaite-ozonepro +ADD configs/senaite/initializer_config /data/importdata/senaite +ADD configs/senaite/oidc /data/oidc diff --git a/demo/docker-compose-sso.yml b/demo/docker-compose-sso.yml new file mode 100644 index 0000000..24f2ea8 --- /dev/null +++ b/demo/docker-compose-sso.yml @@ -0,0 +1,8 @@ +services: + eip-demo: + environment: + OAUTH_ENABLED: ${OAUTH_ENABLED} + OAUTH_ACCESS_TOKEN_URL: ${OAUTH_ACCESS_TOKEN_URL} + OAUTH_CLIENT_ID: ${OAUTH_CLIENT_ID} + OAUTH_CLIENT_SECRET: ${OAUTH_CLIENT_SECRET} + OAUTH_CLIENT_SCOPE: ${OAUTH_CLIENT_SCOPE} diff --git a/demo/eip/config/application.properties b/demo/eip/config/application.properties index 89ba16a..3dc53a4 100644 --- a/demo/eip/config/application.properties +++ b/demo/eip/config/application.properties @@ -10,3 +10,19 @@ openmrs.baseUrl=${OPENMRS_URL} # Number of demo patients used to generate demo data, defaults to 0 number.of.demo.patients=${NUMBER_OF_DEMO_PATIENTS} # ---------------------------------------------------------------------------------------------------------------------- + +# *********************** OAuth2 Configuration ************************************************************************* +# Enable OAuth2 authentication, defaults to false. +oauth.enabled=${OAUTH_ENABLED:false} +# The client ID of the account, defaults to empty. +oauth.access.token.url=${OAUTH_ACCESS_TOKEN_URL:} + +# The client ID of the account to use to authenticate, defaults to empty. +oauth.client.id=${OAUTH_CLIENT_ID:} + +# The client secret of the account to use to authenticate, defaults to empty. +oauth.client.secret=${OAUTH_CLIENT_SECRET:} + +# Authentication scope, can be multiple values separated by commas, defaults to empty. +oauth.client.scope=${OAUTH_CLIENT_SCOPE:} +# ---------------------------------------------------------------------------------------------------------------------- diff --git a/demo/eip/routes/generate-demo-data-route.xml b/demo/eip/routes/generate-demo-data-route.xml index 756c577..0b2a11e 100644 --- a/demo/eip/routes/generate-demo-data-route.xml +++ b/demo/eip/routes/generate-demo-data-route.xml @@ -5,7 +5,15 @@ - + + + {{oauth.enabled}} + + + + + + ${properties:number.of.demo.patients:50} diff --git a/demo/eip/routes/oauth2-authenticate-to-openmrs-route.xml b/demo/eip/routes/oauth2-authenticate-to-openmrs-route.xml new file mode 100644 index 0000000..e80ae84 --- /dev/null +++ b/demo/eip/routes/oauth2-authenticate-to-openmrs-route.xml @@ -0,0 +1,21 @@ + + + + + + {{oauth.access.token.url}} + + + {{oauth.client.id}} + + + {{oauth.client.secret}} + + + {{oauth.client.scope}} + + + + diff --git a/docker-compose-bundled-sso.yml.template b/docker-compose-bundled-sso.yml.template new file mode 100644 index 0000000..6d89d71 --- /dev/null +++ b/docker-compose-bundled-sso.yml.template @@ -0,0 +1,115 @@ +services: + keycloak: + image: ${dockerUserName}/${sanitizedArtifactId}-keycloak:${dockertag} + restart: unless-stopped + environment: + KC_HOSTNAME_URL: \${SERVER_SCHEME}://\${KEYCLOAK_HOSTNAME} + PROXY_ADDRESS_FORWARDING: "true" + KC_HTTP_ENABLED: 'true' + KC_HOSTNAME_STRICT_BACKCHANNEL: "true" + KC_PROXY: reencrypt + KC_HEALTH_ENABLED: 'true' + KC_METRICS_ENABLED: 'true' + KEYCLOAK_DATABASE_VENDOR: postgresql + KEYCLOAK_DATABASE_HOST: postgresql + KEYCLOAK_DATABASE_PORT_NUMBER: 5432 + KEYCLOAK_DATABASE_NAME: \${KEYCLOAK_DB} + KEYCLOAK_DATABASE_USER: \${KEYCLOAK_DB_USER} + KEYCLOAK_DATABASE_PASSWORD: \${KEYCLOAK_DB_PASSWORD} + KEYCLOAK_DATABASE_SCHEMA: \${KEYCLOAK_DB_SCHEMA} + KEYCLOAK_CREATE_ADMIN_USER: "true" + KEYCLOAK_ADMIN_USER: \${KEYCLOAK_USER} + KEYCLOAK_ADMIN_PASSWORD: \${KEYCLOAK_PASSWORD} + HOST_URL: \${SERVER_SCHEME}://\${O3_HOSTNAME} + KEYCLOAK_AUTH_SERVER_URL: \${SERVER_SCHEME}://\${KEYCLOAK_HOSTNAME} + ODOO_PUBLIC_URL: \${SERVER_SCHEME}://\${ODOO_HOSTNAME} + OPENMRS_PUBLIC_URL: \${SERVER_SCHEME}://\${O3_HOSTNAME} + SENAITE_PUBLIC_URL: \${SERVER_SCHEME}://\${SENAITE_HOSTNAME} + SUPERSET_PUBLIC_URL: \${SERVER_SCHEME}://\${SUPERSET_HOSTNAME} + ODOO_CLIENT_SECRET: \${ODOO_CLIENT_SECRET} + ODOO_CLIENT_UUID: \${ODOO_CLIENT_UUID} + OPENMRS_CLIENT_SECRET: \${OPENMRS_CLIENT_SECRET} + OPENMRS_CLIENT_UUID: \${OPENMRS_CLIENT_UUID} + SENAITE_CLIENT_SECRET: \${SENAITE_CLIENT_SECRET} + SENAITE_CLIENT_UUID: \${SENAITE_CLIENT_UUID} + SUPERSET_CLIENT_SECRET: \${SUPERSET_CLIENT_SECRET} + SUPERSET_CLIENT_UUID: \${SUPERSET_CLIENT_UUID} + KEYCLOAK_ADMIN_SA_CLIENT_SECRET: \${KEYCLOAK_ADMIN_SA_CLIENT_SECRET} + EIP_CLIENT_SECRET: \${EIP_CLIENT_SECRET} + KEYCLOAK_EXTRA_ARGS_PREPENDED: "--spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true" + KEYCLOAK_EXTRA_ARGS: " + -Dkeycloak.profile.feature.scripts=enabled + -Dkeycloak.migration.replace-placeholders=true + -Dkeycloak.migration.action=import + -Dkeycloak.migration.provider=dir + -Dkeycloak.migration.dir=/keycloak-files/realm-config + -Dkeycloak.migration.strategy=OVERWRITE_EXISTING" + + healthcheck: + test: ["CMD", "curl", "-f", "http://0.0.0.0:8080/health/ready"] + interval: 15s + timeout: 3s + retries: 5 + start_period: 30s + + depends_on: + postgresql: + condition: service_started + networks: + ozone: + web: + labels: + traefik.enable: "true" + traefik.http.routers.keycloak.rule: "Host(`\${KEYCLOAK_HOSTNAME}`)" + traefik.http.routers.keycloak.entrypoints: "websecure" + traefik.http.services.keycloak.loadbalancer.server.port: 8080 + + postgresql: + environment: + KEYCLOAK_DB: \${KEYCLOAK_DB} + KEYCLOAK_DB_SCHEMA: \${KEYCLOAK_DB_SCHEMA} + KEYCLOAK_DB_USER: \${KEYCLOAK_DB_USER} + KEYCLOAK_DB_PASSWORD: \${KEYCLOAK_DB_PASSWORD} + # Odoo + odoo: + environment: + - KEYCLOAK_URL=\${SERVER_SCHEME}://\${KEYCLOAK_HOSTNAME} + - ODOO_CLIENT_UUID=\${ODOO_CLIENT_UUID} + - ODOO_CLIENT_SECRET=\${ODOO_CLIENT_SECRET} + - ADDONS=sale_management,stock,account_account,purchase,mrp,mrp_product_expiry,product_expiry,l10n_generic_coa,odoo_initializer,ozone_settings,server_environment,auth_oidc_environment,auth_oidc + # EIP Odoo OpenMRS Integration Service + eip-odoo-openmrs: + environment: + OAUTH_ACCESS_TOKEN_URL: \${OAUTH_ACCESS_TOKEN_URL} + OAUTH_ENABLED: \${OAUTH_ENABLED} + OAUTH_CLIENT_ID: \${OAUTH_CLIENT_ID} + OAUTH_CLIENT_SECRET: \${OAUTH_CLIENT_SECRET} + OAUTH_CLIENT_SCOPE: \${OAUTH_CLIENT_SCOPE} + + # OpenMRS Backend + openmrs: + environment: + KEYCLOAK_URL: \${SERVER_SCHEME}://\${KEYCLOAK_HOSTNAME} + OPENMRS_CLIENT_UUID: \${OPENMRS_CLIENT_UUID} + OPENMRS_CLIENT_SECRET: \${OPENMRS_CLIENT_SECRET} + + frontend: + environment: + SPA_CONFIG_URLS: \${SPA_CONFIG_URLS},/openmrs/spa/configs/ozone-frontend-config-sso.json + + # SENAITE + senaite: + environment: + OAUTH_CONFIG_FILE: /data/oidc/client.json + OAUTH_CONFIG_PATH: /data/oidc + KEYCLOAK_URL: \${SERVER_SCHEME}://\${KEYCLOAK_HOSTNAME} + SENAITE_CLIENT_UUID: \${SENAITE_CLIENT_UUID} + SENAITE_CLIENT_SECRET: \${SENAITE_CLIENT_SECRET} + # OpenMRS - SENAITE integration service + eip-openmrs-senaite: + environment: + OAUTH_ACCESS_TOKEN_URL: \${OAUTH_ACCESS_TOKEN_URL} + OAUTH_ENABLED: \${OAUTH_ENABLED} + OAUTH_CLIENT_ID: \${OAUTH_CLIENT_ID} + OAUTH_CLIENT_SECRET: \${OAUTH_CLIENT_SECRET} + OAUTH_CLIENT_SCOPE: \${OAUTH_CLIENT_SCOPE} diff --git a/bundled-docker/docker-compose-bundled.yml.template b/docker-compose-bundled.yml.template similarity index 98% rename from bundled-docker/docker-compose-bundled.yml.template rename to docker-compose-bundled.yml.template index c0f7b4e..75238ad 100644 --- a/bundled-docker/docker-compose-bundled.yml.template +++ b/docker-compose-bundled.yml.template @@ -295,6 +295,10 @@ services: - OPENMRS_DB_PASSWORD=\${OPENMRS_DB_PASSWORD} - OPENMRS_USER=\${OPENMRS_USER} - OPENMRS_PASSWORD=\${OPENMRS_PASSWORD} + - EIP_FHIR_RESOURCES=Patient,ServiceRequest + - EIP_FHIR_SERVER_URL=http://openmrs:8080/openmrs/ws/fhir2/R4 + - EIP_FHIR_USERNAME=\${OPENMRS_USER} + - EIP_FHIR_PASSWORD=\${OPENMRS_PASSWORD} image: ${dockerUserName}/${sanitizedArtifactId}-eip-openmrs-senaite:${dockertag} networks: ozone: @@ -318,11 +322,9 @@ services: - "\${PROXY_PUBLIC_PORT:-80}:80" - "8069:8069" - "8081:8081" - - "8088:8088" - - "8082:8082" + - "8084:8084" volumes: - "\${PROXY_TLS_CERTS_PATH:-proxy-tls-certs}:/etc/tls" -version: "3.7" volumes: mysql-data: ~ @@ -343,4 +345,3 @@ volumes: senaite-blobstorage: ~ senaite-filestorage: ~ proxy-tls-certs: ~ - \ No newline at end of file diff --git a/docker-compose-common.yml b/docker-compose-common.yml index c63c13d..50103e3 100644 --- a/docker-compose-common.yml +++ b/docker-compose-common.yml @@ -41,8 +41,7 @@ services: restic-compose-backup.mariadb: true postgresql: - command: "postgres -c wal_level=logical -c max_wal_senders=10 -c max_replication_slots=10" - image: postgres:13 + command: postgres -c wal_level=logical -c max_wal_senders=10 -c max_replication_slots=10 -c max_connections=200 environment: POSTGRES_DB: postgres POSTGRES_USER: ${POSTGRES_USER} @@ -52,6 +51,7 @@ services: interval: 5s timeout: 5s retries: 5 + image: postgres:13 networks: - ozone ports: diff --git a/docker-compose-erpnext-sso.yml b/docker-compose-erpnext-sso.yml new file mode 100644 index 0000000..c029f00 --- /dev/null +++ b/docker-compose-erpnext-sso.yml @@ -0,0 +1,12 @@ +x-oauth-variables: &oauth-variables + OAUTH_ACCESS_TOKEN_URL: ${OAUTH_ACCESS_TOKEN_URL} + OAUTH_ENABLED: ${OAUTH_ENABLED} + OAUTH_CLIENT_ID: ${OAUTH_CLIENT_ID} + OAUTH_CLIENT_SECRET: ${OAUTH_CLIENT_SECRET} + OAUTH_CLIENT_SCOPE: ${OAUTH_CLIENT_SCOPE} + +services: + + eip-erpnext-openmrs: + environment: + <<: *oauth-variables diff --git a/docker-compose-keycloak.yml b/docker-compose-keycloak.yml new file mode 100644 index 0000000..79353b0 --- /dev/null +++ b/docker-compose-keycloak.yml @@ -0,0 +1,75 @@ +services: + + keycloak: + image: docker.io/bitnami/keycloak:22.0.5 + restart: unless-stopped + volumes: + - ${KEYCLOAK_CONFIG_PATH}/realms:/keycloak-files/realm-config + - ${KEYCLOAK_CONFIG_PATH}/themes/carbon:/opt/bitnami/keycloak/themes/carbon + environment: + KC_HOSTNAME_URL: ${SERVER_SCHEME}://${KEYCLOAK_HOSTNAME} + PROXY_ADDRESS_FORWARDING: "true" + KC_HTTP_ENABLED: 'true' + KC_HOSTNAME_STRICT_BACKCHANNEL: "true" + KC_PROXY: reencrypt + KC_HEALTH_ENABLED: 'true' + KC_METRICS_ENABLED: 'true' + KEYCLOAK_DATABASE_VENDOR: postgresql + KEYCLOAK_DATABASE_HOST: postgresql + KEYCLOAK_DATABASE_PORT_NUMBER: 5432 + KEYCLOAK_DATABASE_NAME: ${KEYCLOAK_DB} + KEYCLOAK_DATABASE_USER: ${KEYCLOAK_DB_USER} + KEYCLOAK_DATABASE_PASSWORD: ${KEYCLOAK_DB_PASSWORD} + KEYCLOAK_DATABASE_SCHEMA: ${KEYCLOAK_DB_SCHEMA} + KEYCLOAK_CREATE_ADMIN_USER: "true" + KEYCLOAK_ADMIN_USER: ${KEYCLOAK_USER} + KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_PASSWORD} + KEYCLOAK_EXTRA_ARGS_PREPENDED: "--spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true" + KEYCLOAK_EXTRA_ARGS: " + -Dkeycloak.profile.feature.scripts=enabled + -Dkeycloak.migration.action=import + -Dkeycloak.migration.provider=dir + -Dkeycloak.migration.dir=/keycloak-files/realm-config + -Dkeycloak.migration.strategy=OVERWRITE_EXISTING" + healthcheck: + test: ["CMD", "curl", "-f", "http://0.0.0.0:8080/health/ready"] + interval: 15s + timeout: 3s + retries: 5 + start_period: 30s + + depends_on: + postgresql: + condition: service_started + env-substitution: + condition: service_completed_successfully + networks: + ozone: + web: + labels: + traefik.enable: "true" + traefik.http.routers.keycloak.rule: "Host(`${KEYCLOAK_HOSTNAME}`)" + traefik.http.routers.keycloak.entrypoints: "websecure" + traefik.http.services.keycloak.loadbalancer.server.port: 8080 + + postgresql: + environment: + KEYCLOAK_DB: ${KEYCLOAK_DB} + KEYCLOAK_DB_SCHEMA: ${KEYCLOAK_DB_SCHEMA} + KEYCLOAK_DB_USER: ${KEYCLOAK_DB_USER} + KEYCLOAK_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD} + volumes: + - "${SQL_SCRIPTS_PATH}/postgresql/keycloak:/docker-entrypoint-initdb.d/db/keycloak" + + env-substitution: + environment: + - KEYCLOAK_URL=${SERVER_SCHEME}://${KEYCLOAK_HOSTNAME} + - KEYCLOAK_INTERNAL_HOST_URL=${KEYCLOAK_INTERNAL_HOST_URL} + - KEYCLOAK_ADMIN_SA_CLIENT_SECRET=${KEYCLOAK_ADMIN_SA_CLIENT_SECRET} + - EIP_CLIENT_SECRET=${EIP_CLIENT_SECRET} + - SUPERSET_CLIENT_SECRET=${SUPERSET_CLIENT_SECRET} + - SUPERSET_CLIENT_UUID=${SUPERSET_CLIENT_UUID} + - SUPERSET_PUBLIC_URL=${SERVER_SCHEME}://${SUPERSET_HOSTNAME} + +volumes: + keycloak-realm: ~ diff --git a/docker-compose-odoo-sso.yml b/docker-compose-odoo-sso.yml new file mode 100644 index 0000000..21ec8ac --- /dev/null +++ b/docker-compose-odoo-sso.yml @@ -0,0 +1,17 @@ +services: + odoo: + environment: + - ADDONS=sale_management,stock,account_account,purchase,mrp,mrp_product_expiry,product_expiry,l10n_generic_coa,odoo_initializer,ozone_settings,server_environment,auth_oidc_environment,auth_oidc + + env-substitution: + environment: + - ODOO_CLIENT_SECRET=${ODOO_CLIENT_SECRET} + - ODOO_CLIENT_UUID=${ODOO_CLIENT_UUID} + + eip-odoo-openmrs: + environment: + OAUTH_ACCESS_TOKEN_URL: ${OAUTH_ACCESS_TOKEN_URL} + OAUTH_ENABLED: ${OAUTH_ENABLED} + OAUTH_CLIENT_ID: ${OAUTH_CLIENT_ID} + OAUTH_CLIENT_SECRET: ${OAUTH_CLIENT_SECRET} + OAUTH_CLIENT_SCOPE: ${OAUTH_CLIENT_SCOPE} diff --git a/docker-compose-openmrs-sso.yml b/docker-compose-openmrs-sso.yml new file mode 100644 index 0000000..36aa7e0 --- /dev/null +++ b/docker-compose-openmrs-sso.yml @@ -0,0 +1,21 @@ +services: + openmrs: + environment: + KEYCLOAK_URL: ${SERVER_SCHEME}://${KEYCLOAK_HOSTNAME} + OAUTH2_ENABLED: ${ENABLE_SSO} + volumes: + - "./openmrs/tomcat/server.xml:/usr/local/tomcat/conf/server.xml" + + frontend: + environment: + SPA_CONFIG_URLS: ${SPA_CONFIG_URLS},/openmrs/spa/configs/ozone-frontend-config-sso.json + volumes: + - "${OPENMRS_FRONTEND_CONFIG_PATH}ozone-frontend-config-sso.json:/usr/share/nginx/html/configs/ozone-frontend-config-sso.json" + + env-substitution: + environment: + - OAUTH2_ENABLED=${ENABLE_SSO} + - HOST_URL=${SERVER_SCHEME}://${O3_HOSTNAME} + - KEYCLOAK_AUTH_SERVER_URL=${SERVER_SCHEME}://${KEYCLOAK_HOSTNAME} + - OPENMRS_CLIENT_SECRET=${OPENMRS_CLIENT_SECRET} + - OPENMRS_CLIENT_UUID=${OPENMRS_CLIENT_UUID} diff --git a/docker-compose-openmrs.yml b/docker-compose-openmrs.yml index 19fe17b..c4141cd 100644 --- a/docker-compose-openmrs.yml +++ b/docker-compose-openmrs.yml @@ -16,13 +16,14 @@ services: OMRS_CONFIG_CONNECTION_USERNAME: ${OPENMRS_DB_USER:-openmrs} OMRS_CONFIG_CONNECTION_PASSWORD: ${OPENMRS_DB_PASSWORD:-openmrs} HOST_URL: https://${O3_HOSTNAME} + OAUTH2_ENABLED: ${ENABLE_SSO} healthcheck: test: [ "CMD", "curl", "-f", "http://localhost:8080/openmrs/health/started" ] interval: 10s timeout: 5s retries: 48 start_period: 120s - image: openmrs/openmrs-reference-application-3-backend:3.1.1 + image: openmrs/openmrs-core:2.6.7 labels: traefik.enable: "true" traefik.http.routers.openmrs.rule: "Host(`${O3_HOSTNAME}`) && PathPrefix(`/openmrs`)" @@ -47,6 +48,7 @@ services: - "${OPENMRS_CONFIG_CHECKSUMS_PATH:-openmrs-config-checksums}:/openmrs/data/configuration_checksums" - "${OPENMRS_PROPERTIES_PATH}:/etc/properties/" - "${OPENMRS_PROPERTIES_PATH}/fhirproxy.properties:/openmrs/data/fhirproxy/config.properties" + - "${OPENMRS_PROPERTIES_PATH}/oauth2.properties:/openmrs/data/oauth2.properties" - "${OPENMRS_PERSON_IMAGES_PATH:-openmrs-person-images}:/openmrs/data/person_images" - "${OPENMRS_COMPLEX_OBS_PATH:-openmrs-complex-obs}:/openmrs/data/complex_obs" diff --git a/docker-compose-senaite-sso.yml b/docker-compose-senaite-sso.yml new file mode 100644 index 0000000..1793070 --- /dev/null +++ b/docker-compose-senaite-sso.yml @@ -0,0 +1,22 @@ +services: + + senaite: + image: mekomsolutions/senaite-ozonepro + restart: unless-stopped + environment: + - OAUTH_CONFIG_FILE=/data/oidc/client.json + volumes: + - ${SENAITE_OIDC_CONFIG_PATH}/:/data/oidc + + env-substitution: + environment: + - SENAITE_CLIENT_SECRET=${SENAITE_CLIENT_SECRET} + - SENAITE_CLIENT_UUID=${SENAITE_CLIENT_UUID} + + eip-openmrs-senaite: + environment: + OAUTH_ACCESS_TOKEN_URL: ${OAUTH_ACCESS_TOKEN_URL} + OAUTH_ENABLED: ${OAUTH_ENABLED} + OAUTH_CLIENT_ID: ${OAUTH_CLIENT_ID} + OAUTH_CLIENT_SECRET: ${OAUTH_CLIENT_SECRET} + OAUTH_CLIENT_SCOPE: ${OAUTH_CLIENT_SCOPE} diff --git a/docker-compose-senaite.yml b/docker-compose-senaite.yml index b830614..302fecb 100644 --- a/docker-compose-senaite.yml +++ b/docker-compose-senaite.yml @@ -5,10 +5,14 @@ services: depends_on: env-substitution: condition: service_completed_successfully + postgresql: + condition: service_healthy environment: - SITE=${SITE} - - ADMIN_USER=${SENAITE_ADMIN_USER} - - ADMIN_PASSWORD=${SENAITE_ADMIN_PASSWORD} + - PASSWORD=${SENAITE_ADMIN_PASSWORD} + - RELSTORAGE_ADAPTER_OPTIONS=type postgresql,dsn dbname='${SENAITE_DB_NAME}' user='${SENAITE_DB_USER}' password='${SENAITE_DB_PASSWORD}' host='${SENAITE_DB_HOST}', driver pg8000 + - RELSTORAGE_KEEP_HISTORY=false + - RELSTORAGE_BLOB_DIR=/home/senaite/senaitelims/blobstorage image: mekomsolutions/senaite:latest labels: - "traefik.enable=true" @@ -17,13 +21,14 @@ services: - "traefik.http.routers.senaite.middlewares=senaite" - "traefik.http.middlewares.senaite.addprefix.prefix=/VirtualHostBase/https/${SENAITE_HOSTNAME}/senaite/VirtualHostRoot" networks: - - ozone - - web + ozone: + aliases: + - senaite + web: restart: unless-stopped volumes: - ${SENAITE_CONFIG_PATH}:/data/importdata/senaite - - senaite-filestorage:/data/filestorage - - senaite-blobstorage:/data/blobstorage + - ${SENAITE_BLOBSTORAGE_PATH:-senaite-blobstorage}:/home/senaite/senaitelims/blobstorage # OpenMRS - SENAITE integration service eip-openmrs-senaite: @@ -78,6 +83,14 @@ services: EIP_DB_PASSWORD_SENAITE: ${EIP_DB_PASSWORD_SENAITE} volumes: - "${SQL_SCRIPTS_PATH}/mysql/eip-openmrs-senaite:/docker-entrypoint-initdb.d/db/eip-openmrs-senaite" + + postgresql: + environment: + SENAITE_DB_NAME: ${SENAITE_DB_NAME} + SENAITE_DB_USER: ${SENAITE_DB_USER} + SENAITE_DB_PASSWORD: ${SENAITE_DB_PASSWORD} + volumes: + - "${SQL_SCRIPTS_PATH}/postgresql/senaite:/docker-entrypoint-initdb.d/db/senaite" env-substitution: environment: diff --git a/openmrs/tomcat/server.xml b/openmrs/tomcat/server.xml new file mode 100644 index 0000000..c4a40ca --- /dev/null +++ b/openmrs/tomcat/server.xml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 4c9527f..a922051 100644 --- a/pom.xml +++ b/pom.xml @@ -79,12 +79,15 @@ ${project.basedir} proxy/ + openmrs/ *docker-compose* *env scripts/ scripts/distro/ + docker-compose-bundled.yml.template + docker-compose-bundled-sso.yml.template @@ -152,4 +155,4 @@ - \ No newline at end of file + diff --git a/proxy/default.conf.template b/proxy/default.conf.template index a33df8c..8a1306b 100644 --- a/proxy/default.conf.template +++ b/proxy/default.conf.template @@ -178,3 +178,14 @@ server { proxy_pass http://$fhirOdoo; } } + +server { + listen 8084; + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Forward-Proto http; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + set $keycloak keycloak:8080; + proxy_pass http://$keycloak; + } +} diff --git a/proxy/docker-compose.yml b/proxy/docker-compose.yml index ce5d854..af86b99 100644 --- a/proxy/docker-compose.yml +++ b/proxy/docker-compose.yml @@ -25,6 +25,7 @@ services: - "8088:8088" - "8082:8082" - "8083:8083" + - "8084:8084" volumes: - "./confs:/usr/local/apache2/conf/extra" - "${PROXY_TLS_CERTS_PATH:-proxy-tls-certs}:/etc/tls" diff --git a/readme/browse.png b/readme/browse.png deleted file mode 100644 index 3f1acfd..0000000 Binary files a/readme/browse.png and /dev/null differ diff --git a/scripts/docker-compose-files.txt b/scripts/docker-compose-files.txt index e05762e..723d993 100755 --- a/scripts/docker-compose-files.txt +++ b/scripts/docker-compose-files.txt @@ -1,5 +1,9 @@ docker-compose-common.yml +docker-compose-keycloak.yml docker-compose-odoo.yml +docker-compose-odoo-sso.yml docker-compose-openmrs.yml +docker-compose-openmrs-sso.yml docker-compose-senaite.yml +docker-compose-senaite-sso.yml docker-compose-backup.yml diff --git a/scripts/ozone-urls-template.csv b/scripts/ozone-urls-template.csv index 7d02a7c..163dd8d 100644 --- a/scripts/ozone-urls-template.csv +++ b/scripts/ozone-urls-template.csv @@ -4,3 +4,4 @@ OpenMRS 3,${SERVER_SCHEME}://${O3_HOSTNAME}/openmrs/spa,admin,Admin123,openmrs SENAITE,${SERVER_SCHEME}://${SENAITE_HOSTNAME},admin,password,senaite Odoo,${SERVER_SCHEME}://${ODOO_HOSTNAME},admin,admin,odoo ERPNext,${SERVER_SCHEME}://${ERPNEXT_HOSTNAME},administrator,password,erpnext +Keycloak,${SERVER_SCHEME}://${KEYCLOAK_HOSTNAME},admin,password,keycloak diff --git a/scripts/start-demo-with-sso.sh b/scripts/start-demo-with-sso.sh new file mode 100755 index 0000000..4111abe --- /dev/null +++ b/scripts/start-demo-with-sso.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e + +# Enable SSO +export ENABLE_SSO=true +echo "$INFO Setting ENABLE_SSO=true..." +echo "→ ENABLE_SSO=$ENABLE_SSO" + +source start-demo.sh diff --git a/scripts/start-demo.sh b/scripts/start-demo.sh index 0721d9f..fa8fb49 100755 --- a/scripts/start-demo.sh +++ b/scripts/start-demo.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -e export DEMO=true echo "$INFO Setting DEMO=true..." diff --git a/scripts/start-with-sso.sh b/scripts/start-with-sso.sh new file mode 100755 index 0000000..35e0833 --- /dev/null +++ b/scripts/start-with-sso.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e + +# Enable SSO +export ENABLE_SSO=true +echo "$INFO Setting ENABLE_SSO=true..." +echo "→ ENABLE_SSO=$ENABLE_SSO" + +source start.sh diff --git a/scripts/start.sh b/scripts/start.sh index 9c3cdd9..56d1997 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -12,6 +12,11 @@ setupDirs # Export the paths variables to point to distro artifacts exportPaths +# Export IP address of the host machine +if [ "$ENABLE_SSO" == "true" ]; then + exportHostIP +fi + # Set the Traefik host names if [ "$TRAEFIK" == "true" ]; then echo "$INFO \$TRAEFIK=true, setting Traefik hostnames..." diff --git a/scripts/utils.sh b/scripts/utils.sh index 9164c0d..c4e994f 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -24,9 +24,11 @@ function exportPaths () { echo "$INFO Exporting distro paths..." export OPENMRS_CONFIG_PATH=$DISTRO_PATH/configs/openmrs/initializer_config export OPENMRS_PROPERTIES_PATH=$DISTRO_PATH/configs/openmrs/properties + export OPENMRS_TOMCAT_CONFIG_PATH=$DISTRO_PATH/configs/openmrs/tomcat export OPENMRS_MODULES_PATH=$DISTRO_PATH/binaries/openmrs/modules export SPA_PATH=/openmrs/spa export SENAITE_CONFIG_PATH=$DISTRO_PATH/configs/senaite/initializer_config + export SENAITE_OIDC_CONFIG_PATH=$DISTRO_PATH/configs/senaite/oidc export ODOO_EXTRA_ADDONS=$DISTRO_PATH/binaries/odoo/addons export ODOO_CONFIG_PATH=$DISTRO_PATH/configs/odoo/initializer_config/ export ODOO_CONFIG_FILE_PATH=$DISTRO_PATH/configs/odoo/config/odoo.conf @@ -38,12 +40,15 @@ function exportPaths () { export SQL_SCRIPTS_PATH=$DISTRO_PATH/data/ export ERPNEXT_CONFIG_PATH=$DISTRO_PATH/configs/erpnext/initializer_config/ export ERPNEXT_SCRIPTS_PATH=$DISTRO_PATH/binaries/erpnext/scripts/ + export KEYCLOAK_CONFIG_PATH=$DISTRO_PATH/configs/keycloak echo "→ OPENMRS_CONFIG_PATH=$OPENMRS_CONFIG_PATH" echo "→ OPENMRS_PROPERTIES_PATH=$OPENMRS_PROPERTIES_PATH" echo "→ OPENMRS_MODULES_PATH=$OPENMRS_MODULES_PATH" + echo "→ OPENMRS_TOMCAT_CONFIG_PATH=$OPENMRS_TOMCAT_CONFIG_PATH" echo "→ SPA_PATH=$SPA_PATH" echo "→ SENAITE_CONFIG_PATH=$SENAITE_CONFIG_PATH" + echo "→ SENAITE_OIDC_CONFIG_PATH=$SENAITE_OIDC_CONFIG_PATH" echo "→ ODOO_EXTRA_ADDONS=$ODOO_EXTRA_ADDONS" echo "→ ODOO_CONFIG_PATH=$ODOO_CONFIG_PATH" echo "→ ODOO_CONFIG_FILE_PATH=$ODOO_CONFIG_FILE_PATH" @@ -54,7 +59,8 @@ function exportPaths () { echo "→ SQL_SCRIPTS_PATH=$SQL_SCRIPTS_PATH" echo "→ ERPNEXT_CONFIG_PATH=$ERPNEXT_CONFIG_PATH" echo "→ ERPNEXT_SCRIPTS_PATH=$ERPNEXT_SCRIPTS_PATH" - + echo "→ KEYCLOAK_CONFIG_PATH=$KEYCLOAK_CONFIG_PATH" + } function setDockerComposeCLIOptions () { @@ -62,18 +68,22 @@ function setDockerComposeCLIOptions () { dockerComposeFiles=$(cat docker-compose-files.txt) for file in ${dockerComposeFiles} do + if [ "$ENABLE_SSO" != "true" ]; then + if [[ "$file" == *"-sso.yml" || "$file" == "docker-compose-keycloak.yml" ]]; then + continue + fi + fi export dockerComposeFilesCLIOptions="$dockerComposeFilesCLIOptions -f ../$file" done # Add restore file if restore env is set - if [ "$RESTORE" == "true" ]; then export dockerComposeFilesCLIOptions="$dockerComposeFilesCLIOptions -f ../docker-compose-restore.yml" fi - + # Set the default env file export dockerComposeEnvFilePath="../.env" - + # Override the default with the concatenated.env file if it is provided concatenatedEnvFilePath="../concatenated.env" if [ -f "$concatenatedEnvFilePath" ]; then @@ -86,7 +96,25 @@ function setDockerComposeCLIOptions () { export dockerComposeProxyCLIOptions="--env-file $dockerComposeEnvFilePath -f ../proxy/docker-compose.yml" # Set args for the demo service - export dockerComposeDemoCLIOptions="--env-file $dockerComposeEnvFilePath -f ../demo/docker-compose.yml" + if [ "$ENABLE_SSO" == "true" ]; then + export dockerComposeDemoCLIOptions="--env-file $dockerComposeEnvFilePath -f ../demo/docker-compose.yml -f ../demo/docker-compose-sso.yml" + else + export dockerComposeDemoCLIOptions="--env-file $dockerComposeEnvFilePath -f ../demo/docker-compose.yml" + fi +} + +function exportHostIP() { + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + # Linux + export HOST_IP_ADDRESS=$(hostname -I | awk '{print $1}') + elif [[ "$OSTYPE" == "darwin"* ]]; then + # Mac OSX + export HOST_IP_ADDRESS=$(ipconfig getifaddr en0) + else + echo "$ERROR Unsupported OS type: $OSTYPE" + return 1 + fi + echo "$INFO IP address set to: $HOST_IP_ADDRESS" } function setTraefikIP { @@ -115,11 +143,13 @@ function setTraefikHostnames { export ODOO_HOSTNAME=erp-"${IP_WITH_DASHES}.traefik.me" export SENAITE_HOSTNAME=lims-"${IP_WITH_DASHES}.traefik.me" export ERPNEXT_HOSTNAME=erpnext-"${IP_WITH_DASHES}.traefik.me" + export KEYCLOAK_HOSTNAME=auth-"${IP_WITH_DASHES}.traefik.me" export FHIR_ODOO_HOSTNAME=fhir-erp-"${IP_WITH_DASHES}.traefik.me" echo "→ O3_HOSTNAME=$O3_HOSTNAME" echo "→ ODOO_HOSTNAME=$ODOO_HOSTNAME" echo "→ SENAITE_HOSTNAME=$SENAITE_HOSTNAME" echo "→ ERPNEXT_HOSTNAME=$ERPNEXT_HOSTNAME" + echo "→ KEYCLOAK_HOSTNAME=$KEYCLOAK_HOSTNAME" echo "→ FHIR_ODOO_HOSTNAME=$FHIR_ODOO_HOSTNAME" } @@ -127,16 +157,19 @@ function setTraefikHostnames { function setNginxHostnames { echo "$INFO Exporting Nginx hostnames..." - export O3_HOSTNAME="localhost" - export ODOO_HOSTNAME="localhost:8069" - export SENAITE_HOSTNAME="localhost:8081" - export ERPNEXT_HOSTNAME="localhost:8082" - export FHIR_ODOO_HOSTNAME="localhost:8083" + export O3_HOSTNAME="${HOST_IP_ADDRESS:-localhost}" + export ODOO_HOSTNAME="${HOST_IP_ADDRESS:-localhost}:8069" + export SENAITE_HOSTNAME="${HOST_IP_ADDRESS:-localhost}:8081" + export ERPNEXT_HOSTNAME="${HOST_IP_ADDRESS:-localhost}:8082" + export FHIR_ODOO_HOSTNAME="${HOST_IP_ADDRESS:-localhost}:8083" + export KEYCLOAK_HOSTNAME="${HOST_IP_ADDRESS:-localhost}:8084" + echo "→ O3_HOSTNAME=$O3_HOSTNAME" echo "→ ODOO_HOSTNAME=$ODOO_HOSTNAME" echo "→ SENAITE_HOSTNAME=$SENAITE_HOSTNAME" echo "→ ERPNEXT_HOSTNAME=$ERPNEXT_HOSTNAME" echo "→ FHIR_ODOO_HOSTNAME=$FHIR_ODOO_HOSTNAME" + echo "→ KEYCLOAK_HOSTNAME=$KEYCLOAK_HOSTNAME" } @@ -165,11 +198,13 @@ function displayAccessURLsWithCredentials { # Read docker-compose-files.txt and extract the list of services run while read -r line; do - serviceWithoutExtension=${line%.yml} - service=${serviceWithoutExtension#docker-compose-} - - services+=("$service") - is_defined+=(1) + if [[ $line != *-sso.yml ]]; then + serviceWithoutExtension=${line%.yml} + service=${serviceWithoutExtension#docker-compose-} + + services+=("$service") + is_defined+=(1) + fi done < docker-compose-files.txt echo "HIS Component,URL,Username,Password" > .urls_1.txt @@ -177,6 +212,9 @@ function displayAccessURLsWithCredentials { tail -n +2 ozone-urls-template.csv | while IFS=',' read -r component url username password service ; do for i in "${!services[@]}"; do if [[ "${services[$i]}" == "$service" && "${is_defined[$i]}" == 1 ]]; then + if [[ "$service" == "keycloak" && "$ENABLE_SSO" == "false" ]]; then + continue + fi echo "$component,$url,$username,$password" >> .urls_1.txt break fi @@ -184,12 +222,13 @@ function displayAccessURLsWithCredentials { done envsubst < .urls_1.txt > .urls_2.txt + echo "" echo "$INFO 🔗 Access each ${OZONE_LABEL:-Ozone FOSS} components at the following URL:" echo "" - - set +e - column -t -s ',' .urls_2.txt > .urls_3.txt 2> /dev/null - set -e - cat .urls_3.txt + if [ "$ENABLE_SSO" == "true" ]; then + awk -F, 'NR==1 {printf "%-15s %-40s\n", $1, $2} NR>2 && $1 != "Keycloak" {printf "%-15s %-40s\n", $1, $2} END {print "-\nUsername: jdoe\nPassword: password\n-\nIdentity Provider(IDP)\nKeycloak -", $2, " Username:", $3, " Password:", $4}' .urls_2.txt + else + awk -F, 'NR==1 {printf "%-15s %-40s %-15s %-15s\n", $1, $2, $3, $4} NR>2 && $1 != "Keycloak" {printf "%-15s %-40s %-15s %-15s\n", $1, $2, $3, $4}' .urls_2.txt + fi }