Skip to content

Commit

Permalink
Merge pull request #22 from zinus92/main
Browse files Browse the repository at this point in the history
Letsencrypt management
  • Loading branch information
zinus92 authored Aug 28, 2023
2 parents 32883ef + 444221a commit 2584280
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 21 deletions.
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,27 @@ Variable for the monitoring service:
- `run_jupyter`: bool, if you want to run the jupyterhub compose (default: `yes`)
- `jupyter_port`: string (default: `"8888"`)
- `jupyter_proxy_token`: string, token needed for the collaborative service, autogenerated if empty (default: `""`)
- `jupyter_images`: string, Comma separated image list (default: `"dodasts/snj-base-lab:v1.0.0-snj"`)
- `jupyter_images`: string, Comma separated image list (default: `"dodasts/snj-base-lab:v1.1.1-snj"`)
- `jupyter_use_gpu`: bool, if to enable the jupyter notebook to use the GPU (default: `no`)
- `jupyter_default_spawner`: string, indicates to start with lab or notebook (possible values: ["LAB", "NOTEBOOK"])
- `jupyter_post_start_cmd`: string, the command to run after jupyter spawned (default: "")
- `jupyter_host_mount_dir`: path of base mount point in the host machine (default: "")
- `jupyter_mount_dir`: path of mount point in the jupyter env (default: "")
- `jupyterlab_collaborative`: bool, if to deploy the collaborative service (default: `no`)
- `jupyterlab_collaborative_use_gpu`: bool, if to enable the collaborative service to use the GPU (default: `no`)
- `jupyterlab_collaborative_image`: string, the collaborative Docker image (default: `"dodasts/snj-base-jlabc:v1.0.0-snj"`)
- `jupyterlab_collaborative_image`: string, the collaborative Docker image (default: `"dodasts/snj-base-jlabc:v1.1.1-snj"`)
- `iam_url`: URL of the IAM service
- `iam_groups`: string with the name of the IAM groups allowed (space separated)
- `iam_admin_groups`: string with the name of the IAM groups that will be admin (space separated)
- `iam_subject` : token subject of the user deploying the service
- `server_ip`: string with the ip of the current server
- `monitoring`: bool, if to deploy the monitoring service (default: `yes`)
- `grafana`: "yes" if you want to setup also grafana
- `monitoring`: bool, if to deploy the Grafana monitoring service (default: `yes`)
- `grafana_port`: int, the grafana service port
- `grafana_admin_user`: string
- `grafana_admin_password`: string
- `grafana_client_id`: string (used for the IAM login)
- `grafana_client_secret`: string (used for the IAM login)
- `grafana_image`: string (default: `"grafana/grafana:9.4.7"`)
- `grafana_image`: string (default: `"grafana/grafana:9.5.7"`)
- `cvmfs_repos`: string, list of the cvmfs repo to mount (default: `""`)

### vars
Expand All @@ -55,12 +54,12 @@ The following string variables will be filled with the docker service informatio

- `jupyter_gpu`: string (default: `"WITH_GPU=false"`)
- `cvmfs_service`: string (default: `""`)
- `compose_base_jhub_image`: string (default: `"dodasts/snj-base-jhub:v1.0.0-snj"`)
- `compose_base_jhub_image`: string (default: `"dodasts/snj-base-jhub:v1.1.1-snj"`)
- `compose_base_http_proxy_image`: string (default: `"jupyterhub/configurable-http-proxy"`)
- `compose_base_collab_http_proxy_image`: string (default: `"dodasts/snj-base-jlabc-proxy:v1.0.0-snj"`)
- `compose_base_collab_http_proxy_image`: string (default: `"dodasts/snj-base-jlabc-proxy:v1.1.1-snj"`)
- `jupyterlab_collaborative_service`: string (default: `""`)
- `jupyterlab_collaborative_service_dependency`: string (default: `""`)
- `jupyterlab_collaborative_image_param`: string (default: `"image: dodasts/snj-base-jlabc:v1.0.0-snj"`)
- `jupyterlab_collaborative_image_param`: string (default: `"image: dodasts/snj-base-jlabc:v1.1.1-snj"`)
- `jupyterlab_collaborative_gpu_param`: string (default: `""`)
- `jupyter_with_cvmfs`: bool (default: `false`)
- `jupyter_collab_service`: bool (default: `false`)
Expand Down
12 changes: 5 additions & 7 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ jupyter_proxy_token: ""

