Skip to content

Commit

Permalink
Make allowed_groups available to everyone
Browse files Browse the repository at this point in the history
- `allowed_groups` functionality is put in basehub, and hence
  available to everyone! Individual authenticators still need to
  figure out how to enable groups, but that's separated out from
  `profile_list` filtering functionality.
- Pending jupyterhub/oauthenticator#735,
  we explicitly also treat GitHub teams from auth_state as 'groups'.
  This allows us to bring all our existing users along, without issue.
- Get rid of the code duplication in earthscope
- Rename all `allowed_teams` to `allowed_groups`.
  • Loading branch information
yuvipanda committed May 7, 2024
1 parent e944f88 commit 667f087
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 179 deletions.
2 changes: 1 addition & 1 deletion config/clusters/2i2c-aws-us/itcoocean.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ jupyterhub:
- display_name: "Bring your own image"
description: Specify your own docker image (must have python and jupyterhub installed in it)
slug: custom
allowed_teams:
allowed_groups:
- Hackweek-ITCOocean:itcoocean-hackweek-2023
- nmfs-opensci:2i2c-demo
- 2i2c-org:hub-access-for-2i2c-staff
Expand Down
16 changes: 8 additions & 8 deletions config/clusters/2i2c-aws-us/showcase.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ basehub:
profileList:
- display_name: "Magic Link Demo"
description: "For demoing magic links"
allowed_teams:
allowed_groups:
- 2i2c-community-showcase:magiclinks-demo
kubespawner_override:
image: pangeo/pangeo-notebook:2023.06.20
Expand All @@ -69,7 +69,7 @@ basehub:
node.kubernetes.io/instance-type: r5.xlarge
- display_name: "NASA TOPS-T ScienceCore-ClimateRisk"
description: "For collaborative work on 2i2c/MD's NASA TOPS-T ScienceCore Module"
allowed_teams:
allowed_groups:
- 2i2c-demo-hub-access:showcase-topst
- 2i2c-org:hub-access-for-2i2c-staff
- ScienceCore:climaterisk-team
Expand All @@ -82,7 +82,7 @@ basehub:
node.kubernetes.io/instance-type: r5.xlarge
- display_name: "NASA TOPS-T ScienceCore"
description: "JupyterHubs for NASA ScienceCore Modules"
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- ScienceCore:2i2c-showcase
profile_options:
Expand Down Expand Up @@ -132,7 +132,7 @@ basehub:
node.kubernetes.io/instance-type: r5.xlarge
- display_name: "Shared Small: 1-4 CPU, 8-32 GB"
description: "A shared machine, the recommended option until you experience a limitation."
allowed_teams: &allowed_teams
allowed_groups: &allowed_groups
- 2i2c-org:hub-access-for-2i2c-staff
- 2i2c-community-showcase:access-2i2c-showcase
profile_options: &profile_options
Expand Down Expand Up @@ -188,7 +188,7 @@ basehub:
- display_name: "Small: 4 CPU, 32 GB"
description: "A dedicated machine for you."
profile_options: *profile_options
allowed_teams: *allowed_teams
allowed_groups: *allowed_groups
kubespawner_override:
mem_guarantee: 28.937G
cpu_guarantee: 0.4
Expand All @@ -199,7 +199,7 @@ basehub:
- display_name: "Medium: 16 CPU, 128 GB"
description: "A dedicated machine for you."
profile_options: *profile_options
allowed_teams: *allowed_teams
allowed_groups: *allowed_groups
kubespawner_override:
mem_guarantee: 120.513G
cpu_guarantee: 1.6
Expand All @@ -210,7 +210,7 @@ basehub:
- display_name: "Large: 64 CPU, 512 GB"
description: "A dedicated machine for you"
profile_options: *profile_options
allowed_teams: *allowed_teams
allowed_groups: *allowed_groups
kubespawner_override:
mem_guarantee: 489.13G
cpu_guarantee: 6.4
Expand All @@ -220,7 +220,7 @@ basehub:

