Skip to content

Commit c46a2bb

Browse files
committed
Merge remote-tracking branch 'origin/main' into rel-v2
# Conflicts: # docs/source/changelog.md
2 parents 168d247 + bec86ce commit c46a2bb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+77966
-5644
lines changed

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# dependabot.yaml reference: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
2+
version: 2
3+
updates:
4+
# Maintain dependencies in our GitHub Workflows
5+
- package-ecosystem: github-actions
6+
directory: "/"
7+
schedule:
8+
interval: monthly
9+
labels:
10+
- maintenance

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ jobs:
2020
runs-on: ubuntu-20.04
2121

2222
steps:
23-
- uses: actions/checkout@v2
23+
- uses: actions/checkout@v3
2424
- name: Set up Python
25-
uses: actions/setup-python@v2
25+
uses: actions/setup-python@v4
2626
with:
2727
python-version: "3.10"
2828
- name: Install build package
@@ -35,7 +35,7 @@ jobs:
3535
python -m build --sdist --wheel .
3636
ls -l dist
3737
- name: Publish to PyPI
38-
uses: pypa/gh-action-pypi-publish@v1.4.1
38+
uses: pypa/gh-action-pypi-publish@v1.7.1
3939
if: startsWith(github.ref, 'refs/tags/')
4040
with:
4141
user: __token__

.github/workflows/test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,18 @@ jobs:
5454
run: |
5555
echo "PATH=$PWD/bin:$PATH" >> $GITHUB_ENV
5656
57-
- uses: actions/checkout@v2
58-
# NOTE: actions/setup-python@v2 make use of a cache within the GitHub base
57+
- uses: actions/checkout@v3
58+
# NOTE: actions/setup-python@v4 make use of a cache within the GitHub base
5959
# environment and setup in a fraction of a second.
6060
- name: Install Python ${{ matrix.python }}
61-
uses: actions/setup-python@v2
61+
uses: actions/setup-python@v4
6262
with:
6363
python-version: ${{ matrix.python }}
6464

6565
- name: Install Python dependencies
6666
run: |
6767
pip install --upgrade setuptools pip
68-
pip install -r dev-requirements.txt --upgrade .
68+
pip install -r dev-requirements.txt -e .
6969
python -m jupyterhub_traefik_proxy.install --output=./bin
7070
7171
pip freeze

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# our own .gitignore
22

3-
/dependencies
3+
dependencies
44
*.etcd
5-
/traefik.toml
5+
traefik.toml
6+
7+
.DS_Store
68

79
## Below: imported standard Python gitignore
810

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# JupyterHub Traefik Proxy
22