#traefik
contact_email: ""
letsencrypt_test: true
cert_manager_type: letsencrypt-prod # [self-signed, letsencrypt-staging, letsencrypt-prod]

# https://github.com/DODAS-TS/jupyterhub-ML_INFN/blob/collaborative/Dockerfile
jupyter_hub_image: "dodasts/snj-base-jhub:v1.0.0-snj"
jupyter_images: "dodasts/snj-base-lab:v1.0.0-snj" # Comma separated image list
jupyter_hub_image: "dodasts/snj-base-jhub:v1.1.1-snj"
jupyter_images: "dodasts/snj-base-lab:v1.1.1-snj" # Comma separated image list
jupyter_use_gpu: no
jupyter_default_spawner: "LAB"
jupyter_post_start_cmd: ""
jupyter_host_mount_dir: ""
jupyter_mount_dir: ""
jupyterlab_collaborative: no
jupyterlab_collaborative_use_gpu: no
jupyterlab_collaborative_image: "dodasts/snj-base-jlabc:v1.0.0-snj"
jupyterlab_collaborative_image: "dodasts/snj-base-jlabc:v1.1.1-snj"
jupyterhub_all_gpu_uuids: "ALL_GPU_UUIDs=None"
jupyterhub_mount_config: ""

Expand All @@ -44,13 +44,11 @@ iam_subject: ""

# monitoring
monitoring: yes

grafana: yes
grafana_port: 3000
grafana_admin_user: ""
grafana_admin_password: ""
grafana_client_id: "CLIENT_ID"
grafana_client_secret: "CLIENT_SECRET"
grafana_image: "grafana/grafana:9.4.7"
grafana_image: "grafana/grafana:9.5.7"
# cvmfs
cvmfs_repos: ""
2 changes: 1 addition & 1 deletion tasks/monitoring.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
monitoring_iam_url: "{{ iam_url }}"
monitoring_iam_groups: "{{ iam_groups }}"
monitoring_iam_admin_groups: "{{ iam_admin_groups }}"
service_grafana: "{{ grafana }}"
service_grafana: "{{ monitoring }}"
service_grafana_port: "{{ grafana_port }}"
service_grafana_admin_user: "{{ grafana_admin_user }}"
service_grafana_admin_password: "{{ grafana_admin_password }}"
Expand Down
9 changes: 9 additions & 0 deletions tasks/prepare-jupyter-hub.yml
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,15 @@
vars:
iam_client_id: "{{ iam_response.json.client_id }}"
iam_client_secret: "{{ iam_response.json.client_secret }}"
when: cert_manager_type != "self-signed"
- name: prepare compose file (private network)
template:
src: jupyter_hub_priv-compose.j2
dest: /usr/local/share/dodasts/jupyterhub/docker-compose.yaml
vars:
iam_client_id: "{{ iam_response.json.client_id }}"
iam_client_secret: "{{ iam_response.json.client_secret }}"
when: cert_manager_type == "self-signed"