- display_name: NVIDIA Tesla T4, ~16 GB, ~4 CPUs
slug: gpu
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
description: "Start a container on a dedicated node with a GPU"
profile_options:
Expand Down
81 changes: 0 additions & 81 deletions config/clusters/earthscope/common.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,87 +98,6 @@ basehub:
c.GenericOAuthenticator.manage_groups = True
c.JupyterHub.authenticator_class = CustomGenericOAuthenticator
002-group-profiles: |
# Filters profileList based on group membership of JupyterHubs
from copy import deepcopy
from textwrap import dedent
from tornado import web
from functools import partial
async def profile_list_allowed_groups_filter(original_profile_list, spawner):
"""
Returns the initially configured profile_list filtered based on the
user's membership in each profile's `allowed_groups`. If
`allowed_groups` isn't set for a profile, its not filtered out.
`allowed_groups` is a list of JupyterHub groups.
If the returned profile_list is filtered to not include a profile,
an error is raised and the user isn't allowed to start a server.
"""
if spawner.user.name == "deployment-service-check":
print("Ignoring allowed_teams check for deployment-service-check")
return original_profile_list
groups = {g.name.casefold() for g in spawner.user.groups}
print(f"User {spawner.user.name} is part of groups {groups}")
# Filter out profiles with allowed_groups set if the user isn't part of any.
allowed_profiles = []
for orig_profile in original_profile_list:
profile = deepcopy(orig_profile)
if 'profile_options' in profile:
for k, po in profile['profile_options'].items():
if 'choices' in po:
new_choices = {}
for k, c in po['choices'].items():
if 'allowed_teams' not in c:
new_choices[k] = c
elif set(c['allowed_teams']) & groups:
new_choices[k] = c
po['choices'] = new_choices
allowed_groups = set(profile.get("allowed_groups"))
if allowed_groups is None:
# If no allowed_groups are set, allow access to everything
allowed_profiles.append(profile)
continue
if allowed_groups & groups:
print(f"Allowing profile {profile['display_name']} for user {spawner.user.name} based on group membership")
allowed_profiles.append(profile)
continue
if len(allowed_profiles) == 0:
# If no profiles are allowed, user should not be able to spawn anything!
# If we don't explicitly stop this, user will be logged into the 'default' settings
# set in singleuser, without any profile overrides. Not desired behavior
# FIXME: User doesn't actually see this error message, just the generic 403.
error_msg = dedent(f"""
Your Group team membership is insufficient to launch any server profiles.
GitHub teams you are a member of that this JupyterHub knows about are {', '.join(groups)}.
If you are part of additional teams, log out of this JupyterHub and log back in to refresh that information.
""")
raise web.HTTPError(403, error_msg)
return allowed_profiles
# Only set this customized profile_list *if* we already have a profile_list set
# otherwise, we'll show users a blank server options form and they won't be able to
# start their server
if c.KubeSpawner.profile_list:
# Customize list of profiles dynamically, rather than override options form.
# This is more secure, as users can't override the options available to them via the hub API
# We pass in a copy of the original profile_list set in config via partial, to reduce possible variable
# capture related issues.
c.KubeSpawner.profile_list = partial(
profile_list_allowed_groups_filter, deepcopy(c.KubeSpawner.profile_list)
)
config:
# JupyterHub:
# authenticator_class: auth0
Expand Down
8 changes: 4 additions & 4 deletions config/clusters/leap/common.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ basehub:
description: &profile_list_description "Start a container limited to a chosen share of capacity on a node of this type"
slug: medium-full
default: true
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- leap-stc:leap-pangeo-full-access
profile_options:
Expand Down Expand Up @@ -235,13 +235,13 @@ basehub:

