Skip to content

Commit

Permalink
Cloud 1996 (#30)
Browse files Browse the repository at this point in the history
* Fix documentation, add variable checks, re-organise IAM-related tasks

---------

Co-authored-by: gioacchino.vino <[email protected]>
  • Loading branch information
jvino and gioacchino.vino authored Nov 29, 2023
1 parent bf55ef4 commit 8483b58
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 67 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ A role to setup a node with a jupyterhub that spawns jupyterlab with or without
Requirements
------------

There are no requirements. This role will setup all the necessary dependencies.
This role needs a working IAM Client in order to configure the JupyterHub authentication plugin.
If you are using this role as it is and not through [INFN PaaS orchestrator](https://my.cloud.infn.it), you should provide `iam_url`, `iam_client_id` and `iam_token` variables.

Role Variables
--------------
Expand Down Expand Up @@ -34,10 +35,12 @@ Variable for the monitoring service:
- `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.1.1-snj"`)
- `iam_url`: URL of the IAM service
- `iam_url`: URL of the IAM service (`Mandatory`)
- `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
- `iam_subject` : string, token subject of the user deploying the service
- `iam_client_id`: string, IAM client id (`Mandatory`)
- `iam_token` : string, token needed to interact with the IAM Issuer (`Mandatory`)
- `server_ip`: string with the ip of the current server
- `monitoring`: bool, if to deploy the Grafana monitoring service (default: `yes`)
- `grafana_port`: int, the grafana service port
Expand Down Expand Up @@ -86,6 +89,8 @@ Including an example of how to use your role (for instance, with variables passe
run_jupyter: no
iam_url: https://iam.example.service.it
iam_groups: groupA
iam_client_id: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iam_token: <TOKEN>

```

Expand Down
2 changes: 2 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ iam_admin_groups: "" # group1 group2
server_ip: "" # 192.168.1.42
dns_name: ""
iam_subject: ""
iam_client_id: ""
iam_token: ""

# monitoring
monitoring: yes
Expand Down
64 changes: 64 additions & 0 deletions tasks/iam-client.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
- name: Retrieve registration endpoint from OpenID configuration
uri:
url: "{{ iam_url }}/.well-known/openid-configuration"
method: GET
return_content: yes
register: openid_config
- name: Set registration endpoint variable
set_fact:
registration_endpoint: "{{ openid_config.json.registration_endpoint }}"

- name: Retrieve the IAM client info
uri:
url: "{{ registration_endpoint }}/{{ iam_client_id }}"
method: GET
headers:
Authorization: "Bearer {{ iam_token }}"
status_code: 200
return_content: yes
register: iam_client_get_response

- name: Save the IAM Client info locally
ansible.builtin.copy:
content: "{{ iam_client_get_response.json | to_nice_json }}"
dest: /usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json

- name: Define the new redirect_uri variable
ansible.builtin.set_fact:
redirect_uri: "https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback"

- name: Import the local IAM Client info file
ansible.builtin.set_fact:
iam_client_info: "{{ lookup('file', '/usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json') }}"

- name: Update the redirect_uris field
ansible.builtin.set_fact:
updated_iam_client_info: "{{ iam_client_info | combine({'redirect_uris': [redirect_uri]}) }}"

- name: Save the updated IAM Client info locally
ansible.builtin.copy:
content: "{{ updated_iam_client_info | to_json }}"
dest: /tmp/updated-iam-client.json

- name: Import the local updated IAM Client info file
ansible.builtin.slurp:
src: /tmp/updated-iam-client.json
register: iam_client_file

- name: Update the IAM client info remotely
uri:
url: "{{ registration_endpoint }}/{{ iam_client_id }}"
method: PUT
headers:
Authorization: "Bearer {{ iam_token }}"
Content-Type: application/json
body_format: json
body: "{{ iam_client_file.content | b64decode | from_json }}"
status_code: 200
register: iam_response

- name: Delete local IAM Client info file
ansible.builtin.file:
path: /tmp/updated-iam-client.json
state: absent
79 changes: 15 additions & 64 deletions tasks/prepare-jupyter-hub.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,70 +167,19 @@
cacheable: yes
when: (jupyter_use_gpu | bool)

- block:
- name: Retrieve registration endpoint from OpenID configuration
uri:
url: "{{ iam_url }}/.well-known/openid-configuration"
method: GET
return_content: yes
register: openid_config
- name: Set registration endpoint variable
set_fact:
registration_endpoint: "{{ openid_config.json.registration_endpoint }}"

- name: Collect the IAM client info
uri:
url: "{{ registration_endpoint }}/{{ iam_client_id }}"
method: GET
headers:
Authorization: "Bearer {{ iam_token }}"
status_code: 200
return_content: yes
register: iam_client_get_response

- name: Save the IAM Client info locally
ansible.builtin.copy:
content: "{{ iam_client_get_response.json | to_nice_json }}"
dest: /usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json

- name: Define the new redirect_uri variable
ansible.builtin.set_fact:
redirect_uri: "https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback"

- name: Import the local IAM Client info file
ansible.builtin.set_fact:
iam_client_info: "{{ lookup('file', '/usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json') }}"

- name: Update the redirect_uris field
ansible.builtin.set_fact:
updated_iam_client_info: "{{ iam_client_info | combine({'redirect_uris': [redirect_uri]}) }}"

- name: Save the updated IAM Client info locally
ansible.builtin.copy:
content: "{{ updated_iam_client_info | to_json }}"
dest: /tmp/updated-iam-client.json

- name: Import the local updated IAM Client info file
ansible.builtin.slurp:
src: /tmp/updated-iam-client.json
register: iam_client_file

- name: Update the IAM client info remotely
uri:
url: "{{ registration_endpoint }}/{{ iam_client_id }}"
method: PUT
headers:
Authorization: "Bearer {{ iam_token }}"
Content-Type: application/json
body_format: json
body: "{{ iam_client_file.content | b64decode | from_json }}"
status_code: 200
register: iam_response

- name: Delete local IAM Client info file
ansible.builtin.file:
path: /tmp/updated-iam-client.json
state: absent
# ---------- IAM Client retrieving, updating and local saving ----------
- name: Check vars before interacting with the IAM issuer
assert:
that:
- iam_url | length > 0
- iam_client_id | length > 0
- iam_token | length > 0
- dns_name | length > 0
- jupyter_port | length > 0
fail_msg: Not defined variable among iam_url, iam_client_id, iam_token, dns_name and jupyter_port.

- name: Collect, Update and store locally the IAM Client info
include_tasks: iam-client.yml

# ---------- Collect MIG GPU UUIDs from nvidia-smi ----------
- name: Collect MIG GPU UUIDs
Expand Down Expand Up @@ -260,6 +209,7 @@
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
Expand All @@ -275,3 +225,4 @@
with_items: "{{ jupyter_images.split() + [ jupyterlab_collaborative_image, compose_base_jhub_image, compose_base_http_proxy_image, compose_base_collab_http_proxy_image ] }}"
async: 1800 # 30 min
poll: 0

0 comments on commit 8483b58

Please sign in to comment.