33
[![Documentation build status](https://img.shields.io/readthedocs/jupyterhub-traefik-proxy?logo=read-the-docs)](https://jupyterhub-traefik-proxy.readthedocs.org/en/latest/)
4-
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/jupyterhub/traefik-proxy/Run%20tests?logo=github)](https://github.com/jupyterhub/traefik-proxy/actions)
5-
[![CircleCI build status](https://img.shields.io/circleci/build/github/jupyterhub/jupyterhub?logo=circleci)](https://circleci.com/gh/jupyterhub/jupyterhub)
4+
[![GitHub Workflow Status](https://github.com/jupyterhub/traefik-proxy/actions/workflows/test.yml/badge.svg)](https://github.com/jupyterhub/traefik-proxy/actions/workflows/test.yml)
65
[![Latest PyPI version](https://img.shields.io/pypi/v/jupyterhub-traefik-proxy?logo=pypi)](https://pypi.python.org/pypi/jupyterhub-traefik-proxy)
76
[![GitHub](https://img.shields.io/badge/issue_tracking-github-blue?logo=github)](https://github.com/jupyterhub/traefik-proxy/issues)
87
[![Discourse](https://img.shields.io/badge/help_forum-discourse-blue?logo=discourse)](https://discourse.jupyter.org/c/jupyterhub)
Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,62 @@
1-
=========
2-
Proxy API
3-
=========
1+
# Proxy API
42

5-
Module: :mod:`jupyterhub_traefik_proxy`
6-
=======================================
3+
## Module: {mod}`jupyterhub_traefik_proxy`
74

5+
```{eval-rst}
86
.. automodule:: jupyterhub_traefik_proxy
7+
```
98

9+
```{eval-rst}
1010
.. currentmodule:: jupyterhub_traefik_proxy.proxy
11+
```
1112

12-
:class:`TraefikProxy`
13-
---------------------
13+
### {class}`TraefikProxy`
1414

15+
```{eval-rst}
1516
.. autoconfigurable:: TraefikProxy
1617
:members:
18+
```
1719

20+
```{eval-rst}
1821
.. currentmodule:: jupyterhub_traefik_proxy.fileprovider
22+
```
1923

20-
:class:`TraefikFileProviderProxy`
21-
---------------------------------
24+
### {class}`TraefikFileProviderProxy`
2225

26+
```{eval-rst}
2327
.. autoconfigurable:: TraefikFileProviderProxy
2428
:members:
29+
```
2530

31+
```{eval-rst}
2632
.. currentmodule:: jupyterhub_traefik_proxy.kv_proxy
33+
```
2734

28-
:class:`TKvProxy`
29-
-----------------
35+
### {class}`TKvProxy`
3036

37+
```{eval-rst}
3138
.. autoconfigurable:: TKvProxy
3239
:members:
40+
```
3341

42+
```{eval-rst}
3443
.. currentmodule:: jupyterhub_traefik_proxy.etcd
44+
```
3545

36-
:class:`TraefikEtcdProxy`
37-
-------------------------
46+
### {class}`TraefikEtcdProxy`
3847

48+
```{eval-rst}
3949
.. autoconfigurable:: TraefikEtcdProxy
4050
:members:
51+
```
4152

53+
```{eval-rst}
4254
.. currentmodule:: jupyterhub_traefik_proxy.consul
55+
```
4356

44-
:class:`TraefikConsulProxy`
45-
---------------------------
57+
### {class}`TraefikConsulProxy`
4658

59+
```{eval-rst}
4760
.. autoconfigurable:: TraefikConsulProxy
4861
:members:
62+
```

docs/source/changelog.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,23 +76,23 @@ See [our definition of contributors](https://github-activity.readthedocs.io/en/l
7676

7777
@alexleach ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3Aalexleach+updated%3A2021-10-18..2023-03-10&type=Issues)) | @consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3AconsideRatio+updated%3A2021-10-18..2023-03-10&type=Issues)) | @devnull-mr ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3Adevnull-mr+updated%3A2021-10-18..2023-03-10&type=Issues)) | @dolfinus ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3Adolfinus+updated%3A2021-10-18..2023-03-10&type=Issues)) | @GeorgianaElena ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3AGeorgianaElena+updated%3A2021-10-18..2023-03-10&type=Issues)) | @manics ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3Amanics+updated%3A2021-10-18..2023-03-10&type=Issues)) | @maulikjs ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3Amaulikjs+updated%3A2021-10-18..2023-03-10&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3Aminrk+updated%3A2021-10-18..2023-03-10&type=Issues)) | @pre-commit-ci ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3Apre-commit-ci+updated%3A2021-10-18..2023-03-10&type=Issues)) | @twalcari ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Ftraefik-proxy+involves%3Atwalcari+updated%3A2021-10-18..2023-03-10&type=Issues))
7878

79-
### [0.3.0](https://github.com/jupyterhub/traefik-proxy/compare/0.2.0...0.3.0) 2021-10-18
79+
## [0.3.0](https://github.com/jupyterhub/traefik-proxy/compare/0.2.0...0.3.0) 2021-10-18
8080

81-
#### Enhancements made
81+
### Enhancements made
8282

