diff --git a/infrastructure/cluster/flux/jhub-dev/jhub-dev-release.yaml b/infrastructure/cluster/flux/jhub-dev/jhub-dev-release.yaml new file mode 100644 index 0000000..ba8659d --- /dev/null +++ b/infrastructure/cluster/flux/jhub-dev/jhub-dev-release.yaml @@ -0,0 +1,248 @@ +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: jhub-dev + namespace: jhub-dev +spec: + releaseName: jhub-dev + interval: 5m + chart: + spec: + sourceRef: + kind: HelmRepository + name: jhub-dev + namespace: jhub-dev + chart: jupyterhub + interval: 5m + version: 3.3.7 + + valuesFrom: + - kind: Secret + name: jhub-dev-iam-secrets + valuesKey: client_id + #targetPath: hub.config.RucioAuthenticator.client_id + targetPath: hub.config.GenericOAuthenticator.client_id + - kind: Secret + name: jhub-dev-iam-secrets + valuesKey: client_secret + #targetPath: hub.config.RucioAuthenticator.client_secret + targetPath: hub.config.GenericOAuthenticator.client_secret + - kind: Secret + name: jhub-dev-db + valuesKey: dbfullstring + targetPath: hub.db.url + # - kind: ConfigMap + # name: jhub-profiles + # valuesKey: values.yaml + # - kind: Secret + # name: api-dask-dask-gateway + # valuesKey: jupyterhub-api-token + # targetPath: hub.services.dask-gateway.apiToken + + values: + proxy: + service: + type: ClusterIP + hub: + service: + type: ClusterIP + # network policy needs to be modified to allow access to the Rucio server + # (disabling it for now as a workaround, see also the ones for singeluser and proxy below) + networkPolicy: + enabled: false + db: + type: postgres # secret dbconnect string set in main-helm.tf + config: + JupyterHub: + authenticator_class: "generic-oauth" + GenericOAuthenticator: + #client_id: "" # set through secret + #client_secret: "" # set through secret + authorize_url: https://iam-escape.cloud.cnaf.infn.it/authorize + token_url: https://iam-escape.cloud.cnaf.infn.it/token + userdata_url: https://iam-escape.cloud.cnaf.infn.it/userinfo + username_key: preferred_username + scope: + - openid + - profile + - email + Authenticator: + admin_users: + - garcia + - gguerrie + # RucioAuthenticator: + # # client_id: "" # set through secret + # # client_secret: "" # set through secret + # authorize_url: https://iam-escape.cloud.cnaf.infn.it/authorize + # token_url: https://iam-escape.cloud.cnaf.infn.it/token + # userdata_url: https://iam-escape.cloud.cnaf.infn.it/userinfo + # username_key: preferred_username + # scope: + # - openid + # - profile + # - email + + # extraConfig: + # token-exchange: | + # import pprint + # import os + # import warnings + # import requests + # from oauthenticator.generic import GenericOAuthenticator + + # # custom authenticator to enable auth_state and get access token to set as env var for rucio extension + # class RucioAuthenticator(GenericOAuthenticator): + # def __init__(self, **kwargs): + # super().__init__(**kwargs) + # self.enable_auth_state = True + + # def exchange_token(self, token): + # params = { + # 'client_id': self.client_id, + # 'client_secret': self.client_secret, + # 'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange', + # 'subject_token': token, + # 'scope': 'openid profile', + # 'audience': 'rucio' + # } + # response = requests.post(self.token_url, data=params) + # rucio_token = response.json()['access_token'] + # return rucio_token + + # async def pre_spawn_start(self, user, spawner): + # auth_state = await user.get_auth_state() + # pprint.pprint(auth_state) + # if not auth_state: + # # user has no auth state + # return + + # # define token environment variable from auth_state + # spawner.environment['RUCIO_ACCESS_TOKEN'] = self.exchange_token(auth_state['access_token']) + # spawner.environment['EOS_ACCESS_TOKEN'] = auth_state['access_token'] + + # # set the above authenticator as the default + # c.JupyterHub.authenticator_class = RucioAuthenticator + + # # enable authentication state + # c.GenericOAuthenticator.enable_auth_state = True + + # if 'JUPYTERHUB_CRYPT_KEY' not in os.environ: + # warnings.warn( + # "Need JUPYTERHUB_CRYPT_KEY env for persistent auth_state.\n" + # " export JUPYTERHUB_CRYPT_KEY=$(openssl rand -hex 32)" + # ) + # c.CryptKeeper.keys = [os.urandom(32)] + + singleuser: + defaultUrl: "/lab" + # The liefcycle hooks are used to create the Rucio configuration file, + # and the token file by copying the REFRESH_TOKEN from the environment variable to the token file. + # lifecycleHooks: + # postStart: + # exec: + # command: + # - "sh" + # - "-c" + # - > + # mkdir -p /certs /tmp; + # echo -n $RUCIO_ACCESS_TOKEN > /tmp/rucio_oauth.token; + # echo -n "oauth2:${EOS_ACCESS_TOKEN}:iam-escape.cloud.cnaf.infn.it/userinfo" > /tmp/eos_oauth.token; + # chmod 0600 /tmp/eos_oauth.token; + # mkdir -p /opt/rucio/etc; + # echo "[client]" >> /opt/rucio/etc/rucio.cfg; + # echo "rucio_host = https://vre-rucio.cern.ch" >> /opt/rucio/etc/rucio.cfg; + # echo "auth_host = https://vre-rucio-auth.cern.ch" >> /opt/rucio/etc/rucio.cfg; + # echo "ca_cert = /certs/rucio_ca.pem" >> /opt/rucio/etc/rucio.cfg; + # echo "account = $JUPYTERHUB_USER" >> /opt/rucio/etc/rucio.cfg; + # echo "auth_type = oidc" >> /opt/rucio/etc/rucio.cfg; + # echo "oidc_audience = rucio" >> /opt/rucio/etc/rucio.cfg; + # echo "oidc_polling = true" >> /opt/rucio/etc/rucio.cfg; + # echo "auth_token_file_path = /tmp/rucio_oauth.token" >> /opt/rucio/etc/rucio.cfg; + + networkPolicy: + enabled: false + storage: + type: static + static: + pvcName: jhub-dev-pvc + extraVolumes: + - name: cvmfs-vre-dev + persistentVolumeClaim: + claimName: cvmfs-pvc + # - name: eulake-cern-eos-rse # mounts the EOS RSE needed for the Rucio JupiterLab extension + # hostPath: + # path: /var/eos/eulake # This is pointing to /eos/eulake/escape/data, defined on the eosxd/configmap + extraVolumeMounts: + - name: cvmfs-vre-dev + mountPath: /cvmfs + # CVMFS automount volumes must be mounted with HostToContainer mount propagation. + mountPropagation: HostToContainer + # - name: eulake-cern-eos-rse # mounts the EOS RSE needed for the Rucio JupiterLab extension + # mountPath: /eos/cern-eos-rse + # mountPropagation: HostToContainer + # readOnly: true + image: + name: quay.io/jupyter/scipy-notebook + tag: python-3.11.8 + # name: jupyter/scipy-notebook + # tag: python-3.10.11 + # name: ghcr.io/vre-hub/vre-singleuser-py311 + # tag: latest + pullPolicy: Always + profileList: + - display_name: "Python 3.11 environment" + description: "quay.io/jupyter/scipy-notebook:python-3.11.8 image " + default: true + - display_name: "Python 3.10 environment" + description: "quay.io/jupyter/scipy-notebook:python-3.10.11 image " + kubespawner_override: + image: jupyter/scipy-notebook:python-3.10.11 + - display_name: "VRE and rucio extension integration" + description: "python3.11 and Rucio extension integration " + kubespawner_override: + image: ghcr.io/vre-hub/vre-singleuser-py311:latest + + # nodeSelector: + # jupyter: singleuser + # extraTolerations: + # - key: jupyter + # operator: Equal + # value: singleuser + # effect: NoSchedule + # memory: + # limit: 3.5G #4G + # guarantee: 3G #2G + + cmd: null + extraEnv: + + # RUCIO_WILDCARD_ENABLED: "1" + # RUCIO_BASE_URL: "https://vre-rucio.cern.ch" + # RUCIO_AUTH_URL: "https://vre-rucio-auth.cern.ch" + # RUCIO_WEBUI_URL: "https://vre-rucio-ui.cern.ch" + # RUCIO_DISPLAY_NAME: "RUCIO - CERN VRE" + # RUCIO_NAME: "vre-rucio.cern.ch" + # RUCIO_SITE_NAME: "CERN" + # RUCIO_OIDC_AUTH: "env" + # RUCIO_OIDC_ENV_NAME: "RUCIO_ACCESS_TOKEN" + # RUCIO_DEFAULT_AUTH_TYPE: "oidc" + # RUCIO_OAUTH_ID: "rucio" + # RUCIO_DEFAULT_INSTANCE: "vre-rucio.cern.ch" + # RUCIO_DESTINATION_RSE: "CERN-EOS" + # RUCIO_RSE_MOUNT_PATH: "/eos/cern-eos-rse" + # RUCIO_PATH_BEGINS_AT: "2" + # RUCIO_CA_CERT: "/certs/rucio_ca.pem" + # OAUTH2_TOKEN: "FILE:/tmp/eos_oauth.token" + + ingress: + enabled: true + ingressClassName: nginx + annotations: + cert-manager.io/cluster-issuer: "letsencrypt" # this issues a certificate for the domain through cert-manager automatically + hosts: + - jhub-vre-dev.cern.ch + tls: + - hosts: + - jhub-vre-dev.cern.ch + secretName: cert-manager-tls-ingress-secret-jhub-dev +