Skip to content

Commit

Permalink
Merge pull request #203 from aaronkanzer/ak-linc
Browse files Browse the repository at this point in the history
Include environment configuration for LINC Hub
  • Loading branch information
asmacdo authored Oct 24, 2024
2 parents b2f344a + 36070cc commit ddde7ba
Show file tree
Hide file tree
Showing 5 changed files with 466 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ scripts/__pycache__/

# Env secrets
*.env

.DS_Store
98 changes: 98 additions & 0 deletions envs/linc/jupyterhub-overrides.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
hub:
config:
Authenticator:
admin_users:
- "asmacdo"
- "dandibot"
- "satra"
- "aaronkanzer"
- "kabilar"
extraConfig:
myConfig: |
# Python executed by jupyterhub at startup
import json
import os
import warnings
from kubernetes_asyncio import client
from oauthenticator.github import GitHubOAuthenticator
from tornado.httpclient import AsyncHTTPClient, HTTPClientError, HTTPRequest
def modify_pod_hook(spawner, pod): # noqa
pod.spec.containers[0].security_context = client.V1SecurityContext(privileged=True)
return pod
# define our OAuthenticator with `.pre_spawn_start`
# for passing auth_state into the user environment
# Based on <https://github.com/jupyterhub/oauthenticator/blob/master/examples/auth_state/jupyterhub_config.py>: # noqa
class IsDandiUserAuthenticator(GitHubOAuthenticator):
async def check_allowed(self, username, auth_model):
"""
Query DANDI API to ensure user is registered.
"""
if auth_model["auth_state"].get("scope", []):
scopes = []
for val in auth_model["auth_state"]["scope"]:
scopes.extend(val.split(","))
auth_model["auth_state"]["scope"] = scopes
auth_model = await self.update_auth_model(auth_model)
# Allowed if admin
if await super().check_allowed(username, auth_model):
return True
# Allowed if user is a registered DANDI user.
req = HTTPRequest(
f"${dandi_api_domain}/api/users/search/?username={username}", # noqa
method="GET",
headers={
"Accept": "application/json",
"User-Agent": "JupyterHub",
"Authorization": "token ${danditoken}",
},
validate_cert=self.validate_server_cert,
)
try:
client = AsyncHTTPClient()
print(f"Attempting to validate {username} with ${dandi_api_domain}") # noqa
resp = await client.fetch(req)
except HTTPClientError as e:
print(
f"Dandi API request to validate {username} returned HTTPClientError: {e}"
)
return False
else:
if resp.body:
resp_json = json.loads(resp.body.decode("utf8", "replace"))
for val in resp_json:
if val["username"].lower() == username.lower():
return True
# If not explicitly allowed, not allowed.
return False
async def pre_spawn_start(self, user, spawner):
auth_state = await user.get_auth_state()
if not auth_state:
# user has no auth state
return
# define some environment variables from auth_state
spawner.environment["GITHUB_TOKEN"] = auth_state["access_token"]
spawner.environment["GITHUB_USER"] = auth_state["github_user"]["login"]
spawner.environment["GITHUB_EMAIL"] = auth_state["github_user"]["email"]
c.KubeSpawner.modify_pod_hook = modify_pod_hook # noqa
c.JupyterHub.authenticator_class = IsDandiUserAuthenticator # noqa
c.GitHubOAuthenticator.enable_auth_state = True # noqa
singleuser:
lifecycleHooks:
postStart:
exec:
command:
- "sh"
- "-c"
- >
/opt/conda/envs/allen/bin/python -m ipykernel install --user --name allen --display-name "Python (Allen SDK)";
/opt/conda/bin/pip install --upgrade dandi;
/opt/conda/bin/pip install --upgrade lincbrain-cli;
git config --global user.email "$${GITHUB_EMAIL}";
git config --global user.name "$${GITHUB_USER}"
Loading

0 comments on commit ddde7ba

Please sign in to comment.