Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hub.extraEnv / singleuser.extraEnv in dict format to support k8s EnvVar spec #1757

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
consideRatio marked this conversation as resolved.
Show resolved Hide resolved
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
consideRatio marked this conversation as resolved.
Show resolved Hide resolved
```

**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
consideRatio marked this conversation as resolved.
Show resolved Hide resolved
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
consideRatio marked this conversation as resolved.
Show resolved Hide resolved
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