Hello @manics,
This is my configuration:
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: jupyterhub
namespace: sandbox
spec:
values:
hub:
extraConfig:
spawner: |
#!/usr/bin/env python3
import json
import os
import sys
import base64
import time
import requests
from jupyterhub.handlers import LogoutHandler
from tornado import web
# install 'cognitojwt' packages to hub container - require to validate user claim
try:
import cognitojwt
except ImportError:
import subprocess
subprocess.call([sys.executable, "-m", "pip", "install", "wheel"])
subprocess.call([sys.executable, "-m", "pip", "install", "kubernetes"])
subprocess.call([sys.executable, "-m", "pip", "install", "--user", "cognitojwt[sync]"])
finally:
sys.path.append(os.path.expanduser('~') + "/.local/lib/python3.9/site-packages")
import cognitojwt
def enum(**enums):
return type('Enum', (), enums)
from kubernetes import client, config
async def verify_claims(self, user):
# Retrieve user authentication info, decode, and verify claims
try:
auth_state = await user.get_auth_state()
# self.log.info(f"auth_state: {auth_state}")
if auth_state is None:
raise ValueError("auth_state is empty")
verified_claims = cognitojwt.decode(
auth_state['access_token'],
os.getenv('COGNITO_REGION', 'us-west-2'),
os.getenv('JUPYTERHUB_USERPOOL_ID'),
testmode=False # Enable token expiration check
)
return verified_claims
except cognitojwt.CognitoJWTException as err:
self.log.error(f"Cliam verification issue: {err}")
raise web.HTTPError(401, "Session is expired!")
async def custom_options_form(self):
self.log.info(f"logged in user: {self.user.name}")
cognito_user_groups = enum(
DEVELOPMENT='dev-group',
DEFAULT='default-group',
NONE='None'
)
# setup default profile_list for all users
default_profile_list = [
{
'default': True,
'display_name': 'Default environment',
'description': '2 Cores, 16 GB Memory',
'kubespawner_override': {
'mem_guarantee': '14G',
'mem_limit': '14G',
'cpu_guarantee': 1.5,
'cpu_limit': 1.5,
'node_selector': {'nodesize': 'L'},
}
},
]
self.profile_list = default_profile_list
dev_profile_list = [
{
'default': False,
'display_name': 'Large environment - test',
'description': '4 Cores, 32 GB Memory',
'kubespawner_override': {
'mem_guarantee': '29G',
'mem_limit': '29G',
'cpu_guarantee': 3.5,
'cpu_limit': 3.5,
'node_selector': {'nodesize': 'XL'},
}
},
]
try:
# Read user access token to collect user group info
verified_claims = await verify_claims(self, self.user)
user_group_info = verified_claims.get('cognito:groups', [])
self.log.info(f"{self.user.name} user belongs to group(s): {(','.join(user_group_info))}")
# Use logic here to decide how to configure user profile_list based on user-group
if cognito_user_groups.DEVELOPMENT in user_group_info:
self.profile_list.extend(dev_profile_list)
# Set extra labels
# Add extra labels - labels are used for cilium network policy and cost
extra_labels = {
'username': '{username}',
'hub.jupyter.org/network-access-hub': 'true'
}
self.singleuser_extra_labels = extra_labels
# Return options_form - Let KubeSpawner inspect profile_list and decide what to return
return self._options_form_default()
except (TypeError, IndexError, ValueError, KeyError) as err:
self.log.error(f"Syntaxt error: {err}")
raise web.HTTPError(400, "Something went wrong. Coud not load profiles")
# Set the log level by value or name
c.JupyterHub.log_level = 'DEBUG'
# Set cookies - jupyterhub-session-id and jupyterhub-hub-login - to less than a day
c.Jupyterhub.cookie_max_age_days = 0.90
c.JupyterHub.tornado_settings['cookie_options'] = dict(expires_days=0.90)
# Enable debug-logging of the single-user server
c.Spawner.debug = True
# Enable debug-logging of the single-user server
c.LocalProcessSpawner.debug = False
c.Spawner.cmd = ['jupyterhub-singleuser']
# displays a notebook with information during the launch
c.Spawner.default_url = '/lab'
# Override spawner timeout - in seconds
c.KubeSpawner.start_timeout = 600
c.KubeSpawner.http_timeout = 60
# Override options_form
c.KubeSpawner.options_form = custom_options_form
templates: |
c.JupyterHub.logo_file = u'/etc/jupyterhub/custom/branding/logo-inline.svg'
Is there anything wrong with this config?