8383
- Support ARM in binary package installs [#129](https://github.com/jupyterhub/traefik-proxy/pull/129) ([@yuvipanda](https://github.com/yuvipanda))
8484

85-
#### Bugs fixed
85+
### Bugs fixed
8686

8787
- Fix handling default server routes in TraefikTomlProxy [#131](https://github.com/jupyterhub/traefik-proxy/pull/131) ([@dolfinus](https://github.com/dolfinus))
8888
- Make etcd3 & python-consul2 soft dependencies [#127](https://github.com/jupyterhub/traefik-proxy/pull/127) ([@yuvipanda](https://github.com/yuvipanda))
8989

90-
#### Continuous integration
90+
### Continuous integration
9191

9292
- ci: don't run tests if docs change [#139](https://github.com/jupyterhub/traefik-proxy/pull/139) ([@consideRatio](https://github.com/consideRatio))
9393
- ci/docs: install autodocs-traits as a PyPI package & pin sphinx [#138](https://github.com/jupyterhub/traefik-proxy/pull/138) ([@consideRatio](https://github.com/consideRatio))
9494

95-
#### Contributors to this release
95+
### Contributors to this release
9696

9797
([GitHub contributors page for this release](https://github.com/jupyterhub/traefik-proxy/graphs/contributors?from=2021-02-24&to=2021-10-18&type=c))
9898

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
#
7474
# This is also used if you do content translation via gettext catalogs.
7575
# Usually you set "language" from the command line for these cases.
76-
language = None
76+
language = "en"
7777

7878
# List of patterns, relative to source directory, that match files and
7979
# directories to ignore when looking for source files.

docs/source/consul.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Using TraefikConsulProxy
22

3+
```{warning}
4+
While it works today (2023), there does not appear to be a maintained Python client for the consul API.
5+
As such, using jupyterhub-traefik-proxy with consul is deprecated in jupyterhub-traefik-proxy 1.0.
6+
You can use etcd instead to achieve the same functionality (and slightly better performance).
7+
```
8+
39
[Consul](https://www.consul.io/)
410
is a distributed key-value store.
511
This and TraefikEtcdProxy is the choice to use when using jupyterhub-traefik-proxy
@@ -13,7 +19,7 @@ e.g. with multiple traefik-proxy instances.
1319
5. Install **traefik**
1420
6. Install **consul**
1521

16-
- You can find the full installation guide and examples in the [Introduction section](install.html#traefik-proxy-installation)
22+
- You can find the full installation guide and examples in the [installation section](install)
1723

1824
## How-To enable TraefikConsulProxy
1925

docs/source/details.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Implementation details
2+
3+
## Traefik API
4+
5+
traefik-proxy uses the [Traefik API](https://doc.traefik.io/traefik/operations/api/) to monitor routes and configurations.
6+
7+
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.
8+
9+
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.:
10+
11+
```
12+
c.TraefikFileProviderProxy.traefik_api_url = "http://127.0.0.1:8099"
13+
c.TraefikFileProviderProxy.traefik_api_password = "admin"
14+
c.TraefikFileProviderProxy.traefik_api_username = "admin"
15+
```
16+
17+
Check out TraefikProxy's [API Reference](TraefikProxy) for more configuration options.
18+
19+
## Class structure
20+
21+
A JupyterHub Proxy implementation must implement these methods:
22+
23+
- `start` / `stop` (starting and stopping the proxy)
24+
- `add_route`
25+
- `delete_route`
26+
- `get_all_routes`
27+
- `get_route` (a default implementation is provided by the base class, based on get_all_routes)
28+
29+
Additionally, for traefik we need to set up the separate "static config" (API access and where routes will be stored) and "dynamic config" (the routing table itself, which changes as servers start and stop).
30+
Where and how dynamic_config is stored is the ~only difference between TraefikProxy subclasses.
31+
32+
Setting up traefik configuration is in these methods:
33+
34+
- `_setup_traefik_static_config` - must be extended by subclasses to add any provider-specific configuration to `self.static_config`
35+
- `_setup_traefik_dynamic_config` - usually not modified
36+
37+
TraefikProxy is organized into three levels:
38+
39+
First, is [](TraefikProxy). This class is responsible for everything traefik-specific.
40+
It implements talking to the traefik API, and computing _what_ dynamic configuration is needed for each step.
41+
This base class provides implementations of `start`, `stop`, `add_route`, `delete_route`, and `get_all_routes`.
42+
43+
TraefikProxy subclasses must implement _how_ dynamic config is stored, and set the appropriate static config to tell traefik how to load the dynamic config.
44+
Specifically, the generic methods:
45+
46+
- `_setup_traefik_static_config` should extend `self.static_config` to configure the traefik [configuration discovery provider](https://doc.traefik.io/traefik/providers/overview/)
47+
- `_apply_dynamic_config` stores a given dynamic config dictionary in the appropriate config store
48+
- `_delete_dynamic_config` removes keys from the dynamic config store
49+
- `_get_jupyterhub_dynamic_config` reads the whole jupyterhub part (not read by traefik itself)
50+
51+
We have two classes at this level:
52+
53+
- TraefikFileProviderProxy, which stores dynamic config in a toml or yaml file, and
54+
- TKvProxy - another base class, which implements the above, based on a generic notion of a key-value store
55+
56+
TKvProxy is an adapter layer, implementing all of the above methods, based on a few basic actions on key-value stores:
57+
58+
- `_kv_atomic_set` should take a _flat dictionary_ of key _paths_ and string values, and store them.
59+
- `_kv_atomic_delete` should delete a number of keys in a single transaction
60+
- `_kv_get_tree` should recursively read everything in the key-value store under a prefix (returning the _flattened_ dictionary)
61+
62+
TKvProxy is responsible for translating between key-value-friendly "flat" dictionaries and the 'true' nested dictionary format of the configuration (i.e. the nested dictionary `{"a": {"b": 5}}` will be flattened to `{"a/b": "5"}`).
63+
64+
Finally, we have our specific key-value store implementations: [](TraefikEtcdProxy) and [](TraefikConsulProxy).
65+
These classes only need to implement:
66+
67+
1. configuration necessary to connect to the key-value provider
68+
2. `_setup_traefik_static_config` to tell traefik how to talk to the same key-value provider
69+
3. the above three `_kv_` methods for reading, writing, and deleting keys
70+
71+
## Testing jupyterhub-traefik-proxy
72+
73+
You can then run the all the test suite from the _traefik-proxy_ directory with:
74+
75+
```
76+
$ pytest -v ./tests
77+
```
78+
79+
Or you can run a specific test with:
80+
81+
```
82+
$ pytest -v ./tests/<test-file-name>
83+
```

0 commit comments

Comments
 (0)