From 85e979f912644f109bf52e7730eadba900e41491 Mon Sep 17 00:00:00 2001 From: GeorgianaElena Date: Fri, 31 May 2019 15:53:14 +0300 Subject: [PATCH] Updated docs with info about TraefikConsulProxy --- docs/source/consul.md | 261 ++++++++++++++++++ docs/source/etcd.md | 41 ++- docs/source/index.rst | 12 +- docs/source/install.md | 116 ++++++-- jupyterhub_traefik_proxy/kv_proxy.py | 11 +- setup.py | 1 + tests/config_files/traefik_consul_config.toml | 2 +- 7 files changed, 391 insertions(+), 53 deletions(-) create mode 100644 docs/source/consul.md diff --git a/docs/source/consul.md b/docs/source/consul.md new file mode 100644 index 00000000..9e2ff47d --- /dev/null +++ b/docs/source/consul.md @@ -0,0 +1,261 @@ +# Using traefik-proxy with consul + +[Consul](https://www.consul.io/) +is a distributed key-value store. +This and TraefikEtcdProxy is the choice to use when using jupyterhub-traefik-proxy +in a distributed setup, such as a Kubernetes cluster, +e.g. with multiple traefik-proxy instances. + +## How-To install TraefikConsulProxy + +3. Install **jupyterhub** +2. Install **jupyterhub-traefik-proxy** +3. Install **traefik** +4. Install **consul** + +* You can find the full installation guide and examples in the [Introduction section](install.html#traefik-proxy-installation) + +## How-To enable TraefikConsulProxy + +You can enable JupyterHub to work with `TraefikConsulProxy` in jupyterhub_config.py, +using the `proxy_class` configuration option. + +You can choose to: + +* use the `traefik_consul` entrypoint, new in JupyterHub 1.0, e.g.: + + ``` + c.JupyterHub.proxy_class = "traefik_consul" + ``` + +* use the TraefikConsulProxy object, in which case, you have to import the module, e.g.: + + ``` + from jupyterhub_traefik_proxy import TraefikConsulProxy + c.JupyterHub.proxy_class = TraefikConsulProxy + ``` + +## Consul configuration + +1. Depending on the value of the ```should_start``` proxy flag, you can choose whether or not TraefikConsulProxy willl be externally managed. + + * When **should_start** is set to **True**, TraefikConsulProxy will auto-generate its static configuration + (using the override values or the defaults) and store it in ```traefik.toml``` file. + The traefik process will then be launched using this file. + * When **should_start** is set to **False**, prior to starting the traefik process, you must create a *toml* file with the desired + traefik static configuration and pass it to traefik. Keep in mind that in order for the routes to be stored in **consul**, + this *toml* file **must** specify consul as the provider. + +2. TraefikConsulProxy searches in the consul key-value store the keys starting with the **kv_traefik_prefix** prefix in order to build its static configuration. + + Similarly, the dynamic configuration is built by searching the **kv_jupyterhub_prefix**. + + **Note**: If you want to change or add traefik's static configuration options, you can add them to consul under this prefix and traefik will pick them up. + + * The **default** values of this configurations options are: + ``` + kv_traefik_prefix = "traefik/" + kv_jupyterhub_prefix = "jupyterhub/" + ``` + + * You can **override** the default values of the prefixes by passing their desired values through `jupyterhub_config.py` e.g.: + ``` + c.TraefikConsulProxy.kv_traefik_prefix="some_static_config_prefix/" + c.TraefikConsulProxy.kv_jupyterhub_prefix="some_dynamic_config_prefix/" + ``` + +3. By **default**, TraefikConsulProxy assumes consul accepts client requests on the official **default** consul port `8500` for client requests. + + ``` + c.TraefikConsulProxy.kv_url="http://127.0.0.1:8500" + ``` + + If the consul cluster is deployed differently than using the consul defaults, then you **must** pass the consul url to the proxy using + the `kv_url` option in *jupyterhub_config.py*: + + ``` + c.TraefikConsulProxy.kv_url="scheme://hostname:port" + ``` + +--- +**Note 1** + + **TraefikConsulProxy does not manage the consul cluster** and assumes it is up and running before the proxy itself starts. + + However, based on how consul is configured and started, TraefikConsulProxy needs to be told about + some consul configuration details, such as: + * consul **address** where it accepts client requests + ``` + c.TraefikConsulProxy.kv_url="scheme://hostname:port" + ``` + * consul **credentials** (if consul has acl enabled) + ``` + c.TraefikConsulProxy.kv_password="123" + ``` + +Checkout the [consul documentation](https://learn.hashicorp.com/consul/) +to find out more about possible consul configuration options. + +## Externally managed TraefikConsulProxy + +If TraefikConsulProxy is used as an externally managed service, then make sure you follow the steps enumerated below: + +1. Let JupyterHub know that the proxy being used is TraefikConsulProxy, using the *proxy_class* configuration option: + ``` + c.JupyterHub.proxy_class = "traefik_consul" + ``` + +2. Configure `TraefikConsulProxy` in **jupyterhub_config.py** + + JupyterHub configuration file, *jupyterhub_config.py* must specify at least: + * That the proxy is externally managed + * The traefik api credentials + * The consul credentials (if consul acl is enabled) + + Example configuration: + ``` + # JupyterHub shouldn't start the proxy, it's already running + c.TraefikConsulProxy.should_start = False + + # if not the default: + c.TraefikConsulProxy.kv_url = "http://consul-host:2379" + + # traefik api credentials + c.TraefikConsulProxy.traefik_api_username = "abc" + c.TraefikConsulProxy.traefik_api_password = "123" + + # consul acl token + c.TraefikConsulProxy.kv_password = "456" + ``` + +3. Create a *toml* file with traefik's desired static configuration + + Before starting the traefik process, you must create a *toml* file with the desired + traefik static configuration and pass it to traefik when you launch the process. + Keep in mind that in order for the routes to be stored in **consul**, + this *toml* file **must** specify consul as the provider/ + + * **Keep in mind that the static configuration must configure at least:** + * The default entrypoint + * The api entrypoint (*and authenticate it*) + * The websockets protocol + * The consul endpoint + + Example: + + ``` + defaultentrypoints = ["http"] + debug = true + logLevel = "ERROR" + + [api] + dashboard = true + entrypoint = "auth_api" + + [wss] + protocol = "http" + + [entryPoints.http] + address = "127.0.0.1:8000" + + [entryPoints.auth_api] + address = "127.0.0.1:8099" + + [entryPoints.auth_api.auth.basic] + users = [ "abc:$apr1$eS/j3kum$q/X2khsIEG/bBGsteP.x./",] + + [consul] + endpoint = "127.0.0.1:8500" + prefix = "traefik/" + watch = true + ``` + + **Note**: **If you choose to enable consul Access Control Lists (ACLs) to secure the UI, API, CLI, service communications, and agent communications**, you can use this *toml* file to pass the credentials to traefik, e.g.: + + ``` + [consul] + password = "admin" + ... + ``` + +## Example setup + +This is an example setup for using JupyterHub and TraefikConsulProxy managed by another service than JupyterHub. + +1. Configure the proxy through the JupyterHub configuration file, *jupyterhub_config.py*, e.g.: + + ``` + from jupyterhub_traefik_proxy import TraefikConsulProxy + + # mark the proxy as externally managed + c.TraefikConsulProxy.should_start = False + + # traefik api endpoint login password + c.TraefikConsulProxy.traefik_api_password = "abc" + + # traefik api endpoint login username + c.TraefikConsulProxy.traefik_api_username = "123" + + # consul url where it accepts client requests + c.TraefikConsulProxy.kv_url = "path/to/rules.toml" + + # configure JupyterHub to use TraefikConsulProxy + c.JupyterHub.proxy_class = TraefikConsulProxy + ``` + + **Note:** If you intend to enable consul acl, add the acl token to *jupyterhub_config.py* under *kv_password*: + + ``` + # consul token + c.TraefikConsulProxy.kv_password = "456" + ``` + +2. Starts the agent in development mode on the default port on localhost. e.g.: + ``` + $ consul agent -dev + ``` + **Note:** If you intend to enable consul acl, checkout + [this guide](https://learn.hashicorp.com/consul/security-networking/production-acls): + +3. Create a traefik static configuration file, *traefik.toml*, e.g:. + + ``` + # the default entrypoint + defaultentrypoints = ["http"] + + # the api entrypoint + [api] + dashboard = true + entrypoint = "auth_api" + + # websockets protocol + [wss] + protocol = "http" + + # the port on localhost where traefik accepts http requests + [entryPoints.http] + address = ":8000" + + # the port on localhost where the traefik api and dashboard can be found + [entryPoints.auth_api] + address = ":8099" + + # authenticate the traefik api entrypoint + [entryPoints.auth_api.auth.basic] + users = [ "abc:$apr1$eS/j3kum$q/X2khsIEG/bBGsteP.x./",] + + [consul] + # the consul acl token (if acl is enabled) + password = "456" + # the consul address + endpoint = "127.0.0.1:8500" + # the prefix to use for the static configuration + prefix = "traefik/" + # watch consul for changes + watch = true + ``` + +4. Start traefik with the configuration specified above, e.g.: + ``` + $ traefik -c traefik.toml + ``` diff --git a/docs/source/etcd.md b/docs/source/etcd.md index 53c2f613..742b44de 100644 --- a/docs/source/etcd.md +++ b/docs/source/etcd.md @@ -2,7 +2,7 @@ [Etcd](https://coreos.com/etcd/) is a distributed key-value store. -This is the choice to use when using jupyterhub-traefik-proxy +This and TraefikConsulProxy is the choice to use when using jupyterhub-traefik-proxy in a distributed setup, such as a Kubernetes cluster, e.g. with multiple traefik-proxy instances. @@ -46,35 +46,35 @@ You can choose to: traefik static configuration and pass it to traefik. Keep in mind that in order for the routes to be stored in **etcd**, this *toml* file **must** specify etcd as the provider. -2. TraefikEtcdProxy searches the etcd key-value store after the **etcd_traefik_prefix** prefix for its static configuration. +2. TraefikEtcdProxy searches in the etcd key-value store the keys starting with the **kv_traefik_prefix** prefix in order to build its static configuration. - Similarly, the dynamic configuration is searched after the **etcd_jupyterhub_prefix**. + Similarly, the dynamic configuration is built by searching the **kv_jupyterhub_prefix**. **Note**: If you want to change or add traefik's static configuration options, you can add them to etcd under this prefix and traefik will pick them up. * The **default** values of this configurations options are: ``` - etcd_traefik_prefix = "/traefik/" - etcd_jupyterhub_prefix = "/jupyterhub/" + kv_traefik_prefix = "/traefik/" + kv_jupyterhub_prefix = "/jupyterhub/" ``` * You can **override** the default values of the prefixes by passing their desired values through `jupyterhub_config.py` e.g.: ``` - c.TraefikEtcdProxy.etcd_traefik_prefix="/some_static_config_prefix/" - c.TraefikEtcdProxy.etcd_jupyterhub_prefix="/some_dynamic_config_prefix/" + c.TraefikEtcdProxy.kv_traefik_prefix="/some_static_config_prefix/" + c.TraefikEtcdProxy.kv_jupyterhub_prefix="/some_dynamic_config_prefix/" ``` 3. By **default**, TraefikEtcdProxy assumes etcd accepts client requests on the official **default** etcd port `2379` for client requests. ``` - c.TraefikEtcdProxy.etcd_url="http://127.0.0.1:2379" + c.TraefikEtcdProxy.kv_url="http://127.0.0.1:2379" ``` If the etcd cluster is deployed differently than using the etcd defaults, then you **must** pass the etcd url to the proxy using - the `etcd_url` option in *jupyterhub_config.py*: + the `kv_url` option in *jupyterhub_config.py*: ``` - c.TraefikEtcdProxy.etcd_url="scheme://hostname:port" + c.TraefikEtcdProxy.kv_url="scheme://hostname:port" ``` --- @@ -86,12 +86,12 @@ You can choose to: some etcd configuration details, such as: * etcd **address** where it accepts client requests ``` - c.TraefikEtcdProxy.etcd_url="scheme://hostname:port" + c.TraefikEtcdProxy.kv_url="scheme://hostname:port" ``` * etcd **credentials** (if etcd has authentication enabled) ``` - c.TraefikEtcdProxy.etcd_username="abc" - c.TraefikEtcdProxy.etcd_password="123" + c.TraefikEtcdProxy.kv_username="abc" + c.TraefikEtcdProxy.kv_password="123" ``` **Note 2** @@ -113,7 +113,7 @@ If TraefikEtcdProxy is used as an externally managed service, then make sure you c.JupyterHub.proxy_class = "traefik_etcd" ``` -2. Configure `TraeficEtcdProxy` in **jupyterhub_config.py** +2. Configure `TraefikEtcdProxy` in **jupyterhub_config.py** JupyterHub configuration file, *jupyterhub_config.py* must specify at least: * That the proxy is externally managed @@ -126,15 +126,15 @@ If TraefikEtcdProxy is used as an externally managed service, then make sure you c.TraefikEtcdProxy.should_start = False # if not the default: - c.TraefikEtcdProxy.etcd_url = "http://etcd-host:2379" + c.TraefikEtcdProxy.kv_url = "http://etcd-host:2379" # traefik api credentials c.TraefikEtcdProxy.traefik_api_username = "abc" c.TraefikEtcdProxy.traefik_api_password = "123" # etcd credentials - c.TraefikEtcdProxy.etcd_username = "def" - c.TraefikEtcdProxy.etcd_password = "456" + c.TraefikEtcdProxy.kv_username = "def" + c.TraefikEtcdProxy.kv_password = "456" ``` 3. Create a *toml* file with traefik's desired static configuration @@ -178,7 +178,6 @@ If TraefikEtcdProxy is used as an externally managed service, then make sure you prefix = "/jupyterhub" useapiv3 = true watch = true - providersThrottleDuration = 1 ``` **Note**: **If you choose to enable the authentication on etcd**, you can use this *toml* file to pass the credentials to traefik, e.g.: @@ -210,7 +209,7 @@ This is an example setup for using JupyterHub and TraefikEtcdProxy managed by an c.TraefikEtcdProxy.traefik_api_username = "123" # etcd url where it accepts client requests - c.TraefikEtcdProxy.etcd_url = "path/to/rules.toml" + c.TraefikEtcdProxy.kv_url = "path/to/rules.toml" # configure JupyterHub to use TraefikEtcdProxy c.JupyterHub.proxy_class = TraefikEtcdProxy @@ -220,10 +219,10 @@ This is an example setup for using JupyterHub and TraefikEtcdProxy managed by an ``` # etcd username - c.TraefikEtcdProxy.etcd_username = "def" + c.TraefikEtcdProxy.kv_username = "def" # etcd password - c.TraefikEtcdProxy.etcd_password = "456" + c.TraefikEtcdProxy.kv_password = "456" ``` 2. Start a single-note etcd cluster on the default port on localhost. e.g.: diff --git a/docs/source/index.rst b/docs/source/index.rst index ee8cb586..6d7a53d2 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,13 +16,16 @@ Why traefik? Currently, the **default** proxy implementation for JupyterHub is `configurable-http-proxy `__ (CHP), which stores the routing table in-memory. This might be the best approach in most of the cases, but because you can only run a single copy of the proxy at a time, it has its limitations when used in dynamic large scale systems. -When using a proxy implementation based on traefik, you can run multiple instances of traefik by using a distributed key-value store like `etcd `__ to store the routing table. This makes the proxy **highly available** and improves the scalability and stability of the system. +When using a proxy implementation based on traefik, you can run multiple instances of traefik by using a distributed key-value store like `etcd `__ or `consul `__ to store the routing table. This makes the proxy **highly available** and improves the scalability and stability of the system. Moreover it offers *HTTPS* support through a straight-forward `ACME (Let's Encrypt) `__ configuration. -There are two versions for the proxy, depending on how traefik stores the routes: +There are three versions for the proxy, depending on how traefik stores the routes: -* TraefikTomlProxy - *for* **smaller**, *single-node deployments* -* TraefikEtcdProxy - *for* **distributed** *setups* +* *for* **smaller**, *single-node deployments*: + * TraefikTomlProxy +* *for* **distributed** *setups*: + * TraefikEtcdProxy + * TraefikConsulProxy Contents ======== @@ -40,6 +43,7 @@ Getting Started toml etcd + consul API Reference ------------- diff --git a/docs/source/install.md b/docs/source/install.md index 79d2cd2d..28ca1718 100644 --- a/docs/source/install.md +++ b/docs/source/install.md @@ -14,9 +14,9 @@ python3 -m pip install jupyterhub-traefik-proxy ``` -3. In order to be able to launch JupyterHub with traefik-proxy or run the tests, **traefik** and **etcd** must first be installed and added to your `PATH`. +3. In order to be able to launch JupyterHub with traefik-proxy or run the tests, **traefik**, **etcd** and **consul** must first be installed and added to your `PATH`. - There are two ways you can install traefik and etcd: + There are two ways you can install traefik, etcd and consul: 1. Through traefik-proxy's **install utility**. @@ -26,7 +26,7 @@ $ python3 -m jupyterhub_traefik_proxy.install --output=/usr/local/bin ``` - This will install the default versions of traefik and etcd, namely `traefik-1.7.5` and `etcd-3.3.10` to `/usr/local/bin` specified through the `--output` option. + This will install the default versions of traefik, etcd and consul, namely `traefik-1.7.5`, `etcd-3.3.10` and `consul_1.5.0` to `/usr/local/bin` specified through the `--output` option. If no directory is passed to the installer, a *dependencies* directory will be created in the `traefik-proxy` directory. In this case, you **must** add this directory to `PATH`, e.g. @@ -34,28 +34,31 @@ $ export PATH=$PATH:{$PWD}/dependencies ``` - If you want to install other versions of traefik and etcd in a directory of your choice, just specify it to the installer through the following arguments: + If you want to install other versions of traefik, etcd and consul in a directory of your choice, just specify it to the installer through the following arguments: * `--traefik-version` * `--etcd-version` + * `--consul-version` * `--output` Example ``` $ python3 -m jupyterhub_traefik_proxy.install --output=dep \ - --traefik-version=1.6.6 --etcd-version=3.2.24 + --traefik-version=1.6.6 --etcd-version=3.2.24 --consul-version=1.5.0 ``` If the desired install directory doesn't exist, it will be created by the installer. - 2. From traefik and etcd **release pages**: + 2. From traefik, etcd and consul **release pages**: * Install [`traefik`](https://traefik.io/#easy-to-install) - * Install [`etcd`](https://traefik.io/#easy-to-install) + * Install [`etcd`](https://github.com/etcd-io/etcd/releases) + + * Install [`consul`](https://github.com/hashicorp/consul/releases) ## Enabling traefik-proxy in JupyterHub -[TraefikEtcdProxy](https://github.com/jupyterhub/traefik-proxy/blob/master/jupyterhub_traefik_proxy/etcd.py) and [TraefikTomlProxy](https://github.com/jupyterhub/traefik-proxy/blob/master/jupyterhub_traefik_proxy/toml.py) are custom proxy implementations that subclass [Proxy](https://github.com/jupyterhub/jupyterhub/blob/master/jupyterhub/proxy.py) and can register in JupyterHub config using `c.JupyterHub.proxy_class` entrypoint. +[TraefikTomlProxy](https://github.com/jupyterhub/traefik-proxy/blob/master/jupyterhub_traefik_proxy/toml.py), [TraefikEtcdProxy](https://github.com/jupyterhub/traefik-proxy/blob/master/jupyterhub_traefik_proxy/etcd.py) and [TraefikConsulProxy](https://github.com/jupyterhub/traefik-proxy/blob/master/jupyterhub_traefik_proxy/consul.py) are custom proxy implementations that subclass [Proxy](https://github.com/jupyterhub/jupyterhub/blob/master/jupyterhub/proxy.py) and can register in JupyterHub config using `c.JupyterHub.proxy_class` entrypoint. On startup, JupyterHub will look by default for a configuration file, *jupyterhub_config.py*, in the current working directory. If the configuration file is not in the current working directory, you can load a specific config file and start JupyterHub using: @@ -68,6 +71,11 @@ There is an example configuration file [here](https://github.com/jupyterhub/trae In *jupyterhub_config.py*: +``` +c.JupyterHub.proxy_class = "traefik_toml" +# will configure JupyterHub to run with TraefikTomlProxy +``` + ``` c.JupyterHub.proxy_class = "traefik_etcd" # will configure JupyterHub to run with TraefikEtcdProxy @@ -75,25 +83,95 @@ c.JupyterHub.proxy_class = "traefik_etcd" ``` ``` -c.JupyterHub.proxy_class = "traefik_toml" -# will configure JupyterHub to run with TraefikTomlProxy +c.JupyterHub.proxy_class = "traefik_consul" +# will configure JupyterHub to run with TraefikConsulProxy + ``` ## Implementation details -Traefik provides a Web UI **dashboard** where you can see the frontends and backends registered, the routing rules, some metrics, but also other configuration elements. Find out more about traefik api's, [here](https://docs.traefik.io/configuration/api/#security). +1. **Traefik Dashboard** -Because of **security** concerns, in traefik-proxy implementation, traefik api endpoint isn't exposed on the public http endpoint. Instead, it runs on a dedicated **authenticated endpoint** that's on localhost by default. + Traefik provides a Web UI **dashboard** where you can see the frontends and backends registered, the routing rules, some metrics, but also other configuration elements. Find out more about traefik api's, [here](https://docs.traefik.io/configuration/api/#security). -The port on which traefik-proxy's api will run, as well as the username and password used for authenticating, can be passed to the proxy through `jupyterhub_config.py`, e.g.: + Because of **security** concerns, in traefik-proxy implementation, traefik api endpoint isn't exposed on the public http endpoint. Instead, it runs on a dedicated **authenticated endpoint** that's on localhost by default. -``` -c.TraefikTomlProxy.traefik_api_url = "http://127.0.0.1:8099" -c.TraefikTomlProxy.traefik_api_password = "admin" -c.TraefikTomlProxy.traefik_api_username = "admin" -``` + The port on which traefik-proxy's api will run, as well as the username and password used for authenticating, can be passed to the proxy through `jupyterhub_config.py`, e.g.: -Check out TraefikProxy's **API Reference** for more configuration options. + ``` + c.TraefikTomlProxy.traefik_api_url = "http://127.0.0.1:8099" + c.TraefikTomlProxy.traefik_api_password = "admin" + c.TraefikTomlProxy.traefik_api_username = "admin" + ``` + Check out TraefikProxy's **API Reference** for more configuration options. +

