Skip to content

Commit 06dd0fb

Browse files
authored
Merge pull request #179 from vre-hub/flux_jhub
Migrate jhub from tf ro flux
2 parents 90bf1df + fa95e8c commit 06dd0fb

File tree

8 files changed

+309
-307
lines changed

8 files changed

+309
-307
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: source.toolkit.fluxcd.io/v1beta1
2+
kind: HelmRepository
3+
metadata:
4+
name: jhub
5+
namespace: jhub
6+
spec:
7+
interval: 10m
8+
url: https://hub.jupyter.org/helm-chart/
9+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# kind: Namespace
2+
# apiVersion: v1
3+
# metadata:
4+
# name: jhub
5+
# labels:
6+
# name: jhub
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: jhub-profiles
5+
namespace: jhub
6+
data:
7+
values.yaml: |
8+
singleuser:
9+
profileList:
10+
- display_name: "Default profile"
11+
description: "A jupyter/scipy-notebook env with python-3.9, the rucio-jupyterlab extension and the reana-client installed."
12+
default: True
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
apiVersion: helm.toolkit.fluxcd.io/v2beta1
2+
kind: HelmRelease
3+
metadata:
4+
name: jhub-cvre
5+
namespace: jhub
6+
spec:
7+
releaseName: jhub-cvre
8+
interval: 5m
9+
chart:
10+
spec:
11+
sourceRef:
12+
kind: HelmRepository
13+
name: jhub
14+
namespace: jhub
15+
chart: jupyterhub
16+
interval: 5m
17+
version: 2.0.0
18+
valuesFrom:
19+
- kind: Secret
20+
name: jhub-cvre-iam-secrets
21+
valuesKey: client_id
22+
targetPath: hub.config.RucioAuthenticator.client_id
23+
- kind: Secret
24+
name: jhub-cvre-iam-secrets
25+
valuesKey: client_secret
26+
targetPath: hub.config.RucioAuthenticator.client_secret
27+
- kind: Secret
28+
name: jhub-cvre-dbconnectstring
29+
valuesKey: dbconnectstring
30+
targetPath: hub.db.url
31+
- kind: ConfigMap
32+
name: jupyter-profiles
33+
valuesKey: values.yaml
34+
values:
35+
proxy:
36+
service:
37+
type: ClusterIP
38+
hub:
39+
service:
40+
type: ClusterIP
41+
# network policy needs to be modified to allow access to the Rucio server
42+
# (disabling it for now as a workaround, see also the ones for singeluser and proxy below)
43+
networkPolicy:
44+
enabled: false
45+
db:
46+
type: postgres # secret dbconnect string set in main-helm.tf
47+
config:
48+
RucioAuthenticator:
49+
# client_id: "" # set through secret
50+
# client_secret: "" # set through secret
51+
authorize_url: https://iam-escape.cloud.cnaf.infn.it/authorize
52+
token_url: https://iam-escape.cloud.cnaf.infn.it/token
53+
userdata_url: https://iam-escape.cloud.cnaf.infn.it/userinfo
54+
username_key: preferred_username
55+
scope:
56+
- openid
57+
- profile
58+
- email
59+
extraConfig:
60+
token-exchange: |
61+
import pprint
62+
import os
63+
import warnings
64+
import requests
65+
from oauthenticator.generic import GenericOAuthenticator
66+
67+
# custom authenticator to exchange the access token for a refresh token for rucio OIDC to work
68+
class RucioAuthenticator(GenericOAuthenticator):
69+
def __init__(self, **kwargs):
70+
super().__init__(**kwargs)
71+
self.enable_auth_state = True
72+
73+
def exchange_token(self, token):
74+
params = {
75+
'client_id': self.client_id,
76+
'client_secret': self.client_secret,
77+
'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange',
78+
'subject_token': token,
79+
'scope': 'openid email profile',
80+
'audience': 'rucio'
81+
}
82+
response = requests.post(self.token_url, data=params)
83+
refresh_token = response.json()['access_token']
84+
return refresh_token
85+
86+
async def pre_spawn_start(self, user, spawner):
87+
auth_state = await user.get_auth_state()
88+
pprint.pprint(auth_state)
89+
if not auth_state:
90+
# user has no auth state
91+
return
92+
93+
# define token environment variable from auth_state
94+
spawner.environment['REFRESH_TOKEN'] = self.exchange_token(auth_state['access_token'])
95+
96+
# set the above authenticator as the default
97+
c.JupyterHub.authenticator_class = RucioAuthenticator
98+
99+
# enable authentication state
100+
c.GenericOAuthenticator.enable_auth_state = True
101+
102+
if 'JUPYTERHUB_CRYPT_KEY' not in os.environ:
103+
warnings.warn(
104+
"Need JUPYTERHUB_CRYPT_KEY env for persistent auth_state.\n"
105+
" export JUPYTERHUB_CRYPT_KEY=$(openssl rand -hex 32)"
106+
)
107+
c.CryptKeeper.keys = [os.urandom(32)]
108+
singleuser:
109+
defaultUrl: "/lab"
110+
# The liefcycle hooks are used to create the Rucio configuration file,
111+
# and the token file by copying the REFRESH_TOKEN from the environment variable to the token file.
112+
lifecycleHooks:
113+
postStart:
114+
exec:
115+
command:
116+
- "sh"
117+
- "-c"
118+
- >
119+
echo -n $REFRESH_TOKEN > /home/jovyan/token;
120+
mkdir -p /opt/rucio/etc;
121+
echo "[client]" >> /opt/rucio/etc/rucio.cfg;
122+
echo "rucio_host = https://vre-rucio.cern.ch" >> /opt/rucio/etc/rucio.cfg;
123+
echo "auth_host = https://vre-rucio-auth.cern.ch" >> /opt/rucio/etc/rucio.cfg;
124+
echo "ca_cert = /opt/cert.pem" >> /opt/rucio/etc/rucio.cfg;
125+
echo "account = $JUPYTERHUB_USER" >> /opt/rucio/etc/rucio.cfg;
126+
echo "auth_type = oidc" >> /opt/rucio/etc/rucio.cfg;
127+
echo "oidc_audience = rucio" >> /opt/rucio/etc/rucio.cfg;
128+
echo "auth_token_file_path = /home/jovyan/token" >> /opt/rucio/etc/rucio.cfg;
129+
networkPolicy:
130+
enabled: false
131+
storage:
132+
type: static
133+
static:
134+
pvcName: jhub-singleuser # manually created StorageClass with Retain policy and PVC with 800Gi (refer to main-k8s.tf)
135+
extraVolumes:
136+
# - name: cvfms-from-vre # commented out not working
137+
# persistentVolumeClaim:
138+
# claimName: cvfms
139+
- name: eulake-escape-data # mounts the EOS RSE needed for the Rucio JupiterLab extension
140+
hostPath:
141+
path: /var/eos-eulake-home/eulake/escape/data
142+
extraVolumeMounts:
143+
# - name: cvfms-from-vre # commented out not working
144+
# mountPath: /cvfms
145+
# # CVMFS automount volumes must be mounted with HostToContainer mount propagation.
146+
# mountPropagation: HostToContainer
147+
- name: eulake-escape-data # mounts the EOS RSE needed for the Rucio JupiterLab extension
148+
mountPath: /eos/escape/
149+
mountPropagation: HostToContainer
150+
readOnly: true
151+
image:
152+
name: ghcr.io/vre-hub/vre-singleuser:sha-7210810
153+
tag: latest
154+
pullPolicy: Always
155+
extraFiles:
156+
ca:
157+
mountPath: /opt/cert.pem
158+
stringData: |
159+
-----BEGIN CERTIFICATE-----
160+
MIIGqTCCBJGgAwIBAgIQAojDcLlcbrhBX0qrEka4mzANBgkqhkiG9w0BAQ0FADBK
161+
MQswCQYDVQQGEwJjaDENMAsGA1UEChMEQ0VSTjEsMCoGA1UEAxMjQ0VSTiBSb290
162+
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IDIwHhcNMTMwMzE5MTI1NTM2WhcNMzMw
163+
MzE5MTMwNTM0WjBKMQswCQYDVQQGEwJjaDENMAsGA1UEChMEQ0VSTjEsMCoGA1UE
164+
AxMjQ0VSTiBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IDIwggIiMA0GCSqG
165+
SIb3DQEBAQUAA4ICDwAwggIKAoICAQDxqYPFW2qVVi3Rw1NKlEf7x70xF+6a8uE/
166+
Tu4ZVQF/K2RXI95QLkYfKItZvy9Az3ib/VlUho5f8fBaqy4n70uwC7+qd3Aq1/xQ
167+
ysykPCbBBAsOSQQpTlhrMD2V5Ya9zrirphOhutddiqV96zBCyMM+Gz5uYv9u+cm4
168+
tg1EOmAMGh2UNxfTFNVmXKkk7eFTSC1+zgb28H6nd3xzV27sn9bfOfGh//ZPy5gm
169+
Qx0Oh/tc6WMreWzRZBQm5SJiK0QOzPv09p5WmdY2WxZoqNTFBDACQO7ysFOktc74
170+
fPVFX/lmt4jFNSZRIOvvaACI/qlEaAJTR4FHIY9uSMsV8DrtzhI1Ucyv3kqlQpbF
171+
jDouq44IryA/np4s/124bW+x8+n/v+at/AxPjvHBLiGhB+J38Z6KcJogoDnGzIXR
172+
S+YUr/vGz34jOmkRuDN5STuuAXzyCKFXaoAm0AwjTziIv3E0jxC1taw6FpKevnd1
173+
CLsTLAEUiEjzStFkDhd/Hpipc57zmMFY8VYet2wVqSFjnt2REWOVbZlbCiMHmSeD
174+
u5EuZLiU8xlkiaCfn4A5XZ6X0qprbgDviGJtwxzNvTg7Hn0ziW5/ELryfQXCwZJ+
175+
FVne8Zu8sbgy/sDkX+pyFuyB4XgiM0eMNkoexIXJaRdlMWDIL5ysiIXQKjhynAv5
176+
KLHbRjciVwIDAQABo4IBiTCCAYUwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMB
177+
Af8wHQYDVR0OBBYEFPp7+96bDaPyUrds7VsPC6KmpvgEMBAGCSsGAQQBgjcVAQQD
178+
AgEAMIIBMgYDVR0gBIIBKTCCASUwggEhBgorBgEEAWAKBAEBMIIBETCBwgYIKwYB
179+
BQUHAgIwgbUegbIAQwBFAFIATgAgAFIAbwBvAHQAIABDAGUAcgB0AGkAZgBpAGMA
180+
YQB0AGkAbwBuACAAQQB1AHQAaABvAHIAaQB0AHkAIAAyACAAQwBlAHIAdABpAGYA
181+
aQBjAGEAdABlACAAUABvAGwAaQBjAHkAIABhAG4AZAAgAEMAZQByAHQAaQBmAGkA
182+
YwBhAHQAZQAgAFAAcgBhAGMAdABpAGMAZQAgAFMAdABhAHQAZQBtAGUAbgB0MEoG
183+
CCsGAQUFBwIBFj5odHRwOi8vY2FmaWxlcy5jZXJuLmNoL2NhZmlsZXMvY3AtY3Bz
184+
L2Nlcm4tcm9vdC1jYTItY3AtY3BzLnBkZjANBgkqhkiG9w0BAQ0FAAOCAgEAo0Px
185+
l4CZ6C6bDH+b6jV5uUO0NIHtvLuVgQLMdKVHtQ2UaxeIrWwD+Kz1FyJCHTRXrCvE
186+
OFOca9SEYK2XrbqZGvRKdDRsq+XYts6aCampXj5ahh6r4oQJ8U7aLVfziKTK13Gy
187+
dYFoAUeUrlNklICt3v2wWBaa1tg2oSlU2g4iCg9kYpRnIW3VKSrVsdVk2lUa4EXs
188+
nTEJ30OS7rqX3SdqZp8G+awtBEReh2XPhRgJ6w3xiScP/UdWYUam2LflCGX3RibB
189+
/DZhgGHRRoE4/D0kQMP2XTz6cClbNklECTlp0qZIbiaf350HbcDEFzYRSSIi0emv
190+
kRGcMgsi8yTTU87q8Cr4hETxAF3ZbSVNC0ZaTZ8RBbM9BXguhYzKkVBgG/cMpUjs
191+
B6tY2HMZbAZ3TKQRb/bRyUigM9DniKWeXkeL/0Nsno+XbcpAqLjtVIRwCg6jTLUi
192+
1NRsl3BP6C824dVaoI8Ry7m+o6O+mtocw4BMhHfTcoWCO8CWjT0ME67JzaAYa5eM
193+
+OqoWtgbgweBlfO0/3GMnVGMAmI4FlhH2oWKWQgWdgr0Wgh9K05VcxSpJ87/zjhb
194+
MQn/bEojWmp6eUppPaqNFcELvud41qoe6hLsOYQVUQ1sHi7n6ouhg4BAbwS2iyD2
195+
uiA6FHTCeLreFGUzs5osPKiz3GE5D6V9she9xIQ=
196+
-----END CERTIFICATE-----
197+
-----BEGIN CERTIFICATE-----
198+
MIIJnDCCB4SgAwIBAgIKYQQltAAAAAAACzANBgkqhkiG9w0BAQ0FADBKMQswCQYD
199+
VQQGEwJjaDENMAsGA1UEChMEQ0VSTjEsMCoGA1UEAxMjQ0VSTiBSb290IENlcnRp
200+
ZmljYXRpb24gQXV0aG9yaXR5IDIwHhcNMjIwMzI5MDgyNDIyWhcNMzIwMzI5MDgz
201+
NDIyWjBWMRIwEAYKCZImiZPyLGQBGRYCY2gxFDASBgoJkiaJk/IsZAEZFgRjZXJu
202+
MSowKAYDVQQDEyFDRVJOIEdyaWQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIi
203+
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDS9Ypy1csm0aZA4/QnWe2oaiQI
204+
LqfeekV8kSSvOhW2peo5cLNIKbXATOo1l2iwIbCWV8SRU2TLKxHIL8fAOJud5n9K
205+
mEKBew7nzubl1wG93B4dY0KREdb3/QB/7OkG8ZZvLqrvQZVGT1CgJ+NFFUiJ315D
206+
FWkKctZv27LjQamzCxpX+gZSsmwZmSReY67cnm6P7z+/3xVNhwb+4Z+1Ww4vHhMc
207+
dh1Dsrkv9vXU01UN752QtQ6l56uQLYEB2+vaHB6IpyC9zAQ/33GulCq8Gbj7ykPd
208+
9AcRVBeJAErSK+oMHThtdLD7mhTkZivakaNe4O1EhPFH0rWwV45IFN7ipELA5qDx
209+
djdzo6JtLJQMaSV/TV+amEf2CaKlD0giqGhjfSNiOX5HCmpqV14kbl+7Qho6ykZy
210+
b1DGpf70yILnX+AUtdpd8lulTu1yg1Bg5cFQskUIk5+s4nsC1VpmeNxYaeFEcYZj
211+
Ph2mdD7zLo889MtF7kZv7+6J6p4NBL3fQ9Os8/h8XVlfDatzbpVH4jYKKAd4nwJb
212+
knJaKPE0LzLzVfJBwnDxqe8hb64gI8Frludp+jaOYzvMqlzAe9z4a9971iXIWaaG
213+
unbAoEkXj69y7MsvCjWXB7o9HdBaS9FL+ZtXTKCyXl+XLFseYQoQburKr+eTcRed
214+
KLJNj4tRF1799PO69wIDAQABo4IEdjCCBHIwEAYJKwYBBAGCNxUBBAMCAQEwIwYJ
215+
KwYBBAGCNxUCBBYEFGPCgXhtlBTXUVYziSFk8YWmsNHgMB0GA1UdDgQWBBSloP1m
216+
WP253Xrhsp2fo9HlUBiU5zCCAS4GA1UdIASCASUwggEhMIIBHQYKKwYBBAFgCgQB
217+
ATCCAQ0wgb4GCCsGAQUFBwICMIGxHoGuAEMARQBSAE4AIABHAHIAaQBkACAAQwBl
218+
AHIAdABpAGYAaQBjAGEAdABpAG8AbgAgAEEAdQB0AGgAbwByAGkAdAB5ACAAQwBl
219+
AHIAdABpAGYAaQBjAGEAdABlACAAUABvAGwAaQBjAHkAIABhAG4AZAAgAEMAZQBy
220+
AHQAaQBmAGkAYwBhAHQAZQAgAFAAcgBhAGMAdABpAGMAZQAgAFMAdABhAHQAZQBt
221+
AGUAbgB0MEoGCCsGAQUFBwIBFj5odHRwOi8vY2FmaWxlcy5jZXJuLmNoL2NhZmls
222+
ZXMvY3AtY3BzL2Nlcm4tZ3JpZC1jYS1jcC1jcHMucGRmADAZBgkrBgEEAYI3FAIE
223+
DB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
224+
HSMEGDAWgBT6e/vemw2j8lK3bO1bDwuipqb4BDCCAUQGA1UdHwSCATswggE3MIIB
225+
M6CCAS+gggErhlJodHRwOi8vY2FmaWxlcy5jZXJuLmNoL2NhZmlsZXMvY3JsL0NF
226+
Uk4lMjBSb290JTIwQ2VydGlmaWNhdGlvbiUyMEF1dGhvcml0eSUyMDIuY3JshoHU
227+
bGRhcDovLy9DTj1DRVJOJTIwUm9vdCUyMENlcnRpZmljYXRpb24lMjBBdXRob3Jp
228+
dHklMjAyLENOPUNFUk5QS0lST09UMDIsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUy
229+
MFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9Y2VybixE
230+
Qz1jaD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9
231+
Y1JMRGlzdHJpYnV0aW9uUG9pbnQwggFEBggrBgEFBQcBAQSCATYwggEyMGcGCCsG
232+
AQUFBzAChltodHRwOi8vY2FmaWxlcy5jZXJuLmNoL2NhZmlsZXMvY2VydGlmaWNh
233+
dGVzL0NFUk4lMjBSb290JTIwQ2VydGlmaWNhdGlvbiUyMEF1dGhvcml0eSUyMDIu
234+
Y3J0MIHGBggrBgEFBQcwAoaBuWxkYXA6Ly8vQ049Q0VSTiUyMFJvb3QlMjBDZXJ0
235+
aWZpY2F0aW9uJTIwQXV0aG9yaXR5JTIwMixDTj1BSUEsQ049UHVibGljJTIwS2V5
236+
JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixEQz1jZXJu
237+
LERDPWNoP2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0
238+
aW9uQXV0aG9yaXR5MA0GCSqGSIb3DQEBDQUAA4ICAQAv56iMPo0VUkrHxPYLjfyW
239+
IL/TmYxxYldO8kCTKXyaRO4ZmwD6JjLaclTgSHz7gOKFL35ZF0Rv4nWk/ZJBl+dU
240+
1udgBjF/uKK0v0m+7iEIOG0HORCCQCDgayuiLomI5eQp8KTgHrswHWL+ESxa3Hdv
241+
vr7GBG/7EhrYwstm/tOJ8cKaeiooSxHw5Lgsqq229SxfO8fSyS8DAa5eUdWT/dVU
242+
RDR8lGQShx4R9JOHSDg0y6rE7V0cw/BO3NQuaxMunFXkQprtWneJfR4uugMOKk/v
243+
tMhQGCDB7o3CVhLGSb+76Tny+eSa2g+Zv17PGVfhnF9oynkCII+shX9TmOUsDEnS
244+
7MWES58YwnpBZrxdeJVPEzVVuYEZP4QsLrIL1ynFqBwFAnPU48Hs6s+kOI/9BFJz
245+
v+Fp/iw8BZSOclpJzA5rkW6yQ7LVfjFBV1CgyhO8GH5jhYBd5ZLvG8eLNm8Gpt+H
246+
n30awoaDoMuHcGS5B6NOZLfwE+suTxMw8pjHhKXx7RkSoeZy72PinlbWn1tWLiPa
247+
UMdkrb/WHOdMKaadQTDO/VyibBL49iJ8BAlERgIl9QaRDLjAIdD45rLdBe95HxSl
248+
zpZqsxuI09eJ8+iLFJhTDH2BODoEuqbn6PB/5z2d5zuG5sr85Vzn81ddapuUT9Ra
249+
/dB5eJQeFZ0WjtUOO3gS/A==
250+
-----END CERTIFICATE-----
251+
cmd: null
252+
extraEnv:
253+
JUPYTERHUB_SINGLEUSER_APP: "notebook.notebookapp.NotebookApp"
254+
RUCIO_MODE: "replica"
255+
RUCIO_WILDCARD_ENABLED: "1"
256+
RUCIO_BASE_URL: "https://vre-rucio.cern.ch"
257+
RUCIO_AUTH_URL: "https://vre-rucio-auth.cern.ch"
258+
RUCIO_DISPLAY_NAME: "VRE-RUCIO"
259+
RUCIO_NAME: "vre-rucio.cern.ch"
260+
RUCIO_SITE_NAME: "ROAMING"
261+
RUCIO_OIDC_AUTH: "env"
262+
RUCIO_OIDC_ENV_NAME: "REFRESH_TOKEN"
263+
RUCIO_DEFAULT_AUTH_TYPE: "oidc"
264+
RUCIO_OAUTH_ID: "rucio"
265+
RUCIO_DEFAULT_INSTANCE: "vre-rucio.cern.ch"
266+
RUCIO_DESTINATION_RSE: "CERN-EOS"
267+
RUCIO_RSE_MOUNT_PATH: "/eos/escape"
268+
RUCIO_PATH_BEGINS_AT: "5"
269+
RUCIO_CA_CERT: "/opt/cert.pem" # this could be set in the image as well
270+
ingress:
271+
enabled: true
272+
ingressClassName: nginx
273+
annotations:
274+
cert-manager.io/cluster-issuer: "letsencrypt" # this issues a certificate for the domain through cert-manager automatically
275+
hosts:
276+
- jhub-vre.cern.ch
277+
tls:
278+
- hosts:
279+
- jhub-vre.cern.ch
280+
secretName: cert-manager-tls-ingress-secret-jhub
281+

0 commit comments

Comments
 (0)