Skip to content

Commit 4f61a55

Browse files
committed
solved merge conflicts
2 parents d80729a + ee5ec2e commit 4f61a55

47 files changed

Lines changed: 990 additions & 67 deletions

Some content is hidden

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

applications/jupyterhub/Dockerfile

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1+
ARG CLOUDHARNESS_BASE
2+
FROM $CLOUDHARNESS_BASE as base
3+
14
FROM jupyterhub/k8s-hub:0.9.0
25
USER root
36

4-
# COPY deploy/resources/hub/* /etc/jupyterhub/
5-
# COPY src/jupyterhub/jupyterhub/handlers/* /usr/local/lib/python3.6/dist-packages/jupyterhub/handlers/
6-
# COPY ./src/kubespawner /usr/local/lib/python3.6/dist-packages/
7+
COPY --from=base /libraries/cloudharness-common /libraries/cloudharness-common
8+
COPY --from=base /libraries/client/cloudharness_cli /libraries/client/cloudharness_cli
9+
10+
RUN pip install -e /libraries/cloudharness-common
11+
RUN pip install -e /libraries/client/cloudharness_cli
12+
713
COPY src src
814
RUN pip install ./src/harness_jupyter
915
RUN pip install ./src/chauthenticator
16+
1017
RUN chmod 777 /usr/local/lib/python3.6/dist-packages/ -R
1118
USER jovyan
12-
13-
14-
# CMD ["jupyterhub", "--config", "/srv/jupyterhub_config.py"]

applications/jupyterhub/deploy/resources/hub/jupyterhub_config.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -384,18 +384,27 @@ def camelCaseify(s):
384384
auth_config = c[auth_class_name]
385385
auth_config.update(get_config('auth.custom.config') or {})
386386
elif auth_type == 'keycloak':
387+
from cloudharness.applications import get_configuration
388+
from cloudharness.utils.config import CloudharnessConfig
387389
from oauthenticator.generic import GenericOAuthenticator
388390

391+
accounts_app = get_configuration('accounts')
392+
393+
accounts_url = accounts_app.get_public_address()
394+
client_id = accounts_app.conf.webclient.id
395+
client_secret = accounts_app.conf.webclient.secret
396+
realm = CloudharnessConfig.get_namespace()
397+
389398
c.JupyterHub.authenticator_class = GenericOAuthenticator
390-
c.OAuthenticator.oauth_callback_url = "http://minianhub.mnp.local/hub/oauth_callback"
391-
c.OAuthenticator.client_id = "web-client"
392-
c.OAuthenticator.client_secret = "452952ae-922c-4766-b912-7b106271e34b"
399+
c.Authenticator.auto_login = True
400+
c.OAuthenticator.client_id = client_id
401+
c.OAuthenticator.client_secret = client_secret
393402

394-
c.GenericOAuthenticator.login_service = "keycloak"
403+
c.GenericOAuthenticator.login_service = "CH"
395404
c.GenericOAuthenticator.username_key = "email"
396-
c.GenericOAuthenticator.authorize_url = "http://accounts.mnp.local/auth/realms/mnp/protocol/openid-connect/auth"
397-
c.GenericOAuthenticator.token_url = "http://accounts.mnp.local/auth/realms/mnp/protocol/openid-connect/token"
398-
c.GenericOAuthenticator.userdata_url = "http://accounts.mnp.local/auth/realms/mnp/protocol/openid-connect/userinfo"
405+
c.GenericOAuthenticator.authorize_url = f"{accounts_url}/auth/realms/{realm}/protocol/openid-connect/auth"
406+
c.GenericOAuthenticator.token_url = f"{accounts_url}/auth/realms/{realm}/protocol/openid-connect/token"
407+
c.GenericOAuthenticator.userdata_url = f"{accounts_url}/auth/realms/{realm}/protocol/openid-connect/userinfo"
399408
c.GenericOAuthenticator.userdata_params = {'state': 'state'}
400409
else:
401410
raise ValueError("Unhandled auth type: %r" % auth_type)
@@ -532,4 +541,5 @@ def camelCaseify(s):
532541
exec(config_py)
533542

