From df021f828b2b68ee1d280ccb70ccb19e57359190 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Thu, 16 Nov 2023 12:50:02 +0100 Subject: [PATCH 01/21] new iam client procedure --- tasks/prepare-jupyter-hub.yml | 68 +++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index bb78db2..5ee1286 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -177,33 +177,49 @@ - name: Set registration endpoint variable set_fact: registration_endpoint: "{{ openid_config.json.registration_endpoint }}" - - name: register iam client - uri: - url: "{{ registration_endpoint }}" - validate_certs: "no" - method: POST - status_code: 201 - headers: - Content-Type: "application/json" - body: - redirect_uris: - - "https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback" - client_name: "jh-client" - token_endpoint_auth_method: client_secret_basic - scope: openid email profile wlcg offline_access address wlcg.groups - grant_types: - - refresh_token - - authorization_code - response_types: - - code - body_format: json - return_content: yes - register: iam_response + - name: iam_issuer + debug: + var: iam_issuer + + - name: iam_client_id + debug: + var: iam_client_id + + - name: iam_token + debug: + var: iam_token + + - name: iam_server_ip + debug: + var: iam_server_ip + + #- name: register iam client + # uri: + # url: "{{ registration_endpoint }}" + # validate_certs: "no" + # method: POST + # status_code: 201 + # headers: + # Content-Type: "application/json" + # body: + # redirect_uris: + # - "https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback" + # client_name: "jh-client" + # token_endpoint_auth_method: client_secret_basic + # scope: openid email profile wlcg offline_access address wlcg.groups + # grant_types: + # - refresh_token + # - authorization_code + # response_types: + # - code + # body_format: json + # return_content: yes + # register: iam_response - - name: Save client info - copy: - content: "{{ iam_response.json }}" - dest: "/usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json" + #- name: Save client info + # copy: + # content: "{{ iam_response.json }}" + # dest: "/usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json" # ---------- Collect MIG GPU UUIDs from nvidia-smi ---------- - name: Collect MIG GPU UUIDs From ddea91b60b864394b23a55954c52444821558908 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Thu, 16 Nov 2023 15:21:46 +0100 Subject: [PATCH 02/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 5ee1286..afa872e 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -177,7 +177,8 @@ - name: Set registration endpoint variable set_fact: registration_endpoint: "{{ openid_config.json.registration_endpoint }}" - - name: iam_issuer + + - name: iam_issuer debug: var: iam_issuer From 8798f76ec0c402953e383bceac058530a154a7c5 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Thu, 16 Nov 2023 16:37:06 +0100 Subject: [PATCH 03/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 63 +++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index afa872e..7987888 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -194,6 +194,69 @@ debug: var: iam_server_ip + - name: registration_endpoint + debug: + var: registration_endpoint + + - name: Do the GET call to get the information about the client_id client + uri: + url: "{{ registration_endpoint }}/{{ iam_client_id }}" + method: GET + headers: + Authorization: "Bearer {{ iam_token }}" + status_code: 200 + return_content: yes + register: get_response + + - name: Save the JSON response into a file + ansible.builtin.copy: + content: "{{ get_response.json | to_nice_json }}" + dest: /usr/local/share/response.json + + - name: Read file directly into fact + ansible.builtin.set_fact: + jsondata: "{{ lookup('file', '/usr/local/share/response.json') }}" + + - name: Define the redirect_uri variable + ansible.builtin.set_fact: + redirect_uri: "https://{{ dns_name }}:8888/hub/oauth_callback" + + - name: Modify the redirect_uris field in the JSON + ansible.builtin.set_fact: + updated_json: "{{ jsondata | combine({'redirect_uris': [redirect_uri]}) }}" + + - name: Save the updated JSON in a file + ansible.builtin.copy: + content: "{{ updated_json | to_json }}" + dest: /usr/local/share/updated_file.json + + - name: Leggi il contenuto del file JSON + ansible.builtin.slurp: + src: /usr/local/share/updated_file.json + register: json_content + + - name: Do the PUT request to modify the client + uri: + url: "{{ registration_endpoint }}/{{ iam_client_id }}" + method: PUT + headers: + Authorization: "Bearer {{ iam_token }}" + Content-Type: application/json + body_format: json + body: "{{json_content.content | b64decode | from_json }}" + status_code: 200 + register: put_response + + - name: Delete response.json + ansible.builtin.file: + path: /usr/local/share/response.json + state: absent + + - name: Delete updated_file.json + ansible.builtin.file: + path: /usr/local/share/updated_file.json + state: absent + #- name: register iam client # uri: # url: "{{ registration_endpoint }}" From fb7a1870affc0b4aaad7d72e32aeb59536fc5273 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Thu, 16 Nov 2023 17:28:55 +0100 Subject: [PATCH 04/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 7987888..7312110 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -219,7 +219,7 @@ - name: Define the redirect_uri variable ansible.builtin.set_fact: - redirect_uri: "https://{{ dns_name }}:8888/hub/oauth_callback" + redirect_uri: "https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback" - name: Modify the redirect_uris field in the JSON ansible.builtin.set_fact: @@ -245,7 +245,7 @@ body_format: json body: "{{json_content.content | b64decode | from_json }}" status_code: 200 - register: put_response + register: iam_response - name: Delete response.json ansible.builtin.file: @@ -257,6 +257,10 @@ path: /usr/local/share/updated_file.json state: absent + - name: iam_response + debug: + var: iam_response + #- name: register iam client # uri: # url: "{{ registration_endpoint }}" From 91d78d23e7fb6e107e52ea774e1619fbc4132a38 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Fri, 17 Nov 2023 16:32:49 +0100 Subject: [PATCH 05/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 7312110..8965352 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -243,7 +243,7 @@ Authorization: "Bearer {{ iam_token }}" Content-Type: application/json body_format: json - body: "{{json_content.content | b64decode | from_json }}" + body: "{{ json_content.content | b64decode | from_json }}" status_code: 200 register: iam_response @@ -261,34 +261,6 @@ debug: var: iam_response - #- name: register iam client - # uri: - # url: "{{ registration_endpoint }}" - # validate_certs: "no" - # method: POST - # status_code: 201 - # headers: - # Content-Type: "application/json" - # body: - # redirect_uris: - # - "https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback" - # client_name: "jh-client" - # token_endpoint_auth_method: client_secret_basic - # scope: openid email profile wlcg offline_access address wlcg.groups - # grant_types: - # - refresh_token - # - authorization_code - # response_types: - # - code - # body_format: json - # return_content: yes - # register: iam_response - - #- name: Save client info - # copy: - # content: "{{ iam_response.json }}" - # dest: "/usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json" - # ---------- Collect MIG GPU UUIDs from nvidia-smi ---------- - name: Collect MIG GPU UUIDs shell: From a8e32a6cde56097d00dfe880c6d8c936ec1169e1 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Fri, 17 Nov 2023 16:36:36 +0100 Subject: [PATCH 06/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 8965352..f3a543d 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -207,7 +207,7 @@ status_code: 200 return_content: yes register: get_response - + - name: Save the JSON response into a file ansible.builtin.copy: content: "{{ get_response.json | to_nice_json }}" @@ -220,11 +220,11 @@ - name: Define the redirect_uri variable ansible.builtin.set_fact: redirect_uri: "https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback" - + - name: Modify the redirect_uris field in the JSON ansible.builtin.set_fact: updated_json: "{{ jsondata | combine({'redirect_uris': [redirect_uri]}) }}" - + - name: Save the updated JSON in a file ansible.builtin.copy: content: "{{ updated_json | to_json }}" From 967bbf7ebd5fb776bee0462b3d3b96e182f3ebfe Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Fri, 17 Nov 2023 16:39:03 +0100 Subject: [PATCH 07/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index f3a543d..fb2cb12 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -177,7 +177,7 @@ - name: Set registration endpoint variable set_fact: registration_endpoint: "{{ openid_config.json.registration_endpoint }}" - + - name: iam_issuer debug: var: iam_issuer From 9a00223a8feedd5b5bfe23b2885153fe8c60916b Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Fri, 17 Nov 2023 17:10:31 +0100 Subject: [PATCH 08/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index fb2cb12..9ad2d3e 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -178,26 +178,6 @@ set_fact: registration_endpoint: "{{ openid_config.json.registration_endpoint }}" - - name: iam_issuer - debug: - var: iam_issuer - - - name: iam_client_id - debug: - var: iam_client_id - - - name: iam_token - debug: - var: iam_token - - - name: iam_server_ip - debug: - var: iam_server_ip - - - name: registration_endpoint - debug: - var: registration_endpoint - - name: Do the GET call to get the information about the client_id client uri: url: "{{ registration_endpoint }}/{{ iam_client_id }}" @@ -211,11 +191,11 @@ - name: Save the JSON response into a file ansible.builtin.copy: content: "{{ get_response.json | to_nice_json }}" - dest: /usr/local/share/response.json + dest: /usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json - name: Read file directly into fact ansible.builtin.set_fact: - jsondata: "{{ lookup('file', '/usr/local/share/response.json') }}" + jsondata: "{{ lookup('file', '/usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json') }}" - name: Define the redirect_uri variable ansible.builtin.set_fact: @@ -230,7 +210,7 @@ content: "{{ updated_json | to_json }}" dest: /usr/local/share/updated_file.json - - name: Leggi il contenuto del file JSON + - name: Read JSON content ansible.builtin.slurp: src: /usr/local/share/updated_file.json register: json_content @@ -247,20 +227,11 @@ status_code: 200 register: iam_response - - name: Delete response.json - ansible.builtin.file: - path: /usr/local/share/response.json - state: absent - - name: Delete updated_file.json ansible.builtin.file: path: /usr/local/share/updated_file.json state: absent - - name: iam_response - debug: - var: iam_response - # ---------- Collect MIG GPU UUIDs from nvidia-smi ---------- - name: Collect MIG GPU UUIDs shell: From 3b1b122320967ff3bbefe0a5527af761f977cffa Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Mon, 27 Nov 2023 12:53:10 +0100 Subject: [PATCH 09/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 40 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 9ad2d3e..25a740b 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -178,7 +178,7 @@ set_fact: registration_endpoint: "{{ openid_config.json.registration_endpoint }}" - - name: Do the GET call to get the information about the client_id client + - name: Collect the IAM client info uri: url: "{{ registration_endpoint }}/{{ iam_client_id }}" method: GET @@ -186,36 +186,36 @@ Authorization: "Bearer {{ iam_token }}" status_code: 200 return_content: yes - register: get_response + register: iam_client_get_response - - name: Save the JSON response into a file + - name: Save the IAM Client info locally ansible.builtin.copy: - content: "{{ get_response.json | to_nice_json }}" + content: "{{ iam_client_get_response.json | to_nice_json }}" dest: /usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json - - name: Read file directly into fact + - name: Define the new redirect_uri variable ansible.builtin.set_fact: - jsondata: "{{ lookup('file', '/usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json') }}" + redirect_uri: "https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback" - - name: Define the redirect_uri variable + - name: Import the local IAM Client info file ansible.builtin.set_fact: - redirect_uri: "https://{{ dns_name }}:{{ jupyter_port }}/hub/oauth_callback" + iam_client_info: "{{ lookup('file', '/usr/local/share/dodasts/jupyterhub/cookies/.client-iam.json') }}" - - name: Modify the redirect_uris field in the JSON + - name: Update the redirect_uris field ansible.builtin.set_fact: - updated_json: "{{ jsondata | combine({'redirect_uris': [redirect_uri]}) }}" + updated_iam_client_info: "{{ iam_client_info | combine({'redirect_uris': [redirect_uri]}) }}" - - name: Save the updated JSON in a file + - name: Save the updated IAM Client info locally ansible.builtin.copy: - content: "{{ updated_json | to_json }}" - dest: /usr/local/share/updated_file.json + content: "{{ updated_iam_client_info | to_json }}" + dest: /tmp/updated-iam-client.json - - name: Read JSON content + - name: Import the local updated IAM Client info file ansible.builtin.slurp: - src: /usr/local/share/updated_file.json - register: json_content + src: /tmp/updated-iam-client.json + register: iam_client_file - - name: Do the PUT request to modify the client + - name: Update the IAM client info remotely uri: url: "{{ registration_endpoint }}/{{ iam_client_id }}" method: PUT @@ -223,13 +223,13 @@ Authorization: "Bearer {{ iam_token }}" Content-Type: application/json body_format: json - body: "{{ json_content.content | b64decode | from_json }}" + body: "{{ iam_client_file.content | b64decode | from_json }}" status_code: 200 register: iam_response - - name: Delete updated_file.json + - name: Delete local IAM Client info file ansible.builtin.file: - path: /usr/local/share/updated_file.json + path: /tmp/updated-iam-client.json state: absent # ---------- Collect MIG GPU UUIDs from nvidia-smi ---------- From a51d490d6698b9f6eb8adc45d9bff1dd56bf5571 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 12:00:51 +0100 Subject: [PATCH 10/21] CLOUD-1996 --- defaults/main.yml | 2 + tasks/prepare-jupyter-hub.yml | 147 +++++++++++++++++++--------------- 2 files changed, 85 insertions(+), 64 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 2f5467e..94b6489 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -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 diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 25a740b..d27a494 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -167,70 +167,88 @@ 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 +- name: Check vars before to interact with IAM + 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: One or multiple among iam_url, iam_client_id, iam_token, dns_name and jupyter_port has not been defined + success_msg: OK + +- name: Collect, Update and store locally the IAM Client info + 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 + failed_when: > + (iam_url | length == 0) or + (iam_client_id | length == 0) or + (iam_token | length == 0) or + (dns_name | length == 0) or + (jupyter_port | length == 0) # ---------- Collect MIG GPU UUIDs from nvidia-smi ---------- - name: Collect MIG GPU UUIDs @@ -260,6 +278,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 From 6ba42846217871da8828119b8f93c88e134c636d Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 12:23:17 +0100 Subject: [PATCH 11/21] CLOUD-1996 --- README.md | 4 ++++ tasks/prepare-jupyter-hub.yml | 34 ++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b018eea..becbe79 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ Variable for the monitoring 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 +- `iam_client_id`: string with the IAM client id to use +- `iam_token` : token used to interact with the IAM Issuer - `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 @@ -86,6 +88,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_toekn: ``` diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index d27a494..9b96ff0 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -243,12 +243,34 @@ ansible.builtin.file: path: /tmp/updated-iam-client.json state: absent - failed_when: > - (iam_url | length == 0) or - (iam_client_id | length == 0) or - (iam_token | length == 0) or - (dns_name | length == 0) or - (jupyter_port | length == 0) + when: + - iam_url | length > 0 + - iam_client_id | length > 0 + - iam_token | length > 0 + - dns_name | length > 0 + - jupyter_port | length > 0 + +- name: Check vars before to interact with IAM 2 + 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: One or multiple among iam_url, iam_client_id, iam_token, dns_name and jupyter_port has not been defined + success_msg: OK + +- name: Check vars before to interact with IAM 3 + 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: One or multiple among iam_url, iam_client_id, iam_token, dns_name and jupyter_port has not been defined + success_msg: OK # ---------- Collect MIG GPU UUIDs from nvidia-smi ---------- - name: Collect MIG GPU UUIDs From 5c49115f482855d2df64b3902dc4763914b9d42b Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 12:52:08 +0100 Subject: [PATCH 12/21] CLOUD-1996 --- README.md | 6 +++--- tasks/prepare-jupyter-hub.yml | 31 +------------------------------ 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index becbe79..af74b8f 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ Variable for the monitoring 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 -- `iam_client_id`: string with the IAM client id to use -- `iam_token` : token used to interact with the IAM Issuer +- `iam_client_id`: string with the IAM client id +- `iam_token` : token needed to interact with the IAM Issuer - `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 @@ -89,7 +89,7 @@ Including an example of how to use your role (for instance, with variables passe iam_url: https://iam.example.service.it iam_groups: groupA iam_client_id: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - iam_toekn: + iam_token: ``` diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 9b96ff0..2904374 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -175,8 +175,7 @@ - iam_token | length > 0 - dns_name | length > 0 - jupyter_port | length > 0 - fail_msg: One or multiple among iam_url, iam_client_id, iam_token, dns_name and jupyter_port has not been defined - success_msg: OK + 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 block: @@ -243,34 +242,6 @@ ansible.builtin.file: path: /tmp/updated-iam-client.json state: absent - when: - - iam_url | length > 0 - - iam_client_id | length > 0 - - iam_token | length > 0 - - dns_name | length > 0 - - jupyter_port | length > 0 - -- name: Check vars before to interact with IAM 2 - 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: One or multiple among iam_url, iam_client_id, iam_token, dns_name and jupyter_port has not been defined - success_msg: OK - -- name: Check vars before to interact with IAM 3 - 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: One or multiple among iam_url, iam_client_id, iam_token, dns_name and jupyter_port has not been defined - success_msg: OK # ---------- Collect MIG GPU UUIDs from nvidia-smi ---------- - name: Collect MIG GPU UUIDs From fa095f430378b1f9bb2bbd1f0639aaf2ad2c2af0 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 12:54:24 +0100 Subject: [PATCH 13/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 2904374..3178bbb 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -167,7 +167,7 @@ cacheable: yes when: (jupyter_use_gpu | bool) -- name: Check vars before to interact with IAM +- name: Check vars before interacting with the IAM issuer assert: that: - iam_url | length > 0 From 695bed87f148da70560bd01113c9e5b68e4ba254 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 13:05:59 +0100 Subject: [PATCH 14/21] CLOUD-1996 --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index af74b8f..795e96f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,9 @@ 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 to configure the JupyterHub authentication plugin. +If you are using this role through [INFN PaaS orchestrator](https://my.cloud.infn.it) the IAM client is created automatically. +Otherwise, you should provide `iam_url`, `iam_client_id` and `iam_token` variables. Role Variables -------------- @@ -34,12 +36,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 (It can not be empty) - `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_client_id`: string with the IAM client id -- `iam_token` : token needed to interact with the IAM Issuer +- `iam_client_id`: string with the IAM client id (It can not be empty) +- `iam_token` : token needed to interact with the IAM Issuer (It can not be empty) - `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 From 9e4c1b574526b5607b9f807f503e293dff9f339d Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 13:08:35 +0100 Subject: [PATCH 15/21] CLOUD-1996 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 795e96f..b92eaa0 100644 --- a/README.md +++ b/README.md @@ -36,12 +36,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 (It can not be empty) +- `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_client_id`: string with the IAM client id (It can not be empty) -- `iam_token` : token needed to interact with the IAM Issuer (It can not be empty) +- `iam_subject` : string, token subject of the user deploying the service +- `iam_client_id`: string with the 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 From e4df817e879dad71248e4608978a9a8309b83ca8 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 13:16:33 +0100 Subject: [PATCH 16/21] CLOUD-1996 --- tasks/iam-client.yml | 64 +++++++++++++++++++++++++++++++++ tasks/prepare-jupyter-hub.yml | 66 ++--------------------------------- 2 files changed, 66 insertions(+), 64 deletions(-) create mode 100644 tasks/iam-client.yml diff --git a/tasks/iam-client.yml b/tasks/iam-client.yml new file mode 100644 index 0000000..ddbbd24 --- /dev/null +++ b/tasks/iam-client.yml @@ -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 diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 3178bbb..9217590 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -167,6 +167,7 @@ cacheable: yes when: (jupyter_use_gpu | bool) +# ---------- IAM Client retrieving, updating and local saving ---------- - name: Check vars before interacting with the IAM issuer assert: that: @@ -178,70 +179,7 @@ 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 - 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 + include_tasks: iam-client.yml # ---------- Collect MIG GPU UUIDs from nvidia-smi ---------- - name: Collect MIG GPU UUIDs From d7cc5e1066517a8211003907a53fbf55177103aa Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 13:31:17 +0100 Subject: [PATCH 17/21] CLOUD-1996 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b92eaa0..41ceeab 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ A role to setup a node with a jupyterhub that spawns jupyterlab with or without Requirements ------------ -This role needs a working IAM Client to configure the JupyterHub authentication plugin. -If you are using this role through [INFN PaaS orchestrator](https://my.cloud.infn.it) the IAM client is created automatically. +This role needs a working IAM Client in order to configure the JupyterHub authentication plugin. +If you are using this role through [INFN PaaS orchestrator](https://my.cloud.infn.it) the IAM client is created automatically and parameter are passed as well. Otherwise, you should provide `iam_url`, `iam_client_id` and `iam_token` variables. Role Variables @@ -40,7 +40,7 @@ Variable for the monitoring 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` : string, token subject of the user deploying the service -- `iam_client_id`: string with the IAM client id (`Mandatory`) +- `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`) From 9fbe91a363ec8ef0623991692f3620d1e9f35ea5 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 13:36:21 +0100 Subject: [PATCH 18/21] CLOUD-1996 --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 41ceeab..e471810 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,7 @@ Requirements ------------ This role needs a working IAM Client in order to configure the JupyterHub authentication plugin. -If you are using this role through [INFN PaaS orchestrator](https://my.cloud.infn.it) the IAM client is created automatically and parameter are passed as well. -Otherwise, you should provide `iam_url`, `iam_client_id` and `iam_token` variables. +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 -------------- From 1d3df1aa6bae741a2e276712c93952f19f35e96c Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 13:43:01 +0100 Subject: [PATCH 19/21] CLOUD-1996 --- defaults/main.yml | 2 +- tasks/prepare-jupyter-hub.yml | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 94b6489..b622d0f 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -41,7 +41,7 @@ iam_admin_groups: "" # group1 group2 server_ip: "" # 192.168.1.42 dns_name: "" iam_subject: "" -iam_client_id: "" +iam_client_id: "" iam_token: "" # monitoring diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 9217590..95db3fe 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -170,7 +170,7 @@ # ---------- IAM Client retrieving, updating and local saving ---------- - name: Check vars before interacting with the IAM issuer assert: - that: + that: - iam_url | length > 0 - iam_client_id | length > 0 - iam_token | length > 0 @@ -178,7 +178,7 @@ - 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 +- name: Collect, Update and store locally the IAM Client info include_tasks: iam-client.yml # ---------- Collect MIG GPU UUIDs from nvidia-smi ---------- @@ -225,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 + \ No newline at end of file From f280c51262f14df2501a0653f75d6a466c8bd108 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 13:50:58 +0100 Subject: [PATCH 20/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index 9b97d93..ea52ecd 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -224,9 +224,5 @@ command: docker pull "{{ item }}" 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 -<<<<<<< HEAD poll: 0 -======= - poll: 0 ->>>>>>> dd815bbcad6bf394576320e1d05fda369c72af8c From 780588dd854ac2057355e3de0db48205b3803198 Mon Sep 17 00:00:00 2001 From: "gioacchino.vino" Date: Tue, 28 Nov 2023 13:52:27 +0100 Subject: [PATCH 21/21] CLOUD-1996 --- tasks/prepare-jupyter-hub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/prepare-jupyter-hub.yml b/tasks/prepare-jupyter-hub.yml index ea52ecd..d710e52 100644 --- a/tasks/prepare-jupyter-hub.yml +++ b/tasks/prepare-jupyter-hub.yml @@ -225,4 +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 - +