allow initializing groups from config

c.JupyterHub.load_groups creates groups and adds users to them.

It *does not* remove users from groups added previously.
This commit is contained in:
Min RK
2016-06-01 14:35:34 +02:00
parent 6d106b24f4
commit 503f21fd37
2 changed files with 51 additions and 2 deletions

View File

@@ -13,7 +13,6 @@ import socket
import sys import sys
import threading import threading
from datetime import datetime from datetime import datetime
from distutils.version import LooseVersion as V
from getpass import getuser from getpass import getuser
from subprocess import Popen from subprocess import Popen
from urllib.parse import urlparse from urllib.parse import urlparse
@@ -202,6 +201,17 @@ class JupyterHub(Application):
PAMAuthenticator, PAMAuthenticator,
]) ])
load_groups = Dict(List(Unicode()),
help="""Dict of 'group': ['usernames'] to load at startup.
This strictly *adds* groups and users to groups.
Loading one set of groups, then starting JupyterHub again with a different
set will not remove users or groups from previous launches.
That must be done through the API.
"""
).tag(config=True)
config_file = Unicode('jupyterhub_config.py', config_file = Unicode('jupyterhub_config.py',
help="The config file to load", help="The config file to load",
).tag(config=True) ).tag(config=True)
@@ -835,6 +845,27 @@ class JupyterHub(Application):
# From this point on, any user changes should be done simultaneously # From this point on, any user changes should be done simultaneously
# to the whitelist set and user db, unless the whitelist is empty (all users allowed). # to the whitelist set and user db, unless the whitelist is empty (all users allowed).
def init_groups(self):
"""Load predefined groups into the database"""
db = self.db
for name, usernames in self.load_groups.items():
group = orm.Group.find(db, name)
if group is None:
group = orm.Group(name=name)
db.add(group)
for username in usernames:
username = self.authenticator.normalize_username(username)
if not self.authenticator.check_whitelist(username):
raise ValueError("Username %r is not in whitelist" % username)
user = orm.User.find(db, name=username)
if user is None:
if not self.authenticator.validate_username(username):
raise ValueError("Group username %r is not valid" % username)
user = orm.User(name=username)
db.add(user)
group.users.append(user)
db.commit()
def init_api_tokens(self): def init_api_tokens(self):
"""Load predefined API tokens (for services) into database""" """Load predefined API tokens (for services) into database"""
db = self.db db = self.db
@@ -1129,6 +1160,7 @@ class JupyterHub(Application):
self.init_hub() self.init_hub()
self.init_proxy() self.init_proxy()
yield self.init_users() yield self.init_users()
self.init_groups()
self.init_api_tokens() self.init_api_tokens()
self.init_tornado_settings() self.init_tornado_settings()
yield self.init_spawners() yield self.init_spawners()

View File

@@ -140,3 +140,20 @@ def test_cookie_secret_env(tmpdir):
assert hub.cookie_secret == binascii.a2b_hex('abc123') assert hub.cookie_secret == binascii.a2b_hex('abc123')
assert not os.path.exists(hub.cookie_secret_file) assert not os.path.exists(hub.cookie_secret_file)
def test_load_groups(io_loop):
to_load = {
'blue': ['cyclops', 'rogue', 'wolverine'],
'gold': ['storm', 'jean-grey', 'colossus'],
}
hub = MockHub(load_groups=to_load)
hub.init_db()
io_loop.run_sync(hub.init_users)
hub.init_groups()
db = hub.db
blue = orm.Group.find(db, name='blue')
assert blue is not None
assert sorted([ u.name for u in blue.users ]) == sorted(to_load['blue'])
gold = orm.Group.find(db, name='gold')
assert gold is not None
assert sorted([ u.name for u in gold.users ]) == sorted(to_load['gold'])