# finally pre-cache default images
- name: pull images
Expand Down
6 changes: 3 additions & 3 deletions templates/jupyter_hub-compose.j2
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ services:
- JUPYTER_IMAGE_LIST={{ jupyter_images }}
- JUPYTER_RAM_LIST={{ list_ram_size }}
- JUPYTER_PROXY_TOKEN={{ jupyter_proxy_token }}
- JUPYTERHUB_API_TOKEN={{ jupyterhub_api_token.stdout | string }}
- JUPYTERHUB_CRYPT_KEY={{ jupyterhub_crypt_key.stdout | string }}
- JUPYTERHUB_API_TOKEN={{ jupyterhub_api_token.stdout | string }}
- JUPYTERHUB_CRYPT_KEY={{ jupyterhub_crypt_key.stdout | string }}
- JUPYTER_WITH_CVMFS={{ jupyter_with_cvmfs }}
- DEFAULT_SPAWNER={{ jupyter_default_spawner }}
- POST_START_CMD={{ jupyter_post_start_cmd }}
Expand Down Expand Up @@ -79,7 +79,7 @@ services:
- "--certificatesresolvers.myhttpchallenge.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.myhttpchallenge.acme.email={{ contact_email }}"
- "--certificatesresolvers.myhttpchallenge.acme.storage=/letsencrypt/acme.json"
{% if letsencrypt_test|bool %}
{% if cert_manager_type == 'letsencrypt-staging' %}
- "--certificatesresolvers.myhttpchallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
{% endif %}

Expand Down
128 changes: 128 additions & 0 deletions templates/jupyter_hub_priv-compose.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
version: "3.9"

services:
{{ cvmfs_service }}

jupyterhub:
depends_on:
- http_proxy
{{ jupyterlab_collaborative_service_dependency }}
image: {{ compose_base_jhub_image }}
restart: unless-stopped
command:
- /usr/bin/python3
- /usr/local/bin/jupyterhub
- --debug
- --config=/srv/jupyterhub/jupyterhub_config.py
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /usr/local/share/dodasts/jupyterhub/cookies:/srv/jupyterhub/cookies
- /usr/local/share/dodasts/jupyterhub/db:/srv/jupyterhub/db
{{ jupyterhub_mount_config }}
environment:
- OAUTH_ENDPOINT={{ iam_url }}
- OAUTH_CALLBACK_URL=https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback
- OAUTH_GROUPS={{ iam_groups }}
- OAUTH_SUB={{ iam_subject }}
- {{ jupyter_gpu }}
- {{ jupyterhub_all_gpu_uuids }}
- ADMIN_OAUTH_GROUPS={{ iam_admin_groups }}
- IAM_CLIENT_ID={{ iam_client_id }}
- IAM_CLIENT_SECRET={{ iam_client_secret }}
- JUPYTER_IMAGE_LIST={{ jupyter_images }}
- JUPYTER_RAM_LIST={{ list_ram_size }}
- JUPYTER_PROXY_TOKEN={{ jupyter_proxy_token }}
- JUPYTERHUB_API_TOKEN={{ jupyterhub_api_token.stdout | string }}
- JUPYTERHUB_CRYPT_KEY={{ jupyterhub_crypt_key.stdout | string }}
- JUPYTER_WITH_CVMFS={{ jupyter_with_cvmfs }}
- DEFAULT_SPAWNER={{ jupyter_default_spawner }}
- POST_START_CMD={{ jupyter_post_start_cmd }}
- JUPYTER_COLLAB_SERVICE={{ jupyter_collab_service }}
- DOCKER_NOTEBOOK_MOUNT_DIR={{ jupyter_host_mount_dir }}
- DOCKER_NOTEBOOK_DIR={{ jupyter_mount_dir }}
labels:
- "traefik.enable=true"
- "traefik.http.middlewares.jupyterhub-redirect-ssl.redirectscheme.scheme=https"
- "traefik.http.routers.jupyterhub-nossl.middlewares=jupyterhub-redirect-ssl"
- "traefik.http.routers.jupyterhub-nossl.rule=Host(`{{ dns_name }}`)"
- "traefik.http.routers.jupyterhub-nossl.entrypoints=web"
- "traefik.http.routers.jupyterhub.rule=Host(`{{ dns_name }}`)"
- "traefik.http.routers.jupyterhub.entrypoints=websecure"
- "traefik.http.routers.jupyterhub.tls=true"
- "traefik.http.services.jupyterhub.loadbalancer.server.port=8000"

proxy:
container_name: proxy
image: harbor.cloud.infn.it/cache/library/traefik:${TRAEFIK_VERSION:-latest}
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /opt/traefik:/config
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.file.directory=/config"
- "--providers.file.watch=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"

