Skip to content

Commit

Permalink
Merge pull request #1757 from consideRatio/pr/extra-env-with-envvar-o…
Browse files Browse the repository at this point in the history
…bjects

hub.extraEnv / singleuser.extraEnv in dict format to support k8s EnvVar spec
  • Loading branch information
yuvipanda authored Sep 4, 2020
2 parents dc2ebee + 5786cc9 commit 079fe5a
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 30 deletions.
74 changes: 65 additions & 9 deletions jupyterhub/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -308,20 +308,39 @@ properties:
description: |
Extra environment variables that should be set for the hub pod.
Environment variables are usually used to:
- Pass parameters to some custom code in `hub.extraConfig`.
- Configure code running in the hub pod, such as an authenticator or
spawner.
String literals with `$(ENV_VAR_NAME)` will be expanded by Kubelet which
is a part of Kubernetes.
```yaml
hub:
extraEnv:
MY_ENV_VARS_NAME: "my env vars value"
# basic notation (for literal values only)
MY_ENV_VARS_NAME1: "my env var value 1"
# explicit notation (the "name" field takes precedence)
HUB_NAMESPACE:
name: HUB_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
# implicit notation (the "name" field is implied)
PREFIXED_HUB_NAMESPACE:
value: "my-prefix-$(HUB_NAMESPACE)"
SECRET_VALUE:
valueFrom:
secretKeyRef:
name: my-k8s-secret
key: password
```
**NOTE**: We still support this field being a list of
[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#envvar-v1-core)
objects as well.
These are usually used in two circumstances:
- Passing parameters to some custom code specified with `extraConfig`
- Passing parameters to an authenticator or spawner that can be directly customized
by environment variables (rarer)
For more information, see the [Kubernetes EnvVar
specification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#envvar-v1-core).
extraConfig:
type: object
description: |
Expand Down Expand Up @@ -872,6 +891,43 @@ properties:
description: |
Deprecated and no longer does anything. Use the user-scheduler instead
in order to accomplish a good packing of the user pods.
extraEnv:
type: object
description: |
Extra environment variables that should be set for the user pods.
String literals with `$(ENV_VAR_NAME)` will be expanded by Kubelet which
is a part of Kubernetes. Note that the user pods will already have
access to a set of environment variables that you can use, like
`JUPYTERHUB_USER` and `JUPYTERHUB_HOST`. For more information about these
inspect [this source
code](https://github.com/jupyterhub/jupyterhub/blob/cc8e7806530466dce8968567d1bbd2b39a7afa26/jupyterhub/spawner.py#L763).
```yaml
singleuser:
extraEnv:
# basic notation (for literal values only)
MY_ENV_VARS_NAME1: "my env var value 1"
# explicit notation (the "name" field takes precedence)
USER_NAMESPACE:
name: USER_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
# implicit notation (the "name" field is implied)
PREFIXED_USER_NAMESPACE:
value: "my-prefix-$(USER_NAMESPACE)"
SECRET_VALUE:
valueFrom:
secretKeyRef:
name: my-k8s-secret
key: password
```
For more information, see the [Kubernetes EnvVar
specification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#envvar-v1-core).
extraTolerations:
type: list
description: |
Expand Down
39 changes: 39 additions & 0 deletions jupyterhub/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,42 @@ limits:
{{- end }}
{{- end }}
{{- end }}

{{- /*
jupyterhub.extraEnv:
Output YAML formatted EnvVar entries for use in a containers env field.
*/}}
{{- define "jupyterhub.extraEnv" -}}
{{- include "jupyterhub.extraEnv.withTrailingNewLine" . | trimSuffix "\n" }}
{{- end }}

{{- define "jupyterhub.extraEnv.withTrailingNewLine" -}}
{{- if . }}
{{- /* If extraEnv is a list, we inject it as it is. */}}
{{- if eq (typeOf .) "[]interface {}" }}
{{- . | toYaml }}

{{- /* If extraEnv is a map, we differentiate two cases: */}}
{{- else if eq (typeOf .) "map[string]interface {}" }}
{{- range $key, $value := . }}
{{- /*
- If extraEnv.someKey has a map value, then we add the value as a YAML
parsed list element and use the key as the name value unless its
explicitly set.
*/}}
{{- if eq (typeOf $value) "map[string]interface {}" }}
{{- merge (dict) $value (dict "name" $key) | list | toYaml | println }}
{{- /*
- If extraEnv.someKey has a string value, then we use the key as the
environment variable name for the value.
*/}}
{{- else if eq (typeOf $value) "string" -}}
- name: {{ $key | quote }}
value: {{ $value | quote | println }}
{{- else }}
{{- printf "?.extraEnv.%s had an unexpected type (%s)" $key (typeOf $value) | fail }}
{{- end }}
{{- end }} {{- /* end of range */}}
{{- end }}
{{- end }} {{- /* end of: if . */}}
{{- end }} {{- /* end of definition */}}
14 changes: 1 addition & 13 deletions jupyterhub/templates/hub/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -205,19 +205,7 @@ spec:
key: hub.db.password
{{- end }}
{{- end }}
{{- if .Values.hub.extraEnv }}
{{- $extraEnvType := typeOf .Values.hub.extraEnv }}
{{- /* If we have a list, embed that here directly. This allows for complex configuration from configmap, downward API, etc. */}}
{{- if eq $extraEnvType "[]interface {}" }}
{{- .Values.hub.extraEnv | toYaml | trimSuffix "\n" | nindent 12 }}
{{- else if eq $extraEnvType "map[string]interface {}" }}
{{- /* If we have a map, treat those as key-value pairs. */}}
{{- range $key, $value := .Values.hub.extraEnv }}
- name: {{ $key | quote }}
value: {{ $value | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- include "jupyterhub.extraEnv" .Values.hub.extraEnv | nindent 12 }}
ports:
- name: http
containerPort: 8081
Expand Down
6 changes: 5 additions & 1 deletion tools/templates/lint-and-validate-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ hub:
extraConfigMap:
mock.entry: mock-config-map-entry
extraEnv:
MOCK_HUB_ENV: mock
IGNORED_KEY_NAME:
name: MOCK_ENV_VAR_NAME1
value: MOCK_ENV_VAR_VALUE1
MOCK_ENV_VAR_NAME2:
value: MOCK_ENV_VAR_VALUE2
extraContainers: []
extraVolumes: []
extraVolumeMounts: []
Expand Down
20 changes: 13 additions & 7 deletions tools/templates/lint-and-validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@
any cluster interaction. For this script to function, you must install yamllint
and kubeval.
- https://github.com/adrienverge/yamllint
USAGE:
pip install yamllint
tools/templates/lint-and-validate.py
- https://github.com/instrumenta/kubeval
DEPENDENCIES:
LATEST=curl --silent "https://api.github.com/repos/instrumenta/kubeval/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'
wget https://github.com/instrumenta/kubeval/releases/download/$LATEST/kubeval-linux-amd64.tar.gz
tar xf kubeval-darwin-amd64.tar.gz
mv kubeval /usr/local/bin
yamllint: https://github.com/adrienverge/yamllint
pip install yamllint
kubeval: https://github.com/instrumenta/kubeval
LATEST=$(curl --silent "https://api.github.com/repos/instrumenta/kubeval/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
wget https://github.com/instrumenta/kubeval/releases/download/$LATEST/kubeval-linux-amd64.tar.gz
tar xf kubeval-linux-amd64.tar.gz
sudo mv kubeval /usr/local/bin
"""

import os
Expand Down

0 comments on commit 079fe5a

Please sign in to comment.