mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-14 05:23:01 +00:00
add proxy API
- GET fetches proxy table (relays same request to proxy's API endpoint) - POST prods routing table sync (useful when proxy restarts) - PATCH allows updating the proxy API location, auth token
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
from .base import *
|
||||
from .auth import *
|
||||
from .proxy import *
|
||||
from .users import *
|
||||
|
||||
from . import auth, users
|
||||
from . import auth, proxy, users
|
||||
|
||||
default_handlers = []
|
||||
for mod in (auth, users):
|
||||
for mod in (auth, proxy, users):
|
||||
default_handlers.extend(mod.default_handlers)
|
||||
|
68
jupyterhub/apihandlers/proxy.py
Normal file
68
jupyterhub/apihandlers/proxy.py
Normal file
@@ -0,0 +1,68 @@
|
||||
"""Proxy handlers"""
|
||||
|
||||
# Copyright (c) Jupyter Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import json
|
||||
|
||||
from tornado import gen, web
|
||||
|
||||
from .. import orm
|
||||
from ..utils import admin_only
|
||||
from .base import APIHandler
|
||||
|
||||
class ProxyAPIHandler(APIHandler):
|
||||
|
||||
@admin_only
|
||||
@gen.coroutine
|
||||
def get(self):
|
||||
"""GET /api/proxy fetches the routing table
|
||||
|
||||
This is the same as fetching the routing table directly from the proxy,
|
||||
but without clients needing to maintain separate
|
||||
"""
|
||||
routes = yield self.proxy.get_routes()
|
||||
self.write(json.dumps(routes))
|
||||
|
||||
@admin_only
|
||||
@gen.coroutine
|
||||
def post(self):
|
||||
"""POST checks the proxy to ensure"""
|
||||
yield self.proxy.check_routes()
|
||||
|
||||
|
||||
@admin_only
|
||||
@gen.coroutine
|
||||
def patch(self):
|
||||
"""PATCH updates the location of the proxy
|
||||
|
||||
Can be used to notify the Hub that a new proxy is in charge
|
||||
"""
|
||||
if not self.request.body:
|
||||
raise web.HTTPError(400, "need JSON body")
|
||||
|
||||
try:
|
||||
model = json.loads(self.request.body.decode('utf8', 'replace'))
|
||||
except ValueError:
|
||||
raise web.HTTPError(400, "Request body must be JSON dict")
|
||||
if not isinstance(model, dict):
|
||||
raise web.HTTPError(400, "Request body must be JSON dict")
|
||||
|
||||
server = self.proxy.api_server
|
||||
if 'ip' in model:
|
||||
server.ip = model['ip']
|
||||
if 'port' in model:
|
||||
server.port = model['port']
|
||||
if 'protocol' in model:
|
||||
server.proto = model['protocol']
|
||||
if 'auth_token' in model:
|
||||
self.proxy.auth_token = model['auth_token']
|
||||
self.db.commit()
|
||||
self.log.info("Updated proxy at %s", server.url)
|
||||
yield self.proxy.check_routes()
|
||||
|
||||
|
||||
|
||||
default_handlers = [
|
||||
(r"/api/proxy", ProxyAPIHandler),
|
||||
]
|
@@ -1,4 +1,4 @@
|
||||
"""Authorization handlers"""
|
||||
"""User handlers"""
|
||||
|
||||
# Copyright (c) Jupyter Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
@@ -275,3 +275,10 @@ def test_never_spawn(app, io_loop):
|
||||
assert not user.spawn_pending
|
||||
status = io_loop.run_sync(user.spawner.poll)
|
||||
assert status is not None
|
||||
|
||||
|
||||
def test_get_proxy(app, io_loop):
|
||||
r = api_request(app, 'proxy')
|
||||
r.raise_for_status()
|
||||
reply = r.json()
|
||||
assert list(reply.keys()) == ['/']
|
||||
|
Reference in New Issue
Block a user