From 8cc7d6e3c917fba27cd8b85b2fc70d89f8b4ab98 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Tue, 3 May 2022 17:32:29 +0000 Subject: [PATCH] grafana: dashboard with SSO --- grafana/docker-compose.yaml | 26 ++++++++ grafana/env.production | 0 grafana/setup | 46 ++++++++++++++ nginx/nginx/templates/dashboard.conf.template | 60 +++++++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 grafana/docker-compose.yaml create mode 100644 grafana/env.production create mode 100755 grafana/setup create mode 100644 nginx/nginx/templates/dashboard.conf.template diff --git a/grafana/docker-compose.yaml b/grafana/docker-compose.yaml new file mode 100644 index 0000000..8b5fc0d --- /dev/null +++ b/grafana/docker-compose.yaml @@ -0,0 +1,26 @@ +version: "3" + +services: + grafana: + image: grafana/grafana-oss:8.5.1 + user: "0:0" + environment: + GF_AUTH_GENERIC_OAUTH_ENABLED: 'True' + GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP: 'True' # otherwise no login is possible + #GF_AUTH_GENERIC_OAUTH_TEAM_IDS: '' + #GF_AUTH_GENERIC_OAUTH_ALLOWED_ORGANIZATIONS: '' + #GF_AUTH_GENERIC_OAUTH_ALLOWED_DOMAINS: '' + GF_AUTH_GENERIC_OAUTH_NAME: Keycloak + GF_AUTH_GENERIC_OAUTH_CLIENT_ID: grafana + GF_AUTH_GENERIC_OAUTH_SCOPES: openid profile email + # GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET is in env.secrets + # auth URLs are in the env.secrets since they have hostname expansion + volumes: + - ./data/grafana:/var/lib/grafana + restart: unless-stopped + ports: + - 8000:3000 + env_file: + - ../env.production + - env.production + - env.secrets diff --git a/grafana/env.production b/grafana/env.production new file mode 100644 index 0000000..e69de29 diff --git a/grafana/setup b/grafana/setup new file mode 100755 index 0000000..2de31f5 --- /dev/null +++ b/grafana/setup @@ -0,0 +1,46 @@ +#!/bin/bash +die() { echo >&2 "$@" ; exit 1 ; } + +DIRNAME="$(dirname $0)" +cd "$DIRNAME" +source ../env.production || die "no top level env?" +source env.production || die "no local env?" + +BASE="https://$KEYCLOAK_HOSTNAME/realms/$REALM/protocol/openid-connect" + +if [ ! -r "env.secrets" ]; then + GRAFANA_CLIENT_SECRET="$(openssl rand -hex 32)" + GRAFANA_ADMIN_PASSWORD="$(openssl rand -hex 4)" + + echo "Generating secrets: admin password $GRAFANA_ADMIN_PASSWORD" + cat < env.secrets +# Do not check in! +GRAFANA_ADMIN_PASSWORD=$GRAFANA_ADMIN_PASSWORD +GF_SERVER_ROOT_URL=https://$GRAFANA_HOSTNAME/ +GF_SERVER_DOMAIN=$GRAFANA_HOSTNAME +GF_AUTH_GENERIC_OAUTH_AUTH_URL=$BASE/auth +GF_AUTH_GENERIC_OAUTH_TOKEN_URL=$BASE/token +GF_AUTH_GENERIC_OAUTH_API_URL=$BASE/userinfo +GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=$GRAFANA_CLIENT_SECRET +EOF +else + source env.secrets || die "no secret env?" +fi + +docker-compose down + +../keycloak/client-delete 'grafana' || echo "client did not exist?" + +../keycloak/client-create << EOF || die "unable to create client id" +{ + "clientId": "grafana", + "rootUrl": "https://$GRAFANA_HOSTNAME/", + "adminUrl": "https://$GRAFANA_HOSTNAME/", + "redirectUris": [ "https://$GRAFANA_HOSTNAME/*" ], + "webOrigins": [ "https://$GRAFANA_HOSTNAME" ], + "clientAuthenticatorType": "client-secret", + "secret": "$GRAFANA_CLIENT_SECRET" +} +EOF + +docker-compose up -d || die "unable to bring up grafana" diff --git a/nginx/nginx/templates/dashboard.conf.template b/nginx/nginx/templates/dashboard.conf.template new file mode 100644 index 0000000..f6eba64 --- /dev/null +++ b/nginx/nginx/templates/dashboard.conf.template @@ -0,0 +1,60 @@ +server { + listen 80; + server_name ${GRAFANA_HOSTNAME}; + location / { + return 301 https://$host$request_uri; + } +} + +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + server_name ${GRAFANA_HOSTNAME}; + client_max_body_size 128m; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + #include /etc/nginx/mime.types; + #default_type application/octet-stream; + + gzip on; + gzip_disable "msie6"; + + proxy_read_timeout 1800s; + + # required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486) + chunked_transfer_encoding on; + + location / { + proxy_pass http://host.docker.internal:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /socket.io/ { + proxy_pass http://host.docker.internal:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } + + listen 443 ssl; + ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem; + include /etc/nginx/includes/options-ssl-nginx.conf; + include /etc/nginx/includes/challenge.conf; + ssl_dhparam /etc/nginx/includes/ssl-dhparams.pem; +} + +