diff --git a/charts/jupyterhub/README.md b/charts/jupyterhub/README.md index 72489628b..09dd38c1e 100644 --- a/charts/jupyterhub/README.md +++ b/charts/jupyterhub/README.md @@ -9,6 +9,10 @@ user pods, optional user PVCs, Gateway API, Ingress, dual-stack Service, NetworkPolicy, ExternalSecret, ServiceMonitor, PodDisruptionBudget, schema, and Helm tests. +NetworkPolicy supports `networkPolicy.extraEgress` for appending Hub egress +rules without replacing the default DNS, HTTPS, same-namespace, and +`networkPolicy.hub.egress` rules. + ## Install ```bash diff --git a/charts/jupyterhub/templates/NOTES.txt b/charts/jupyterhub/templates/NOTES.txt index e3f6f5122..fea7d72a0 100644 --- a/charts/jupyterhub/templates/NOTES.txt +++ b/charts/jupyterhub/templates/NOTES.txt @@ -1,16 +1,16 @@ {{/* SPDX-License-Identifier: Apache-2.0 */}} JupyterHub deployed successfully! -ACCESS: +1. Access kubectl port-forward svc/{{ include "jupyterhub.proxyName" . }} -n {{ .Release.Namespace }} 8080:{{ .Values.service.port }} Open: http://localhost:8080{{ .Values.hub.baseUrl }} -SERVICES: +2. Services Proxy: {{ include "jupyterhub.proxyName" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.port }} Proxy API: {{ include "jupyterhub.proxyApiName" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.proxyApiPort }} Hub: {{ include "jupyterhub.hubName" . }}.{{ .Release.Namespace }}.svc.cluster.local:8081 -AUTHENTICATION: +3. Authentication Auth type: {{ .Values.auth.type }} {{- if and (eq .Values.auth.type "dummy") (not .Values.auth.dummyPassword) }} Dummy password: empty @@ -18,7 +18,7 @@ AUTHENTICATION: Dummy password: configured {{- end }} -PERSISTENCE: +4. Persistence {{- if .Values.hub.persistence.enabled }} Hub PVC: {{ include "jupyterhub.hubDataClaimName" . }} {{- else }} @@ -30,7 +30,7 @@ PERSISTENCE: Single-user PVCs: disabled {{- end }} -NETWORKING: +5. Networking {{- if .Values.ingress.enabled }} Ingress: enabled Class: {{ .Values.ingress.ingressClassName | default "(cluster default)" }} @@ -43,8 +43,9 @@ NETWORKING: {{- else }} Gateway API: disabled {{- end }} + NetworkPolicy: {{ ternary "enabled" "disabled" .Values.networkPolicy.enabled }} -OPERATIONS: +6. Operations Run Helm tests: helm test {{ .Release.Name }} -n {{ .Release.Namespace }} @@ -52,12 +53,12 @@ OPERATIONS: kubectl get pods -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} kubectl logs -n {{ .Release.Namespace }} deploy/{{ include "jupyterhub.hubName" . }} -SECURITY REMINDERS: +7. Security Reminders 1. Do not expose DummyAuthenticator publicly without auth.dummyPassword. 2. Use a real authenticator through hub.extraConfig for production. 3. Keep the proxy token in an existing Secret or ExternalSecret for GitOps. -DOCUMENTATION: +8. Documentation Chart: https://helmforge.dev/docs/charts/jupyterhub Source: https://github.com/helmforgedev/charts/tree/main/charts/jupyterhub JupyterHub: https://jupyter.org/hub diff --git a/charts/jupyterhub/templates/networkpolicy.yaml b/charts/jupyterhub/templates/networkpolicy.yaml index 159e5a53f..264d71af8 100644 --- a/charts/jupyterhub/templates/networkpolicy.yaml +++ b/charts/jupyterhub/templates/networkpolicy.yaml @@ -85,7 +85,7 @@ spec: port: 443 - to: - podSelector: {} - {{- with .Values.networkPolicy.hub.egress }} + {{- with (concat .Values.networkPolicy.hub.egress .Values.networkPolicy.extraEgress) }} {{- toYaml . | nindent 4 }} {{- end }} --- diff --git a/charts/jupyterhub/tests/networkpolicy-extra-egress-values.yaml b/charts/jupyterhub/tests/networkpolicy-extra-egress-values.yaml new file mode 100644 index 000000000..0e40e7223 --- /dev/null +++ b/charts/jupyterhub/tests/networkpolicy-extra-egress-values.yaml @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +networkPolicy: + enabled: true + extraEgress: + - to: + - ipBlock: + cidr: 10.60.0.0/16 + ports: + - protocol: TCP + port: 443 diff --git a/charts/jupyterhub/tests/networkpolicy_test.yaml b/charts/jupyterhub/tests/networkpolicy_test.yaml index d9e4023ee..aaf30bb9f 100644 --- a/charts/jupyterhub/tests/networkpolicy_test.yaml +++ b/charts/jupyterhub/tests/networkpolicy_test.yaml @@ -158,3 +158,18 @@ tests: - protocol: TCP port: 5432 documentIndex: 1 + + - it: should append extra Hub egress rules + values: + - networkpolicy-extra-egress-values.yaml + asserts: + - contains: + path: spec.egress + content: + to: + - ipBlock: + cidr: 10.60.0.0/16 + ports: + - protocol: TCP + port: 443 + documentIndex: 1 diff --git a/charts/jupyterhub/values.schema.json b/charts/jupyterhub/values.schema.json index e77f4b0af..32ae772d4 100644 --- a/charts/jupyterhub/values.schema.json +++ b/charts/jupyterhub/values.schema.json @@ -77,7 +77,15 @@ } }, "gateway": { "type": "object", "additionalProperties": true }, - "networkPolicy": { "type": "object", "additionalProperties": true }, + "networkPolicy": { + "type": "object", + "additionalProperties": true, + "properties": { + "enabled": { "type": "boolean" }, + "hub": { "type": "object", "additionalProperties": true }, + "extraEgress": { "type": "array", "items": { "type": "object" } } + } + }, "serviceAccount": { "type": "object", "additionalProperties": true }, "rbac": { "type": "object", "additionalProperties": true }, "metrics": { diff --git a/charts/jupyterhub/values.yaml b/charts/jupyterhub/values.yaml index 0d9b9539a..a6b0d5905 100644 --- a/charts/jupyterhub/values.yaml +++ b/charts/jupyterhub/values.yaml @@ -186,6 +186,8 @@ networkPolicy: hub: # -- Additional Hub egress rules appended after the default DNS, HTTPS, and same-namespace rules. Use this for external PostgreSQL/MySQL databases or private endpoints. egress: [] + # -- Additional Hub egress rules appended after networkPolicy.hub.egress. + extraEgress: [] serviceAccount: # -- Create a dedicated ServiceAccount.