cert_sidecar:
depends_on:
- proxy
image: alpine:latest
container_name: cert_sidecar
command: /bin/sh -c "
apk add --no-cache openssl
&& openssl req -newkey rsa:4096 -keyout /usr/local/share/dodasts/certs/grafana/hostcert.key -out /usr/local/share/dodasts/certs/grafana/hostcert.csr -nodes -subj /C=IT/ST=Italy/O=INFN/CN={{ dns_name }}
&& openssl x509 -signkey /usr/local/share/dodasts/certs/grafana/hostcert.key -in /usr/local/share/dodasts/certs/grafana/hostcert.csr -req -days 1800 -out /usr/local/share/dodasts/certs/grafana/hostcert.pem
&& openssl req -newkey rsa:4096 -keyout /usr/local/share/dodasts/certs/jupyter/hostcert.key -out /usr/local/share/dodasts/certs/jupyter/hostcert.csr -nodes -subj /C=IT/ST=Italy/O=INFN/CN={{ dns_name }}
&& openssl x509 -signkey /usr/local/share/dodasts/certs/jupyter/hostcert.key -in /usr/local/share/dodasts/certs/jupyter/hostcert.csr -req -days 1800 -out /usr/local/share/dodasts/certs/jupyter/hostcert.pem
&& chown -R 472:472 /usr/local/share/dodasts/certs/grafana
&& chmod 644 /usr/local/share/dodasts/certs/grafana/*
&& chown -R nobody:nogroup /usr/local/share/dodasts/certs/jupyter
&& chmod 644 /usr/local/share/dodasts/certs/jupyter/*
&& nc -klp 1337
"
volumes:
- /usr/local/share/dodasts/certs/grafana:/usr/local/share/dodasts/certs/grafana
- /usr/local/share/dodasts/certs/jupyter:/usr/local/share/dodasts/certs/jupyter

http_proxy:
depends_on:
- cert_sidecar
image: {{ compose_base_http_proxy_image }}
restart: unless-stopped
entrypoint: /bin/sh
command: -c "
while ! nc -z cert_sidecar 1337; do sleep 5; done
&& configurable-http-proxy
--ip=0.0.0.0
--port={{ jupyter_port }}
--api-ip=0.0.0.0
--api-port=8001
--default-target=http://jupyterhub:8088
--error-target=http://jupyterhub:8088/hub/error
--ssl-key=/usr/local/share/dodasts/certs/jupyter/hostcert.key
--ssl-cert=/usr/local/share/dodasts/certs/jupyter/hostcert.pem
"
volumes:
- /usr/local/share/dodasts/certs/jupyter:/usr/local/share/dodasts/certs/jupyter
environment:
- CONFIGPROXY_AUTH_TOKEN={{ jupyter_proxy_token }}
ports:
- {{ jupyter_port }}:{{ jupyter_port }}
- 8001:8001

{{ jupyterlab_collaborative_service }}

networks:
default:
name: jupyterhub
4 changes: 2 additions & 2 deletions vars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ jupyter_gpu: "WITH_GPU=false"
cvmfs_service: ""
compose_base_jhub_image: "{{ jupyter_hub_image }}"
compose_base_http_proxy_image: "jupyterhub/configurable-http-proxy"
compose_base_collab_http_proxy_image: "dodasts/snj-base-jlabc-proxy:v1.0.0-snj"
compose_base_collab_http_proxy_image: "dodasts/snj-base-jlabc-proxy:v1.1.1-snj"
jupyterlab_collaborative_service: ""
jupyterlab_collaborative_service_dependency: ""
jupyterlab_collaborative_image_param: "image: dodasts/snj-base-jlabc:v1.0.0-snj"
jupyterlab_collaborative_image_param: "image: dodasts/snj-base-jlabc:v1.1.1-snj"
jupyterlab_collaborative_gpu_param: ""
jupyter_with_cvmfs: false
jupyter_collab_service: false
Expand Down

0 comments on commit 2584280

Please sign in to comment.