534543
c.apps = get_config('apps')
535-
c.registry = get_config('registry')
544+
c.registry = get_config('registry')
545+
c.domain = get_config('root.domain')

applications/jupyterhub/deploy/resources/hub/z2jh.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def _load_config():
3434
with open(path) as f:
3535
values = yaml.safe_load(f)
3636
cfg = _merge_dictionaries(cfg, values)
37+
cfg['root'] = cfg
3738
return cfg
3839

3940

@@ -44,6 +45,7 @@ def _merge_dictionaries(a, b):
4445
"""
4546
merged = a.copy()
4647
for key in b:
48+
4749
if key in a:
4850
if isinstance(a[key], Mapping) and isinstance(b[key], Mapping):
4951
merged[key] = _merge_dictionaries(a[key], b[key])

applications/jupyterhub/deploy/values.yaml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ harness:
66
name: proxy-public
77
deployment:
88
auto: false
9+
dependencies:
10+
build:
11+
- cloudharness-base
912
custom: {}
1013
hub:
1114
allowNamedServers: true
@@ -203,8 +206,8 @@ singleuser:
203206
type: dynamic
204207
capacity: 2Mi
205208
dynamic:
206-
pvcNameTemplate: jupyter-{userid}
207-
volumeNameTemplate: jupyter-{userid}
209+
pvcNameTemplate: jupyter-{username}
210+
volumeNameTemplate: jupyter-{username}
208211
homeMountPath: /home/workspace
209212
extraLabels: {}
210213
image:
@@ -223,7 +226,7 @@ singleuser:
223226
extraResource:
224227
limits: {}
225228
guarantees: {}
226-
cmd: jupyterhub-singleuser
229+
cmd: /usr/local/bin/start-singleuser.sh
227230
defaultUrl: null
228231
scheduling:
229232
userScheduler:
@@ -260,7 +263,7 @@ prePuller:
260263
name: jupyterhub/k8s-image-awaiter
261264
tag: 0.9-b51ffeb
262265
continuous:
263-
enabled: false
266+
enabled: true
264267
extraImages: {}
265268
pause:
266269
image:

applications/jupyterhub/src/harness_jupyter/harness_jupyter/jupyterhub.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import imp
12
import logging
23
import sys
3-
import imp
4+
import urllib.parse
45

56
from kubespawner.spawner import KubeSpawner
67
handler = logging.StreamHandler(sys.stdout)
@@ -17,15 +18,46 @@ def spawner_pod_manifest(self: KubeSpawner):
1718

1819
return KubeSpawner.get_pod_manifest_base(self)
1920

21+
def affinity_spec(key, value):
22+
return {
23+
24+
'labelSelector':
25+
{
26+
'matchExpressions': [
27+
{
28+
'key': str(key),
29+
'operator': 'In',
30+
'values': [str(value)]
31+
},
32+
]
33+
},
34+
'topologyKey': 'kubernetes.io/hostname'
35+
}
36+
37+
def set_user_volume_affinity(self: KubeSpawner):
38+
# Add labels to use for affinity
39+
labels = {
40+
'user': urllib.parse.quote(self.user.name, safe='').replace('%', ''),
41+
}
42+
43+
self.common_labels = labels
44+
self.extra_labels = labels
45+
46+
for key, value in labels.items():
47+
self.pod_affinity_required.append(affinity_spec(key, value))
48+
2049
def change_pod_manifest(self: KubeSpawner):
2150

2251
try:
23-
subdomain = self.handler.request.host.split('.')[0]
52+
53+
54+
55+
56+
subdomain = self.handler.request.host.split(str(self.config['domain']))[0][0:-1]
2457
app_config = self.config['apps']
2558
registry = self.config['registry']
2659
for app in app_config.values():
2760
if 'harness' in app:
28-
2961
harness = app['harness']
3062
if 'jupyterhub' in harness and harness['jupyterhub']\
3163
and 'subdomain' in harness and harness['subdomain'] == subdomain:
@@ -36,6 +68,16 @@ def change_pod_manifest(self: KubeSpawner):
3668
if 'args' in harness['jupyterhub']:
3769
self.args = harness['jupyterhub']['args']
3870

71+
if harness['jupyterhub'].get('mountUserVolume', True):
72+
set_user_volume_affinity(self)
73+
else:
74+
self.volume_mounts = []
75+
self.volumes = []
76+
77+
if 'spawnerExtraConfig' in harness['jupyterhub']:
78+
for k, v in harness['jupyterhub']['spawnerExtraConfig'].items():
79+
setattr(self, k, v)
80+
3981
# check if there is an applicationHook defined in the values.yaml
4082
# if so then execute the applicationHook function with "self" as parameter
4183
#
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
harness:
2+
subdomain: notifications
3+
secured: false
4+
service:
5+
auto: false
6+
deployment:
7+
name: notifications
8+
auto: true
9+
resources:
10+
requests:
11+
memory: 64Mi
12+
cpu: 25m
13+
limits:
14+
memory: 256Mi
15+
cpu: 100m
16+
dependencies:
17+
build:
18+
- cloudharness-base
19+
secrets:
20+
email-user:
21+
email-password:
22+
events: # events the notification service is listening to
23+
cdc: # change data capture events, see https://devshawn.com/blog/apache-kafka-topic-naming-conventions/
24+
# - app: notifications
25+
# types:
26+
# - name: TypeA
27+
# events:
28+
# - create
29+
# - name: TypeB
30+
# events:
31+
# - create
32+
33+
notification:
34+
channels:
35+
admins:
36+
adapter: email
37+
backends:
38+
- email
39+
templateFolder: html
40+
from: info@example.com
41+
to:
42+
- info@example.com
43+
log:
44+
adapter: email
45+
backends:
46+
- console
47+
templateFolder: text
48+
from: info@example.com
49+
to:
50+
- info@example.com
51+
operations:
52+
create:
53+
subject: New {{ message_type }} - {{ domain }}
54+
template: model-instance-create
55+
channels:
56+
- admins
57+
update:
58+
subject: Update {{ message_type }} - {{ domain }}
59+
template: model-instance-update
60+
channels:
61+
- admins
62+
delete:
63+
subject: Delete {{ message_type }} - {{ domain }}
64+
template: model-instance-delete
65+
channels:
66+
- admins
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
.travis.yaml
2+
.openapi-generator-ignore
3+
README.md
4+
tox.ini
5+
git_push.sh
6+
test-requirements.txt
7+
8+
# Byte-compiled / optimized / DLL files
9+
__pycache__/
10+
*.py[cod]
11+
*$py.class
12+
13+
# C extensions
14+
*.so
15+
16+
# Distribution / packaging
17+
.Python
18+
env/
19+
build/
20+
develop-eggs/
21+
dist/
22+
downloads/
23+
eggs/
24+
.eggs/
25+
lib/
26+
lib64/
27+
parts/
28+
sdist/
29+
var/
30+
*.egg-info/
31+
.installed.cfg
32+
*.egg
33+
34+
# PyInstaller
35+
# Usually these files are written by a python script from a template
36+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
37+
*.manifest
38+
*.spec
39+
40+
# Installer logs
41+
pip-log.txt
42+
pip-delete-this-directory.txt
43+
44+
# Unit test / coverage reports
45+
htmlcov/
46+
.tox/
47+
.coverage
48+
.coverage.*
49+
.cache
50+
nosetests.xml
51+
coverage.xml
52+
*,cover
53+
.hypothesis/
54+
venv/
55+
.python-version
56+
57+
# Translations
58+
*.mo
59+
*.pot
60+
61+
# Django stuff:
62+
*.log
63+
64+
# Sphinx documentation
65+
docs/_build/
66+
67+
# PyBuilder
68+
target/
69+
70+
#Ipython Notebook
71+
.ipynb_checkpoints

0 commit comments

Comments
 (0)