+2. **TKvProxy class** + + TKvProxy is a JupyterHub Proxy implementation that uses traefik and a key-value store. + **TraefikEtcdProxy** and **TraefikConsulProxy** are proxy implementations that sublass `TKvProxy`. + Other custom proxies that wish to implementat a JupyterHub Trafik KV store Proxy can sublass `TKvProxy`. + **TKvProxy** implements JupyterHub's Proxy public API and there is no need to override these public methods. + The methods that **must be implemented** by the proxies that sublass `TKvProxy` are: + * ***_define_kv_specific_static_config()*** + * Define the traefik static configuration that configures + traefik's communication with the key-value store. + * Will be called during startup if should_start is True. + * Subclasses must define this method if the proxy is to be started by the Hub. + * In order to be picked up by the proxy, the static configuration + must be stored into `proxy.static_config` dict under the `kv_name` key. + * ***_kv_atomic_add_route_parts(jupyterhub_routespec, target, data, route_keys, rule)*** + * Add the key-value pairs associated with a route within a key-value store transaction. + * Will be called during add_route. + * When retrieving or deleting a route, the parts of a route are expected to have the following structure: + ``` + [ key: jupyterhub_routespec , value: target ] + [ key: target , value: data ] + [ key: route_keys.backend_url_path , value: target ] + [ key: route_keys.frontend_rule_path , value: rule ] + [ key: route_keys.frontend_backend_path, value: route_keys.backend_alias] + [ key: route_keys.backend_weight_path , value: w(int) ] + # where w is the weight of the backend to be used during load balancing) + ``` + * Returns: + * result (tuple): + * The transaction status (int, 0: failure, positive: success) + * The transaction response(str) + * ***_kv_atomic_delete_route_parts(jupyterhub_routespec, route_keys)*** + * Delete the key-value pairs associated with a route, within a key-value store transaction (if the route exists). + * Will be called during delete_route. + * The keys associated with a route are: + * jupyterhub_routespec + * target + * route_keys.backend_url_path + * route_keys.frontend_rule_path + * route_keys.frontend_backend_path + * route_keys.backend_weight_path + * Returns: + * result (tuple): + * The transaction status (int, 0: failure, positive: success) + * The transaction response (str) + * ***_kv_get_target(jupyterhub_routespec)*** + * Retrive the target from the key-value store. + * The target is the value associated with `jupyterhub_routespec` key. + * Returns: + * The full URL associated with this route (str) + * ***_kv_get_data(target)*** + * Retrive the data associated with the `target` from the key-value store. + * Returns: + * A JSONable dict that holds extra info about the route (dict) + * ***_kv_get_route_parts(kv_entry)*** + * Retrive all the parts that make up a route (i.e. routespec, target, data) from the key-value store given a `kv_entry`. + * A `kv_entry` is a key-value store entry where the key starts with `proxy.jupyterhub_prefix`. It is expected that only the routespecs + will be prefixed with `proxy.jupyterhub_prefix` when added to the kv store. + * Returns: + * routespec: The normalized route specification passed in to add_route ([host]/path/) + * target: The target host for this route (proto://host) + * data: The arbitrary data dict that was passed in by JupyterHub when adding this route. + * ***_kv_get_jupyterhub_prefixed_entries()*** + * Retrive from the kv store all the key-value pairs where the key starts with `proxy.jupyterhub_prefix`. + * It is expected that only the routespecs will be prefixed with `proxy.jupyterhub_prefix` when added to the kv store. + * Returns: + * routes: A list of key-value store entries where the keys start with `proxy.jupyterhub_prefix`. ## Testing jupyterhub-traefik-proxy diff --git a/jupyterhub_traefik_proxy/kv_proxy.py b/jupyterhub_traefik_proxy/kv_proxy.py index 8a9c355c..cd1ab7e5 100644 --- a/jupyterhub_traefik_proxy/kv_proxy.py +++ b/jupyterhub_traefik_proxy/kv_proxy.py @@ -18,16 +18,11 @@ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. -from concurrent.futures import ThreadPoolExecutor import json import os -from urllib.parse import urlparse -import etcd3 -from tornado.concurrent import run_on_executor -from traitlets import Any, default, Unicode +from traitlets import Any, Unicode -from jupyterhub.utils import maybe_future from . import traefik_utils from jupyterhub_traefik_proxy import TraefikProxy @@ -55,11 +50,11 @@ class TKvProxy(TraefikProxy): kv_url = Unicode(config=True, help="""The URL of the key value store server""") kv_traefik_prefix = Unicode( - config=True, help="""The etcd key prefix for traefik static configuration""" + config=True, help="""The key value store key prefix for traefik static configuration""" ) kv_jupyterhub_prefix = Unicode( - config=True, help="""The etcd key prefix for traefik dynamic configuration""" + config=True, help="""The key value store key prefix for traefik dynamic configuration""" ) def _define_kv_specific_static_config(self): diff --git a/setup.py b/setup.py index 10aa11b4..6996817d 100644 --- a/setup.py +++ b/setup.py @@ -73,6 +73,7 @@ def run(self): cmdclass=cmdclass, entry_points={ "jupyterhub.proxies": [ + "traefik_consul = jupyterhub_consul_proxy:TraefikConsulProxy", "traefik_etcd = jupyterhub_traefik_proxy:TraefikEtcdProxy", "traefik_toml = jupyterhub_traefik_proxy:TraefikTomlProxy", ] diff --git a/tests/config_files/traefik_consul_config.toml b/tests/config_files/traefik_consul_config.toml index 07e1bca5..71901d05 100644 --- a/tests/config_files/traefik_consul_config.toml +++ b/tests/config_files/traefik_consul_config.toml @@ -20,5 +20,5 @@ users = [ "api_admin:$apr1$eS/j3kum$q/X2khsIEG/bBGsteP.x./",] [consul] endpoint = "127.0.0.1:8500" -prefix = "/traefik/" +prefix = "traefik/" watch = true