# NOTE: This is the second medium profile list entry, with less node
# share options for a different subset of users via the basehub
# specific allowed_teams configuration.
# specific allowed_groups configuration.
#
- display_name: "CPU only"
description: *profile_list_description
slug: medium-base
default: true
allowed_teams:
allowed_groups:
- leap-stc:leap-pangeo-base-access
profile_options:
requests:
Expand All @@ -262,7 +262,7 @@ basehub:
- display_name: GPU
slug: gpu
description: NVIDIA Tesla T4, 24GB RAM, 8 CPUs
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- leap-stc:leap-pangeo-full-access
profile_options:
Expand Down
12 changes: 6 additions & 6 deletions config/clusters/meom-ige/common.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ basehub:
#
# - display_name: Grenoble demo
# default: true
# allowed_teams:
# allowed_groups:
# - 2i2c-org:hub-access-for-2i2c-staff
# - meom-group:hub-users # long term users
# - demo-dask-grenoble2023:demo # temporary users for event
Expand Down Expand Up @@ -93,7 +93,7 @@ basehub:
# RAM on a node, not total node capacity
- display_name: "Small"
default: true
allowed_teams: &allowed_teams_normal_use
allowed_groups: &allowed_groups_normal_use
- 2i2c-org:hub-access-for-2i2c-staff
- meom-group:hub-users # long term users
description: "~2 CPU, ~8G RAM"
Expand All @@ -103,31 +103,31 @@ basehub:
node_selector:
node.kubernetes.io/instance-type: n1-standard-2
- display_name: "Medium"
allowed_teams: *allowed_teams_normal_use
allowed_groups: *allowed_groups_normal_use
description: "~8 CPU, ~32G RAM"
kubespawner_override:
mem_limit: 32G
mem_guarantee: 22G
node_selector:
node.kubernetes.io/instance-type: n1-standard-8
- display_name: "Large"
allowed_teams: *allowed_teams_normal_use
allowed_groups: *allowed_groups_normal_use
description: "~16 CPU, ~64G RAM"
kubespawner_override:
mem_limit: 64G
mem_guarantee: 47G
node_selector:
node.kubernetes.io/instance-type: n1-standard-16
- display_name: "Very Large"
allowed_teams: *allowed_teams_normal_use
allowed_groups: *allowed_groups_normal_use
description: "~32 CPU, ~128G RAM"
kubespawner_override:
mem_limit: 128G
mem_guarantee: 100G
node_selector:
node.kubernetes.io/instance-type: n1-standard-32
- display_name: "Huge"
allowed_teams: *allowed_teams_normal_use
allowed_groups: *allowed_groups_normal_use
description: "~64 CPU, ~256G RAM"
kubespawner_override:
mem_limit: 256G
Expand Down
8 changes: 4 additions & 4 deletions config/clusters/nasa-cryo/common.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ basehub:
description: &profile_list_description "Start a container with at least a chosen share of capacity on a node of this type"
slug: small
default: true
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- CryoInTheCloud:cryoclouduser
- CryoInTheCloud:cryocloudadvanced
Expand Down Expand Up @@ -200,7 +200,7 @@ basehub:
- display_name: "Medium: up to 16 CPU / 128 GB RAM"
description: *profile_list_description
slug: medium
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- CryoInTheCloud:cryocloudadvanced
- CryoInTheCloud:ml-in-glaciology
Expand Down Expand Up @@ -268,7 +268,7 @@ basehub:
# - display_name: "Large: up to 64 CPU / 512 GB RAM"
# description: *profile_list_description
# slug: large
# allowed_teams:
# allowed_groups:
# - 2i2c-org:hub-access-for-2i2c-staff
# - CryoInTheCloud:cryocloudadvanced
# profile_options:
Expand Down Expand Up @@ -328,7 +328,7 @@ basehub:
- display_name: NVIDIA Tesla T4, ~16 GB, ~4 CPUs
description: "Start a container on a dedicated node with a GPU"
slug: "gpu"
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- CryoInTheCloud:ml-in-glaciology
profile_options:
Expand Down
8 changes: 4 additions & 4 deletions config/clusters/openscapes/common.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ basehub:
- display_name: Python
description: Python datascience environment
default: true
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- NASA-Openscapes:workshopaccess-2i2c # legacy but no plans to delete immediately until fledged
- NASA-Openscapes:longtermaccess-2i2c
Expand Down Expand Up @@ -128,7 +128,7 @@ basehub:
node.kubernetes.io/instance-type: r5.4xlarge
- display_name: R
description: R (with RStudio) + Python environment
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- NASA-Openscapes:workshopaccess-2i2c
- NASA-Openscapes:longtermaccess-2i2c
Expand All @@ -147,7 +147,7 @@ basehub:
profile_options: *profile_options
- display_name: Matlab
description: Matlab environment
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- NASA-Openscapes:workshopaccess-2i2c
- NASA-Openscapes:longtermaccess-2i2c
Expand All @@ -164,7 +164,7 @@ basehub:
- display_name: "Bring your own image"
description: Specify your own docker image (must have python and jupyterhub installed in it)
slug: custom
allowed_teams:
allowed_groups:
- NASA-Openscapes:longtermaccess-2i2c
- 2i2c-org:hub-access-for-2i2c-staff
# Requested in: https://2i2c.freshdesk.com/a/tickets/1284
Expand Down
8 changes: 4 additions & 4 deletions config/clusters/pangeo-hubs/common.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ basehub:
- display_name: "Small"
description: 5GB RAM, 2 CPUs
default: true
allowed_teams:
allowed_groups:
- pangeo-data:us-central1-b-gcp
- 2i2c-org:hub-access-for-2i2c-staff
kubespawner_override:
Expand All @@ -72,7 +72,7 @@ basehub:
node.kubernetes.io/instance-type: n1-standard-2
- display_name: Medium
description: 11GB RAM, 4 CPUs
allowed_teams:
allowed_groups:
- pangeo-data:us-central1-b-gcp
- 2i2c-org:hub-access-for-2i2c-staff
kubespawner_override:
Expand All @@ -82,7 +82,7 @@ basehub:
node.kubernetes.io/instance-type: n1-standard-4
- display_name: Large
description: 24GB RAM, 8 CPUs
allowed_teams:
allowed_groups:
- pangeo-data:cds-lab
- 2i2c-org:hub-access-for-2i2c-staff
kubespawner_override:
Expand All @@ -92,7 +92,7 @@ basehub:
node.kubernetes.io/instance-type: n1-standard-8
- display_name: Huge
description: 52GB RAM, 16 CPUs
allowed_teams:
allowed_groups:
- pangeo-data:cds-lab
- 2i2c-org:hub-access-for-2i2c-staff
kubespawner_override:
Expand Down
2 changes: 1 addition & 1 deletion config/clusters/smithsonian/common.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ basehub:
- display_name: NVIDIA Tesla T4, ~16 GB, ~4 CPUs
slug: gpu
description: "Start a container on a dedicated node with a GPU"
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- Smithsonian-SDCH:gpu-users
profile_options:
Expand Down
4 changes: 2 additions & 2 deletions docs/howto/features/allow-unlisted-profile-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ jupyterhub:
In some hubs, we don't want *everyone* to be able to specify an image - but
we do want some subset of users to be able to do so, for testing
purposes. This can be done by coupling `unlisted_choice` with
[`allowed_teams`](auth:github-orgs:profile-list).
[`allowed_groups`](auth:github-orgs:profile-list).

In the `profileList` for the hub in question, add a profile like this:

```yaml
- display_name: "Test custom image"
description: Test any custom image before rolling it out to rest of your users
slug: custom-image-only
allowed_teams:
allowed_groups:
- 2i2c-org:hub-access-for-2i2c-staff
- <other-github-teams>
profile_options:
Expand Down
Loading

0 comments on commit 667f087

Please sign in to comment.